blob: 53da48264e0b5d00753cad918c4951ac462a58e6 [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 Ward1190ee31998-12-18 23:46:33 +000018
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":
80 if platform_specific:
81 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 Ward9ddaaa11999-01-06 14:46:06 +0000100def get_config_h_filename():
Fred Drake522af3a1999-01-06 16:28:34 +0000101 """Return full pathname of installed config.h file."""
Fred Drakec1ee39a2000-03-09 15:54:52 +0000102 inc_dir = get_python_inc(plat_specific=1)
103 return os.path.join(inc_dir, "config.h")
Greg Ward7d73b9e2000-03-09 03:16:05 +0000104
Greg Ward1190ee31998-12-18 23:46:33 +0000105
Greg Ward9ddaaa11999-01-06 14:46:06 +0000106def get_makefile_filename():
Fred Drake522af3a1999-01-06 16:28:34 +0000107 """Return full pathname of installed Makefile from the Python build."""
Fred Drakec1ee39a2000-03-09 15:54:52 +0000108 lib_dir = get_python_lib(plat_specific=1, standard_lib=1)
109 return os.path.join(lib_dir, "config", "Makefile")
Greg Ward7d73b9e2000-03-09 03:16:05 +0000110
Greg Ward1190ee31998-12-18 23:46:33 +0000111
Greg Ward9ddaaa11999-01-06 14:46:06 +0000112def parse_config_h(fp, g=None):
Fred Drakec1ee39a2000-03-09 15:54:52 +0000113 """Parse a config.h-style file.
114
115 A dictionary containing name/value pairs is returned. If an
116 optional dictionary is passed in as the second argument, it is
117 used instead of a new dictionary.
Fred Drake522af3a1999-01-06 16:28:34 +0000118 """
Greg Ward9ddaaa11999-01-06 14:46:06 +0000119 if g is None:
120 g = {}
Greg Ward1190ee31998-12-18 23:46:33 +0000121 define_rx = re.compile("#define ([A-Z][A-Z0-9_]+) (.*)\n")
122 undef_rx = re.compile("/[*] #undef ([A-Z][A-Z0-9_]+) [*]/\n")
Greg Ward9ddaaa11999-01-06 14:46:06 +0000123 #
Greg Ward1190ee31998-12-18 23:46:33 +0000124 while 1:
125 line = fp.readline()
126 if not line:
127 break
128 m = define_rx.match(line)
129 if m:
130 n, v = m.group(1, 2)
Greg Ward3c8e54b1998-12-22 12:42:04 +0000131 try: v = string.atoi(v)
132 except ValueError: pass
133 g[n] = v
Greg Ward1190ee31998-12-18 23:46:33 +0000134 else:
135 m = undef_rx.match(line)
136 if m:
137 g[m.group(1)] = 0
Greg Ward9ddaaa11999-01-06 14:46:06 +0000138 return g
Greg Ward1190ee31998-12-18 23:46:33 +0000139
Greg Ward9ddaaa11999-01-06 14:46:06 +0000140def parse_makefile(fp, g=None):
Fred Drakec1ee39a2000-03-09 15:54:52 +0000141 """Parse a Makefile-style file.
142
143 A dictionary containing name/value pairs is returned. If an
144 optional dictionary is passed in as the second argument, it is
145 used instead of a new dictionary.
146
Fred Drake522af3a1999-01-06 16:28:34 +0000147 """
Greg Ward9ddaaa11999-01-06 14:46:06 +0000148 if g is None:
149 g = {}
Greg Ward1190ee31998-12-18 23:46:33 +0000150 variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)\n")
151 done = {}
152 notdone = {}
Greg Ward9ddaaa11999-01-06 14:46:06 +0000153 #
Greg Ward1190ee31998-12-18 23:46:33 +0000154 while 1:
155 line = fp.readline()
156 if not line:
157 break
158 m = variable_rx.match(line)
159 if m:
160 n, v = m.group(1, 2)
Greg Ward3c8e54b1998-12-22 12:42:04 +0000161 v = string.strip(v)
Greg Ward1190ee31998-12-18 23:46:33 +0000162 if "$" in v:
163 notdone[n] = v
164 else:
Greg Ward3c8e54b1998-12-22 12:42:04 +0000165 try: v = string.atoi(v)
166 except ValueError: pass
Greg Ward1190ee31998-12-18 23:46:33 +0000167 done[n] = v
168
169 # do variable interpolation here
170 findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
171 findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
172 while notdone:
173 for name in notdone.keys():
174 value = notdone[name]
175 m = findvar1_rx.search(value)
176 if not m:
177 m = findvar2_rx.search(value)
178 if m:
179 n = m.group(1)
180 if done.has_key(n):
181 after = value[m.end():]
182 value = value[:m.start()] + done[n] + after
183 if "$" in after:
184 notdone[name] = value
185 else:
Greg Ward3c8e54b1998-12-22 12:42:04 +0000186 try: value = string.atoi(value)
187 except ValueError: pass
188 done[name] = string.strip(value)
Greg Ward1190ee31998-12-18 23:46:33 +0000189 del notdone[name]
190 elif notdone.has_key(n):
191 # get it on a subsequent round
192 pass
193 else:
194 done[n] = ""
195 after = value[m.end():]
196 value = value[:m.start()] + after
197 if "$" in after:
198 notdone[name] = value
199 else:
Greg Ward3c8e54b1998-12-22 12:42:04 +0000200 try: value = string.atoi(value)
201 except ValueError: pass
202 done[name] = string.strip(value)
Greg Ward1190ee31998-12-18 23:46:33 +0000203 del notdone[name]
204 else:
Greg Ward3c8e54b1998-12-22 12:42:04 +0000205 # bogus variable reference; just drop it since we can't deal
Greg Ward1190ee31998-12-18 23:46:33 +0000206 del notdone[name]
207
Greg Wardb1e4a6e2000-04-19 02:22:07 +0000208 # "Fix" all pathnames in the Makefile that are explicitly relative,
209 # ie. that start with "./". This is a kludge to fix the "./ld_so_aix"
210 # problem, the nature of which is that Python's installed Makefile
211 # refers to "./ld_so_aix", but when we are building extensions we are
212 # far from the directory where Python's Makefile (and ld_so_aix, for
213 # that matter) is installed. Unfortunately, there are several other
214 # relative pathnames in the Makefile, and this fix doesn't fix them,
215 # because the layout of Python's source tree -- which is what the
216 # Makefile refers to -- is not fully preserved in the Python
217 # installation. Grumble.
218 from os.path import normpath, join, dirname
219 for (name, value) in done.items():
220 if value[0:2] == "./":
221 done[name] = normpath(join(dirname(fp.name), value))
222
Greg Ward1190ee31998-12-18 23:46:33 +0000223 # save the results in the global dictionary
224 g.update(done)
Greg Ward9ddaaa11999-01-06 14:46:06 +0000225 return g
Greg Ward1190ee31998-12-18 23:46:33 +0000226
227
Greg Ward9ddaaa11999-01-06 14:46:06 +0000228def _init_posix():
Fred Drake522af3a1999-01-06 16:28:34 +0000229 """Initialize the module as appropriate for POSIX systems."""
Greg Ward9ddaaa11999-01-06 14:46:06 +0000230 g = globals()
Greg Warda0ca3f22000-02-02 00:05:14 +0000231 # load the installed Makefile:
Greg Warda570c052000-05-23 23:14:00 +0000232 try:
233 filename = get_makefile_filename()
234 file = open(filename)
235 except IOError, msg:
236 my_msg = "invalid Python installation: unable to open %s" % filename
237 if hasattr(msg, "strerror"):
238 my_msg = my_msg + " (%s)" % msg.strerror
239
240 raise DistutilsPlatformError, my_msg
241
242 parse_makefile(file, g)
Greg Ward9ddaaa11999-01-06 14:46:06 +0000243
244
Greg Ward4d74d731999-06-08 01:58:36 +0000245def _init_nt():
246 """Initialize the module as appropriate for NT"""
Fred Drake69e2c6e2000-02-08 15:55:42 +0000247 g = globals()
Greg Ward4d74d731999-06-08 01:58:36 +0000248 # set basic install directories
Fred Drakec1ee39a2000-03-09 15:54:52 +0000249 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
250 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
Greg Ward4d74d731999-06-08 01:58:36 +0000251
Greg Ward32162e81999-08-29 18:22:13 +0000252 # XXX hmmm.. a normal install puts include files here
Fred Drakec1ee39a2000-03-09 15:54:52 +0000253 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
Greg Ward32162e81999-08-29 18:22:13 +0000254
Fred Drake69e2c6e2000-02-08 15:55:42 +0000255 g['SO'] = '.pyd'
Greg Wardcf6bea32000-04-10 01:15:06 +0000256 g['exec_prefix'] = EXEC_PREFIX
Greg Ward9ddaaa11999-01-06 14:46:06 +0000257
Greg Ward82d71ca2000-06-03 00:44:30 +0000258 # These are needed for the CygwinCCompiler and Mingw32CCompiler
259 # classes, which are just UnixCCompiler classes that happen to work on
260 # Windows. UnixCCompiler expects to find these values in sysconfig, so
261 # here they are. The fact that other Windows compilers don't need
262 # these values is pure luck (hmmm).
263 g['CC'] = "cc" # not gcc?
264 g['RANLIB'] = "ranlib"
265 g['AR'] = "ar"
266 g['OPT'] = "-O2"
267 g['SO'] = ".pyd"
268 g['LDSHARED'] = "ld"
269 g['CCSHARED'] = ""
270 g['EXE'] = ".exe"
271
Fred Drake69e2c6e2000-02-08 15:55:42 +0000272
Greg Ward0eff87a2000-03-07 03:30:09 +0000273def _init_mac():
274 """Initialize the module as appropriate for Macintosh systems"""
275 g = globals()
Greg Ward0eff87a2000-03-07 03:30:09 +0000276 # set basic install directories
Fred Drakec1ee39a2000-03-09 15:54:52 +0000277 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
278 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
Greg Ward0eff87a2000-03-07 03:30:09 +0000279
280 # XXX hmmm.. a normal install puts include files here
Fred Drakec1ee39a2000-03-09 15:54:52 +0000281 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
Greg Ward0eff87a2000-03-07 03:30:09 +0000282
283 g['SO'] = '.ppc.slb'
Greg Wardcf6bea32000-04-10 01:15:06 +0000284 g['exec_prefix'] = EXEC_PREFIX
285 print sys.prefix, PREFIX
Greg Ward7d73b9e2000-03-09 03:16:05 +0000286
287 # XXX are these used anywhere?
Greg Wardcf6bea32000-04-10 01:15:06 +0000288 g['install_lib'] = os.path.join(EXEC_PREFIX, "Lib")
289 g['install_platlib'] = os.path.join(EXEC_PREFIX, "Mac", "Lib")
Greg Ward0eff87a2000-03-07 03:30:09 +0000290
291
Greg Ward9ddaaa11999-01-06 14:46:06 +0000292try:
293 exec "_init_" + os.name
294except NameError:
295 # not needed for this platform
296 pass
297else:
298 exec "_init_%s()" % os.name
299
Fred Drake69e2c6e2000-02-08 15:55:42 +0000300
Greg Ward1190ee31998-12-18 23:46:33 +0000301del _init_posix
Greg Ward4d74d731999-06-08 01:58:36 +0000302del _init_nt
Greg Ward0eff87a2000-03-07 03:30:09 +0000303del _init_mac