blob: b433fc86ffccd788975db4d4eb0800861bad8a2b [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
Steve Dower65e4cb12014-11-22 12:54:57 -080012import _imp
Greg Ward9ddaaa11999-01-06 14:46:06 +000013import os
14import re
Tarek Ziadé36797272010-07-22 12:50:05 +000015import sys
Greg Ward1190ee31998-12-18 23:46:33 +000016
Tarek Ziadé36797272010-07-22 12:50:05 +000017from .errors import DistutilsPlatformError
Greg Warda0ca3f22000-02-02 00:05:14 +000018
Tarek Ziadé36797272010-07-22 12:50:05 +000019# These are needed in a couple of spots, so just compute them once.
20PREFIX = os.path.normpath(sys.prefix)
21EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
Vinay Sajip7ded1f02012-05-26 03:45:29 +010022BASE_PREFIX = os.path.normpath(sys.base_prefix)
23BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix)
Fred Drakec1ee39a2000-03-09 15:54:52 +000024
Tarek Ziadé36797272010-07-22 12:50:05 +000025# Path to the base directory of the project. On Windows the binary may
Stefan Grönkef1502d02017-09-25 18:58:10 +020026# live in project/PCbuild/win32 or project/PCbuild/amd64.
doko@python.org97313302013-01-25 14:33:33 +010027# set for cross builds
28if "_PYTHON_PROJECT_BASE" in os.environ:
29 project_base = os.path.abspath(os.environ["_PYTHON_PROJECT_BASE"])
30else:
31 project_base = os.path.dirname(os.path.abspath(sys.executable))
Steve Dower65e4cb12014-11-22 12:54:57 -080032if (os.name == 'nt' and
33 project_base.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))):
34 project_base = os.path.dirname(os.path.dirname(project_base))
Tarek Ziadé8b441d02010-01-29 11:46:31 +000035
Tarek Ziadé36797272010-07-22 12:50:05 +000036# python_build: (Boolean) if true, we're either building Python or
37# building an extension with an un-installed Python, so we use
38# different (hard-wired) directories.
Vinay Sajip7ded1f02012-05-26 03:45:29 +010039def _is_python_source_dir(d):
Antoine Pitrou961d54c2018-07-16 19:03:03 +020040 for fn in ("Setup", "Setup.local"):
Vinay Sajip7ded1f02012-05-26 03:45:29 +010041 if os.path.isfile(os.path.join(d, "Modules", fn)):
Tarek Ziadé36797272010-07-22 12:50:05 +000042 return True
43 return False
Vinay Sajip7ded1f02012-05-26 03:45:29 +010044_sys_home = getattr(sys, '_home', None)
Steve Dower65e4cb12014-11-22 12:54:57 -080045if (_sys_home and os.name == 'nt' and
46 _sys_home.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))):
47 _sys_home = os.path.dirname(os.path.dirname(_sys_home))
Vinay Sajip7ded1f02012-05-26 03:45:29 +010048def _python_build():
49 if _sys_home:
50 return _is_python_source_dir(_sys_home)
51 return _is_python_source_dir(project_base)
Christian Heimes2202f872008-02-06 14:31:34 +000052python_build = _python_build()
Fred Drakec916cdc2001-08-02 20:03:12 +000053
Barry Warsaw14d98ac2010-11-24 19:43:47 +000054# Calculate the build qualifier flags if they are defined. Adding the flags
55# to the include and lib directories only makes sense for an installation, not
56# an in-source build.
57build_flags = ''
58try:
59 if not python_build:
60 build_flags = sys.abiflags
61except AttributeError:
62 # It's not a configure-based build, so the sys module doesn't have
63 # this attribute, which is fine.
64 pass
65
Tarek Ziadé36797272010-07-22 12:50:05 +000066def get_python_version():
67 """Return a string containing the major and minor Python version,
68 leaving off the patchlevel. Sample return values could be '1.5'
69 or '2.2'.
70 """
Serhiy Storchaka885bdc42016-02-11 13:10:36 +020071 return '%d.%d' % sys.version_info[:2]
Tarek Ziadéedacea32010-01-29 11:41:03 +000072
Tarek Ziadé36797272010-07-22 12:50:05 +000073
74def get_python_inc(plat_specific=0, prefix=None):
75 """Return the directory containing installed Python header files.
Fred Drakec1ee39a2000-03-09 15:54:52 +000076
77 If 'plat_specific' is false (the default), this is the path to the
78 non-platform-specific header files, i.e. Python.h and so on;
79 otherwise, this is the path to platform-specific header files
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000080 (namely pyconfig.h).
Fred Drakec1ee39a2000-03-09 15:54:52 +000081
Vinay Sajip7ded1f02012-05-26 03:45:29 +010082 If 'prefix' is supplied, use it instead of sys.base_prefix or
83 sys.base_exec_prefix -- i.e., ignore 'plat_specific'.
Fred Drakeb94b8492001-12-06 20:51:35 +000084 """
Tarek Ziadé36797272010-07-22 12:50:05 +000085 if prefix is None:
Vinay Sajip7ded1f02012-05-26 03:45:29 +010086 prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX
Tarek Ziadé36797272010-07-22 12:50:05 +000087 if os.name == "posix":
88 if python_build:
Vinay Sajipae7d7fa2010-09-20 10:29:54 +000089 # Assume the executable is in the build directory. The
90 # pyconfig.h file should be in the same directory. Since
91 # the build directory may not be the source directory, we
92 # must use "srcdir" from the makefile to find the "Include"
93 # directory.
Vinay Sajipae7d7fa2010-09-20 10:29:54 +000094 if plat_specific:
Jeremy Klothdbdea622017-05-09 09:24:13 -060095 return _sys_home or project_base
Vinay Sajipae7d7fa2010-09-20 10:29:54 +000096 else:
Vinay Sajip048b0632012-07-16 18:24:55 +010097 incdir = os.path.join(get_config_var('srcdir'), 'Include')
Jeremy Klothdbdea622017-05-09 09:24:13 -060098 return os.path.normpath(incdir)
Barry Warsaw14d98ac2010-11-24 19:43:47 +000099 python_dir = 'python' + get_python_version() + build_flags
100 return os.path.join(prefix, "include", python_dir)
Tarek Ziadé36797272010-07-22 12:50:05 +0000101 elif os.name == "nt":
102 return os.path.join(prefix, "include")
Greg Ward7d73b9e2000-03-09 03:16:05 +0000103 else:
Tarek Ziadé36797272010-07-22 12:50:05 +0000104 raise DistutilsPlatformError(
105 "I don't know where Python installs its C header files "
106 "on platform '%s'" % os.name)
Greg Ward7d73b9e2000-03-09 03:16:05 +0000107
108
Tarek Ziadé36797272010-07-22 12:50:05 +0000109def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
110 """Return the directory containing the Python library (standard or
Fred Drakec1ee39a2000-03-09 15:54:52 +0000111 site additions).
Greg Ward7d73b9e2000-03-09 03:16:05 +0000112
Fred Drakec1ee39a2000-03-09 15:54:52 +0000113 If 'plat_specific' is true, return the directory containing
114 platform-specific modules, i.e. any module from a non-pure-Python
115 module distribution; otherwise, return the platform-shared library
116 directory. If 'standard_lib' is true, return the directory
117 containing standard Python library modules; otherwise, return the
118 directory for site-specific modules.
119
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100120 If 'prefix' is supplied, use it instead of sys.base_prefix or
121 sys.base_exec_prefix -- i.e., ignore 'plat_specific'.
Fred Drakec1ee39a2000-03-09 15:54:52 +0000122 """
Tarek Ziadé36797272010-07-22 12:50:05 +0000123 if prefix is None:
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100124 if standard_lib:
125 prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX
126 else:
127 prefix = plat_specific and EXEC_PREFIX or PREFIX
Tarek Ziadé36797272010-07-22 12:50:05 +0000128
129 if os.name == "posix":
130 libpython = os.path.join(prefix,
131 "lib", "python" + get_python_version())
132 if standard_lib:
133 return libpython
Greg Ward7d73b9e2000-03-09 03:16:05 +0000134 else:
Tarek Ziadé36797272010-07-22 12:50:05 +0000135 return os.path.join(libpython, "site-packages")
136 elif os.name == "nt":
137 if standard_lib:
138 return os.path.join(prefix, "Lib")
Marc-André Lemburg2544f512002-01-31 18:56:00 +0000139 else:
Benjamin Petersondf0eb952014-09-06 17:24:12 -0400140 return os.path.join(prefix, "Lib", "site-packages")
Greg Ward7d73b9e2000-03-09 03:16:05 +0000141 else:
Tarek Ziadé36797272010-07-22 12:50:05 +0000142 raise DistutilsPlatformError(
143 "I don't know where Python installs its library "
144 "on platform '%s'" % os.name)
145
Ned Deilycbfb9a52012-06-23 16:02:19 -0700146
Tarek Ziadé36797272010-07-22 12:50:05 +0000147
148def customize_compiler(compiler):
149 """Do any platform-specific customization of a CCompiler instance.
150
151 Mainly needed on Unix, so we can plug in the information that
152 varies across Unices and is stored in Python's Makefile.
153 """
154 if compiler.compiler_type == "unix":
Ned Deilydf8aa2b2012-07-21 05:36:30 -0700155 if sys.platform == "darwin":
156 # Perform first-time customization of compiler-related
157 # config vars on OS X now that we know we need a compiler.
158 # This is primarily to support Pythons from binary
159 # installers. The kind and paths to build tools on
160 # the user system may vary significantly from the system
161 # that Python itself was built on. Also the user OS
162 # version and build tools may not support the same set
163 # of CPU architectures for universal builds.
164 global _config_vars
Ned Deily7bc5fb62014-07-06 16:14:33 -0700165 # Use get_config_var() to ensure _config_vars is initialized.
166 if not get_config_var('CUSTOMIZED_OSX_COMPILER'):
Ned Deilydf8aa2b2012-07-21 05:36:30 -0700167 import _osx_support
168 _osx_support.customize_compiler(_config_vars)
169 _config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True'
170
doko@ubuntu.comd5537d02013-03-21 13:21:49 -0700171 (cc, cxx, opt, cflags, ccshared, ldshared, shlib_suffix, ar, ar_flags) = \
Tarek Ziadé36797272010-07-22 12:50:05 +0000172 get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
doko@ubuntu.comd5537d02013-03-21 13:21:49 -0700173 'CCSHARED', 'LDSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS')
Tarek Ziadé36797272010-07-22 12:50:05 +0000174
175 if 'CC' in os.environ:
Ned Deily97345682013-05-28 16:35:30 -0700176 newcc = os.environ['CC']
177 if (sys.platform == 'darwin'
178 and 'LDSHARED' not in os.environ
179 and ldshared.startswith(cc)):
180 # On OS X, if CC is overridden, use that as the default
181 # command for LDSHARED as well
182 ldshared = newcc + ldshared[len(cc):]
183 cc = newcc
Tarek Ziadé36797272010-07-22 12:50:05 +0000184 if 'CXX' in os.environ:
185 cxx = os.environ['CXX']
186 if 'LDSHARED' in os.environ:
187 ldshared = os.environ['LDSHARED']
188 if 'CPP' in os.environ:
189 cpp = os.environ['CPP']
Andrew M. Kuchling29c86232002-11-04 19:53:24 +0000190 else:
Tarek Ziadé36797272010-07-22 12:50:05 +0000191 cpp = cc + " -E" # not always
192 if 'LDFLAGS' in os.environ:
193 ldshared = ldshared + ' ' + os.environ['LDFLAGS']
194 if 'CFLAGS' in os.environ:
195 cflags = opt + ' ' + os.environ['CFLAGS']
196 ldshared = ldshared + ' ' + os.environ['CFLAGS']
197 if 'CPPFLAGS' in os.environ:
198 cpp = cpp + ' ' + os.environ['CPPFLAGS']
199 cflags = cflags + ' ' + os.environ['CPPFLAGS']
200 ldshared = ldshared + ' ' + os.environ['CPPFLAGS']
201 if 'AR' in os.environ:
202 ar = os.environ['AR']
203 if 'ARFLAGS' in os.environ:
204 archiver = ar + ' ' + os.environ['ARFLAGS']
205 else:
206 archiver = ar + ' ' + ar_flags
207
208 cc_cmd = cc + ' ' + cflags
209 compiler.set_executables(
210 preprocessor=cpp,
211 compiler=cc_cmd,
212 compiler_so=cc_cmd + ' ' + ccshared,
213 compiler_cxx=cxx,
214 linker_so=ldshared,
215 linker_exe=cc,
216 archiver=archiver)
217
doko@ubuntu.comd5537d02013-03-21 13:21:49 -0700218 compiler.shared_lib_extension = shlib_suffix
Tarek Ziadé36797272010-07-22 12:50:05 +0000219
220
221def get_config_h_filename():
222 """Return full pathname of installed pyconfig.h file."""
223 if python_build:
224 if os.name == "nt":
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100225 inc_dir = os.path.join(_sys_home or project_base, "PC")
Tarek Ziadé36797272010-07-22 12:50:05 +0000226 else:
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100227 inc_dir = _sys_home or project_base
Tarek Ziadé36797272010-07-22 12:50:05 +0000228 else:
229 inc_dir = get_python_inc(plat_specific=1)
Benjamin Petersondf0eb952014-09-06 17:24:12 -0400230
231 return os.path.join(inc_dir, 'pyconfig.h')
Tarek Ziadé36797272010-07-22 12:50:05 +0000232
Greg Ward1190ee31998-12-18 23:46:33 +0000233
Greg Ward9ddaaa11999-01-06 14:46:06 +0000234def get_makefile_filename():
Tarek Ziadé36797272010-07-22 12:50:05 +0000235 """Return full pathname of installed Makefile from the Python build."""
236 if python_build:
doko@python.org97313302013-01-25 14:33:33 +0100237 return os.path.join(_sys_home or project_base, "Makefile")
Éric Araujofea2d042011-10-08 01:56:52 +0200238 lib_dir = get_python_lib(plat_specific=0, standard_lib=1)
Barry Warsaw14d98ac2010-11-24 19:43:47 +0000239 config_file = 'config-{}{}'.format(get_python_version(), build_flags)
doko@ubuntu.com55532312016-06-14 08:55:19 +0200240 if hasattr(sys.implementation, '_multiarch'):
241 config_file += '-%s' % sys.implementation._multiarch
Barry Warsaw14d98ac2010-11-24 19:43:47 +0000242 return os.path.join(lib_dir, config_file, 'Makefile')
Greg Ward7d73b9e2000-03-09 03:16:05 +0000243
Tarek Ziadé36797272010-07-22 12:50:05 +0000244
245def parse_config_h(fp, g=None):
246 """Parse a config.h-style file.
247
248 A dictionary containing name/value pairs is returned. If an
249 optional dictionary is passed in as the second argument, it is
250 used instead of a new dictionary.
Fred Drake522af3a1999-01-06 16:28:34 +0000251 """
Tarek Ziadé36797272010-07-22 12:50:05 +0000252 if g is None:
253 g = {}
254 define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
255 undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
256 #
257 while True:
258 line = fp.readline()
259 if not line:
260 break
261 m = define_rx.match(line)
262 if m:
263 n, v = m.group(1, 2)
264 try: v = int(v)
265 except ValueError: pass
266 g[n] = v
267 else:
268 m = undef_rx.match(line)
269 if m:
270 g[m.group(1)] = 0
271 return g
Greg Ward1190ee31998-12-18 23:46:33 +0000272
Greg Wardd283ce72000-09-17 00:53:02 +0000273
274# Regexes needed for parsing Makefile (and similar syntaxes,
275# like old-style Setup files).
R David Murray44b548d2016-09-08 13:59:53 -0400276_variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
Greg Wardd283ce72000-09-17 00:53:02 +0000277_findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
278_findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
279
Greg Ward3fff8d22000-09-15 00:03:13 +0000280def parse_makefile(fn, g=None):
Tarek Ziadé36797272010-07-22 12:50:05 +0000281 """Parse a Makefile-style file.
Fred Drakec1ee39a2000-03-09 15:54:52 +0000282
283 A dictionary containing name/value pairs is returned. If an
284 optional dictionary is passed in as the second argument, it is
285 used instead of a new dictionary.
Fred Drake522af3a1999-01-06 16:28:34 +0000286 """
Tarek Ziadé36797272010-07-22 12:50:05 +0000287 from distutils.text_file import TextFile
Victor Stinner75d8c5c2010-10-23 17:02:31 +0000288 fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1, errors="surrogateescape")
Tarek Ziadé36797272010-07-22 12:50:05 +0000289
290 if g is None:
291 g = {}
292 done = {}
293 notdone = {}
294
295 while True:
296 line = fp.readline()
297 if line is None: # eof
298 break
299 m = _variable_rx.match(line)
300 if m:
301 n, v = m.group(1, 2)
302 v = v.strip()
303 # `$$' is a literal `$' in make
304 tmpv = v.replace('$$', '')
305
306 if "$" in tmpv:
307 notdone[n] = v
308 else:
309 try:
310 v = int(v)
311 except ValueError:
312 # insert literal `$'
313 done[n] = v.replace('$$', '$')
314 else:
315 done[n] = v
316
Ronald Oussorene8d252d2010-07-23 09:43:17 +0000317 # Variables with a 'PY_' prefix in the makefile. These need to
318 # be made available without that prefix through sysconfig.
319 # Special care is needed to ensure that variable expansion works, even
320 # if the expansion uses the name without a prefix.
321 renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS')
322
Tarek Ziadé36797272010-07-22 12:50:05 +0000323 # do variable interpolation here
324 while notdone:
325 for name in list(notdone):
326 value = notdone[name]
327 m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
328 if m:
329 n = m.group(1)
330 found = True
331 if n in done:
332 item = str(done[n])
333 elif n in notdone:
334 # get it on a subsequent round
335 found = False
336 elif n in os.environ:
337 # do it like make: fall back to environment
338 item = os.environ[n]
Ronald Oussorene8d252d2010-07-23 09:43:17 +0000339
340 elif n in renamed_variables:
341 if name.startswith('PY_') and name[3:] in renamed_variables:
342 item = ""
343
344 elif 'PY_' + n in notdone:
345 found = False
346
347 else:
348 item = str(done['PY_' + n])
Tarek Ziadé36797272010-07-22 12:50:05 +0000349 else:
350 done[n] = item = ""
351 if found:
352 after = value[m.end():]
353 value = value[:m.start()] + item + after
354 if "$" in after:
355 notdone[name] = value
356 else:
357 try: value = int(value)
358 except ValueError:
359 done[name] = value.strip()
360 else:
361 done[name] = value
362 del notdone[name]
Ronald Oussorene8d252d2010-07-23 09:43:17 +0000363
364 if name.startswith('PY_') \
365 and name[3:] in renamed_variables:
366
367 name = name[3:]
368 if name not in done:
369 done[name] = value
Tarek Ziadé36797272010-07-22 12:50:05 +0000370 else:
371 # bogus variable reference; just drop it since we can't deal
372 del notdone[name]
373
374 fp.close()
375
Antoine Pitroudbec7802010-10-10 09:37:12 +0000376 # strip spurious spaces
377 for k, v in done.items():
378 if isinstance(v, str):
379 done[k] = v.strip()
380
Tarek Ziadé36797272010-07-22 12:50:05 +0000381 # save the results in the global dictionary
382 g.update(done)
383 return g
384
Greg Ward1190ee31998-12-18 23:46:33 +0000385
Greg Wardd283ce72000-09-17 00:53:02 +0000386def expand_makefile_vars(s, vars):
Tarek Ziadé36797272010-07-22 12:50:05 +0000387 """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in
Greg Wardd283ce72000-09-17 00:53:02 +0000388 'string' according to 'vars' (a dictionary mapping variable names to
389 values). Variables not present in 'vars' are silently expanded to the
390 empty string. The variable values in 'vars' should not contain further
391 variable expansions; if 'vars' is the output of 'parse_makefile()',
392 you're fine. Returns a variable-expanded version of 's'.
393 """
394
395 # This algorithm does multiple expansion, so if vars['foo'] contains
396 # "${bar}", it will expand ${foo} to ${bar}, and then expand
397 # ${bar}... and so forth. This is fine as long as 'vars' comes from
398 # 'parse_makefile()', which takes care of such expansions eagerly,
399 # according to make's variable expansion semantics.
400
Collin Winter5b7e9d72007-08-30 03:52:21 +0000401 while True:
Greg Wardd283ce72000-09-17 00:53:02 +0000402 m = _findvar1_rx.search(s) or _findvar2_rx.search(s)
403 if m:
Greg Wardd283ce72000-09-17 00:53:02 +0000404 (beg, end) = m.span()
405 s = s[0:beg] + vars.get(m.group(1)) + s[end:]
406 else:
407 break
408 return s
Tarek Ziadé36797272010-07-22 12:50:05 +0000409
410
411_config_vars = None
412
413def _init_posix():
414 """Initialize the module as appropriate for POSIX systems."""
doko@ubuntu.com40948222016-06-05 01:17:57 +0200415 # _sysconfigdata is generated at build time, see the sysconfig module
Xavier de Gaye92dec542016-09-11 22:22:24 +0200416 name = os.environ.get('_PYTHON_SYSCONFIGDATA_NAME',
417 '_sysconfigdata_{abi}_{platform}_{multiarch}'.format(
Zachary Ware80da9932016-09-09 18:29:10 -0700418 abi=sys.abiflags,
419 platform=sys.platform,
420 multiarch=getattr(sys.implementation, '_multiarch', ''),
Xavier de Gaye92dec542016-09-11 22:22:24 +0200421 ))
doko@ubuntu.comeea86b02016-06-14 09:22:16 +0200422 _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
423 build_time_vars = _temp.build_time_vars
Tarek Ziadé36797272010-07-22 12:50:05 +0000424 global _config_vars
doko@ubuntu.com40948222016-06-05 01:17:57 +0200425 _config_vars = {}
426 _config_vars.update(build_time_vars)
Tarek Ziadé36797272010-07-22 12:50:05 +0000427
428
429def _init_nt():
430 """Initialize the module as appropriate for NT"""
431 g = {}
432 # set basic install directories
433 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
434 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
435
436 # XXX hmmm.. a normal install puts include files here
437 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
438
Steve Dower65e4cb12014-11-22 12:54:57 -0800439 g['EXT_SUFFIX'] = _imp.extension_suffixes()[0]
Tarek Ziadé36797272010-07-22 12:50:05 +0000440 g['EXE'] = ".exe"
441 g['VERSION'] = get_python_version().replace(".", "")
442 g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable))
443
444 global _config_vars
445 _config_vars = g
446
447
Tarek Ziadé36797272010-07-22 12:50:05 +0000448def get_config_vars(*args):
449 """With no arguments, return a dictionary of all configuration
450 variables relevant for the current platform. Generally this includes
451 everything needed to build extensions and install both pure modules and
452 extensions. On Unix, this means every variable defined in Python's
Ned Deilydf8aa2b2012-07-21 05:36:30 -0700453 installed Makefile; on Windows it's a much smaller set.
Tarek Ziadé36797272010-07-22 12:50:05 +0000454
455 With arguments, return a list of values that result from looking up
456 each argument in the configuration variable dictionary.
457 """
458 global _config_vars
459 if _config_vars is None:
460 func = globals().get("_init_" + os.name)
461 if func:
462 func()
463 else:
464 _config_vars = {}
465
466 # Normalized versions of prefix and exec_prefix are handy to have;
467 # in fact, these are the standard versions used most places in the
468 # Distutils.
469 _config_vars['prefix'] = PREFIX
470 _config_vars['exec_prefix'] = EXEC_PREFIX
471
Barry Warsaw9121f8d2013-11-22 15:31:35 -0500472 # For backward compatibility, see issue19555
473 SO = _config_vars.get('EXT_SUFFIX')
474 if SO is not None:
475 _config_vars['SO'] = SO
476
Richard Oudkerk46874ad2012-07-27 12:06:55 +0100477 # Always convert srcdir to an absolute path
478 srcdir = _config_vars.get('srcdir', project_base)
479 if os.name == 'posix':
480 if python_build:
481 # If srcdir is a relative path (typically '.' or '..')
482 # then it should be interpreted relative to the directory
483 # containing Makefile.
484 base = os.path.dirname(get_makefile_filename())
485 srcdir = os.path.join(base, srcdir)
486 else:
487 # srcdir is not meaningful since the installation is
488 # spread about the filesystem. We choose the
489 # directory containing the Makefile since we know it
490 # exists.
491 srcdir = os.path.dirname(get_makefile_filename())
492 _config_vars['srcdir'] = os.path.abspath(os.path.normpath(srcdir))
493
Tarek Ziadé36797272010-07-22 12:50:05 +0000494 # Convert srcdir into an absolute path if it appears necessary.
495 # Normally it is relative to the build directory. However, during
496 # testing, for example, we might be running a non-installed python
497 # from a different directory.
498 if python_build and os.name == "posix":
doko@python.org97313302013-01-25 14:33:33 +0100499 base = project_base
Tarek Ziadé36797272010-07-22 12:50:05 +0000500 if (not os.path.isabs(_config_vars['srcdir']) and
501 base != os.getcwd()):
502 # srcdir is relative and we are not in the same directory
503 # as the executable. Assume executable is in the build
504 # directory and make srcdir absolute.
505 srcdir = os.path.join(base, _config_vars['srcdir'])
506 _config_vars['srcdir'] = os.path.normpath(srcdir)
507
Ned Deilydf8aa2b2012-07-21 05:36:30 -0700508 # OS X platforms require special customization to handle
509 # multi-architecture, multi-os-version installers
Tarek Ziadé36797272010-07-22 12:50:05 +0000510 if sys.platform == 'darwin':
Ned Deilydf8aa2b2012-07-21 05:36:30 -0700511 import _osx_support
512 _osx_support.customize_config_vars(_config_vars)
Ned Deily27471772012-07-15 21:30:03 -0700513
Tarek Ziadé36797272010-07-22 12:50:05 +0000514 if args:
515 vals = []
516 for name in args:
517 vals.append(_config_vars.get(name))
518 return vals
519 else:
520 return _config_vars
521
522def get_config_var(name):
523 """Return the value of a single variable using the dictionary
524 returned by 'get_config_vars()'. Equivalent to
525 get_config_vars().get(name)
526 """
Barry Warsaw9121f8d2013-11-22 15:31:35 -0500527 if name == 'SO':
528 import warnings
Serhiy Storchakaeaec3592013-11-26 17:08:24 +0200529 warnings.warn('SO is deprecated, use EXT_SUFFIX', DeprecationWarning, 2)
Tarek Ziadé36797272010-07-22 12:50:05 +0000530 return get_config_vars().get(name)