blob: 3ae0a5f91d566ef77bd421d9ca11c8ec59a53c9a [file] [log] [blame]
Fred Drake522af3a1999-01-06 16:28:34 +00001"""Provide access to Python's configuration information. The specific names
2defined in the module depend heavily on the platform and configuration.
Greg Ward1190ee31998-12-18 23:46:33 +00003
4Written by: Fred L. Drake, Jr.
5Email: <fdrake@acm.org>
6Initial date: 17-Dec-1998
7"""
8
Greg Ward82d71ca2000-06-03 00:44:30 +00009__revision__ = "$Id$"
Greg Ward1190ee31998-12-18 23:46:33 +000010
Greg Ward9ddaaa11999-01-06 14:46:06 +000011import os
12import re
13import string
14import sys
Greg Ward1190ee31998-12-18 23:46:33 +000015
Fred Drakec1ee39a2000-03-09 15:54:52 +000016from errors import DistutilsPlatformError
Greg Warda0ca3f22000-02-02 00:05:14 +000017
Greg Ward879f0f12000-09-15 01:15:08 +000018# These are needed in a couple of spots, so just compute them once.
Greg Wardcf6bea32000-04-10 01:15:06 +000019PREFIX = os.path.normpath(sys.prefix)
20EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
Fred Drakec1ee39a2000-03-09 15:54:52 +000021
Andrew M. Kuchlingc14fa302001-01-17 15:16:52 +000022# Boolean; if it's true, we're still building Python, so
23# we use different (hard-wired) directories.
24
25python_build = 0
26
27def set_python_build():
28 """Set the python_build flag to true; this means that we're
29 building Python itself. Only called from the setup.py script
30 shipped with Python.
31 """
32
33 global python_build
34 python_build = 1
Fred Drakec1ee39a2000-03-09 15:54:52 +000035
Greg Wardd38e6f72000-04-10 01:17:49 +000036def get_python_inc(plat_specific=0, prefix=None):
Greg Ward7d73b9e2000-03-09 03:16:05 +000037 """Return the directory containing installed Python header files.
Fred Drakec1ee39a2000-03-09 15:54:52 +000038
39 If 'plat_specific' is false (the default), this is the path to the
40 non-platform-specific header files, i.e. Python.h and so on;
41 otherwise, this is the path to platform-specific header files
42 (namely config.h).
43
Greg Wardd38e6f72000-04-10 01:17:49 +000044 If 'prefix' is supplied, use it instead of sys.prefix or
45 sys.exec_prefix -- i.e., ignore 'plat_specific'.
Fred Drakec1ee39a2000-03-09 15:54:52 +000046 """
Greg Wardd38e6f72000-04-10 01:17:49 +000047 if prefix is None:
48 prefix = (plat_specific and EXEC_PREFIX or PREFIX)
Greg Ward7d73b9e2000-03-09 03:16:05 +000049 if os.name == "posix":
Andrew M. Kuchlingc14fa302001-01-17 15:16:52 +000050 if python_build:
51 return "Include/"
Greg Wardcf6bea32000-04-10 01:15:06 +000052 return os.path.join(prefix, "include", "python" + sys.version[:3])
Greg Ward7d73b9e2000-03-09 03:16:05 +000053 elif os.name == "nt":
Greg Wardcf6bea32000-04-10 01:15:06 +000054 return os.path.join(prefix, "Include") # include or Include?
Greg Ward7d73b9e2000-03-09 03:16:05 +000055 elif os.name == "mac":
Greg Wardcf6bea32000-04-10 01:15:06 +000056 return os.path.join(prefix, "Include")
Greg Ward7d73b9e2000-03-09 03:16:05 +000057 else:
58 raise DistutilsPlatformError, \
59 ("I don't know where Python installs its C header files " +
60 "on platform '%s'") % os.name
61
62
Greg Wardd38e6f72000-04-10 01:17:49 +000063def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
Greg Ward7d73b9e2000-03-09 03:16:05 +000064 """Return the directory containing the Python library (standard or
Fred Drakec1ee39a2000-03-09 15:54:52 +000065 site additions).
Greg Ward7d73b9e2000-03-09 03:16:05 +000066
Fred Drakec1ee39a2000-03-09 15:54:52 +000067 If 'plat_specific' is true, return the directory containing
68 platform-specific modules, i.e. any module from a non-pure-Python
69 module distribution; otherwise, return the platform-shared library
70 directory. If 'standard_lib' is true, return the directory
71 containing standard Python library modules; otherwise, return the
72 directory for site-specific modules.
73
Greg Wardd38e6f72000-04-10 01:17:49 +000074 If 'prefix' is supplied, use it instead of sys.prefix or
75 sys.exec_prefix -- i.e., ignore 'plat_specific'.
Fred Drakec1ee39a2000-03-09 15:54:52 +000076 """
Greg Wardd38e6f72000-04-10 01:17:49 +000077 if prefix is None:
78 prefix = (plat_specific and EXEC_PREFIX or PREFIX)
Greg Ward7d73b9e2000-03-09 03:16:05 +000079
80 if os.name == "posix":
Greg Wardcf6bea32000-04-10 01:15:06 +000081 libpython = os.path.join(prefix,
Fred Drakec1ee39a2000-03-09 15:54:52 +000082 "lib", "python" + sys.version[:3])
Greg Ward7d73b9e2000-03-09 03:16:05 +000083 if standard_lib:
84 return libpython
85 else:
Fred Drakec1ee39a2000-03-09 15:54:52 +000086 return os.path.join(libpython, "site-packages")
Greg Ward7d73b9e2000-03-09 03:16:05 +000087
88 elif os.name == "nt":
89 if standard_lib:
Greg Wardcf6bea32000-04-10 01:15:06 +000090 return os.path.join(PREFIX, "Lib")
Greg Ward7d73b9e2000-03-09 03:16:05 +000091 else:
Greg Wardcf6bea32000-04-10 01:15:06 +000092 return prefix
Greg Ward7d73b9e2000-03-09 03:16:05 +000093
94 elif os.name == "mac":
Greg Warddc9fe8a2000-08-02 01:49:40 +000095 if plat_specific:
Greg Ward7d73b9e2000-03-09 03:16:05 +000096 if standard_lib:
Greg Wardcf6bea32000-04-10 01:15:06 +000097 return os.path.join(EXEC_PREFIX, "Mac", "Plugins")
Greg Ward7d73b9e2000-03-09 03:16:05 +000098 else:
99 raise DistutilsPlatformError, \
100 "OK, where DO site-specific extensions go on the Mac?"
101 else:
102 if standard_lib:
Greg Wardcf6bea32000-04-10 01:15:06 +0000103 return os.path.join(PREFIX, "Lib")
Greg Ward7d73b9e2000-03-09 03:16:05 +0000104 else:
105 raise DistutilsPlatformError, \
106 "OK, where DO site-specific modules go on the Mac?"
107 else:
108 raise DistutilsPlatformError, \
109 ("I don't know where Python installs its library " +
110 "on platform '%s'") % os.name
111
Fred Drakec1ee39a2000-03-09 15:54:52 +0000112# get_python_lib()
Greg Ward7d73b9e2000-03-09 03:16:05 +0000113
114
Greg Wardbb7baa72000-06-25 02:09:14 +0000115def customize_compiler (compiler):
116 """Do any platform-specific customization of the CCompiler instance
117 'compiler'. Mainly needed on Unix, so we can plug in the information
118 that varies across Unices and is stored in Python's Makefile.
119 """
120 if compiler.compiler_type == "unix":
Greg Ward879f0f12000-09-15 01:15:08 +0000121 (cc, opt, ccshared, ldshared, so_ext) = \
122 get_config_vars('CC', 'OPT', 'CCSHARED', 'LDSHARED', 'SO')
Greg Wardbb7baa72000-06-25 02:09:14 +0000123
Greg Ward879f0f12000-09-15 01:15:08 +0000124 cc_cmd = cc + ' ' + opt
125 compiler.set_executables(
126 preprocessor=cc + " -E", # not always!
127 compiler=cc_cmd,
128 compiler_so=cc_cmd + ' ' + ccshared,
129 linker_so=ldshared,
130 linker_exe=cc)
131
132 compiler.shared_lib_extension = so_ext
Greg Wardbb7baa72000-06-25 02:09:14 +0000133
134
Greg Ward9ddaaa11999-01-06 14:46:06 +0000135def get_config_h_filename():
Fred Drake522af3a1999-01-06 16:28:34 +0000136 """Return full pathname of installed config.h file."""
Andrew M. Kuchlingc14fa302001-01-17 15:16:52 +0000137 if python_build: inc_dir = '.'
138 else: inc_dir = get_python_inc(plat_specific=1)
Fred Drakec1ee39a2000-03-09 15:54:52 +0000139 return os.path.join(inc_dir, "config.h")
Greg Ward7d73b9e2000-03-09 03:16:05 +0000140
Greg Ward1190ee31998-12-18 23:46:33 +0000141
Greg Ward9ddaaa11999-01-06 14:46:06 +0000142def get_makefile_filename():
Fred Drake522af3a1999-01-06 16:28:34 +0000143 """Return full pathname of installed Makefile from the Python build."""
Andrew M. Kuchlingc14fa302001-01-17 15:16:52 +0000144 if python_build:
145 return './Modules/Makefile'
Fred Drakec1ee39a2000-03-09 15:54:52 +0000146 lib_dir = get_python_lib(plat_specific=1, standard_lib=1)
147 return os.path.join(lib_dir, "config", "Makefile")
Greg Ward7d73b9e2000-03-09 03:16:05 +0000148
Greg Ward1190ee31998-12-18 23:46:33 +0000149
Greg Ward9ddaaa11999-01-06 14:46:06 +0000150def parse_config_h(fp, g=None):
Fred Drakec1ee39a2000-03-09 15:54:52 +0000151 """Parse a config.h-style file.
152
153 A dictionary containing name/value pairs is returned. If an
154 optional dictionary is passed in as the second argument, it is
155 used instead of a new dictionary.
Fred Drake522af3a1999-01-06 16:28:34 +0000156 """
Greg Ward9ddaaa11999-01-06 14:46:06 +0000157 if g is None:
158 g = {}
Greg Ward1190ee31998-12-18 23:46:33 +0000159 define_rx = re.compile("#define ([A-Z][A-Z0-9_]+) (.*)\n")
160 undef_rx = re.compile("/[*] #undef ([A-Z][A-Z0-9_]+) [*]/\n")
Greg Ward9ddaaa11999-01-06 14:46:06 +0000161 #
Greg Ward1190ee31998-12-18 23:46:33 +0000162 while 1:
163 line = fp.readline()
164 if not line:
165 break
166 m = define_rx.match(line)
167 if m:
168 n, v = m.group(1, 2)
Greg Ward3c8e54b1998-12-22 12:42:04 +0000169 try: v = string.atoi(v)
170 except ValueError: pass
171 g[n] = v
Greg Ward1190ee31998-12-18 23:46:33 +0000172 else:
173 m = undef_rx.match(line)
174 if m:
175 g[m.group(1)] = 0
Greg Ward9ddaaa11999-01-06 14:46:06 +0000176 return g
Greg Ward1190ee31998-12-18 23:46:33 +0000177
Greg Wardd283ce72000-09-17 00:53:02 +0000178
179# Regexes needed for parsing Makefile (and similar syntaxes,
180# like old-style Setup files).
181_variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
182_findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
183_findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
184
Greg Ward3fff8d22000-09-15 00:03:13 +0000185def parse_makefile(fn, g=None):
Fred Drakec1ee39a2000-03-09 15:54:52 +0000186 """Parse a Makefile-style file.
187
188 A dictionary containing name/value pairs is returned. If an
189 optional dictionary is passed in as the second argument, it is
190 used instead of a new dictionary.
191
Fred Drake522af3a1999-01-06 16:28:34 +0000192 """
Greg Ward3fff8d22000-09-15 00:03:13 +0000193 from distutils.text_file import TextFile
Greg Wardd283ce72000-09-17 00:53:02 +0000194 fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1)
Greg Ward3fff8d22000-09-15 00:03:13 +0000195
Greg Ward9ddaaa11999-01-06 14:46:06 +0000196 if g is None:
197 g = {}
Greg Ward1190ee31998-12-18 23:46:33 +0000198 done = {}
199 notdone = {}
Greg Ward3fff8d22000-09-15 00:03:13 +0000200
Greg Ward1190ee31998-12-18 23:46:33 +0000201 while 1:
202 line = fp.readline()
Greg Wardd283ce72000-09-17 00:53:02 +0000203 if line is None: # eof
Greg Ward1190ee31998-12-18 23:46:33 +0000204 break
Greg Wardd283ce72000-09-17 00:53:02 +0000205 m = _variable_rx.match(line)
Greg Ward1190ee31998-12-18 23:46:33 +0000206 if m:
207 n, v = m.group(1, 2)
Greg Ward3c8e54b1998-12-22 12:42:04 +0000208 v = string.strip(v)
Greg Ward1190ee31998-12-18 23:46:33 +0000209 if "$" in v:
210 notdone[n] = v
211 else:
Greg Ward3c8e54b1998-12-22 12:42:04 +0000212 try: v = string.atoi(v)
213 except ValueError: pass
Greg Ward1190ee31998-12-18 23:46:33 +0000214 done[n] = v
215
216 # do variable interpolation here
Greg Ward1190ee31998-12-18 23:46:33 +0000217 while notdone:
218 for name in notdone.keys():
219 value = notdone[name]
Greg Wardd283ce72000-09-17 00:53:02 +0000220 m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
Greg Ward1190ee31998-12-18 23:46:33 +0000221 if m:
222 n = m.group(1)
223 if done.has_key(n):
224 after = value[m.end():]
Andrew M. Kuchlingb11bd032001-01-16 16:33:28 +0000225 value = value[:m.start()] + str(done[n]) + after
Greg Ward1190ee31998-12-18 23:46:33 +0000226 if "$" in after:
227 notdone[name] = value
228 else:
Greg Ward3c8e54b1998-12-22 12:42:04 +0000229 try: value = string.atoi(value)
Andrew M. Kuchlingb11bd032001-01-16 16:33:28 +0000230 except ValueError:
231 done[name] = string.strip(value)
232 else:
233 done[name] = value
Greg Ward1190ee31998-12-18 23:46:33 +0000234 del notdone[name]
235 elif notdone.has_key(n):
236 # get it on a subsequent round
237 pass
238 else:
239 done[n] = ""
240 after = value[m.end():]
241 value = value[:m.start()] + after
242 if "$" in after:
243 notdone[name] = value
244 else:
Greg Ward3c8e54b1998-12-22 12:42:04 +0000245 try: value = string.atoi(value)
Andrew M. Kuchlingb11bd032001-01-16 16:33:28 +0000246 except ValueError:
247 done[name] = string.strip(value)
248 else:
249 done[name] = value
Greg Ward1190ee31998-12-18 23:46:33 +0000250 del notdone[name]
251 else:
Greg Ward3c8e54b1998-12-22 12:42:04 +0000252 # bogus variable reference; just drop it since we can't deal
Greg Ward1190ee31998-12-18 23:46:33 +0000253 del notdone[name]
254
Greg Wardd283ce72000-09-17 00:53:02 +0000255 fp.close()
256
Greg Ward1190ee31998-12-18 23:46:33 +0000257 # save the results in the global dictionary
258 g.update(done)
Greg Ward9ddaaa11999-01-06 14:46:06 +0000259 return g
Greg Ward1190ee31998-12-18 23:46:33 +0000260
261
Greg Wardd283ce72000-09-17 00:53:02 +0000262def expand_makefile_vars(s, vars):
263 """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in
264 'string' according to 'vars' (a dictionary mapping variable names to
265 values). Variables not present in 'vars' are silently expanded to the
266 empty string. The variable values in 'vars' should not contain further
267 variable expansions; if 'vars' is the output of 'parse_makefile()',
268 you're fine. Returns a variable-expanded version of 's'.
269 """
270
271 # This algorithm does multiple expansion, so if vars['foo'] contains
272 # "${bar}", it will expand ${foo} to ${bar}, and then expand
273 # ${bar}... and so forth. This is fine as long as 'vars' comes from
274 # 'parse_makefile()', which takes care of such expansions eagerly,
275 # according to make's variable expansion semantics.
276
277 while 1:
278 m = _findvar1_rx.search(s) or _findvar2_rx.search(s)
279 if m:
280 name = m.group(1)
281 (beg, end) = m.span()
282 s = s[0:beg] + vars.get(m.group(1)) + s[end:]
283 else:
284 break
285 return s
286
287
Greg Ward879f0f12000-09-15 01:15:08 +0000288_config_vars = None
289
Greg Ward9ddaaa11999-01-06 14:46:06 +0000290def _init_posix():
Fred Drake522af3a1999-01-06 16:28:34 +0000291 """Initialize the module as appropriate for POSIX systems."""
Greg Ward879f0f12000-09-15 01:15:08 +0000292 g = {}
Greg Warda0ca3f22000-02-02 00:05:14 +0000293 # load the installed Makefile:
Greg Warda570c052000-05-23 23:14:00 +0000294 try:
295 filename = get_makefile_filename()
Greg Ward3fff8d22000-09-15 00:03:13 +0000296 parse_makefile(filename, g)
Greg Warda570c052000-05-23 23:14:00 +0000297 except IOError, msg:
298 my_msg = "invalid Python installation: unable to open %s" % filename
299 if hasattr(msg, "strerror"):
300 my_msg = my_msg + " (%s)" % msg.strerror
301
302 raise DistutilsPlatformError, my_msg
303
Greg Ward4f880282000-06-27 01:59:06 +0000304
305 # On AIX, there are wrong paths to the linker scripts in the Makefile
306 # -- these paths are relative to the Python source, but when installed
307 # the scripts are in another directory.
Greg Wardb231e1a2000-06-27 01:59:43 +0000308 if sys.platform == 'aix4': # what about AIX 3.x ?
Greg Ward4f880282000-06-27 01:59:06 +0000309 # Linker script is in the config directory, not in Modules as the
310 # Makefile says.
311 python_lib = get_python_lib(standard_lib=1)
312 ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix')
313 python_exp = os.path.join(python_lib, 'config', 'python.exp')
314
315 g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp)
Greg Ward9ddaaa11999-01-06 14:46:06 +0000316
Greg Ward879f0f12000-09-15 01:15:08 +0000317 elif sys.platform == 'beos':
Greg Ward66e966f2000-09-01 01:23:26 +0000318
319 # Linker script is in the config directory. In the Makefile it is
320 # relative to the srcdir, which after installation no longer makes
321 # sense.
322 python_lib = get_python_lib(standard_lib=1)
323 linkerscript_name = os.path.basename(string.split(g['LDSHARED'])[0])
324 linkerscript = os.path.join(python_lib, 'config', linkerscript_name)
325
326 # XXX this isn't the right place to do this: adding the Python
327 # library to the link, if needed, should be in the "build_ext"
328 # command. (It's also needed for non-MS compilers on Windows, and
329 # it's taken care of for them by the 'build_ext.get_libraries()'
330 # method.)
331 g['LDSHARED'] = ("%s -L%s/lib -lpython%s" %
Greg Ward879f0f12000-09-15 01:15:08 +0000332 (linkerscript, PREFIX, sys.version[0:3]))
333
334 global _config_vars
335 _config_vars = g
Greg Ward66e966f2000-09-01 01:23:26 +0000336
Greg Ward9ddaaa11999-01-06 14:46:06 +0000337
Greg Ward4d74d731999-06-08 01:58:36 +0000338def _init_nt():
339 """Initialize the module as appropriate for NT"""
Greg Ward879f0f12000-09-15 01:15:08 +0000340 g = {}
Greg Ward4d74d731999-06-08 01:58:36 +0000341 # set basic install directories
Fred Drakec1ee39a2000-03-09 15:54:52 +0000342 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
343 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
Greg Ward4d74d731999-06-08 01:58:36 +0000344
Greg Ward32162e81999-08-29 18:22:13 +0000345 # XXX hmmm.. a normal install puts include files here
Fred Drakec1ee39a2000-03-09 15:54:52 +0000346 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
Greg Ward32162e81999-08-29 18:22:13 +0000347
Fred Drake69e2c6e2000-02-08 15:55:42 +0000348 g['SO'] = '.pyd'
Greg Ward82d71ca2000-06-03 00:44:30 +0000349 g['EXE'] = ".exe"
Greg Ward879f0f12000-09-15 01:15:08 +0000350
351 global _config_vars
352 _config_vars = g
Greg Ward82d71ca2000-06-03 00:44:30 +0000353
Fred Drake69e2c6e2000-02-08 15:55:42 +0000354
Greg Ward0eff87a2000-03-07 03:30:09 +0000355def _init_mac():
356 """Initialize the module as appropriate for Macintosh systems"""
Greg Ward879f0f12000-09-15 01:15:08 +0000357 g = {}
Greg Ward0eff87a2000-03-07 03:30:09 +0000358 # set basic install directories
Fred Drakec1ee39a2000-03-09 15:54:52 +0000359 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
360 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
Greg Ward0eff87a2000-03-07 03:30:09 +0000361
362 # XXX hmmm.. a normal install puts include files here
Fred Drakec1ee39a2000-03-09 15:54:52 +0000363 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
Greg Ward0eff87a2000-03-07 03:30:09 +0000364
365 g['SO'] = '.ppc.slb'
Greg Ward7d73b9e2000-03-09 03:16:05 +0000366
367 # XXX are these used anywhere?
Greg Wardcf6bea32000-04-10 01:15:06 +0000368 g['install_lib'] = os.path.join(EXEC_PREFIX, "Lib")
369 g['install_platlib'] = os.path.join(EXEC_PREFIX, "Mac", "Lib")
Greg Ward0eff87a2000-03-07 03:30:09 +0000370
Greg Ward879f0f12000-09-15 01:15:08 +0000371 global _config_vars
372 _config_vars = g
Greg Ward9ddaaa11999-01-06 14:46:06 +0000373
Fred Drake69e2c6e2000-02-08 15:55:42 +0000374
Greg Ward879f0f12000-09-15 01:15:08 +0000375def get_config_vars(*args):
376 """With no arguments, return a dictionary of all configuration
377 variables relevant for the current platform. Generally this includes
378 everything needed to build extensions and install both pure modules and
379 extensions. On Unix, this means every variable defined in Python's
380 installed Makefile; on Windows and Mac OS it's a much smaller set.
381
382 With arguments, return a list of values that result from looking up
383 each argument in the configuration variable dictionary.
384 """
385 global _config_vars
386 if _config_vars is None:
Greg Ward879f0f12000-09-15 01:15:08 +0000387 func = globals().get("_init_" + os.name)
388 if func:
389 func()
390 else:
391 _config_vars = {}
392
393 # Normalized versions of prefix and exec_prefix are handy to have;
394 # in fact, these are the standard versions used most places in the
395 # Distutils.
396 _config_vars['prefix'] = PREFIX
397 _config_vars['exec_prefix'] = EXEC_PREFIX
398
399 if args:
400 vals = []
401 for name in args:
402 vals.append(_config_vars.get(name))
403 return vals
404 else:
405 return _config_vars
406
407def get_config_var(name):
408 """Return the value of a single variable using the dictionary
409 returned by 'get_config_vars()'. Equivalent to
410 get_config_vars().get(name)
411 """
412 return get_config_vars().get(name)