python-2.5.2/win32/Lib/distutils/sysconfig.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     1 """Provide access to Python's configuration information.  The specific
       
     2 configuration variables available depend heavily on the platform and
       
     3 configuration.  The values may be retrieved using
       
     4 get_config_var(name), and the list of variables is available via
       
     5 get_config_vars().keys().  Additional convenience functions are also
       
     6 available.
       
     7 
       
     8 Written by:   Fred L. Drake, Jr.
       
     9 Email:        <fdrake@acm.org>
       
    10 """
       
    11 
       
    12 __revision__ = "$Id: sysconfig.py 52234 2006-10-08 17:50:26Z ronald.oussoren $"
       
    13 
       
    14 import os
       
    15 import re
       
    16 import string
       
    17 import sys
       
    18 
       
    19 from distutils.errors import DistutilsPlatformError
       
    20 
       
    21 # These are needed in a couple of spots, so just compute them once.
       
    22 PREFIX = os.path.normpath(sys.prefix)
       
    23 EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
       
    24 
       
    25 # python_build: (Boolean) if true, we're either building Python or
       
    26 # building an extension with an un-installed Python, so we use
       
    27 # different (hard-wired) directories.
       
    28 
       
    29 argv0_path = os.path.dirname(os.path.abspath(sys.executable))
       
    30 landmark = os.path.join(argv0_path, "Modules", "Setup")
       
    31 
       
    32 python_build = os.path.isfile(landmark)
       
    33 
       
    34 del landmark
       
    35 
       
    36 
       
    37 def get_python_version():
       
    38     """Return a string containing the major and minor Python version,
       
    39     leaving off the patchlevel.  Sample return values could be '1.5'
       
    40     or '2.2'.
       
    41     """
       
    42     return sys.version[:3]
       
    43 
       
    44 
       
    45 def get_python_inc(plat_specific=0, prefix=None):
       
    46     """Return the directory containing installed Python header files.
       
    47 
       
    48     If 'plat_specific' is false (the default), this is the path to the
       
    49     non-platform-specific header files, i.e. Python.h and so on;
       
    50     otherwise, this is the path to platform-specific header files
       
    51     (namely pyconfig.h).
       
    52 
       
    53     If 'prefix' is supplied, use it instead of sys.prefix or
       
    54     sys.exec_prefix -- i.e., ignore 'plat_specific'.
       
    55     """
       
    56     if prefix is None:
       
    57         prefix = plat_specific and EXEC_PREFIX or PREFIX
       
    58     if os.name == "posix":
       
    59         if python_build:
       
    60             base = os.path.dirname(os.path.abspath(sys.executable))
       
    61             if plat_specific:
       
    62                 inc_dir = base
       
    63             else:
       
    64                 inc_dir = os.path.join(base, "Include")
       
    65                 if not os.path.exists(inc_dir):
       
    66                     inc_dir = os.path.join(os.path.dirname(base), "Include")
       
    67             return inc_dir
       
    68         return os.path.join(prefix, "include", "python" + get_python_version())
       
    69     elif os.name == "nt":
       
    70         return os.path.join(prefix, "include")
       
    71     elif os.name == "mac":
       
    72         if plat_specific:
       
    73             return os.path.join(prefix, "Mac", "Include")
       
    74         else:
       
    75             return os.path.join(prefix, "Include")
       
    76     elif os.name == "os2":
       
    77         return os.path.join(prefix, "Include")
       
    78     else:
       
    79         raise DistutilsPlatformError(
       
    80             "I don't know where Python installs its C header files "
       
    81             "on platform '%s'" % os.name)
       
    82 
       
    83 
       
    84 def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
       
    85     """Return the directory containing the Python library (standard or
       
    86     site additions).
       
    87 
       
    88     If 'plat_specific' is true, return the directory containing
       
    89     platform-specific modules, i.e. any module from a non-pure-Python
       
    90     module distribution; otherwise, return the platform-shared library
       
    91     directory.  If 'standard_lib' is true, return the directory
       
    92     containing standard Python library modules; otherwise, return the
       
    93     directory for site-specific modules.
       
    94 
       
    95     If 'prefix' is supplied, use it instead of sys.prefix or
       
    96     sys.exec_prefix -- i.e., ignore 'plat_specific'.
       
    97     """
       
    98     if prefix is None:
       
    99         prefix = plat_specific and EXEC_PREFIX or PREFIX
       
   100 
       
   101     if os.name == "posix":
       
   102         libpython = os.path.join(prefix,
       
   103                                  "lib", "python" + get_python_version())
       
   104         if standard_lib:
       
   105             return libpython
       
   106         else:
       
   107             return os.path.join(libpython, "site-packages")
       
   108 
       
   109     elif os.name == "nt":
       
   110         if standard_lib:
       
   111             return os.path.join(prefix, "Lib")
       
   112         else:
       
   113             if get_python_version() < "2.2":
       
   114                 return prefix
       
   115             else:
       
   116                 return os.path.join(PREFIX, "Lib", "site-packages")
       
   117 
       
   118     elif os.name == "mac":
       
   119         if plat_specific:
       
   120             if standard_lib:
       
   121                 return os.path.join(prefix, "Lib", "lib-dynload")
       
   122             else:
       
   123                 return os.path.join(prefix, "Lib", "site-packages")
       
   124         else:
       
   125             if standard_lib:
       
   126                 return os.path.join(prefix, "Lib")
       
   127             else:
       
   128                 return os.path.join(prefix, "Lib", "site-packages")
       
   129 
       
   130     elif os.name == "os2":
       
   131         if standard_lib:
       
   132             return os.path.join(PREFIX, "Lib")
       
   133         else:
       
   134             return os.path.join(PREFIX, "Lib", "site-packages")
       
   135 
       
   136     else:
       
   137         raise DistutilsPlatformError(
       
   138             "I don't know where Python installs its library "
       
   139             "on platform '%s'" % os.name)
       
   140 
       
   141 
       
   142 def customize_compiler(compiler):
       
   143     """Do any platform-specific customization of a CCompiler instance.
       
   144 
       
   145     Mainly needed on Unix, so we can plug in the information that
       
   146     varies across Unices and is stored in Python's Makefile.
       
   147     """
       
   148     if compiler.compiler_type == "unix":
       
   149         (cc, cxx, opt, cflags, ccshared, ldshared, so_ext) = \
       
   150             get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
       
   151                             'CCSHARED', 'LDSHARED', 'SO')
       
   152 
       
   153         if os.environ.has_key('CC'):
       
   154             cc = os.environ['CC']
       
   155         if os.environ.has_key('CXX'):
       
   156             cxx = os.environ['CXX']
       
   157         if os.environ.has_key('LDSHARED'):
       
   158             ldshared = os.environ['LDSHARED']
       
   159         if os.environ.has_key('CPP'):
       
   160             cpp = os.environ['CPP']
       
   161         else:
       
   162             cpp = cc + " -E"           # not always
       
   163         if os.environ.has_key('LDFLAGS'):
       
   164             ldshared = ldshared + ' ' + os.environ['LDFLAGS']
       
   165         if os.environ.has_key('CFLAGS'):
       
   166             cflags = opt + ' ' + os.environ['CFLAGS']
       
   167             ldshared = ldshared + ' ' + os.environ['CFLAGS']
       
   168         if os.environ.has_key('CPPFLAGS'):
       
   169             cpp = cpp + ' ' + os.environ['CPPFLAGS']
       
   170             cflags = cflags + ' ' + os.environ['CPPFLAGS']
       
   171             ldshared = ldshared + ' ' + os.environ['CPPFLAGS']
       
   172 
       
   173         cc_cmd = cc + ' ' + cflags
       
   174         compiler.set_executables(
       
   175             preprocessor=cpp,
       
   176             compiler=cc_cmd,
       
   177             compiler_so=cc_cmd + ' ' + ccshared,
       
   178             compiler_cxx=cxx,
       
   179             linker_so=ldshared,
       
   180             linker_exe=cc)
       
   181 
       
   182         compiler.shared_lib_extension = so_ext
       
   183 
       
   184 
       
   185 def get_config_h_filename():
       
   186     """Return full pathname of installed pyconfig.h file."""
       
   187     if python_build:
       
   188         inc_dir = argv0_path
       
   189     else:
       
   190         inc_dir = get_python_inc(plat_specific=1)
       
   191     if get_python_version() < '2.2':
       
   192         config_h = 'config.h'
       
   193     else:
       
   194         # The name of the config.h file changed in 2.2
       
   195         config_h = 'pyconfig.h'
       
   196     return os.path.join(inc_dir, config_h)
       
   197 
       
   198 
       
   199 def get_makefile_filename():
       
   200     """Return full pathname of installed Makefile from the Python build."""
       
   201     if python_build:
       
   202         return os.path.join(os.path.dirname(sys.executable), "Makefile")
       
   203     lib_dir = get_python_lib(plat_specific=1, standard_lib=1)
       
   204     return os.path.join(lib_dir, "config", "Makefile")
       
   205 
       
   206 
       
   207 def parse_config_h(fp, g=None):
       
   208     """Parse a config.h-style file.
       
   209 
       
   210     A dictionary containing name/value pairs is returned.  If an
       
   211     optional dictionary is passed in as the second argument, it is
       
   212     used instead of a new dictionary.
       
   213     """
       
   214     if g is None:
       
   215         g = {}
       
   216     define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
       
   217     undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
       
   218     #
       
   219     while 1:
       
   220         line = fp.readline()
       
   221         if not line:
       
   222             break
       
   223         m = define_rx.match(line)
       
   224         if m:
       
   225             n, v = m.group(1, 2)
       
   226             try: v = int(v)
       
   227             except ValueError: pass
       
   228             g[n] = v
       
   229         else:
       
   230             m = undef_rx.match(line)
       
   231             if m:
       
   232                 g[m.group(1)] = 0
       
   233     return g
       
   234 
       
   235 
       
   236 # Regexes needed for parsing Makefile (and similar syntaxes,
       
   237 # like old-style Setup files).
       
   238 _variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
       
   239 _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
       
   240 _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
       
   241 
       
   242 def parse_makefile(fn, g=None):
       
   243     """Parse a Makefile-style file.
       
   244 
       
   245     A dictionary containing name/value pairs is returned.  If an
       
   246     optional dictionary is passed in as the second argument, it is
       
   247     used instead of a new dictionary.
       
   248     """
       
   249     from distutils.text_file import TextFile
       
   250     fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1)
       
   251 
       
   252     if g is None:
       
   253         g = {}
       
   254     done = {}
       
   255     notdone = {}
       
   256 
       
   257     while 1:
       
   258         line = fp.readline()
       
   259         if line is None:                # eof
       
   260             break
       
   261         m = _variable_rx.match(line)
       
   262         if m:
       
   263             n, v = m.group(1, 2)
       
   264             v = string.strip(v)
       
   265             if "$" in v:
       
   266                 notdone[n] = v
       
   267             else:
       
   268                 try: v = int(v)
       
   269                 except ValueError: pass
       
   270                 done[n] = v
       
   271 
       
   272     # do variable interpolation here
       
   273     while notdone:
       
   274         for name in notdone.keys():
       
   275             value = notdone[name]
       
   276             m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
       
   277             if m:
       
   278                 n = m.group(1)
       
   279                 found = True
       
   280                 if done.has_key(n):
       
   281                     item = str(done[n])
       
   282                 elif notdone.has_key(n):
       
   283                     # get it on a subsequent round
       
   284                     found = False
       
   285                 elif os.environ.has_key(n):
       
   286                     # do it like make: fall back to environment
       
   287                     item = os.environ[n]
       
   288                 else:
       
   289                     done[n] = item = ""
       
   290                 if found:
       
   291                     after = value[m.end():]
       
   292                     value = value[:m.start()] + item + after
       
   293                     if "$" in after:
       
   294                         notdone[name] = value
       
   295                     else:
       
   296                         try: value = int(value)
       
   297                         except ValueError:
       
   298                             done[name] = string.strip(value)
       
   299                         else:
       
   300                             done[name] = value
       
   301                         del notdone[name]
       
   302             else:
       
   303                 # bogus variable reference; just drop it since we can't deal
       
   304                 del notdone[name]
       
   305 
       
   306     fp.close()
       
   307 
       
   308     # save the results in the global dictionary
       
   309     g.update(done)
       
   310     return g
       
   311 
       
   312 
       
   313 def expand_makefile_vars(s, vars):
       
   314     """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in
       
   315     'string' according to 'vars' (a dictionary mapping variable names to
       
   316     values).  Variables not present in 'vars' are silently expanded to the
       
   317     empty string.  The variable values in 'vars' should not contain further
       
   318     variable expansions; if 'vars' is the output of 'parse_makefile()',
       
   319     you're fine.  Returns a variable-expanded version of 's'.
       
   320     """
       
   321 
       
   322     # This algorithm does multiple expansion, so if vars['foo'] contains
       
   323     # "${bar}", it will expand ${foo} to ${bar}, and then expand
       
   324     # ${bar}... and so forth.  This is fine as long as 'vars' comes from
       
   325     # 'parse_makefile()', which takes care of such expansions eagerly,
       
   326     # according to make's variable expansion semantics.
       
   327 
       
   328     while 1:
       
   329         m = _findvar1_rx.search(s) or _findvar2_rx.search(s)
       
   330         if m:
       
   331             (beg, end) = m.span()
       
   332             s = s[0:beg] + vars.get(m.group(1)) + s[end:]
       
   333         else:
       
   334             break
       
   335     return s
       
   336 
       
   337 
       
   338 _config_vars = None
       
   339 
       
   340 def _init_posix():
       
   341     """Initialize the module as appropriate for POSIX systems."""
       
   342     g = {}
       
   343     # load the installed Makefile:
       
   344     try:
       
   345         filename = get_makefile_filename()
       
   346         parse_makefile(filename, g)
       
   347     except IOError, msg:
       
   348         my_msg = "invalid Python installation: unable to open %s" % filename
       
   349         if hasattr(msg, "strerror"):
       
   350             my_msg = my_msg + " (%s)" % msg.strerror
       
   351 
       
   352         raise DistutilsPlatformError(my_msg)
       
   353 
       
   354     # load the installed pyconfig.h:
       
   355     try:
       
   356         filename = get_config_h_filename()
       
   357         parse_config_h(file(filename), g)
       
   358     except IOError, msg:
       
   359         my_msg = "invalid Python installation: unable to open %s" % filename
       
   360         if hasattr(msg, "strerror"):
       
   361             my_msg = my_msg + " (%s)" % msg.strerror
       
   362 
       
   363         raise DistutilsPlatformError(my_msg)
       
   364 
       
   365     # On MacOSX we need to check the setting of the environment variable
       
   366     # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so
       
   367     # it needs to be compatible.
       
   368     # If it isn't set we set it to the configure-time value
       
   369     if sys.platform == 'darwin' and g.has_key('MACOSX_DEPLOYMENT_TARGET'):
       
   370         cfg_target = g['MACOSX_DEPLOYMENT_TARGET']
       
   371         cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '')
       
   372         if cur_target == '':
       
   373             cur_target = cfg_target
       
   374             os.putenv('MACOSX_DEPLOYMENT_TARGET', cfg_target)
       
   375         elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')):
       
   376             my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure'
       
   377                 % (cur_target, cfg_target))
       
   378             raise DistutilsPlatformError(my_msg)
       
   379 
       
   380     # On AIX, there are wrong paths to the linker scripts in the Makefile
       
   381     # -- these paths are relative to the Python source, but when installed
       
   382     # the scripts are in another directory.
       
   383     if python_build:
       
   384         g['LDSHARED'] = g['BLDSHARED']
       
   385 
       
   386     elif get_python_version() < '2.1':
       
   387         # The following two branches are for 1.5.2 compatibility.
       
   388         if sys.platform == 'aix4':          # what about AIX 3.x ?
       
   389             # Linker script is in the config directory, not in Modules as the
       
   390             # Makefile says.
       
   391             python_lib = get_python_lib(standard_lib=1)
       
   392             ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix')
       
   393             python_exp = os.path.join(python_lib, 'config', 'python.exp')
       
   394 
       
   395             g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp)
       
   396 
       
   397         elif sys.platform == 'beos':
       
   398             # Linker script is in the config directory.  In the Makefile it is
       
   399             # relative to the srcdir, which after installation no longer makes
       
   400             # sense.
       
   401             python_lib = get_python_lib(standard_lib=1)
       
   402             linkerscript_path = string.split(g['LDSHARED'])[0]
       
   403             linkerscript_name = os.path.basename(linkerscript_path)
       
   404             linkerscript = os.path.join(python_lib, 'config',
       
   405                                         linkerscript_name)
       
   406 
       
   407             # XXX this isn't the right place to do this: adding the Python
       
   408             # library to the link, if needed, should be in the "build_ext"
       
   409             # command.  (It's also needed for non-MS compilers on Windows, and
       
   410             # it's taken care of for them by the 'build_ext.get_libraries()'
       
   411             # method.)
       
   412             g['LDSHARED'] = ("%s -L%s/lib -lpython%s" %
       
   413                              (linkerscript, PREFIX, get_python_version()))
       
   414 
       
   415     global _config_vars
       
   416     _config_vars = g
       
   417 
       
   418 
       
   419 def _init_nt():
       
   420     """Initialize the module as appropriate for NT"""
       
   421     g = {}
       
   422     # set basic install directories
       
   423     g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
       
   424     g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
       
   425 
       
   426     # XXX hmmm.. a normal install puts include files here
       
   427     g['INCLUDEPY'] = get_python_inc(plat_specific=0)
       
   428 
       
   429     g['SO'] = '.pyd'
       
   430     g['EXE'] = ".exe"
       
   431 
       
   432     global _config_vars
       
   433     _config_vars = g
       
   434 
       
   435 
       
   436 def _init_mac():
       
   437     """Initialize the module as appropriate for Macintosh systems"""
       
   438     g = {}
       
   439     # set basic install directories
       
   440     g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
       
   441     g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
       
   442 
       
   443     # XXX hmmm.. a normal install puts include files here
       
   444     g['INCLUDEPY'] = get_python_inc(plat_specific=0)
       
   445 
       
   446     import MacOS
       
   447     if not hasattr(MacOS, 'runtimemodel'):
       
   448         g['SO'] = '.ppc.slb'
       
   449     else:
       
   450         g['SO'] = '.%s.slb' % MacOS.runtimemodel
       
   451 
       
   452     # XXX are these used anywhere?
       
   453     g['install_lib'] = os.path.join(EXEC_PREFIX, "Lib")
       
   454     g['install_platlib'] = os.path.join(EXEC_PREFIX, "Mac", "Lib")
       
   455 
       
   456     # These are used by the extension module build
       
   457     g['srcdir'] = ':'
       
   458     global _config_vars
       
   459     _config_vars = g
       
   460 
       
   461 
       
   462 def _init_os2():
       
   463     """Initialize the module as appropriate for OS/2"""
       
   464     g = {}
       
   465     # set basic install directories
       
   466     g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
       
   467     g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
       
   468 
       
   469     # XXX hmmm.. a normal install puts include files here
       
   470     g['INCLUDEPY'] = get_python_inc(plat_specific=0)
       
   471 
       
   472     g['SO'] = '.pyd'
       
   473     g['EXE'] = ".exe"
       
   474 
       
   475     global _config_vars
       
   476     _config_vars = g
       
   477 
       
   478 
       
   479 def get_config_vars(*args):
       
   480     """With no arguments, return a dictionary of all configuration
       
   481     variables relevant for the current platform.  Generally this includes
       
   482     everything needed to build extensions and install both pure modules and
       
   483     extensions.  On Unix, this means every variable defined in Python's
       
   484     installed Makefile; on Windows and Mac OS it's a much smaller set.
       
   485 
       
   486     With arguments, return a list of values that result from looking up
       
   487     each argument in the configuration variable dictionary.
       
   488     """
       
   489     global _config_vars
       
   490     if _config_vars is None:
       
   491         func = globals().get("_init_" + os.name)
       
   492         if func:
       
   493             func()
       
   494         else:
       
   495             _config_vars = {}
       
   496 
       
   497         # Normalized versions of prefix and exec_prefix are handy to have;
       
   498         # in fact, these are the standard versions used most places in the
       
   499         # Distutils.
       
   500         _config_vars['prefix'] = PREFIX
       
   501         _config_vars['exec_prefix'] = EXEC_PREFIX
       
   502 
       
   503         if sys.platform == 'darwin':
       
   504             kernel_version = os.uname()[2] # Kernel version (8.4.3)
       
   505             major_version = int(kernel_version.split('.')[0])
       
   506 
       
   507             if major_version < 8:
       
   508                 # On Mac OS X before 10.4, check if -arch and -isysroot
       
   509                 # are in CFLAGS or LDFLAGS and remove them if they are.
       
   510                 # This is needed when building extensions on a 10.3 system
       
   511                 # using a universal build of python.
       
   512                 for key in ('LDFLAGS', 'BASECFLAGS',
       
   513                         # a number of derived variables. These need to be
       
   514                         # patched up as well.
       
   515                         'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
       
   516 
       
   517                     flags = _config_vars[key]
       
   518                     flags = re.sub('-arch\s+\w+\s', ' ', flags)
       
   519                     flags = re.sub('-isysroot [^ \t]*', ' ', flags)
       
   520                     _config_vars[key] = flags
       
   521 
       
   522     if args:
       
   523         vals = []
       
   524         for name in args:
       
   525             vals.append(_config_vars.get(name))
       
   526         return vals
       
   527     else:
       
   528         return _config_vars
       
   529 
       
   530 def get_config_var(name):
       
   531     """Return the value of a single variable using the dictionary
       
   532     returned by 'get_config_vars()'.  Equivalent to
       
   533     get_config_vars().get(name)
       
   534     """
       
   535     return get_config_vars().get(name)