blob: de7da1d41394f0ba479eb7f6f60e95b89e130d63 [file] [log] [blame]
Fred Drake70b014d2001-07-18 18:39:56 +00001"""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.
Greg Ward1190ee31998-12-18 23:46:33 +00007
8Written by: Fred L. Drake, Jr.
9Email: <fdrake@acm.org>
Greg Ward1190ee31998-12-18 23:46:33 +000010"""
11
Greg Ward82d71ca2000-06-03 00:44:30 +000012__revision__ = "$Id$"
Greg Ward1190ee31998-12-18 23:46:33 +000013
Tarek Ziadédd7bef92010-03-05 00:16:02 +000014import os
Greg Ward9ddaaa11999-01-06 14:46:06 +000015import re
Tarek Ziadédd7bef92010-03-05 00:16:02 +000016import string
17import sys
Greg Ward1190ee31998-12-18 23:46:33 +000018
Tarek Ziadédd7bef92010-03-05 00:16:02 +000019from distutils.errors import DistutilsPlatformError
Greg Warda0ca3f22000-02-02 00:05:14 +000020
Tarek Ziadédd7bef92010-03-05 00:16:02 +000021# 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)
Tarek Ziadé0276c7a2010-01-26 21:21:54 +000024
Tarek Ziadédd7bef92010-03-05 00:16:02 +000025# 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))
Fred Drakec1ee39a2000-03-09 15:54:52 +000039
doko@python.orgd65e2ba2013-01-31 23:52:03 +010040# 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
Tarek Ziadédd7bef92010-03-05 00:16:02 +000045# 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
Marc-André Lemburg2db7cd32008-02-05 14:50:40 +000050def _python_build():
Tarek Ziadédd7bef92010-03-05 00:16:02 +000051 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
Marc-André Lemburg2db7cd32008-02-05 14:50:40 +000055python_build = _python_build()
Fred Drakec1ee39a2000-03-09 15:54:52 +000056
Tarek Ziadé5633a802010-01-23 09:23:15 +000057
Tarek Ziadédd7bef92010-03-05 00:16:02 +000058def 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.
Fred Drakec1ee39a2000-03-09 15:54:52 +000068
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
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000072 (namely pyconfig.h).
Fred Drakec1ee39a2000-03-09 15:54:52 +000073
Greg Wardd38e6f72000-04-10 01:17:49 +000074 If 'prefix' is supplied, use it instead of sys.prefix or
75 sys.exec_prefix -- i.e., ignore 'plat_specific'.
Fred Drakeb94b8492001-12-06 20:51:35 +000076 """
Tarek Ziadédd7bef92010-03-05 00:16:02 +000077 if prefix is None:
78 prefix = plat_specific and EXEC_PREFIX or PREFIX
Tarek Ziadéa5cd1822010-04-30 12:15:12 +000079
Tarek Ziadédd7bef92010-03-05 00:16:02 +000080 if os.name == "posix":
81 if python_build:
Tarek Ziadéa5cd1822010-04-30 12:15:12 +000082 buildir = os.path.dirname(sys.executable)
Tarek Ziadédd7bef92010-03-05 00:16:02 +000083 if plat_specific:
Tarek Ziadéa5cd1822010-04-30 12:15:12 +000084 # python.h is located in the buildir
85 inc_dir = buildir
Tarek Ziadédd7bef92010-03-05 00:16:02 +000086 else:
Tarek Ziadéa5cd1822010-04-30 12:15:12 +000087 # 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")
Tarek Ziadédd7bef92010-03-05 00:16:02 +000092 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")
Tarek Ziadédd7bef92010-03-05 00:16:02 +000096 elif os.name == "os2":
97 return os.path.join(prefix, "Include")
Greg Ward7d73b9e2000-03-09 03:16:05 +000098 else:
Tarek Ziadédd7bef92010-03-05 00:16:02 +000099 raise DistutilsPlatformError(
100 "I don't know where Python installs its C header files "
101 "on platform '%s'" % os.name)
Greg Ward7d73b9e2000-03-09 03:16:05 +0000102
103
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000104def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
105 """Return the directory containing the Python library (standard or
Fred Drakec1ee39a2000-03-09 15:54:52 +0000106 site additions).
Greg Ward7d73b9e2000-03-09 03:16:05 +0000107
Fred Drakec1ee39a2000-03-09 15:54:52 +0000108 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
Greg Wardd38e6f72000-04-10 01:17:49 +0000115 If 'prefix' is supplied, use it instead of sys.prefix or
116 sys.exec_prefix -- i.e., ignore 'plat_specific'.
Fred Drakec1ee39a2000-03-09 15:54:52 +0000117 """
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000118 if prefix is None:
119 prefix = plat_specific and EXEC_PREFIX or PREFIX
Marc-André Lemburg2544f512002-01-31 18:56:00 +0000120
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000121 if os.name == "posix":
122 libpython = os.path.join(prefix,
123 "lib", "python" + get_python_version())
124 if standard_lib:
125 return libpython
Marc-André Lemburg2544f512002-01-31 18:56:00 +0000126 else:
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000127 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
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000138 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
Greg Ward7d73b9e2000-03-09 03:16:05 +0000144 else:
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000145 raise DistutilsPlatformError(
146 "I don't know where Python installs its library "
147 "on platform '%s'" % os.name)
148
Ned Deily18fae3f2013-01-31 01:24:55 -0800149
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000150
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":
Ned Deily18fae3f2013-01-31 01:24:55 -0800158 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
Ned Deily9be57892014-07-06 16:11:44 -0700168 # Use get_config_var() to ensure _config_vars is initialized.
169 if not get_config_var('CUSTOMIZED_OSX_COMPILER'):
Ned Deily18fae3f2013-01-31 01:24:55 -0800170 import _osx_support
171 _osx_support.customize_compiler(_config_vars)
172 _config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True'
173
Ned Deilyc47a4592012-02-11 20:40:24 +0100174 (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000175 get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
Ned Deilyc47a4592012-02-11 20:40:24 +0100176 'CCSHARED', 'LDSHARED', 'SO', 'AR',
177 'ARFLAGS')
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000178
179 if 'CC' in os.environ:
Ned Deily1ab29e72013-05-28 16:31:45 -0700180 newcc = os.environ['CC']
181 if (sys.platform == 'darwin'
182 and 'LDSHARED' not in os.environ
183 and ldshared.startswith(cc)):
184 # On OS X, if CC is overridden, use that as the default
185 # command for LDSHARED as well
186 ldshared = newcc + ldshared[len(cc):]
187 cc = newcc
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000188 if 'CXX' in os.environ:
189 cxx = os.environ['CXX']
190 if 'LDSHARED' in os.environ:
191 ldshared = os.environ['LDSHARED']
192 if 'CPP' in os.environ:
193 cpp = os.environ['CPP']
Andrew M. Kuchling29c86232002-11-04 19:53:24 +0000194 else:
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000195 cpp = cc + " -E" # not always
196 if 'LDFLAGS' in os.environ:
197 ldshared = ldshared + ' ' + os.environ['LDFLAGS']
198 if 'CFLAGS' in os.environ:
199 cflags = opt + ' ' + os.environ['CFLAGS']
200 ldshared = ldshared + ' ' + os.environ['CFLAGS']
201 if 'CPPFLAGS' in os.environ:
202 cpp = cpp + ' ' + os.environ['CPPFLAGS']
203 cflags = cflags + ' ' + os.environ['CPPFLAGS']
204 ldshared = ldshared + ' ' + os.environ['CPPFLAGS']
Ned Deilyc47a4592012-02-11 20:40:24 +0100205 if 'AR' in os.environ:
206 ar = os.environ['AR']
207 if 'ARFLAGS' in os.environ:
208 archiver = ar + ' ' + os.environ['ARFLAGS']
209 else:
210 archiver = ar + ' ' + ar_flags
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000211
212 cc_cmd = cc + ' ' + cflags
213 compiler.set_executables(
214 preprocessor=cpp,
215 compiler=cc_cmd,
216 compiler_so=cc_cmd + ' ' + ccshared,
217 compiler_cxx=cxx,
218 linker_so=ldshared,
Ned Deilyc47a4592012-02-11 20:40:24 +0100219 linker_exe=cc,
220 archiver=archiver)
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000221
222 compiler.shared_lib_extension = so_ext
223
224
225def get_config_h_filename():
226 """Return full pathname of installed pyconfig.h file."""
227 if python_build:
228 if os.name == "nt":
229 inc_dir = os.path.join(project_base, "PC")
230 else:
231 inc_dir = project_base
232 else:
233 inc_dir = get_python_inc(plat_specific=1)
234 if get_python_version() < '2.2':
235 config_h = 'config.h'
236 else:
237 # The name of the config.h file changed in 2.2
238 config_h = 'pyconfig.h'
239 return os.path.join(inc_dir, config_h)
240
Greg Ward1190ee31998-12-18 23:46:33 +0000241
Greg Ward9ddaaa11999-01-06 14:46:06 +0000242def get_makefile_filename():
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000243 """Return full pathname of installed Makefile from the Python build."""
244 if python_build:
doko@python.orgd65e2ba2013-01-31 23:52:03 +0100245 return os.path.join(project_base, "Makefile")
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000246 lib_dir = get_python_lib(plat_specific=1, standard_lib=1)
247 return os.path.join(lib_dir, "config", "Makefile")
Greg Ward7d73b9e2000-03-09 03:16:05 +0000248
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000249
250def parse_config_h(fp, g=None):
251 """Parse a config.h-style file.
252
253 A dictionary containing name/value pairs is returned. If an
254 optional dictionary is passed in as the second argument, it is
255 used instead of a new dictionary.
Fred Drake522af3a1999-01-06 16:28:34 +0000256 """
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000257 if g is None:
258 g = {}
259 define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
260 undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
261 #
262 while 1:
263 line = fp.readline()
264 if not line:
265 break
266 m = define_rx.match(line)
267 if m:
268 n, v = m.group(1, 2)
269 try: v = int(v)
270 except ValueError: pass
271 g[n] = v
272 else:
273 m = undef_rx.match(line)
274 if m:
275 g[m.group(1)] = 0
276 return g
277
Greg Wardd283ce72000-09-17 00:53:02 +0000278
279# Regexes needed for parsing Makefile (and similar syntaxes,
280# like old-style Setup files).
281_variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
282_findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
283_findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
284
Greg Ward3fff8d22000-09-15 00:03:13 +0000285def parse_makefile(fn, g=None):
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000286 """Parse a Makefile-style file.
Fred Drakec1ee39a2000-03-09 15:54:52 +0000287
288 A dictionary containing name/value pairs is returned. If an
289 optional dictionary is passed in as the second argument, it is
290 used instead of a new dictionary.
Fred Drake522af3a1999-01-06 16:28:34 +0000291 """
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000292 from distutils.text_file import TextFile
293 fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1)
294
295 if g is None:
296 g = {}
297 done = {}
298 notdone = {}
299
300 while 1:
301 line = fp.readline()
302 if line is None: # eof
303 break
304 m = _variable_rx.match(line)
305 if m:
306 n, v = m.group(1, 2)
307 v = v.strip()
308 # `$$' is a literal `$' in make
309 tmpv = v.replace('$$', '')
310
311 if "$" in tmpv:
312 notdone[n] = v
313 else:
314 try:
315 v = int(v)
316 except ValueError:
317 # insert literal `$'
318 done[n] = v.replace('$$', '$')
319 else:
320 done[n] = v
321
322 # do variable interpolation here
323 while notdone:
324 for name in notdone.keys():
325 value = notdone[name]
326 m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
327 if m:
328 n = m.group(1)
329 found = True
330 if n in done:
331 item = str(done[n])
332 elif n in notdone:
333 # get it on a subsequent round
334 found = False
335 elif n in os.environ:
336 # do it like make: fall back to environment
337 item = os.environ[n]
338 else:
339 done[n] = item = ""
340 if found:
341 after = value[m.end():]
342 value = value[:m.start()] + item + after
343 if "$" in after:
344 notdone[name] = value
345 else:
346 try: value = int(value)
347 except ValueError:
348 done[name] = value.strip()
349 else:
350 done[name] = value
351 del notdone[name]
352 else:
353 # bogus variable reference; just drop it since we can't deal
354 del notdone[name]
355
356 fp.close()
357
Antoine Pitrou58dab672010-10-10 09:54:59 +0000358 # strip spurious spaces
359 for k, v in done.items():
360 if isinstance(v, str):
361 done[k] = v.strip()
362
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000363 # save the results in the global dictionary
364 g.update(done)
365 return g
366
Greg Ward1190ee31998-12-18 23:46:33 +0000367
Greg Wardd283ce72000-09-17 00:53:02 +0000368def expand_makefile_vars(s, vars):
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000369 """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in
Greg Wardd283ce72000-09-17 00:53:02 +0000370 'string' according to 'vars' (a dictionary mapping variable names to
371 values). Variables not present in 'vars' are silently expanded to the
372 empty string. The variable values in 'vars' should not contain further
373 variable expansions; if 'vars' is the output of 'parse_makefile()',
374 you're fine. Returns a variable-expanded version of 's'.
375 """
376
377 # This algorithm does multiple expansion, so if vars['foo'] contains
378 # "${bar}", it will expand ${foo} to ${bar}, and then expand
379 # ${bar}... and so forth. This is fine as long as 'vars' comes from
380 # 'parse_makefile()', which takes care of such expansions eagerly,
381 # according to make's variable expansion semantics.
382
383 while 1:
384 m = _findvar1_rx.search(s) or _findvar2_rx.search(s)
385 if m:
Greg Wardd283ce72000-09-17 00:53:02 +0000386 (beg, end) = m.span()
387 s = s[0:beg] + vars.get(m.group(1)) + s[end:]
388 else:
389 break
390 return s
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000391
392
393_config_vars = None
394
395def _init_posix():
396 """Initialize the module as appropriate for POSIX systems."""
doko@ubuntu.com6cb43432013-04-08 21:20:09 +0200397 # _sysconfigdata is generated at build time, see the sysconfig module
398 from _sysconfigdata import build_time_vars
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000399 global _config_vars
doko@ubuntu.com6cb43432013-04-08 21:20:09 +0200400 _config_vars = {}
401 _config_vars.update(build_time_vars)
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000402
403
404def _init_nt():
405 """Initialize the module as appropriate for NT"""
406 g = {}
407 # set basic install directories
408 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
409 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
410
411 # XXX hmmm.. a normal install puts include files here
412 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
413
414 g['SO'] = '.pyd'
415 g['EXE'] = ".exe"
416 g['VERSION'] = get_python_version().replace(".", "")
417 g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable))
418
419 global _config_vars
420 _config_vars = g
421
422
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000423def _init_os2():
424 """Initialize the module as appropriate for OS/2"""
425 g = {}
426 # set basic install directories
427 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
428 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
429
430 # XXX hmmm.. a normal install puts include files here
431 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
432
433 g['SO'] = '.pyd'
434 g['EXE'] = ".exe"
435
436 global _config_vars
437 _config_vars = g
438
439
440def get_config_vars(*args):
441 """With no arguments, return a dictionary of all configuration
442 variables relevant for the current platform. Generally this includes
443 everything needed to build extensions and install both pure modules and
444 extensions. On Unix, this means every variable defined in Python's
445 installed Makefile; on Windows and Mac OS it's a much smaller set.
446
447 With arguments, return a list of values that result from looking up
448 each argument in the configuration variable dictionary.
449 """
450 global _config_vars
451 if _config_vars is None:
452 func = globals().get("_init_" + os.name)
453 if func:
454 func()
455 else:
456 _config_vars = {}
457
458 # Normalized versions of prefix and exec_prefix are handy to have;
459 # in fact, these are the standard versions used most places in the
460 # Distutils.
461 _config_vars['prefix'] = PREFIX
462 _config_vars['exec_prefix'] = EXEC_PREFIX
463
Ned Deily18fae3f2013-01-31 01:24:55 -0800464 # OS X platforms require special customization to handle
465 # multi-architecture, multi-os-version installers
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000466 if sys.platform == 'darwin':
Ned Deily18fae3f2013-01-31 01:24:55 -0800467 import _osx_support
468 _osx_support.customize_config_vars(_config_vars)
Tarek Ziadédd7bef92010-03-05 00:16:02 +0000469
470 if args:
471 vals = []
472 for name in args:
473 vals.append(_config_vars.get(name))
474 return vals
475 else:
476 return _config_vars
477
478def get_config_var(name):
479 """Return the value of a single variable using the dictionary
480 returned by 'get_config_vars()'. Equivalent to
481 get_config_vars().get(name)
482 """
483 return get_config_vars().get(name)