blob: 409ef74ca10b2265fd7d565b0603a47a2d43d76e [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 Ward9ddaaa11999-01-06 14:46:06 +000012import os
13import re
Tarek Ziadé36797272010-07-22 12:50:05 +000014import sys
Greg Ward1190ee31998-12-18 23:46:33 +000015
Tarek Ziadé36797272010-07-22 12:50:05 +000016from .errors import DistutilsPlatformError
Greg Warda0ca3f22000-02-02 00:05:14 +000017
Tarek Ziadé36797272010-07-22 12:50:05 +000018# These are needed in a couple of spots, so just compute them once.
19PREFIX = os.path.normpath(sys.prefix)
20EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
Vinay Sajip7ded1f02012-05-26 03:45:29 +010021BASE_PREFIX = os.path.normpath(sys.base_prefix)
22BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix)
Fred Drakec1ee39a2000-03-09 15:54:52 +000023
Tarek Ziadé36797272010-07-22 12:50:05 +000024# Path to the base directory of the project. On Windows the binary may
25# live in project/PCBuild9. If we're dealing with an x64 Windows build,
26# it'll live in project/PCbuild/amd64.
27project_base = os.path.dirname(os.path.abspath(sys.executable))
28if os.name == "nt" and "pcbuild" in project_base[-8:].lower():
29 project_base = os.path.abspath(os.path.join(project_base, os.path.pardir))
30# PC/VS7.1
31if os.name == "nt" and "\\pc\\v" in project_base[-10:].lower():
32 project_base = os.path.abspath(os.path.join(project_base, os.path.pardir,
33 os.path.pardir))
34# PC/AMD64
35if os.name == "nt" and "\\pcbuild\\amd64" in project_base[-14:].lower():
36 project_base = os.path.abspath(os.path.join(project_base, os.path.pardir,
37 os.path.pardir))
Tarek Ziadé8b441d02010-01-29 11:46:31 +000038
Tarek Ziadé36797272010-07-22 12:50:05 +000039# python_build: (Boolean) if true, we're either building Python or
40# building an extension with an un-installed Python, so we use
41# different (hard-wired) directories.
42# Setup.local is available for Makefile builds including VPATH builds,
43# Setup.dist is available on Windows
Vinay Sajip7ded1f02012-05-26 03:45:29 +010044def _is_python_source_dir(d):
Tarek Ziadé36797272010-07-22 12:50:05 +000045 for fn in ("Setup.dist", "Setup.local"):
Vinay Sajip7ded1f02012-05-26 03:45:29 +010046 if os.path.isfile(os.path.join(d, "Modules", fn)):
Tarek Ziadé36797272010-07-22 12:50:05 +000047 return True
48 return False
Vinay Sajip7ded1f02012-05-26 03:45:29 +010049_sys_home = getattr(sys, '_home', None)
Vinay Sajip42211422012-05-26 20:36:12 +010050if _sys_home and os.name == 'nt' and \
51 _sys_home.lower().endswith(('pcbuild', 'pcbuild\\amd64')):
Vinay Sajip7ded1f02012-05-26 03:45:29 +010052 _sys_home = os.path.dirname(_sys_home)
Vinay Sajip7e203492012-05-27 17:30:09 +010053 if _sys_home.endswith('pcbuild'): # must be amd64
54 _sys_home = os.path.dirname(_sys_home)
Vinay Sajip7ded1f02012-05-26 03:45:29 +010055def _python_build():
56 if _sys_home:
57 return _is_python_source_dir(_sys_home)
58 return _is_python_source_dir(project_base)
Christian Heimes2202f872008-02-06 14:31:34 +000059python_build = _python_build()
Fred Drakec916cdc2001-08-02 20:03:12 +000060
Barry Warsaw14d98ac2010-11-24 19:43:47 +000061# Calculate the build qualifier flags if they are defined. Adding the flags
62# to the include and lib directories only makes sense for an installation, not
63# an in-source build.
64build_flags = ''
65try:
66 if not python_build:
67 build_flags = sys.abiflags
68except AttributeError:
69 # It's not a configure-based build, so the sys module doesn't have
70 # this attribute, which is fine.
71 pass
72
Tarek Ziadé36797272010-07-22 12:50:05 +000073def get_python_version():
74 """Return a string containing the major and minor Python version,
75 leaving off the patchlevel. Sample return values could be '1.5'
76 or '2.2'.
77 """
78 return sys.version[:3]
Tarek Ziadéedacea32010-01-29 11:41:03 +000079
Tarek Ziadé36797272010-07-22 12:50:05 +000080
81def get_python_inc(plat_specific=0, prefix=None):
82 """Return the directory containing installed Python header files.
Fred Drakec1ee39a2000-03-09 15:54:52 +000083
84 If 'plat_specific' is false (the default), this is the path to the
85 non-platform-specific header files, i.e. Python.h and so on;
86 otherwise, this is the path to platform-specific header files
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000087 (namely pyconfig.h).
Fred Drakec1ee39a2000-03-09 15:54:52 +000088
Vinay Sajip7ded1f02012-05-26 03:45:29 +010089 If 'prefix' is supplied, use it instead of sys.base_prefix or
90 sys.base_exec_prefix -- i.e., ignore 'plat_specific'.
Fred Drakeb94b8492001-12-06 20:51:35 +000091 """
Tarek Ziadé36797272010-07-22 12:50:05 +000092 if prefix is None:
Vinay Sajip7ded1f02012-05-26 03:45:29 +010093 prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX
Tarek Ziadé36797272010-07-22 12:50:05 +000094 if os.name == "posix":
95 if python_build:
Vinay Sajipae7d7fa2010-09-20 10:29:54 +000096 # Assume the executable is in the build directory. The
97 # pyconfig.h file should be in the same directory. Since
98 # the build directory may not be the source directory, we
99 # must use "srcdir" from the makefile to find the "Include"
100 # directory.
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100101 base = _sys_home or os.path.dirname(os.path.abspath(sys.executable))
Vinay Sajipae7d7fa2010-09-20 10:29:54 +0000102 if plat_specific:
103 return base
Vinay Sajip048b0632012-07-16 18:24:55 +0100104 if _sys_home:
105 incdir = os.path.join(_sys_home, get_config_var('AST_H_DIR'))
Vinay Sajipae7d7fa2010-09-20 10:29:54 +0000106 else:
Vinay Sajip048b0632012-07-16 18:24:55 +0100107 incdir = os.path.join(get_config_var('srcdir'), 'Include')
108 return os.path.normpath(incdir)
Barry Warsaw14d98ac2010-11-24 19:43:47 +0000109 python_dir = 'python' + get_python_version() + build_flags
110 return os.path.join(prefix, "include", python_dir)
Tarek Ziadé36797272010-07-22 12:50:05 +0000111 elif os.name == "nt":
112 return os.path.join(prefix, "include")
Tarek Ziadé36797272010-07-22 12:50:05 +0000113 elif os.name == "os2":
114 return os.path.join(prefix, "Include")
Greg Ward7d73b9e2000-03-09 03:16:05 +0000115 else:
Tarek Ziadé36797272010-07-22 12:50:05 +0000116 raise DistutilsPlatformError(
117 "I don't know where Python installs its C header files "
118 "on platform '%s'" % os.name)
Greg Ward7d73b9e2000-03-09 03:16:05 +0000119
120
Tarek Ziadé36797272010-07-22 12:50:05 +0000121def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
122 """Return the directory containing the Python library (standard or
Fred Drakec1ee39a2000-03-09 15:54:52 +0000123 site additions).
Greg Ward7d73b9e2000-03-09 03:16:05 +0000124
Fred Drakec1ee39a2000-03-09 15:54:52 +0000125 If 'plat_specific' is true, return the directory containing
126 platform-specific modules, i.e. any module from a non-pure-Python
127 module distribution; otherwise, return the platform-shared library
128 directory. If 'standard_lib' is true, return the directory
129 containing standard Python library modules; otherwise, return the
130 directory for site-specific modules.
131
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100132 If 'prefix' is supplied, use it instead of sys.base_prefix or
133 sys.base_exec_prefix -- i.e., ignore 'plat_specific'.
Fred Drakec1ee39a2000-03-09 15:54:52 +0000134 """
Tarek Ziadé36797272010-07-22 12:50:05 +0000135 if prefix is None:
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100136 if standard_lib:
137 prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX
138 else:
139 prefix = plat_specific and EXEC_PREFIX or PREFIX
Tarek Ziadé36797272010-07-22 12:50:05 +0000140
141 if os.name == "posix":
142 libpython = os.path.join(prefix,
143 "lib", "python" + get_python_version())
144 if standard_lib:
145 return libpython
Greg Ward7d73b9e2000-03-09 03:16:05 +0000146 else:
Tarek Ziadé36797272010-07-22 12:50:05 +0000147 return os.path.join(libpython, "site-packages")
148 elif os.name == "nt":
149 if standard_lib:
150 return os.path.join(prefix, "Lib")
Marc-André Lemburg2544f512002-01-31 18:56:00 +0000151 else:
Tarek Ziadé36797272010-07-22 12:50:05 +0000152 if get_python_version() < "2.2":
153 return prefix
154 else:
155 return os.path.join(prefix, "Lib", "site-packages")
Tarek Ziadé36797272010-07-22 12:50:05 +0000156 elif os.name == "os2":
157 if standard_lib:
158 return os.path.join(prefix, "Lib")
159 else:
160 return os.path.join(prefix, "Lib", "site-packages")
Greg Ward7d73b9e2000-03-09 03:16:05 +0000161 else:
Tarek Ziadé36797272010-07-22 12:50:05 +0000162 raise DistutilsPlatformError(
163 "I don't know where Python installs its library "
164 "on platform '%s'" % os.name)
165
Ned Deilycbfb9a52012-06-23 16:02:19 -0700166
Tarek Ziadé36797272010-07-22 12:50:05 +0000167
168def customize_compiler(compiler):
169 """Do any platform-specific customization of a CCompiler instance.
170
171 Mainly needed on Unix, so we can plug in the information that
172 varies across Unices and is stored in Python's Makefile.
173 """
174 if compiler.compiler_type == "unix":
175 (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \
176 get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
177 'CCSHARED', 'LDSHARED', 'SO', 'AR', 'ARFLAGS')
178
Ned Deily99377482012-02-10 13:01:08 +0100179 newcc = None
Tarek Ziadé36797272010-07-22 12:50:05 +0000180 if 'CC' in os.environ:
Ned Deilycbfb9a52012-06-23 16:02:19 -0700181 cc = os.environ['CC']
Tarek Ziadé36797272010-07-22 12:50:05 +0000182 if 'CXX' in os.environ:
183 cxx = os.environ['CXX']
184 if 'LDSHARED' in os.environ:
185 ldshared = os.environ['LDSHARED']
186 if 'CPP' in os.environ:
187 cpp = os.environ['CPP']
Andrew M. Kuchling29c86232002-11-04 19:53:24 +0000188 else:
Tarek Ziadé36797272010-07-22 12:50:05 +0000189 cpp = cc + " -E" # not always
190 if 'LDFLAGS' in os.environ:
191 ldshared = ldshared + ' ' + os.environ['LDFLAGS']
192 if 'CFLAGS' in os.environ:
193 cflags = opt + ' ' + os.environ['CFLAGS']
194 ldshared = ldshared + ' ' + os.environ['CFLAGS']
195 if 'CPPFLAGS' in os.environ:
196 cpp = cpp + ' ' + os.environ['CPPFLAGS']
197 cflags = cflags + ' ' + os.environ['CPPFLAGS']
198 ldshared = ldshared + ' ' + os.environ['CPPFLAGS']
199 if 'AR' in os.environ:
200 ar = os.environ['AR']
201 if 'ARFLAGS' in os.environ:
202 archiver = ar + ' ' + os.environ['ARFLAGS']
203 else:
204 archiver = ar + ' ' + ar_flags
205
206 cc_cmd = cc + ' ' + cflags
207 compiler.set_executables(
208 preprocessor=cpp,
209 compiler=cc_cmd,
210 compiler_so=cc_cmd + ' ' + ccshared,
211 compiler_cxx=cxx,
212 linker_so=ldshared,
213 linker_exe=cc,
214 archiver=archiver)
215
216 compiler.shared_lib_extension = so_ext
217
218
219def get_config_h_filename():
220 """Return full pathname of installed pyconfig.h file."""
221 if python_build:
222 if os.name == "nt":
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100223 inc_dir = os.path.join(_sys_home or project_base, "PC")
Tarek Ziadé36797272010-07-22 12:50:05 +0000224 else:
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100225 inc_dir = _sys_home or project_base
Tarek Ziadé36797272010-07-22 12:50:05 +0000226 else:
227 inc_dir = get_python_inc(plat_specific=1)
228 if get_python_version() < '2.2':
229 config_h = 'config.h'
230 else:
231 # The name of the config.h file changed in 2.2
232 config_h = 'pyconfig.h'
233 return os.path.join(inc_dir, config_h)
234
Greg Ward1190ee31998-12-18 23:46:33 +0000235
Greg Ward9ddaaa11999-01-06 14:46:06 +0000236def get_makefile_filename():
Tarek Ziadé36797272010-07-22 12:50:05 +0000237 """Return full pathname of installed Makefile from the Python build."""
238 if python_build:
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100239 return os.path.join(_sys_home or os.path.dirname(sys.executable),
240 "Makefile")
Éric Araujofea2d042011-10-08 01:56:52 +0200241 lib_dir = get_python_lib(plat_specific=0, standard_lib=1)
Barry Warsaw14d98ac2010-11-24 19:43:47 +0000242 config_file = 'config-{}{}'.format(get_python_version(), build_flags)
243 return os.path.join(lib_dir, config_file, 'Makefile')
Greg Ward7d73b9e2000-03-09 03:16:05 +0000244
Tarek Ziadé36797272010-07-22 12:50:05 +0000245
246def parse_config_h(fp, g=None):
247 """Parse a config.h-style file.
248
249 A dictionary containing name/value pairs is returned. If an
250 optional dictionary is passed in as the second argument, it is
251 used instead of a new dictionary.
Fred Drake522af3a1999-01-06 16:28:34 +0000252 """
Tarek Ziadé36797272010-07-22 12:50:05 +0000253 if g is None:
254 g = {}
255 define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
256 undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
257 #
258 while True:
259 line = fp.readline()
260 if not line:
261 break
262 m = define_rx.match(line)
263 if m:
264 n, v = m.group(1, 2)
265 try: v = int(v)
266 except ValueError: pass
267 g[n] = v
268 else:
269 m = undef_rx.match(line)
270 if m:
271 g[m.group(1)] = 0
272 return g
Greg Ward1190ee31998-12-18 23:46:33 +0000273
Greg Wardd283ce72000-09-17 00:53:02 +0000274
275# Regexes needed for parsing Makefile (and similar syntaxes,
276# like old-style Setup files).
277_variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
278_findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
279_findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
280
Greg Ward3fff8d22000-09-15 00:03:13 +0000281def parse_makefile(fn, g=None):
Tarek Ziadé36797272010-07-22 12:50:05 +0000282 """Parse a Makefile-style file.
Fred Drakec1ee39a2000-03-09 15:54:52 +0000283
284 A dictionary containing name/value pairs is returned. If an
285 optional dictionary is passed in as the second argument, it is
286 used instead of a new dictionary.
Fred Drake522af3a1999-01-06 16:28:34 +0000287 """
Tarek Ziadé36797272010-07-22 12:50:05 +0000288 from distutils.text_file import TextFile
Victor Stinner75d8c5c2010-10-23 17:02:31 +0000289 fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1, errors="surrogateescape")
Tarek Ziadé36797272010-07-22 12:50:05 +0000290
291 if g is None:
292 g = {}
293 done = {}
294 notdone = {}
295
296 while True:
297 line = fp.readline()
298 if line is None: # eof
299 break
300 m = _variable_rx.match(line)
301 if m:
302 n, v = m.group(1, 2)
303 v = v.strip()
304 # `$$' is a literal `$' in make
305 tmpv = v.replace('$$', '')
306
307 if "$" in tmpv:
308 notdone[n] = v
309 else:
310 try:
311 v = int(v)
312 except ValueError:
313 # insert literal `$'
314 done[n] = v.replace('$$', '$')
315 else:
316 done[n] = v
317
Ronald Oussorene8d252d2010-07-23 09:43:17 +0000318 # Variables with a 'PY_' prefix in the makefile. These need to
319 # be made available without that prefix through sysconfig.
320 # Special care is needed to ensure that variable expansion works, even
321 # if the expansion uses the name without a prefix.
322 renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS')
323
Tarek Ziadé36797272010-07-22 12:50:05 +0000324 # do variable interpolation here
325 while notdone:
326 for name in list(notdone):
327 value = notdone[name]
328 m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
329 if m:
330 n = m.group(1)
331 found = True
332 if n in done:
333 item = str(done[n])
334 elif n in notdone:
335 # get it on a subsequent round
336 found = False
337 elif n in os.environ:
338 # do it like make: fall back to environment
339 item = os.environ[n]
Ronald Oussorene8d252d2010-07-23 09:43:17 +0000340
341 elif n in renamed_variables:
342 if name.startswith('PY_') and name[3:] in renamed_variables:
343 item = ""
344
345 elif 'PY_' + n in notdone:
346 found = False
347
348 else:
349 item = str(done['PY_' + n])
Tarek Ziadé36797272010-07-22 12:50:05 +0000350 else:
351 done[n] = item = ""
352 if found:
353 after = value[m.end():]
354 value = value[:m.start()] + item + after
355 if "$" in after:
356 notdone[name] = value
357 else:
358 try: value = int(value)
359 except ValueError:
360 done[name] = value.strip()
361 else:
362 done[name] = value
363 del notdone[name]
Ronald Oussorene8d252d2010-07-23 09:43:17 +0000364
365 if name.startswith('PY_') \
366 and name[3:] in renamed_variables:
367
368 name = name[3:]
369 if name not in done:
370 done[name] = value
Tarek Ziadé36797272010-07-22 12:50:05 +0000371 else:
372 # bogus variable reference; just drop it since we can't deal
373 del notdone[name]
374
375 fp.close()
376
Antoine Pitroudbec7802010-10-10 09:37:12 +0000377 # strip spurious spaces
378 for k, v in done.items():
379 if isinstance(v, str):
380 done[k] = v.strip()
381
Tarek Ziadé36797272010-07-22 12:50:05 +0000382 # save the results in the global dictionary
383 g.update(done)
384 return g
385
Greg Ward1190ee31998-12-18 23:46:33 +0000386
Greg Wardd283ce72000-09-17 00:53:02 +0000387def expand_makefile_vars(s, vars):
Tarek Ziadé36797272010-07-22 12:50:05 +0000388 """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in
Greg Wardd283ce72000-09-17 00:53:02 +0000389 'string' according to 'vars' (a dictionary mapping variable names to
390 values). Variables not present in 'vars' are silently expanded to the
391 empty string. The variable values in 'vars' should not contain further
392 variable expansions; if 'vars' is the output of 'parse_makefile()',
393 you're fine. Returns a variable-expanded version of 's'.
394 """
395
396 # This algorithm does multiple expansion, so if vars['foo'] contains
397 # "${bar}", it will expand ${foo} to ${bar}, and then expand
398 # ${bar}... and so forth. This is fine as long as 'vars' comes from
399 # 'parse_makefile()', which takes care of such expansions eagerly,
400 # according to make's variable expansion semantics.
401
Collin Winter5b7e9d72007-08-30 03:52:21 +0000402 while True:
Greg Wardd283ce72000-09-17 00:53:02 +0000403 m = _findvar1_rx.search(s) or _findvar2_rx.search(s)
404 if m:
Greg Wardd283ce72000-09-17 00:53:02 +0000405 (beg, end) = m.span()
406 s = s[0:beg] + vars.get(m.group(1)) + s[end:]
407 else:
408 break
409 return s
Tarek Ziadé36797272010-07-22 12:50:05 +0000410
411
412_config_vars = None
413
414def _init_posix():
415 """Initialize the module as appropriate for POSIX systems."""
416 g = {}
417 # load the installed Makefile:
418 try:
419 filename = get_makefile_filename()
420 parse_makefile(filename, g)
421 except IOError as msg:
422 my_msg = "invalid Python installation: unable to open %s" % filename
423 if hasattr(msg, "strerror"):
424 my_msg = my_msg + " (%s)" % msg.strerror
425
426 raise DistutilsPlatformError(my_msg)
427
428 # load the installed pyconfig.h:
429 try:
430 filename = get_config_h_filename()
Brett Cannon5c035c02010-10-29 22:36:08 +0000431 with open(filename) as file:
432 parse_config_h(file, g)
Tarek Ziadé36797272010-07-22 12:50:05 +0000433 except IOError as msg:
434 my_msg = "invalid Python installation: unable to open %s" % filename
435 if hasattr(msg, "strerror"):
436 my_msg = my_msg + " (%s)" % msg.strerror
437
438 raise DistutilsPlatformError(my_msg)
439
Tarek Ziadé36797272010-07-22 12:50:05 +0000440 # On AIX, there are wrong paths to the linker scripts in the Makefile
441 # -- these paths are relative to the Python source, but when installed
442 # the scripts are in another directory.
443 if python_build:
444 g['LDSHARED'] = g['BLDSHARED']
445
446 elif get_python_version() < '2.1':
447 # The following two branches are for 1.5.2 compatibility.
448 if sys.platform == 'aix4': # what about AIX 3.x ?
449 # Linker script is in the config directory, not in Modules as the
450 # Makefile says.
451 python_lib = get_python_lib(standard_lib=1)
452 ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix')
453 python_exp = os.path.join(python_lib, 'config', 'python.exp')
454
455 g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp)
456
457 global _config_vars
458 _config_vars = g
459
460
461def _init_nt():
462 """Initialize the module as appropriate for NT"""
463 g = {}
464 # set basic install directories
465 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
466 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
467
468 # XXX hmmm.. a normal install puts include files here
469 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
470
471 g['SO'] = '.pyd'
472 g['EXE'] = ".exe"
473 g['VERSION'] = get_python_version().replace(".", "")
474 g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable))
475
476 global _config_vars
477 _config_vars = g
478
479
Tarek Ziadé36797272010-07-22 12:50:05 +0000480def _init_os2():
481 """Initialize the module as appropriate for OS/2"""
482 g = {}
483 # set basic install directories
484 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
485 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
486
487 # XXX hmmm.. a normal install puts include files here
488 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
489
490 g['SO'] = '.pyd'
491 g['EXE'] = ".exe"
492
493 global _config_vars
494 _config_vars = g
495
496
Ned Deilycbfb9a52012-06-23 16:02:19 -0700497def _read_output(commandstring):
498 """
499 Returns os.popen(commandstring, "r").read(), but
500 without actually using os.popen because that
501 function is not usable during python bootstrap
502 """
503 # NOTE: tempfile is also not useable during
504 # bootstrap
505 import contextlib
506 try:
507 import tempfile
508 fp = tempfile.NamedTemporaryFile()
509 except ImportError:
510 fp = open("/tmp/distutils.%s"%(
511 os.getpid(),), "w+b")
512
513 with contextlib.closing(fp) as fp:
514 cmd = "%s >'%s'"%(commandstring, fp.name)
515 os.system(cmd)
516 data = fp.read()
517
518 return data.decode('utf-8')
519
Tarek Ziadé36797272010-07-22 12:50:05 +0000520def get_config_vars(*args):
521 """With no arguments, return a dictionary of all configuration
522 variables relevant for the current platform. Generally this includes
523 everything needed to build extensions and install both pure modules and
524 extensions. On Unix, this means every variable defined in Python's
525 installed Makefile; on Windows and Mac OS it's a much smaller set.
526
527 With arguments, return a list of values that result from looking up
528 each argument in the configuration variable dictionary.
529 """
530 global _config_vars
531 if _config_vars is None:
532 func = globals().get("_init_" + os.name)
533 if func:
534 func()
535 else:
536 _config_vars = {}
537
538 # Normalized versions of prefix and exec_prefix are handy to have;
539 # in fact, these are the standard versions used most places in the
540 # Distutils.
541 _config_vars['prefix'] = PREFIX
542 _config_vars['exec_prefix'] = EXEC_PREFIX
543
544 # Convert srcdir into an absolute path if it appears necessary.
545 # Normally it is relative to the build directory. However, during
546 # testing, for example, we might be running a non-installed python
547 # from a different directory.
548 if python_build and os.name == "posix":
549 base = os.path.dirname(os.path.abspath(sys.executable))
550 if (not os.path.isabs(_config_vars['srcdir']) and
551 base != os.getcwd()):
552 # srcdir is relative and we are not in the same directory
553 # as the executable. Assume executable is in the build
554 # directory and make srcdir absolute.
555 srcdir = os.path.join(base, _config_vars['srcdir'])
556 _config_vars['srcdir'] = os.path.normpath(srcdir)
557
558 if sys.platform == 'darwin':
Ned Deilycbfb9a52012-06-23 16:02:19 -0700559 from distutils.spawn import find_executable
560
Tarek Ziadé36797272010-07-22 12:50:05 +0000561 kernel_version = os.uname()[2] # Kernel version (8.4.3)
562 major_version = int(kernel_version.split('.')[0])
563
Ned Deilycbfb9a52012-06-23 16:02:19 -0700564 # Issue #13590:
565 # The OSX location for the compiler varies between OSX
566 # (or rather Xcode) releases. With older releases (up-to 10.5)
567 # the compiler is in /usr/bin, with newer releases the compiler
568 # can only be found inside Xcode.app if the "Command Line Tools"
569 # are not installed.
570 #
571 # Futhermore, the compiler that can be used varies between
572 # Xcode releases. Upto Xcode 4 it was possible to use 'gcc-4.2'
573 # as the compiler, after that 'clang' should be used because
574 # gcc-4.2 is either not present, or a copy of 'llvm-gcc' that
575 # miscompiles Python.
576
577 # skip checks if the compiler was overriden with a CC env variable
578 if 'CC' not in os.environ:
579 cc = oldcc = _config_vars['CC']
580 if not find_executable(cc):
581 # Compiler is not found on the shell search PATH.
582 # Now search for clang, first on PATH (if the Command LIne
583 # Tools have been installed in / or if the user has provided
584 # another location via CC). If not found, try using xcrun
585 # to find an uninstalled clang (within a selected Xcode).
586
587 # NOTE: Cannot use subprocess here because of bootstrap
588 # issues when building Python itself (and os.popen is
589 # implemented on top of subprocess and is therefore not
590 # usable as well)
591
592 data = (find_executable('clang') or
593 _read_output(
594 "/usr/bin/xcrun -find clang 2>/dev/null").strip())
595 if not data:
596 raise DistutilsPlatformError(
597 "Cannot locate working compiler")
598
599 _config_vars['CC'] = cc = data
600 _config_vars['CXX'] = cc + '++'
601
602 elif os.path.basename(cc).startswith('gcc'):
603 # Compiler is GCC, check if it is LLVM-GCC
604 data = _read_output("'%s' --version 2>/dev/null"
605 % (cc.replace("'", "'\"'\"'"),))
606 if 'llvm-gcc' in data:
607 # Found LLVM-GCC, fall back to clang
608 data = (find_executable('clang') or
609 _read_output(
610 "/usr/bin/xcrun -find clang 2>/dev/null").strip())
611 if find_executable(data):
612 _config_vars['CC'] = cc = data
613 _config_vars['CXX'] = cc + '++'
614
615 if (cc != oldcc
616 and 'LDSHARED' in _config_vars
617 and 'LDSHARED' not in os.environ):
618 # modify LDSHARED if we modified CC
619 ldshared = _config_vars['LDSHARED']
620 if ldshared.startswith(oldcc):
621 _config_vars['LDSHARED'] = cc + ldshared[len(oldcc):]
622
Tarek Ziadé36797272010-07-22 12:50:05 +0000623 if major_version < 8:
624 # On Mac OS X before 10.4, check if -arch and -isysroot
625 # are in CFLAGS or LDFLAGS and remove them if they are.
626 # This is needed when building extensions on a 10.3 system
627 # using a universal build of python.
Ned Deily27471772012-07-15 21:30:03 -0700628 for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED',
Tarek Ziadé36797272010-07-22 12:50:05 +0000629 # a number of derived variables. These need to be
630 # patched up as well.
631 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
632 flags = _config_vars[key]
633 flags = re.sub('-arch\s+\w+\s', ' ', flags, re.ASCII)
634 flags = re.sub('-isysroot [^ \t]*', ' ', flags)
635 _config_vars[key] = flags
636
637 else:
Ned Deilycbfb9a52012-06-23 16:02:19 -0700638 # Different Xcode releases support different sets for '-arch'
639 # flags. In particular, Xcode 4.x no longer supports the
640 # PPC architectures.
641 #
642 # This code automatically removes '-arch ppc' and '-arch ppc64'
643 # when these are not supported. That makes it possible to
644 # build extensions on OSX 10.7 and later with the prebuilt
645 # 32-bit installer on the python.org website.
646 flags = _config_vars['CFLAGS']
647 if re.search('-arch\s+ppc', flags) is not None:
648 # NOTE: Cannot use subprocess here because of bootstrap
649 # issues when building Python itself
650 status = os.system("'%s' -arch ppc -x c /dev/null 2>/dev/null"%(
651 _config_vars['CC'].replace("'", "'\"'\"'"),))
652
653 if status != 0:
654 # Compiler doesn't support PPC, remove the related
655 # '-arch' flags.
656 for key in ('LDFLAGS', 'BASECFLAGS',
657 # a number of derived variables. These need to be
658 # patched up as well.
659 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED', 'LDSHARED'):
660
661 flags = _config_vars[key]
662 flags = re.sub('-arch\s+ppc\w*\s', ' ', flags)
663 _config_vars[key] = flags
664
Tarek Ziadé36797272010-07-22 12:50:05 +0000665
666 # Allow the user to override the architecture flags using
667 # an environment variable.
668 # NOTE: This name was introduced by Apple in OSX 10.5 and
669 # is used by several scripting languages distributed with
670 # that OS release.
Tarek Ziadé36797272010-07-22 12:50:05 +0000671 if 'ARCHFLAGS' in os.environ:
672 arch = os.environ['ARCHFLAGS']
Ned Deily27471772012-07-15 21:30:03 -0700673 for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED',
Tarek Ziadé36797272010-07-22 12:50:05 +0000674 # a number of derived variables. These need to be
675 # patched up as well.
Ned Deily27471772012-07-15 21:30:03 -0700676 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
Tarek Ziadé36797272010-07-22 12:50:05 +0000677
678 flags = _config_vars[key]
679 flags = re.sub('-arch\s+\w+\s', ' ', flags)
680 flags = flags + ' ' + arch
681 _config_vars[key] = flags
682
Ned Deily27471772012-07-15 21:30:03 -0700683 # If we're on OSX 10.5 or later and the user tries to
684 # compiles an extension using an SDK that is not present
685 # on the current machine it is better to not use an SDK
686 # than to fail.
687 #
688 # The major usecase for this is users using a Python.org
689 # binary installer on OSX 10.6: that installer uses
690 # the 10.4u SDK, but that SDK is not installed by default
691 # when you install Xcode.
692 #
693 m = re.search('-isysroot\s+(\S+)', _config_vars['CFLAGS'])
694 if m is not None:
695 sdk = m.group(1)
696 if not os.path.exists(sdk):
697 for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED',
698 # a number of derived variables. These need to be
699 # patched up as well.
700 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
701
702 flags = _config_vars[key]
703 flags = re.sub('-isysroot\s+\S+(\s|$)', ' ', flags)
704 _config_vars[key] = flags
705
Tarek Ziadé36797272010-07-22 12:50:05 +0000706 if args:
707 vals = []
708 for name in args:
709 vals.append(_config_vars.get(name))
710 return vals
711 else:
712 return _config_vars
713
714def get_config_var(name):
715 """Return the value of a single variable using the dictionary
716 returned by 'get_config_vars()'. Equivalent to
717 get_config_vars().get(name)
718 """
719 return get_config_vars().get(name)