1 | """Provide access to Python's configuration information. The specific
|
---|
2 | configuration variables available depend heavily on the platform and
|
---|
3 | configuration. The values may be retrieved using
|
---|
4 | get_config_var(name), and the list of variables is available via
|
---|
5 | get_config_vars().keys(). Additional convenience functions are also
|
---|
6 | available.
|
---|
7 |
|
---|
8 | Written by: Fred L. Drake, Jr.
|
---|
9 | Email: <fdrake@acm.org>
|
---|
10 | """
|
---|
11 |
|
---|
12 | __revision__ = "$Id: sysconfig.py 76739 2009-12-10 10:29:05Z ronald.oussoren $"
|
---|
13 |
|
---|
14 | import os
|
---|
15 | import re
|
---|
16 | import string
|
---|
17 | import sys
|
---|
18 |
|
---|
19 | from distutils.errors import DistutilsPlatformError
|
---|
20 |
|
---|
21 | # These are needed in a couple of spots, so just compute them once.
|
---|
22 | PREFIX = os.path.normpath(sys.prefix)
|
---|
23 | EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
|
---|
24 |
|
---|
25 | # Path to the base directory of the project. On Windows the binary may
|
---|
26 | # live in project/PCBuild9. If we're dealing with an x64 Windows build,
|
---|
27 | # it'll live in project/PCbuild/amd64.
|
---|
28 | project_base = os.path.dirname(os.path.abspath(sys.executable))
|
---|
29 | if os.name == "nt" and "pcbuild" in project_base[-8:].lower():
|
---|
30 | project_base = os.path.abspath(os.path.join(project_base, os.path.pardir))
|
---|
31 | # PC/VS7.1
|
---|
32 | if os.name == "nt" and "\\pc\\v" in project_base[-10:].lower():
|
---|
33 | project_base = os.path.abspath(os.path.join(project_base, os.path.pardir,
|
---|
34 | os.path.pardir))
|
---|
35 | # PC/AMD64
|
---|
36 | if os.name == "nt" and "\\pcbuild\\amd64" in project_base[-14:].lower():
|
---|
37 | project_base = os.path.abspath(os.path.join(project_base, os.path.pardir,
|
---|
38 | os.path.pardir))
|
---|
39 |
|
---|
40 | # python_build: (Boolean) if true, we're either building Python or
|
---|
41 | # building an extension with an un-installed Python, so we use
|
---|
42 | # different (hard-wired) directories.
|
---|
43 | # Setup.local is available for Makefile builds including VPATH builds,
|
---|
44 | # Setup.dist is available on Windows
|
---|
45 | def _python_build():
|
---|
46 | for fn in ("Setup.dist", "Setup.local"):
|
---|
47 | if os.path.isfile(os.path.join(project_base, "Modules", fn)):
|
---|
48 | return True
|
---|
49 | return False
|
---|
50 | python_build = _python_build()
|
---|
51 |
|
---|
52 |
|
---|
53 | def get_python_version():
|
---|
54 | """Return a string containing the major and minor Python version,
|
---|
55 | leaving off the patchlevel. Sample return values could be '1.5'
|
---|
56 | or '2.2'.
|
---|
57 | """
|
---|
58 | return sys.version[:3]
|
---|
59 |
|
---|
60 |
|
---|
61 | def get_python_inc(plat_specific=0, prefix=None):
|
---|
62 | """Return the directory containing installed Python header files.
|
---|
63 |
|
---|
64 | If 'plat_specific' is false (the default), this is the path to the
|
---|
65 | non-platform-specific header files, i.e. Python.h and so on;
|
---|
66 | otherwise, this is the path to platform-specific header files
|
---|
67 | (namely pyconfig.h).
|
---|
68 |
|
---|
69 | If 'prefix' is supplied, use it instead of sys.prefix or
|
---|
70 | sys.exec_prefix -- i.e., ignore 'plat_specific'.
|
---|
71 | """
|
---|
72 | if prefix is None:
|
---|
73 | prefix = plat_specific and EXEC_PREFIX or PREFIX
|
---|
74 | if os.name == "posix":
|
---|
75 | if python_build:
|
---|
76 | base = os.path.dirname(os.path.abspath(sys.executable))
|
---|
77 | if plat_specific:
|
---|
78 | inc_dir = base
|
---|
79 | else:
|
---|
80 | inc_dir = os.path.join(base, "Include")
|
---|
81 | if not os.path.exists(inc_dir):
|
---|
82 | inc_dir = os.path.join(os.path.dirname(base), "Include")
|
---|
83 | return inc_dir
|
---|
84 | return os.path.join(prefix, "include", "python" + get_python_version())
|
---|
85 | elif os.name == "nt":
|
---|
86 | return os.path.join(prefix, "include")
|
---|
87 | elif os.name == "mac":
|
---|
88 | if plat_specific:
|
---|
89 | return os.path.join(prefix, "Mac", "Include")
|
---|
90 | else:
|
---|
91 | return os.path.join(prefix, "Include")
|
---|
92 | elif os.name == "os2":
|
---|
93 | return os.path.join(prefix, "Include")
|
---|
94 | else:
|
---|
95 | raise DistutilsPlatformError(
|
---|
96 | "I don't know where Python installs its C header files "
|
---|
97 | "on platform '%s'" % os.name)
|
---|
98 |
|
---|
99 |
|
---|
100 | def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
|
---|
101 | """Return the directory containing the Python library (standard or
|
---|
102 | site additions).
|
---|
103 |
|
---|
104 | If 'plat_specific' is true, return the directory containing
|
---|
105 | platform-specific modules, i.e. any module from a non-pure-Python
|
---|
106 | module distribution; otherwise, return the platform-shared library
|
---|
107 | directory. If 'standard_lib' is true, return the directory
|
---|
108 | containing standard Python library modules; otherwise, return the
|
---|
109 | directory for site-specific modules.
|
---|
110 |
|
---|
111 | If 'prefix' is supplied, use it instead of sys.prefix or
|
---|
112 | sys.exec_prefix -- i.e., ignore 'plat_specific'.
|
---|
113 | """
|
---|
114 | if prefix is None:
|
---|
115 | prefix = plat_specific and EXEC_PREFIX or PREFIX
|
---|
116 |
|
---|
117 | if os.name == "posix":
|
---|
118 | libpython = os.path.join(prefix,
|
---|
119 | "lib", "python" + get_python_version())
|
---|
120 | if standard_lib:
|
---|
121 | return libpython
|
---|
122 | else:
|
---|
123 | return os.path.join(libpython, "site-packages")
|
---|
124 |
|
---|
125 | elif os.name == "nt":
|
---|
126 | if standard_lib:
|
---|
127 | return os.path.join(prefix, "Lib")
|
---|
128 | else:
|
---|
129 | if get_python_version() < "2.2":
|
---|
130 | return prefix
|
---|
131 | else:
|
---|
132 | return os.path.join(prefix, "Lib", "site-packages")
|
---|
133 |
|
---|
134 | elif os.name == "mac":
|
---|
135 | if plat_specific:
|
---|
136 | if standard_lib:
|
---|
137 | return os.path.join(prefix, "Lib", "lib-dynload")
|
---|
138 | else:
|
---|
139 | return os.path.join(prefix, "Lib", "site-packages")
|
---|
140 | else:
|
---|
141 | if standard_lib:
|
---|
142 | return os.path.join(prefix, "Lib")
|
---|
143 | else:
|
---|
144 | return os.path.join(prefix, "Lib", "site-packages")
|
---|
145 |
|
---|
146 | elif os.name == "os2":
|
---|
147 | if standard_lib:
|
---|
148 | return os.path.join(prefix, "Lib")
|
---|
149 | else:
|
---|
150 | return os.path.join(prefix, "Lib", "site-packages")
|
---|
151 |
|
---|
152 | else:
|
---|
153 | raise DistutilsPlatformError(
|
---|
154 | "I don't know where Python installs its library "
|
---|
155 | "on platform '%s'" % os.name)
|
---|
156 |
|
---|
157 |
|
---|
158 | def customize_compiler(compiler):
|
---|
159 | """Do any platform-specific customization of a CCompiler instance.
|
---|
160 |
|
---|
161 | Mainly needed on Unix, so we can plug in the information that
|
---|
162 | varies across Unices and is stored in Python's Makefile.
|
---|
163 | """
|
---|
164 | if compiler.compiler_type == "unix":
|
---|
165 | (cc, cxx, opt, cflags, ccshared, ldshared, so_ext) = \
|
---|
166 | get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
|
---|
167 | 'CCSHARED', 'LDSHARED', 'SO')
|
---|
168 |
|
---|
169 | if 'CC' in os.environ:
|
---|
170 | cc = os.environ['CC']
|
---|
171 | if 'CXX' in os.environ:
|
---|
172 | cxx = os.environ['CXX']
|
---|
173 | if 'LDSHARED' in os.environ:
|
---|
174 | ldshared = os.environ['LDSHARED']
|
---|
175 | if 'CPP' in os.environ:
|
---|
176 | cpp = os.environ['CPP']
|
---|
177 | else:
|
---|
178 | cpp = cc + " -E" # not always
|
---|
179 | if 'LDFLAGS' in os.environ:
|
---|
180 | ldshared = ldshared + ' ' + os.environ['LDFLAGS']
|
---|
181 | if 'CFLAGS' in os.environ:
|
---|
182 | cflags = opt + ' ' + os.environ['CFLAGS']
|
---|
183 | ldshared = ldshared + ' ' + os.environ['CFLAGS']
|
---|
184 | if 'CPPFLAGS' in os.environ:
|
---|
185 | cpp = cpp + ' ' + os.environ['CPPFLAGS']
|
---|
186 | cflags = cflags + ' ' + os.environ['CPPFLAGS']
|
---|
187 | ldshared = ldshared + ' ' + os.environ['CPPFLAGS']
|
---|
188 |
|
---|
189 | cc_cmd = cc + ' ' + cflags
|
---|
190 | compiler.set_executables(
|
---|
191 | preprocessor=cpp,
|
---|
192 | compiler=cc_cmd,
|
---|
193 | compiler_so=cc_cmd + ' ' + ccshared,
|
---|
194 | compiler_cxx=cxx,
|
---|
195 | linker_so=ldshared,
|
---|
196 | linker_exe=cc)
|
---|
197 |
|
---|
198 | compiler.shared_lib_extension = so_ext
|
---|
199 |
|
---|
200 |
|
---|
201 | def get_config_h_filename():
|
---|
202 | """Return full pathname of installed pyconfig.h file."""
|
---|
203 | if python_build:
|
---|
204 | if os.name == "nt":
|
---|
205 | inc_dir = os.path.join(project_base, "PC")
|
---|
206 | else:
|
---|
207 | inc_dir = project_base
|
---|
208 | else:
|
---|
209 | inc_dir = get_python_inc(plat_specific=1)
|
---|
210 | if get_python_version() < '2.2':
|
---|
211 | config_h = 'config.h'
|
---|
212 | else:
|
---|
213 | # The name of the config.h file changed in 2.2
|
---|
214 | config_h = 'pyconfig.h'
|
---|
215 | return os.path.join(inc_dir, config_h)
|
---|
216 |
|
---|
217 |
|
---|
218 | def get_makefile_filename():
|
---|
219 | """Return full pathname of installed Makefile from the Python build."""
|
---|
220 | if python_build:
|
---|
221 | return os.path.join(os.path.dirname(sys.executable), "Makefile")
|
---|
222 | lib_dir = get_python_lib(plat_specific=1, standard_lib=1)
|
---|
223 | return os.path.join(lib_dir, "config", "Makefile")
|
---|
224 |
|
---|
225 |
|
---|
226 | def parse_config_h(fp, g=None):
|
---|
227 | """Parse a config.h-style file.
|
---|
228 |
|
---|
229 | A dictionary containing name/value pairs is returned. If an
|
---|
230 | optional dictionary is passed in as the second argument, it is
|
---|
231 | used instead of a new dictionary.
|
---|
232 | """
|
---|
233 | if g is None:
|
---|
234 | g = {}
|
---|
235 | define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
|
---|
236 | undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
|
---|
237 | #
|
---|
238 | while 1:
|
---|
239 | line = fp.readline()
|
---|
240 | if not line:
|
---|
241 | break
|
---|
242 | m = define_rx.match(line)
|
---|
243 | if m:
|
---|
244 | n, v = m.group(1, 2)
|
---|
245 | try: v = int(v)
|
---|
246 | except ValueError: pass
|
---|
247 | g[n] = v
|
---|
248 | else:
|
---|
249 | m = undef_rx.match(line)
|
---|
250 | if m:
|
---|
251 | g[m.group(1)] = 0
|
---|
252 | return g
|
---|
253 |
|
---|
254 |
|
---|
255 | # Regexes needed for parsing Makefile (and similar syntaxes,
|
---|
256 | # like old-style Setup files).
|
---|
257 | _variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
|
---|
258 | _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
|
---|
259 | _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
|
---|
260 |
|
---|
261 | def parse_makefile(fn, g=None):
|
---|
262 | """Parse a Makefile-style file.
|
---|
263 |
|
---|
264 | A dictionary containing name/value pairs is returned. If an
|
---|
265 | optional dictionary is passed in as the second argument, it is
|
---|
266 | used instead of a new dictionary.
|
---|
267 | """
|
---|
268 | from distutils.text_file import TextFile
|
---|
269 | fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1)
|
---|
270 |
|
---|
271 | if g is None:
|
---|
272 | g = {}
|
---|
273 | done = {}
|
---|
274 | notdone = {}
|
---|
275 |
|
---|
276 | while 1:
|
---|
277 | line = fp.readline()
|
---|
278 | if line is None: # eof
|
---|
279 | break
|
---|
280 | m = _variable_rx.match(line)
|
---|
281 | if m:
|
---|
282 | n, v = m.group(1, 2)
|
---|
283 | v = v.strip()
|
---|
284 | # `$$' is a literal `$' in make
|
---|
285 | tmpv = v.replace('$$', '')
|
---|
286 |
|
---|
287 | if "$" in tmpv:
|
---|
288 | notdone[n] = v
|
---|
289 | else:
|
---|
290 | try:
|
---|
291 | v = int(v)
|
---|
292 | except ValueError:
|
---|
293 | # insert literal `$'
|
---|
294 | done[n] = v.replace('$$', '$')
|
---|
295 | else:
|
---|
296 | done[n] = v
|
---|
297 |
|
---|
298 | # do variable interpolation here
|
---|
299 | while notdone:
|
---|
300 | for name in notdone.keys():
|
---|
301 | value = notdone[name]
|
---|
302 | m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
|
---|
303 | if m:
|
---|
304 | n = m.group(1)
|
---|
305 | found = True
|
---|
306 | if n in done:
|
---|
307 | item = str(done[n])
|
---|
308 | elif n in notdone:
|
---|
309 | # get it on a subsequent round
|
---|
310 | found = False
|
---|
311 | elif n in os.environ:
|
---|
312 | # do it like make: fall back to environment
|
---|
313 | item = os.environ[n]
|
---|
314 | else:
|
---|
315 | done[n] = item = ""
|
---|
316 | if found:
|
---|
317 | after = value[m.end():]
|
---|
318 | value = value[:m.start()] + item + after
|
---|
319 | if "$" in after:
|
---|
320 | notdone[name] = value
|
---|
321 | else:
|
---|
322 | try: value = int(value)
|
---|
323 | except ValueError:
|
---|
324 | done[name] = value.strip()
|
---|
325 | else:
|
---|
326 | done[name] = value
|
---|
327 | del notdone[name]
|
---|
328 | else:
|
---|
329 | # bogus variable reference; just drop it since we can't deal
|
---|
330 | del notdone[name]
|
---|
331 |
|
---|
332 | fp.close()
|
---|
333 |
|
---|
334 | # save the results in the global dictionary
|
---|
335 | g.update(done)
|
---|
336 | return g
|
---|
337 |
|
---|
338 |
|
---|
339 | def expand_makefile_vars(s, vars):
|
---|
340 | """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in
|
---|
341 | 'string' according to 'vars' (a dictionary mapping variable names to
|
---|
342 | values). Variables not present in 'vars' are silently expanded to the
|
---|
343 | empty string. The variable values in 'vars' should not contain further
|
---|
344 | variable expansions; if 'vars' is the output of 'parse_makefile()',
|
---|
345 | you're fine. Returns a variable-expanded version of 's'.
|
---|
346 | """
|
---|
347 |
|
---|
348 | # This algorithm does multiple expansion, so if vars['foo'] contains
|
---|
349 | # "${bar}", it will expand ${foo} to ${bar}, and then expand
|
---|
350 | # ${bar}... and so forth. This is fine as long as 'vars' comes from
|
---|
351 | # 'parse_makefile()', which takes care of such expansions eagerly,
|
---|
352 | # according to make's variable expansion semantics.
|
---|
353 |
|
---|
354 | while 1:
|
---|
355 | m = _findvar1_rx.search(s) or _findvar2_rx.search(s)
|
---|
356 | if m:
|
---|
357 | (beg, end) = m.span()
|
---|
358 | s = s[0:beg] + vars.get(m.group(1)) + s[end:]
|
---|
359 | else:
|
---|
360 | break
|
---|
361 | return s
|
---|
362 |
|
---|
363 |
|
---|
364 | _config_vars = None
|
---|
365 |
|
---|
366 | def _init_posix():
|
---|
367 | """Initialize the module as appropriate for POSIX systems."""
|
---|
368 | g = {}
|
---|
369 | # load the installed Makefile:
|
---|
370 | try:
|
---|
371 | filename = get_makefile_filename()
|
---|
372 | parse_makefile(filename, g)
|
---|
373 | except IOError, msg:
|
---|
374 | my_msg = "invalid Python installation: unable to open %s" % filename
|
---|
375 | if hasattr(msg, "strerror"):
|
---|
376 | my_msg = my_msg + " (%s)" % msg.strerror
|
---|
377 |
|
---|
378 | raise DistutilsPlatformError(my_msg)
|
---|
379 |
|
---|
380 | # load the installed pyconfig.h:
|
---|
381 | try:
|
---|
382 | filename = get_config_h_filename()
|
---|
383 | parse_config_h(file(filename), g)
|
---|
384 | except IOError, msg:
|
---|
385 | my_msg = "invalid Python installation: unable to open %s" % filename
|
---|
386 | if hasattr(msg, "strerror"):
|
---|
387 | my_msg = my_msg + " (%s)" % msg.strerror
|
---|
388 |
|
---|
389 | raise DistutilsPlatformError(my_msg)
|
---|
390 |
|
---|
391 | # On MacOSX we need to check the setting of the environment variable
|
---|
392 | # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so
|
---|
393 | # it needs to be compatible.
|
---|
394 | # If it isn't set we set it to the configure-time value
|
---|
395 | if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g:
|
---|
396 | cfg_target = g['MACOSX_DEPLOYMENT_TARGET']
|
---|
397 | cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '')
|
---|
398 | if cur_target == '':
|
---|
399 | cur_target = cfg_target
|
---|
400 | os.putenv('MACOSX_DEPLOYMENT_TARGET', cfg_target)
|
---|
401 | elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')):
|
---|
402 | my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure'
|
---|
403 | % (cur_target, cfg_target))
|
---|
404 | raise DistutilsPlatformError(my_msg)
|
---|
405 |
|
---|
406 | # On AIX, there are wrong paths to the linker scripts in the Makefile
|
---|
407 | # -- these paths are relative to the Python source, but when installed
|
---|
408 | # the scripts are in another directory.
|
---|
409 | if python_build:
|
---|
410 | g['LDSHARED'] = g['BLDSHARED']
|
---|
411 |
|
---|
412 | elif get_python_version() < '2.1':
|
---|
413 | # The following two branches are for 1.5.2 compatibility.
|
---|
414 | if sys.platform == 'aix4': # what about AIX 3.x ?
|
---|
415 | # Linker script is in the config directory, not in Modules as the
|
---|
416 | # Makefile says.
|
---|
417 | python_lib = get_python_lib(standard_lib=1)
|
---|
418 | ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix')
|
---|
419 | python_exp = os.path.join(python_lib, 'config', 'python.exp')
|
---|
420 |
|
---|
421 | g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp)
|
---|
422 |
|
---|
423 | elif sys.platform == 'beos':
|
---|
424 | # Linker script is in the config directory. In the Makefile it is
|
---|
425 | # relative to the srcdir, which after installation no longer makes
|
---|
426 | # sense.
|
---|
427 | python_lib = get_python_lib(standard_lib=1)
|
---|
428 | linkerscript_path = string.split(g['LDSHARED'])[0]
|
---|
429 | linkerscript_name = os.path.basename(linkerscript_path)
|
---|
430 | linkerscript = os.path.join(python_lib, 'config',
|
---|
431 | linkerscript_name)
|
---|
432 |
|
---|
433 | # XXX this isn't the right place to do this: adding the Python
|
---|
434 | # library to the link, if needed, should be in the "build_ext"
|
---|
435 | # command. (It's also needed for non-MS compilers on Windows, and
|
---|
436 | # it's taken care of for them by the 'build_ext.get_libraries()'
|
---|
437 | # method.)
|
---|
438 | g['LDSHARED'] = ("%s -L%s/lib -lpython%s" %
|
---|
439 | (linkerscript, PREFIX, get_python_version()))
|
---|
440 |
|
---|
441 | global _config_vars
|
---|
442 | _config_vars = g
|
---|
443 |
|
---|
444 |
|
---|
445 | def _init_nt():
|
---|
446 | """Initialize the module as appropriate for NT"""
|
---|
447 | g = {}
|
---|
448 | # set basic install directories
|
---|
449 | g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
|
---|
450 | g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
|
---|
451 |
|
---|
452 | # XXX hmmm.. a normal install puts include files here
|
---|
453 | g['INCLUDEPY'] = get_python_inc(plat_specific=0)
|
---|
454 |
|
---|
455 | g['SO'] = '.pyd'
|
---|
456 | g['EXE'] = ".exe"
|
---|
457 | g['VERSION'] = get_python_version().replace(".", "")
|
---|
458 | g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable))
|
---|
459 |
|
---|
460 | global _config_vars
|
---|
461 | _config_vars = g
|
---|
462 |
|
---|
463 |
|
---|
464 | def _init_mac():
|
---|
465 | """Initialize the module as appropriate for Macintosh systems"""
|
---|
466 | g = {}
|
---|
467 | # set basic install directories
|
---|
468 | g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
|
---|
469 | g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
|
---|
470 |
|
---|
471 | # XXX hmmm.. a normal install puts include files here
|
---|
472 | g['INCLUDEPY'] = get_python_inc(plat_specific=0)
|
---|
473 |
|
---|
474 | import MacOS
|
---|
475 | if not hasattr(MacOS, 'runtimemodel'):
|
---|
476 | g['SO'] = '.ppc.slb'
|
---|
477 | else:
|
---|
478 | g['SO'] = '.%s.slb' % MacOS.runtimemodel
|
---|
479 |
|
---|
480 | # XXX are these used anywhere?
|
---|
481 | g['install_lib'] = os.path.join(EXEC_PREFIX, "Lib")
|
---|
482 | g['install_platlib'] = os.path.join(EXEC_PREFIX, "Mac", "Lib")
|
---|
483 |
|
---|
484 | # These are used by the extension module build
|
---|
485 | g['srcdir'] = ':'
|
---|
486 | global _config_vars
|
---|
487 | _config_vars = g
|
---|
488 |
|
---|
489 |
|
---|
490 | def _init_os2():
|
---|
491 | """Initialize the module as appropriate for OS/2"""
|
---|
492 | g = {}
|
---|
493 | # set basic install directories
|
---|
494 | g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
|
---|
495 | g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
|
---|
496 |
|
---|
497 | # XXX hmmm.. a normal install puts include files here
|
---|
498 | g['INCLUDEPY'] = get_python_inc(plat_specific=0)
|
---|
499 |
|
---|
500 | g['SO'] = '.pyd'
|
---|
501 | g['EXE'] = ".exe"
|
---|
502 |
|
---|
503 | global _config_vars
|
---|
504 | _config_vars = g
|
---|
505 |
|
---|
506 |
|
---|
507 | def get_config_vars(*args):
|
---|
508 | """With no arguments, return a dictionary of all configuration
|
---|
509 | variables relevant for the current platform. Generally this includes
|
---|
510 | everything needed to build extensions and install both pure modules and
|
---|
511 | extensions. On Unix, this means every variable defined in Python's
|
---|
512 | installed Makefile; on Windows and Mac OS it's a much smaller set.
|
---|
513 |
|
---|
514 | With arguments, return a list of values that result from looking up
|
---|
515 | each argument in the configuration variable dictionary.
|
---|
516 | """
|
---|
517 | global _config_vars
|
---|
518 | if _config_vars is None:
|
---|
519 | func = globals().get("_init_" + os.name)
|
---|
520 | if func:
|
---|
521 | func()
|
---|
522 | else:
|
---|
523 | _config_vars = {}
|
---|
524 |
|
---|
525 | # Normalized versions of prefix and exec_prefix are handy to have;
|
---|
526 | # in fact, these are the standard versions used most places in the
|
---|
527 | # Distutils.
|
---|
528 | _config_vars['prefix'] = PREFIX
|
---|
529 | _config_vars['exec_prefix'] = EXEC_PREFIX
|
---|
530 |
|
---|
531 | if sys.platform == 'darwin':
|
---|
532 | kernel_version = os.uname()[2] # Kernel version (8.4.3)
|
---|
533 | major_version = int(kernel_version.split('.')[0])
|
---|
534 |
|
---|
535 | if major_version < 8:
|
---|
536 | # On Mac OS X before 10.4, check if -arch and -isysroot
|
---|
537 | # are in CFLAGS or LDFLAGS and remove them if they are.
|
---|
538 | # This is needed when building extensions on a 10.3 system
|
---|
539 | # using a universal build of python.
|
---|
540 | for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED',
|
---|
541 | # a number of derived variables. These need to be
|
---|
542 | # patched up as well.
|
---|
543 | 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
|
---|
544 | flags = _config_vars[key]
|
---|
545 | flags = re.sub('-arch\s+\w+\s', ' ', flags)
|
---|
546 | flags = re.sub('-isysroot [^ \t]*', ' ', flags)
|
---|
547 | _config_vars[key] = flags
|
---|
548 |
|
---|
549 | else:
|
---|
550 |
|
---|
551 | # Allow the user to override the architecture flags using
|
---|
552 | # an environment variable.
|
---|
553 | # NOTE: This name was introduced by Apple in OSX 10.5 and
|
---|
554 | # is used by several scripting languages distributed with
|
---|
555 | # that OS release.
|
---|
556 |
|
---|
557 | if 'ARCHFLAGS' in os.environ:
|
---|
558 | arch = os.environ['ARCHFLAGS']
|
---|
559 | for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED',
|
---|
560 | # a number of derived variables. These need to be
|
---|
561 | # patched up as well.
|
---|
562 | 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
|
---|
563 |
|
---|
564 | flags = _config_vars[key]
|
---|
565 | flags = re.sub('-arch\s+\w+\s', ' ', flags)
|
---|
566 | flags = flags + ' ' + arch
|
---|
567 | _config_vars[key] = flags
|
---|
568 |
|
---|
569 | # If we're on OSX 10.5 or later and the user tries to
|
---|
570 | # compiles an extension using an SDK that is not present
|
---|
571 | # on the current machine it is better to not use an SDK
|
---|
572 | # than to fail.
|
---|
573 | #
|
---|
574 | # The major usecase for this is users using a Python.org
|
---|
575 | # binary installer on OSX 10.6: that installer uses
|
---|
576 | # the 10.4u SDK, but that SDK is not installed by default
|
---|
577 | # when you install Xcode.
|
---|
578 | #
|
---|
579 | m = re.search('-isysroot\s+(\S+)', _config_vars['CFLAGS'])
|
---|
580 | if m is not None:
|
---|
581 | sdk = m.group(1)
|
---|
582 | if not os.path.exists(sdk):
|
---|
583 | for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED',
|
---|
584 | # a number of derived variables. These need to be
|
---|
585 | # patched up as well.
|
---|
586 | 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
|
---|
587 |
|
---|
588 | flags = _config_vars[key]
|
---|
589 | flags = re.sub('-isysroot\s+\S+(\s|$)', ' ', flags)
|
---|
590 | _config_vars[key] = flags
|
---|
591 |
|
---|
592 | if args:
|
---|
593 | vals = []
|
---|
594 | for name in args:
|
---|
595 | vals.append(_config_vars.get(name))
|
---|
596 | return vals
|
---|
597 | else:
|
---|
598 | return _config_vars
|
---|
599 |
|
---|
600 | def get_config_var(name):
|
---|
601 | """Return the value of a single variable using the dictionary
|
---|
602 | returned by 'get_config_vars()'. Equivalent to
|
---|
603 | get_config_vars().get(name)
|
---|
604 | """
|
---|
605 | return get_config_vars().get(name)
|
---|