0001 """Provide access to Python's configuration information. The specific 0002 configuration variables available depend heavily on the platform and 0003 configuration. The values may be retrieved using 0004 get_config_var(name), and the list of variables is available via 0005 get_config_vars().keys(). Additional convenience functions are also 0006 available. 0007 0008 Written by: Fred L. Drake, Jr. 0009 Email: <fdrake@acm.org> 0010 """ 0011 0012 __revision__ = "$Id: sysconfig.py,v 1.61 2004/10/13 15:54:16 anthonybaxter Exp $" 0013 0014 import os 0015 import re 0016 import string 0017 import sys 0018 0019 from errors import DistutilsPlatformError 0020 0021 # These are needed in a couple of spots, so just compute them once. 0022 PREFIX = os.path.normpath(sys.prefix) 0023 EXEC_PREFIX = os.path.normpath(sys.exec_prefix) 0024 0025 # python_build: (Boolean) if true, we're either building Python or 0026 # building an extension with an un-installed Python, so we use 0027 # different (hard-wired) directories. 0028 0029 argv0_path = os.path.dirname(os.path.abspath(sys.executable)) 0030 landmark = os.path.join(argv0_path, "Modules", "Setup") 0031 0032 python_build = os.path.isfile(landmark) 0033 0034 del argv0_path, landmark 0035 0036 0037 def get_python_version (): 0038 """Return a string containing the major and minor Python version, 0039 leaving off the patchlevel. Sample return values could be '1.5' 0040 or '2.2'. 0041 """ 0042 return sys.version[:3] 0043 0044 0045 def get_python_inc(plat_specific=0, prefix=None): 0046 """Return the directory containing installed Python header files. 0047 0048 If 'plat_specific' is false (the default), this is the path to the 0049 non-platform-specific header files, i.e. Python.h and so on; 0050 otherwise, this is the path to platform-specific header files 0051 (namely pyconfig.h). 0052 0053 If 'prefix' is supplied, use it instead of sys.prefix or 0054 sys.exec_prefix -- i.e., ignore 'plat_specific'. 0055 """ 0056 if prefix is None: 0057 prefix = plat_specific and EXEC_PREFIX or PREFIX 0058 if os.name == "posix": 0059 if python_build: 0060 base = os.path.dirname(os.path.abspath(sys.executable)) 0061 if plat_specific: 0062 inc_dir = base 0063 else: 0064 inc_dir = os.path.join(base, "Include") 0065 if not os.path.exists(inc_dir): 0066 inc_dir = os.path.join(os.path.dirname(base), "Include") 0067 return inc_dir 0068 return os.path.join(prefix, "include", "python" + sys.version[:3]) 0069 elif os.name == "nt": 0070 return os.path.join(prefix, "include") 0071 elif os.name == "mac": 0072 if plat_specific: 0073 return os.path.join(prefix, "Mac", "Include") 0074 else: 0075 return os.path.join(prefix, "Include") 0076 elif os.name == "os2": 0077 return os.path.join(prefix, "Include") 0078 else: 0079 raise DistutilsPlatformError( 0080 "I don't know where Python installs its C header files " 0081 "on platform '%s'" % os.name) 0082 0083 0084 def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): 0085 """Return the directory containing the Python library (standard or 0086 site additions). 0087 0088 If 'plat_specific' is true, return the directory containing 0089 platform-specific modules, i.e. any module from a non-pure-Python 0090 module distribution; otherwise, return the platform-shared library 0091 directory. If 'standard_lib' is true, return the directory 0092 containing standard Python library modules; otherwise, return the 0093 directory for site-specific modules. 0094 0095 If 'prefix' is supplied, use it instead of sys.prefix or 0096 sys.exec_prefix -- i.e., ignore 'plat_specific'. 0097 """ 0098 if prefix is None: 0099 prefix = plat_specific and EXEC_PREFIX or PREFIX 0100 0101 if os.name == "posix": 0102 libpython = os.path.join(prefix, 0103 "lib", "python" + get_python_version()) 0104 if standard_lib: 0105 return libpython 0106 else: 0107 return os.path.join(libpython, "site-packages") 0108 0109 elif os.name == "nt": 0110 if standard_lib: 0111 return os.path.join(prefix, "Lib") 0112 else: 0113 if sys.version < "2.2": 0114 return prefix 0115 else: 0116 return os.path.join(PREFIX, "Lib", "site-packages") 0117 0118 elif os.name == "mac": 0119 if plat_specific: 0120 if standard_lib: 0121 return os.path.join(prefix, "Lib", "lib-dynload") 0122 else: 0123 return os.path.join(prefix, "Lib", "site-packages") 0124 else: 0125 if standard_lib: 0126 return os.path.join(prefix, "Lib") 0127 else: 0128 return os.path.join(prefix, "Lib", "site-packages") 0129 0130 elif os.name == "os2": 0131 if standard_lib: 0132 return os.path.join(PREFIX, "Lib") 0133 else: 0134 return os.path.join(PREFIX, "Lib", "site-packages") 0135 0136 else: 0137 raise DistutilsPlatformError( 0138 "I don't know where Python installs its library " 0139 "on platform '%s'" % os.name) 0140 0141 0142 def customize_compiler(compiler): 0143 """Do any platform-specific customization of a CCompiler instance. 0144 0145 Mainly needed on Unix, so we can plug in the information that 0146 varies across Unices and is stored in Python's Makefile. 0147 """ 0148 if compiler.compiler_type == "unix": 0149 (cc, cxx, opt, basecflags, ccshared, ldshared, so_ext) = \ 0150 get_config_vars('CC', 'CXX', 'OPT', 'BASECFLAGS', 'CCSHARED', 'LDSHARED', 'SO') 0151 0152 if os.environ.has_key('CC'): 0153 cc = os.environ['CC'] 0154 if os.environ.has_key('CXX'): 0155 cxx = os.environ['CXX'] 0156 if os.environ.has_key('LDSHARED'): 0157 ldshared = os.environ['LDSHARED'] 0158 if os.environ.has_key('CPP'): 0159 cpp = os.environ['CPP'] 0160 else: 0161 cpp = cc + " -E" # not always 0162 if os.environ.has_key('LDFLAGS'): 0163 ldshared = ldshared + ' ' + os.environ['LDFLAGS'] 0164 if basecflags: 0165 opt = basecflags + ' ' + opt 0166 if os.environ.has_key('CFLAGS'): 0167 opt = opt + ' ' + os.environ['CFLAGS'] 0168 ldshared = ldshared + ' ' + os.environ['CFLAGS'] 0169 if os.environ.has_key('CPPFLAGS'): 0170 cpp = cpp + ' ' + os.environ['CPPFLAGS'] 0171 opt = opt + ' ' + os.environ['CPPFLAGS'] 0172 ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] 0173 0174 cc_cmd = cc + ' ' + opt 0175 compiler.set_executables( 0176 preprocessor=cpp, 0177 compiler=cc_cmd, 0178 compiler_so=cc_cmd + ' ' + ccshared, 0179 compiler_cxx=cxx, 0180 linker_so=ldshared, 0181 linker_exe=cc) 0182 0183 compiler.shared_lib_extension = so_ext 0184 0185 0186 def get_config_h_filename(): 0187 """Return full pathname of installed pyconfig.h file.""" 0188 if python_build: 0189 inc_dir = os.curdir 0190 else: 0191 inc_dir = get_python_inc(plat_specific=1) 0192 if sys.version < '2.2': 0193 config_h = 'config.h' 0194 else: 0195 # The name of the config.h file changed in 2.2 0196 config_h = 'pyconfig.h' 0197 return os.path.join(inc_dir, config_h) 0198 0199 0200 def get_makefile_filename(): 0201 """Return full pathname of installed Makefile from the Python build.""" 0202 if python_build: 0203 return os.path.join(os.path.dirname(sys.executable), "Makefile") 0204 lib_dir = get_python_lib(plat_specific=1, standard_lib=1) 0205 return os.path.join(lib_dir, "config", "Makefile") 0206 0207 0208 def parse_config_h(fp, g=None): 0209 """Parse a config.h-style file. 0210 0211 A dictionary containing name/value pairs is returned. If an 0212 optional dictionary is passed in as the second argument, it is 0213 used instead of a new dictionary. 0214 """ 0215 if g is None: 0216 g = {} 0217 define_rx = re.compile("#define ([A-Z][A-Z0-9_]+) (.*)\n") 0218 undef_rx = re.compile("/[*] #undef ([A-Z][A-Z0-9_]+) [*]/\n") 0219 # 0220 while 1: 0221 line = fp.readline() 0222 if not line: 0223 break 0224 m = define_rx.match(line) 0225 if m: 0226 n, v = m.group(1, 2) 0227 try: v = int(v) 0228 except ValueError: pass 0229 g[n] = v 0230 else: 0231 m = undef_rx.match(line) 0232 if m: 0233 g[m.group(1)] = 0 0234 return g 0235 0236 0237 # Regexes needed for parsing Makefile (and similar syntaxes, 0238 # like old-style Setup files). 0239 _variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") 0240 _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") 0241 _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") 0242 0243 def parse_makefile(fn, g=None): 0244 """Parse a Makefile-style file. 0245 0246 A dictionary containing name/value pairs is returned. If an 0247 optional dictionary is passed in as the second argument, it is 0248 used instead of a new dictionary. 0249 """ 0250 from distutils.text_file import TextFile 0251 fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1) 0252 0253 if g is None: 0254 g = {} 0255 done = {} 0256 notdone = {} 0257 0258 while 1: 0259 line = fp.readline() 0260 if line is None: # eof 0261 break 0262 m = _variable_rx.match(line) 0263 if m: 0264 n, v = m.group(1, 2) 0265 v = string.strip(v) 0266 if "$" in v: 0267 notdone[n] = v 0268 else: 0269 try: v = int(v) 0270 except ValueError: pass 0271 done[n] = v 0272 0273 # do variable interpolation here 0274 while notdone: 0275 for name in notdone.keys(): 0276 value = notdone[name] 0277 m = _findvar1_rx.search(value) or _findvar2_rx.search(value) 0278 if m: 0279 n = m.group(1) 0280 if done.has_key(n): 0281 after = value[m.end():] 0282 value = value[:m.start()] + str(done[n]) + after 0283 if "$" in after: 0284 notdone[name] = value 0285 else: 0286 try: value = int(value) 0287 except ValueError: 0288 done[name] = string.strip(value) 0289 else: 0290 done[name] = value 0291 del notdone[name] 0292 elif notdone.has_key(n): 0293 # get it on a subsequent round 0294 pass 0295 else: 0296 done[n] = "" 0297 after = value[m.end():] 0298 value = value[:m.start()] + after 0299 if "$" in after: 0300 notdone[name] = value 0301 else: 0302 try: value = int(value) 0303 except ValueError: 0304 done[name] = string.strip(value) 0305 else: 0306 done[name] = value 0307 del notdone[name] 0308 else: 0309 # bogus variable reference; just drop it since we can't deal 0310 del notdone[name] 0311 0312 fp.close() 0313 0314 # save the results in the global dictionary 0315 g.update(done) 0316 return g 0317 0318 0319 def expand_makefile_vars(s, vars): 0320 """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in 0321 'string' according to 'vars' (a dictionary mapping variable names to 0322 values). Variables not present in 'vars' are silently expanded to the 0323 empty string. The variable values in 'vars' should not contain further 0324 variable expansions; if 'vars' is the output of 'parse_makefile()', 0325 you're fine. Returns a variable-expanded version of 's'. 0326 """ 0327 0328 # This algorithm does multiple expansion, so if vars['foo'] contains 0329 # "${bar}", it will expand ${foo} to ${bar}, and then expand 0330 # ${bar}... and so forth. This is fine as long as 'vars' comes from 0331 # 'parse_makefile()', which takes care of such expansions eagerly, 0332 # according to make's variable expansion semantics. 0333 0334 while 1: 0335 m = _findvar1_rx.search(s) or _findvar2_rx.search(s) 0336 if m: 0337 (beg, end) = m.span() 0338 s = s[0:beg] + vars.get(m.group(1)) + s[end:] 0339 else: 0340 break 0341 return s 0342 0343 0344 _config_vars = None 0345 0346 def _init_posix(): 0347 """Initialize the module as appropriate for POSIX systems.""" 0348 g = {} 0349 # load the installed Makefile: 0350 try: 0351 filename = get_makefile_filename() 0352 parse_makefile(filename, g) 0353 except IOError, msg: 0354 my_msg = "invalid Python installation: unable to open %s" % filename 0355 if hasattr(msg, "strerror"): 0356 my_msg = my_msg + " (%s)" % msg.strerror 0357 0358 raise DistutilsPlatformError(my_msg) 0359 0360 # On MacOSX we need to check the setting of the environment variable 0361 # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so 0362 # it needs to be compatible. 0363 # An alternative would be to force MACOSX_DEPLOYMENT_TARGET to be 0364 # the same as during configure. 0365 if sys.platform == 'darwin' and g.has_key('CONFIGURE_MACOSX_DEPLOYMENT_TARGET'): 0366 cfg_target = g['CONFIGURE_MACOSX_DEPLOYMENT_TARGET'] 0367 cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') 0368 if cfg_target != cur_target: 0369 my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' 0370 % (cur_target, cfg_target)) 0371 raise DistutilsPlatformError(my_msg) 0372 0373 # On AIX, there are wrong paths to the linker scripts in the Makefile 0374 # -- these paths are relative to the Python source, but when installed 0375 # the scripts are in another directory. 0376 if python_build: 0377 g['LDSHARED'] = g['BLDSHARED'] 0378 0379 elif sys.version < '2.1': 0380 # The following two branches are for 1.5.2 compatibility. 0381 if sys.platform == 'aix4': # what about AIX 3.x ? 0382 # Linker script is in the config directory, not in Modules as the 0383 # Makefile says. 0384 python_lib = get_python_lib(standard_lib=1) 0385 ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix') 0386 python_exp = os.path.join(python_lib, 'config', 'python.exp') 0387 0388 g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp) 0389 0390 elif sys.platform == 'beos': 0391 # Linker script is in the config directory. In the Makefile it is 0392 # relative to the srcdir, which after installation no longer makes 0393 # sense. 0394 python_lib = get_python_lib(standard_lib=1) 0395 linkerscript_path = string.split(g['LDSHARED'])[0] 0396 linkerscript_name = os.path.basename(linkerscript_path) 0397 linkerscript = os.path.join(python_lib, 'config', 0398 linkerscript_name) 0399 0400 # XXX this isn't the right place to do this: adding the Python 0401 # library to the link, if needed, should be in the "build_ext" 0402 # command. (It's also needed for non-MS compilers on Windows, and 0403 # it's taken care of for them by the 'build_ext.get_libraries()' 0404 # method.) 0405 g['LDSHARED'] = ("%s -L%s/lib -lpython%s" % 0406 (linkerscript, PREFIX, sys.version[0:3])) 0407 0408 global _config_vars 0409 _config_vars = g 0410 0411 0412 def _init_nt(): 0413 """Initialize the module as appropriate for NT""" 0414 g = {} 0415 # set basic install directories 0416 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) 0417 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) 0418 0419 # XXX hmmm.. a normal install puts include files here 0420 g['INCLUDEPY'] = get_python_inc(plat_specific=0) 0421 0422 g['SO'] = '.pyd' 0423 g['EXE'] = ".exe" 0424 0425 global _config_vars 0426 _config_vars = g 0427 0428 0429 def _init_mac(): 0430 """Initialize the module as appropriate for Macintosh systems""" 0431 g = {} 0432 # set basic install directories 0433 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) 0434 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) 0435 0436 # XXX hmmm.. a normal install puts include files here 0437 g['INCLUDEPY'] = get_python_inc(plat_specific=0) 0438 0439 import MacOS 0440 if not hasattr(MacOS, 'runtimemodel'): 0441 g['SO'] = '.ppc.slb' 0442 else: 0443 g['SO'] = '.%s.slb' % MacOS.runtimemodel 0444 0445 # XXX are these used anywhere? 0446 g['install_lib'] = os.path.join(EXEC_PREFIX, "Lib") 0447 g['install_platlib'] = os.path.join(EXEC_PREFIX, "Mac", "Lib") 0448 0449 # These are used by the extension module build 0450 g['srcdir'] = ':' 0451 global _config_vars 0452 _config_vars = g 0453 0454 0455 def _init_os2(): 0456 """Initialize the module as appropriate for OS/2""" 0457 g = {} 0458 # set basic install directories 0459 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) 0460 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) 0461 0462 # XXX hmmm.. a normal install puts include files here 0463 g['INCLUDEPY'] = get_python_inc(plat_specific=0) 0464 0465 g['SO'] = '.pyd' 0466 g['EXE'] = ".exe" 0467 0468 global _config_vars 0469 _config_vars = g 0470 0471 0472 def get_config_vars(*args): 0473 """With no arguments, return a dictionary of all configuration 0474 variables relevant for the current platform. Generally this includes 0475 everything needed to build extensions and install both pure modules and 0476 extensions. On Unix, this means every variable defined in Python's 0477 installed Makefile; on Windows and Mac OS it's a much smaller set. 0478 0479 With arguments, return a list of values that result from looking up 0480 each argument in the configuration variable dictionary. 0481 """ 0482 global _config_vars 0483 if _config_vars is None: 0484 func = globals().get("_init_" + os.name) 0485 if func: 0486 func() 0487 else: 0488 _config_vars = {} 0489 0490 # Normalized versions of prefix and exec_prefix are handy to have; 0491 # in fact, these are the standard versions used most places in the 0492 # Distutils. 0493 _config_vars['prefix'] = PREFIX 0494 _config_vars['exec_prefix'] = EXEC_PREFIX 0495 0496 if args: 0497 vals = [] 0498 for name in args: 0499 vals.append(_config_vars.get(name)) 0500 return vals 0501 else: 0502 return _config_vars 0503 0504 def get_config_var(name): 0505 """Return the value of a single variable using the dictionary 0506 returned by 'get_config_vars()'. Equivalent to 0507 get_config_vars().get(name) 0508 """ 0509 return get_config_vars().get(name) 0510
Generated by PyXR 0.9.4