blob: de35d96a8d4d6cc7ff5805a9af23b0a1a0038196 [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
22
Greg Wardd38e6f72000-04-10 01:17:49 +000023def get_python_inc(plat_specific=0, prefix=None):
Greg Ward7d73b9e2000-03-09 03:16:05 +000024 """Return the directory containing installed Python header files.
Fred Drakec1ee39a2000-03-09 15:54:52 +000025
26 If 'plat_specific' is false (the default), this is the path to the
27 non-platform-specific header files, i.e. Python.h and so on;
28 otherwise, this is the path to platform-specific header files
29 (namely config.h).
30
Greg Wardd38e6f72000-04-10 01:17:49 +000031 If 'prefix' is supplied, use it instead of sys.prefix or
32 sys.exec_prefix -- i.e., ignore 'plat_specific'.
Fred Drakec1ee39a2000-03-09 15:54:52 +000033 """
Greg Wardd38e6f72000-04-10 01:17:49 +000034 if prefix is None:
35 prefix = (plat_specific and EXEC_PREFIX or PREFIX)
Greg Ward7d73b9e2000-03-09 03:16:05 +000036 if os.name == "posix":
Greg Wardcf6bea32000-04-10 01:15:06 +000037 return os.path.join(prefix, "include", "python" + sys.version[:3])
Greg Ward7d73b9e2000-03-09 03:16:05 +000038 elif os.name == "nt":
Greg Wardcf6bea32000-04-10 01:15:06 +000039 return os.path.join(prefix, "Include") # include or Include?
Greg Ward7d73b9e2000-03-09 03:16:05 +000040 elif os.name == "mac":
Greg Wardcf6bea32000-04-10 01:15:06 +000041 return os.path.join(prefix, "Include")
Greg Ward7d73b9e2000-03-09 03:16:05 +000042 else:
43 raise DistutilsPlatformError, \
44 ("I don't know where Python installs its C header files " +
45 "on platform '%s'") % os.name
46
47
Greg Wardd38e6f72000-04-10 01:17:49 +000048def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
Greg Ward7d73b9e2000-03-09 03:16:05 +000049 """Return the directory containing the Python library (standard or
Fred Drakec1ee39a2000-03-09 15:54:52 +000050 site additions).
Greg Ward7d73b9e2000-03-09 03:16:05 +000051
Fred Drakec1ee39a2000-03-09 15:54:52 +000052 If 'plat_specific' is true, return the directory containing
53 platform-specific modules, i.e. any module from a non-pure-Python
54 module distribution; otherwise, return the platform-shared library
55 directory. If 'standard_lib' is true, return the directory
56 containing standard Python library modules; otherwise, return the
57 directory for site-specific modules.
58
Greg Wardd38e6f72000-04-10 01:17:49 +000059 If 'prefix' is supplied, use it instead of sys.prefix or
60 sys.exec_prefix -- i.e., ignore 'plat_specific'.
Fred Drakec1ee39a2000-03-09 15:54:52 +000061 """
Greg Wardd38e6f72000-04-10 01:17:49 +000062 if prefix is None:
63 prefix = (plat_specific and EXEC_PREFIX or PREFIX)
Greg Ward7d73b9e2000-03-09 03:16:05 +000064
65 if os.name == "posix":
Greg Wardcf6bea32000-04-10 01:15:06 +000066 libpython = os.path.join(prefix,
Fred Drakec1ee39a2000-03-09 15:54:52 +000067 "lib", "python" + sys.version[:3])
Greg Ward7d73b9e2000-03-09 03:16:05 +000068 if standard_lib:
69 return libpython
70 else:
Fred Drakec1ee39a2000-03-09 15:54:52 +000071 return os.path.join(libpython, "site-packages")
Greg Ward7d73b9e2000-03-09 03:16:05 +000072
73 elif os.name == "nt":
74 if standard_lib:
Greg Wardcf6bea32000-04-10 01:15:06 +000075 return os.path.join(PREFIX, "Lib")
Greg Ward7d73b9e2000-03-09 03:16:05 +000076 else:
Greg Wardcf6bea32000-04-10 01:15:06 +000077 return prefix
Greg Ward7d73b9e2000-03-09 03:16:05 +000078
79 elif os.name == "mac":
Greg Warddc9fe8a2000-08-02 01:49:40 +000080 if plat_specific:
Greg Ward7d73b9e2000-03-09 03:16:05 +000081 if standard_lib:
Greg Wardcf6bea32000-04-10 01:15:06 +000082 return os.path.join(EXEC_PREFIX, "Mac", "Plugins")
Greg Ward7d73b9e2000-03-09 03:16:05 +000083 else:
84 raise DistutilsPlatformError, \
85 "OK, where DO site-specific extensions go on the Mac?"
86 else:
87 if standard_lib:
Greg Wardcf6bea32000-04-10 01:15:06 +000088 return os.path.join(PREFIX, "Lib")
Greg Ward7d73b9e2000-03-09 03:16:05 +000089 else:
90 raise DistutilsPlatformError, \
91 "OK, where DO site-specific modules go on the Mac?"
92 else:
93 raise DistutilsPlatformError, \
94 ("I don't know where Python installs its library " +
95 "on platform '%s'") % os.name
96
Fred Drakec1ee39a2000-03-09 15:54:52 +000097# get_python_lib()
Greg Ward7d73b9e2000-03-09 03:16:05 +000098
99
Greg Wardbb7baa72000-06-25 02:09:14 +0000100def customize_compiler (compiler):
101 """Do any platform-specific customization of the CCompiler instance
102 'compiler'. Mainly needed on Unix, so we can plug in the information
103 that varies across Unices and is stored in Python's Makefile.
104 """
105 if compiler.compiler_type == "unix":
Greg Ward879f0f12000-09-15 01:15:08 +0000106 (cc, opt, ccshared, ldshared, so_ext) = \
107 get_config_vars('CC', 'OPT', 'CCSHARED', 'LDSHARED', 'SO')
Greg Wardbb7baa72000-06-25 02:09:14 +0000108
Greg Ward879f0f12000-09-15 01:15:08 +0000109 cc_cmd = cc + ' ' + opt
110 compiler.set_executables(
111 preprocessor=cc + " -E", # not always!
112 compiler=cc_cmd,
113 compiler_so=cc_cmd + ' ' + ccshared,
114 linker_so=ldshared,
115 linker_exe=cc)
116
117 compiler.shared_lib_extension = so_ext
Greg Wardbb7baa72000-06-25 02:09:14 +0000118
119
Greg Ward9ddaaa11999-01-06 14:46:06 +0000120def get_config_h_filename():
Fred Drake522af3a1999-01-06 16:28:34 +0000121 """Return full pathname of installed config.h file."""
Fred Drakec1ee39a2000-03-09 15:54:52 +0000122 inc_dir = get_python_inc(plat_specific=1)
123 return os.path.join(inc_dir, "config.h")
Greg Ward7d73b9e2000-03-09 03:16:05 +0000124
Greg Ward1190ee31998-12-18 23:46:33 +0000125
Greg Ward9ddaaa11999-01-06 14:46:06 +0000126def get_makefile_filename():
Fred Drake522af3a1999-01-06 16:28:34 +0000127 """Return full pathname of installed Makefile from the Python build."""
Fred Drakec1ee39a2000-03-09 15:54:52 +0000128 lib_dir = get_python_lib(plat_specific=1, standard_lib=1)
129 return os.path.join(lib_dir, "config", "Makefile")
Greg Ward7d73b9e2000-03-09 03:16:05 +0000130
Greg Ward1190ee31998-12-18 23:46:33 +0000131
Greg Ward9ddaaa11999-01-06 14:46:06 +0000132def parse_config_h(fp, g=None):
Fred Drakec1ee39a2000-03-09 15:54:52 +0000133 """Parse a config.h-style file.
134
135 A dictionary containing name/value pairs is returned. If an
136 optional dictionary is passed in as the second argument, it is
137 used instead of a new dictionary.
Fred Drake522af3a1999-01-06 16:28:34 +0000138 """
Greg Ward9ddaaa11999-01-06 14:46:06 +0000139 if g is None:
140 g = {}
Greg Ward1190ee31998-12-18 23:46:33 +0000141 define_rx = re.compile("#define ([A-Z][A-Z0-9_]+) (.*)\n")
142 undef_rx = re.compile("/[*] #undef ([A-Z][A-Z0-9_]+) [*]/\n")
Greg Ward9ddaaa11999-01-06 14:46:06 +0000143 #
Greg Ward1190ee31998-12-18 23:46:33 +0000144 while 1:
145 line = fp.readline()
146 if not line:
147 break
148 m = define_rx.match(line)
149 if m:
150 n, v = m.group(1, 2)
Greg Ward3c8e54b1998-12-22 12:42:04 +0000151 try: v = string.atoi(v)
152 except ValueError: pass
153 g[n] = v
Greg Ward1190ee31998-12-18 23:46:33 +0000154 else:
155 m = undef_rx.match(line)
156 if m:
157 g[m.group(1)] = 0
Greg Ward9ddaaa11999-01-06 14:46:06 +0000158 return g
Greg Ward1190ee31998-12-18 23:46:33 +0000159
Greg Ward3fff8d22000-09-15 00:03:13 +0000160def parse_makefile(fn, g=None):
Fred Drakec1ee39a2000-03-09 15:54:52 +0000161 """Parse a Makefile-style file.
162
163 A dictionary containing name/value pairs is returned. If an
164 optional dictionary is passed in as the second argument, it is
165 used instead of a new dictionary.
166
Fred Drake522af3a1999-01-06 16:28:34 +0000167 """
Greg Ward3fff8d22000-09-15 00:03:13 +0000168 from distutils.text_file import TextFile
169 fp = TextFile(fn, strip_comments=1, join_lines=1)
170
Greg Ward9ddaaa11999-01-06 14:46:06 +0000171 if g is None:
172 g = {}
Greg Ward3fff8d22000-09-15 00:03:13 +0000173 variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
Greg Ward1190ee31998-12-18 23:46:33 +0000174 done = {}
175 notdone = {}
Greg Ward3fff8d22000-09-15 00:03:13 +0000176
Greg Ward1190ee31998-12-18 23:46:33 +0000177 while 1:
178 line = fp.readline()
Greg Ward3fff8d22000-09-15 00:03:13 +0000179 if line is None:
Greg Ward1190ee31998-12-18 23:46:33 +0000180 break
181 m = variable_rx.match(line)
182 if m:
183 n, v = m.group(1, 2)
Greg Ward3c8e54b1998-12-22 12:42:04 +0000184 v = string.strip(v)
Greg Ward1190ee31998-12-18 23:46:33 +0000185 if "$" in v:
186 notdone[n] = v
187 else:
Greg Ward3c8e54b1998-12-22 12:42:04 +0000188 try: v = string.atoi(v)
189 except ValueError: pass
Greg Ward1190ee31998-12-18 23:46:33 +0000190 done[n] = v
191
192 # do variable interpolation here
193 findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
194 findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
195 while notdone:
196 for name in notdone.keys():
197 value = notdone[name]
198 m = findvar1_rx.search(value)
199 if not m:
200 m = findvar2_rx.search(value)
201 if m:
202 n = m.group(1)
203 if done.has_key(n):
204 after = value[m.end():]
205 value = value[:m.start()] + done[n] + after
206 if "$" in after:
207 notdone[name] = value
208 else:
Greg Ward3c8e54b1998-12-22 12:42:04 +0000209 try: value = string.atoi(value)
210 except ValueError: pass
211 done[name] = string.strip(value)
Greg Ward1190ee31998-12-18 23:46:33 +0000212 del notdone[name]
213 elif notdone.has_key(n):
214 # get it on a subsequent round
215 pass
216 else:
217 done[n] = ""
218 after = value[m.end():]
219 value = value[:m.start()] + after
220 if "$" in after:
221 notdone[name] = value
222 else:
Greg Ward3c8e54b1998-12-22 12:42:04 +0000223 try: value = string.atoi(value)
224 except ValueError: pass
225 done[name] = string.strip(value)
Greg Ward1190ee31998-12-18 23:46:33 +0000226 del notdone[name]
227 else:
Greg Ward3c8e54b1998-12-22 12:42:04 +0000228 # bogus variable reference; just drop it since we can't deal
Greg Ward1190ee31998-12-18 23:46:33 +0000229 del notdone[name]
230
231 # save the results in the global dictionary
232 g.update(done)
Greg Ward9ddaaa11999-01-06 14:46:06 +0000233 return g
Greg Ward1190ee31998-12-18 23:46:33 +0000234
235
Greg Ward879f0f12000-09-15 01:15:08 +0000236_config_vars = None
237
Greg Ward9ddaaa11999-01-06 14:46:06 +0000238def _init_posix():
Fred Drake522af3a1999-01-06 16:28:34 +0000239 """Initialize the module as appropriate for POSIX systems."""
Greg Ward879f0f12000-09-15 01:15:08 +0000240 g = {}
Greg Warda0ca3f22000-02-02 00:05:14 +0000241 # load the installed Makefile:
Greg Warda570c052000-05-23 23:14:00 +0000242 try:
243 filename = get_makefile_filename()
Greg Ward3fff8d22000-09-15 00:03:13 +0000244 parse_makefile(filename, g)
Greg Warda570c052000-05-23 23:14:00 +0000245 except IOError, msg:
246 my_msg = "invalid Python installation: unable to open %s" % filename
247 if hasattr(msg, "strerror"):
248 my_msg = my_msg + " (%s)" % msg.strerror
249
250 raise DistutilsPlatformError, my_msg
251
Greg Ward4f880282000-06-27 01:59:06 +0000252
253 # On AIX, there are wrong paths to the linker scripts in the Makefile
254 # -- these paths are relative to the Python source, but when installed
255 # the scripts are in another directory.
Greg Wardb231e1a2000-06-27 01:59:43 +0000256 if sys.platform == 'aix4': # what about AIX 3.x ?
Greg Ward4f880282000-06-27 01:59:06 +0000257 # Linker script is in the config directory, not in Modules as the
258 # Makefile says.
259 python_lib = get_python_lib(standard_lib=1)
260 ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix')
261 python_exp = os.path.join(python_lib, 'config', 'python.exp')
262
263 g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp)
Greg Ward9ddaaa11999-01-06 14:46:06 +0000264
Greg Ward879f0f12000-09-15 01:15:08 +0000265 elif sys.platform == 'beos':
Greg Ward66e966f2000-09-01 01:23:26 +0000266
267 # Linker script is in the config directory. In the Makefile it is
268 # relative to the srcdir, which after installation no longer makes
269 # sense.
270 python_lib = get_python_lib(standard_lib=1)
271 linkerscript_name = os.path.basename(string.split(g['LDSHARED'])[0])
272 linkerscript = os.path.join(python_lib, 'config', linkerscript_name)
273
274 # XXX this isn't the right place to do this: adding the Python
275 # library to the link, if needed, should be in the "build_ext"
276 # command. (It's also needed for non-MS compilers on Windows, and
277 # it's taken care of for them by the 'build_ext.get_libraries()'
278 # method.)
279 g['LDSHARED'] = ("%s -L%s/lib -lpython%s" %
Greg Ward879f0f12000-09-15 01:15:08 +0000280 (linkerscript, PREFIX, sys.version[0:3]))
281
282 global _config_vars
283 _config_vars = g
Greg Ward66e966f2000-09-01 01:23:26 +0000284
Greg Ward9ddaaa11999-01-06 14:46:06 +0000285
Greg Ward4d74d731999-06-08 01:58:36 +0000286def _init_nt():
287 """Initialize the module as appropriate for NT"""
Greg Ward879f0f12000-09-15 01:15:08 +0000288 g = {}
Greg Ward4d74d731999-06-08 01:58:36 +0000289 # set basic install directories
Fred Drakec1ee39a2000-03-09 15:54:52 +0000290 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
291 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
Greg Ward4d74d731999-06-08 01:58:36 +0000292
Greg Ward32162e81999-08-29 18:22:13 +0000293 # XXX hmmm.. a normal install puts include files here
Fred Drakec1ee39a2000-03-09 15:54:52 +0000294 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
Greg Ward32162e81999-08-29 18:22:13 +0000295
Fred Drake69e2c6e2000-02-08 15:55:42 +0000296 g['SO'] = '.pyd'
Greg Ward82d71ca2000-06-03 00:44:30 +0000297 g['EXE'] = ".exe"
Greg Ward879f0f12000-09-15 01:15:08 +0000298
299 global _config_vars
300 _config_vars = g
Greg Ward82d71ca2000-06-03 00:44:30 +0000301
Fred Drake69e2c6e2000-02-08 15:55:42 +0000302
Greg Ward0eff87a2000-03-07 03:30:09 +0000303def _init_mac():
304 """Initialize the module as appropriate for Macintosh systems"""
Greg Ward879f0f12000-09-15 01:15:08 +0000305 g = {}
Greg Ward0eff87a2000-03-07 03:30:09 +0000306 # set basic install directories
Fred Drakec1ee39a2000-03-09 15:54:52 +0000307 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
308 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
Greg Ward0eff87a2000-03-07 03:30:09 +0000309
310 # XXX hmmm.. a normal install puts include files here
Fred Drakec1ee39a2000-03-09 15:54:52 +0000311 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
Greg Ward0eff87a2000-03-07 03:30:09 +0000312
313 g['SO'] = '.ppc.slb'
Greg Ward7d73b9e2000-03-09 03:16:05 +0000314
315 # XXX are these used anywhere?
Greg Wardcf6bea32000-04-10 01:15:06 +0000316 g['install_lib'] = os.path.join(EXEC_PREFIX, "Lib")
317 g['install_platlib'] = os.path.join(EXEC_PREFIX, "Mac", "Lib")
Greg Ward0eff87a2000-03-07 03:30:09 +0000318
Greg Ward879f0f12000-09-15 01:15:08 +0000319 global _config_vars
320 _config_vars = g
Greg Ward9ddaaa11999-01-06 14:46:06 +0000321
Fred Drake69e2c6e2000-02-08 15:55:42 +0000322
Greg Ward879f0f12000-09-15 01:15:08 +0000323def get_config_vars(*args):
324 """With no arguments, return a dictionary of all configuration
325 variables relevant for the current platform. Generally this includes
326 everything needed to build extensions and install both pure modules and
327 extensions. On Unix, this means every variable defined in Python's
328 installed Makefile; on Windows and Mac OS it's a much smaller set.
329
330 With arguments, return a list of values that result from looking up
331 each argument in the configuration variable dictionary.
332 """
333 global _config_vars
334 if _config_vars is None:
335 from pprint import pprint
336 func = globals().get("_init_" + os.name)
337 if func:
338 func()
339 else:
340 _config_vars = {}
341
342 # Normalized versions of prefix and exec_prefix are handy to have;
343 # in fact, these are the standard versions used most places in the
344 # Distutils.
345 _config_vars['prefix'] = PREFIX
346 _config_vars['exec_prefix'] = EXEC_PREFIX
347
348 if args:
349 vals = []
350 for name in args:
351 vals.append(_config_vars.get(name))
352 return vals
353 else:
354 return _config_vars
355
356def get_config_var(name):
357 """Return the value of a single variable using the dictionary
358 returned by 'get_config_vars()'. Equivalent to
359 get_config_vars().get(name)
360 """
361 return get_config_vars().get(name)