source: python/vendor/Python-2.7.6/Lib/distutils/sysconfig.py

Last change on this file was 388, checked in by dmik, 11 years ago

python: Update vendor to 2.7.6.

  • Property svn:eol-style set to native
File size: 16.6 KB
Line 
1"""Provide access to Python's configuration information. The specific
2configuration variables available depend heavily on the platform and
3configuration. The values may be retrieved using
4get_config_var(name), and the list of variables is available via
5get_config_vars().keys(). Additional convenience functions are also
6available.
7
8Written by: Fred L. Drake, Jr.
9Email: <fdrake@acm.org>
10"""
11
12__revision__ = "$Id$"
13
14import os
15import re
16import string
17import sys
18
19from distutils.errors import DistutilsPlatformError
20
21# These are needed in a couple of spots, so just compute them once.
22PREFIX = os.path.normpath(sys.prefix)
23EXEC_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.
28project_base = os.path.dirname(os.path.abspath(sys.executable))
29if 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
32if 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
36if 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# set for cross builds
41if "_PYTHON_PROJECT_BASE" in os.environ:
42 # this is the build directory, at least for posix
43 project_base = os.path.normpath(os.environ["_PYTHON_PROJECT_BASE"])
44
45# python_build: (Boolean) if true, we're either building Python or
46# building an extension with an un-installed Python, so we use
47# different (hard-wired) directories.
48# Setup.local is available for Makefile builds including VPATH builds,
49# Setup.dist is available on Windows
50def _python_build():
51 for fn in ("Setup.dist", "Setup.local"):
52 if os.path.isfile(os.path.join(project_base, "Modules", fn)):
53 return True
54 return False
55python_build = _python_build()
56
57
58def get_python_version():
59 """Return a string containing the major and minor Python version,
60 leaving off the patchlevel. Sample return values could be '1.5'
61 or '2.2'.
62 """
63 return sys.version[:3]
64
65
66def get_python_inc(plat_specific=0, prefix=None):
67 """Return the directory containing installed Python header files.
68
69 If 'plat_specific' is false (the default), this is the path to the
70 non-platform-specific header files, i.e. Python.h and so on;
71 otherwise, this is the path to platform-specific header files
72 (namely pyconfig.h).
73
74 If 'prefix' is supplied, use it instead of sys.prefix or
75 sys.exec_prefix -- i.e., ignore 'plat_specific'.
76 """
77 if prefix is None:
78 prefix = plat_specific and EXEC_PREFIX or PREFIX
79
80 if os.name == "posix":
81 if python_build:
82 buildir = os.path.dirname(sys.executable)
83 if plat_specific:
84 # python.h is located in the buildir
85 inc_dir = buildir
86 else:
87 # the source dir is relative to the buildir
88 srcdir = os.path.abspath(os.path.join(buildir,
89 get_config_var('srcdir')))
90 # Include is located in the srcdir
91 inc_dir = os.path.join(srcdir, "Include")
92 return inc_dir
93 return os.path.join(prefix, "include", "python" + get_python_version())
94 elif os.name == "nt":
95 return os.path.join(prefix, "include")
96 elif os.name == "os2":
97 return os.path.join(prefix, "Include")
98 else:
99 raise DistutilsPlatformError(
100 "I don't know where Python installs its C header files "
101 "on platform '%s'" % os.name)
102
103
104def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
105 """Return the directory containing the Python library (standard or
106 site additions).
107
108 If 'plat_specific' is true, return the directory containing
109 platform-specific modules, i.e. any module from a non-pure-Python
110 module distribution; otherwise, return the platform-shared library
111 directory. If 'standard_lib' is true, return the directory
112 containing standard Python library modules; otherwise, return the
113 directory for site-specific modules.
114
115 If 'prefix' is supplied, use it instead of sys.prefix or
116 sys.exec_prefix -- i.e., ignore 'plat_specific'.
117 """
118 if prefix is None:
119 prefix = plat_specific and EXEC_PREFIX or PREFIX
120
121 if os.name == "posix":
122 libpython = os.path.join(prefix,
123 "lib", "python" + get_python_version())
124 if standard_lib:
125 return libpython
126 else:
127 return os.path.join(libpython, "site-packages")
128
129 elif os.name == "nt":
130 if standard_lib:
131 return os.path.join(prefix, "Lib")
132 else:
133 if get_python_version() < "2.2":
134 return prefix
135 else:
136 return os.path.join(prefix, "Lib", "site-packages")
137
138 elif os.name == "os2":
139 if standard_lib:
140 return os.path.join(prefix, "Lib")
141 else:
142 return os.path.join(prefix, "Lib", "site-packages")
143
144 else:
145 raise DistutilsPlatformError(
146 "I don't know where Python installs its library "
147 "on platform '%s'" % os.name)
148
149
150
151def customize_compiler(compiler):
152 """Do any platform-specific customization of a CCompiler instance.
153
154 Mainly needed on Unix, so we can plug in the information that
155 varies across Unices and is stored in Python's Makefile.
156 """
157 if compiler.compiler_type == "unix":
158 if sys.platform == "darwin":
159 # Perform first-time customization of compiler-related
160 # config vars on OS X now that we know we need a compiler.
161 # This is primarily to support Pythons from binary
162 # installers. The kind and paths to build tools on
163 # the user system may vary significantly from the system
164 # that Python itself was built on. Also the user OS
165 # version and build tools may not support the same set
166 # of CPU architectures for universal builds.
167 global _config_vars
168 if not _config_vars.get('CUSTOMIZED_OSX_COMPILER', ''):
169 import _osx_support
170 _osx_support.customize_compiler(_config_vars)
171 _config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True'
172
173 (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \
174 get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
175 'CCSHARED', 'LDSHARED', 'SO', 'AR',
176 'ARFLAGS')
177
178 if 'CC' in os.environ:
179 newcc = os.environ['CC']
180 if (sys.platform == 'darwin'
181 and 'LDSHARED' not in os.environ
182 and ldshared.startswith(cc)):
183 # On OS X, if CC is overridden, use that as the default
184 # command for LDSHARED as well
185 ldshared = newcc + ldshared[len(cc):]
186 cc = newcc
187 if 'CXX' in os.environ:
188 cxx = os.environ['CXX']
189 if 'LDSHARED' in os.environ:
190 ldshared = os.environ['LDSHARED']
191 if 'CPP' in os.environ:
192 cpp = os.environ['CPP']
193 else:
194 cpp = cc + " -E" # not always
195 if 'LDFLAGS' in os.environ:
196 ldshared = ldshared + ' ' + os.environ['LDFLAGS']
197 if 'CFLAGS' in os.environ:
198 cflags = opt + ' ' + os.environ['CFLAGS']
199 ldshared = ldshared + ' ' + os.environ['CFLAGS']
200 if 'CPPFLAGS' in os.environ:
201 cpp = cpp + ' ' + os.environ['CPPFLAGS']
202 cflags = cflags + ' ' + os.environ['CPPFLAGS']
203 ldshared = ldshared + ' ' + os.environ['CPPFLAGS']
204 if 'AR' in os.environ:
205 ar = os.environ['AR']
206 if 'ARFLAGS' in os.environ:
207 archiver = ar + ' ' + os.environ['ARFLAGS']
208 else:
209 archiver = ar + ' ' + ar_flags
210
211 cc_cmd = cc + ' ' + cflags
212 compiler.set_executables(
213 preprocessor=cpp,
214 compiler=cc_cmd,
215 compiler_so=cc_cmd + ' ' + ccshared,
216 compiler_cxx=cxx,
217 linker_so=ldshared,
218 linker_exe=cc,
219 archiver=archiver)
220
221 compiler.shared_lib_extension = so_ext
222
223
224def get_config_h_filename():
225 """Return full pathname of installed pyconfig.h file."""
226 if python_build:
227 if os.name == "nt":
228 inc_dir = os.path.join(project_base, "PC")
229 else:
230 inc_dir = project_base
231 else:
232 inc_dir = get_python_inc(plat_specific=1)
233 if get_python_version() < '2.2':
234 config_h = 'config.h'
235 else:
236 # The name of the config.h file changed in 2.2
237 config_h = 'pyconfig.h'
238 return os.path.join(inc_dir, config_h)
239
240
241def get_makefile_filename():
242 """Return full pathname of installed Makefile from the Python build."""
243 if python_build:
244 return os.path.join(project_base, "Makefile")
245 lib_dir = get_python_lib(plat_specific=1, standard_lib=1)
246 return os.path.join(lib_dir, "config", "Makefile")
247
248
249def parse_config_h(fp, g=None):
250 """Parse a config.h-style file.
251
252 A dictionary containing name/value pairs is returned. If an
253 optional dictionary is passed in as the second argument, it is
254 used instead of a new dictionary.
255 """
256 if g is None:
257 g = {}
258 define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
259 undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
260 #
261 while 1:
262 line = fp.readline()
263 if not line:
264 break
265 m = define_rx.match(line)
266 if m:
267 n, v = m.group(1, 2)
268 try: v = int(v)
269 except ValueError: pass
270 g[n] = v
271 else:
272 m = undef_rx.match(line)
273 if m:
274 g[m.group(1)] = 0
275 return g
276
277
278# Regexes needed for parsing Makefile (and similar syntaxes,
279# like old-style Setup files).
280_variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
281_findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
282_findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
283
284def parse_makefile(fn, g=None):
285 """Parse a Makefile-style file.
286
287 A dictionary containing name/value pairs is returned. If an
288 optional dictionary is passed in as the second argument, it is
289 used instead of a new dictionary.
290 """
291 from distutils.text_file import TextFile
292 fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1)
293
294 if g is None:
295 g = {}
296 done = {}
297 notdone = {}
298
299 while 1:
300 line = fp.readline()
301 if line is None: # eof
302 break
303 m = _variable_rx.match(line)
304 if m:
305 n, v = m.group(1, 2)
306 v = v.strip()
307 # `$$' is a literal `$' in make
308 tmpv = v.replace('$$', '')
309
310 if "$" in tmpv:
311 notdone[n] = v
312 else:
313 try:
314 v = int(v)
315 except ValueError:
316 # insert literal `$'
317 done[n] = v.replace('$$', '$')
318 else:
319 done[n] = v
320
321 # do variable interpolation here
322 while notdone:
323 for name in notdone.keys():
324 value = notdone[name]
325 m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
326 if m:
327 n = m.group(1)
328 found = True
329 if n in done:
330 item = str(done[n])
331 elif n in notdone:
332 # get it on a subsequent round
333 found = False
334 elif n in os.environ:
335 # do it like make: fall back to environment
336 item = os.environ[n]
337 else:
338 done[n] = item = ""
339 if found:
340 after = value[m.end():]
341 value = value[:m.start()] + item + after
342 if "$" in after:
343 notdone[name] = value
344 else:
345 try: value = int(value)
346 except ValueError:
347 done[name] = value.strip()
348 else:
349 done[name] = value
350 del notdone[name]
351 else:
352 # bogus variable reference; just drop it since we can't deal
353 del notdone[name]
354
355 fp.close()
356
357 # strip spurious spaces
358 for k, v in done.items():
359 if isinstance(v, str):
360 done[k] = v.strip()
361
362 # save the results in the global dictionary
363 g.update(done)
364 return g
365
366
367def expand_makefile_vars(s, vars):
368 """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in
369 'string' according to 'vars' (a dictionary mapping variable names to
370 values). Variables not present in 'vars' are silently expanded to the
371 empty string. The variable values in 'vars' should not contain further
372 variable expansions; if 'vars' is the output of 'parse_makefile()',
373 you're fine. Returns a variable-expanded version of 's'.
374 """
375
376 # This algorithm does multiple expansion, so if vars['foo'] contains
377 # "${bar}", it will expand ${foo} to ${bar}, and then expand
378 # ${bar}... and so forth. This is fine as long as 'vars' comes from
379 # 'parse_makefile()', which takes care of such expansions eagerly,
380 # according to make's variable expansion semantics.
381
382 while 1:
383 m = _findvar1_rx.search(s) or _findvar2_rx.search(s)
384 if m:
385 (beg, end) = m.span()
386 s = s[0:beg] + vars.get(m.group(1)) + s[end:]
387 else:
388 break
389 return s
390
391
392_config_vars = None
393
394def _init_posix():
395 """Initialize the module as appropriate for POSIX systems."""
396 # _sysconfigdata is generated at build time, see the sysconfig module
397 from _sysconfigdata import build_time_vars
398 global _config_vars
399 _config_vars = {}
400 _config_vars.update(build_time_vars)
401
402
403def _init_nt():
404 """Initialize the module as appropriate for NT"""
405 g = {}
406 # set basic install directories
407 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
408 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
409
410 # XXX hmmm.. a normal install puts include files here
411 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
412
413 g['SO'] = '.pyd'
414 g['EXE'] = ".exe"
415 g['VERSION'] = get_python_version().replace(".", "")
416 g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable))
417
418 global _config_vars
419 _config_vars = g
420
421
422def _init_os2():
423 """Initialize the module as appropriate for OS/2"""
424 g = {}
425 # set basic install directories
426 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
427 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
428
429 # XXX hmmm.. a normal install puts include files here
430 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
431
432 g['SO'] = '.pyd'
433 g['EXE'] = ".exe"
434
435 global _config_vars
436 _config_vars = g
437
438
439def get_config_vars(*args):
440 """With no arguments, return a dictionary of all configuration
441 variables relevant for the current platform. Generally this includes
442 everything needed to build extensions and install both pure modules and
443 extensions. On Unix, this means every variable defined in Python's
444 installed Makefile; on Windows and Mac OS it's a much smaller set.
445
446 With arguments, return a list of values that result from looking up
447 each argument in the configuration variable dictionary.
448 """
449 global _config_vars
450 if _config_vars is None:
451 func = globals().get("_init_" + os.name)
452 if func:
453 func()
454 else:
455 _config_vars = {}
456
457 # Normalized versions of prefix and exec_prefix are handy to have;
458 # in fact, these are the standard versions used most places in the
459 # Distutils.
460 _config_vars['prefix'] = PREFIX
461 _config_vars['exec_prefix'] = EXEC_PREFIX
462
463 # OS X platforms require special customization to handle
464 # multi-architecture, multi-os-version installers
465 if sys.platform == 'darwin':
466 import _osx_support
467 _osx_support.customize_config_vars(_config_vars)
468
469 if args:
470 vals = []
471 for name in args:
472 vals.append(_config_vars.get(name))
473 return vals
474 else:
475 return _config_vars
476
477def get_config_var(name):
478 """Return the value of a single variable using the dictionary
479 returned by 'get_config_vars()'. Equivalent to
480 get_config_vars().get(name)
481 """
482 return get_config_vars().get(name)
Note: See TracBrowser for help on using the repository browser.