Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1)

Delta Between Two Patch Sets: Lib/sysconfig.py

Issue 3871: cross and native build of python for mingw32 with distutils
Left Patch Set: Created 9 years, 6 months ago
Right Patch Set: Created 7 years, 2 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/plat-generic/regen ('k') | Lib/test/test_capi.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 """Provide access to Python's configuration information. 1 """Access to Python's configuration information."""
2 2
3 """ 3 import os
4 import re
4 import sys 5 import sys
5 import os
6 from os.path import pardir, realpath 6 from os.path import pardir, realpath
7 7
8 __all__ = ['parse_config_h', 'get_config_h_filename', 'get_scheme_names', 8 __all__ = [
9 'get_path_names', 'get_paths', 'get_path', 'get_config_vars', 9 'get_config_h_filename',
10 'get_config_var', 'get_platform', 'get_python_version'] 10 'get_config_var',
11 if 'msys' not in sys.builtin_module_names: 11 'get_config_vars',
12 NT_SCHEME = { 12 'get_makefile_filename',
13 'stdlib': '{base}/Lib', 13 'get_path',
14 'platstdlib': '{base}/Lib', 14 'get_path_names',
15 'purelib': '{base}/Lib/site-packages', 15 'get_paths',
16 'platlib': '{base}/Lib/site-packages', 16 'get_platform',
17 'include': '{base}/Include', 17 'get_python_version',
18 'platinclude': '{base}/Include', 18 'get_scheme_names',
19 'scripts': '{base}/Scripts', 19 'parse_config_h',
20 'data' : '{base}', 20 ]
21 } 21
22 else: 22 _INSTALL_SCHEMES = {
23 NT_SCHEME = { 23 'posix_prefix': {
24 'stdlib': '{base}/lib/python{py_version_short}', 24 'stdlib': '{installed_base}/lib/python{py_version_short}',
25 'platstdlib': '{platbase}/lib/python{py_version_short}', 25 'platstdlib': '{platbase}/lib/python{py_version_short}',
26 'purelib': '{base}/lib/python{py_version_short}/site-packages', 26 'purelib': '{base}/lib/python{py_version_short}/site-packages',
27 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', 27 'platlib': '{platbase}/lib/python{py_version_short}/site-packages',
28 'include': '{base}/include/python{py_version_short}', 28 'include':
29 'platinclude': '{platbase}/include/python{py_version_short}', 29 '{installed_base}/include/python{py_version_short}{abiflags}',
30 'scripts': '{base}/bin', 30 'platinclude':
31 'data': '{base}', 31 '{installed_platbase}/include/python{py_version_short}{abiflags}',
32 }
33 _INSTALL_SCHEMES = {
34 'posix_prefix': {
35 'stdlib': '{base}/lib/python{py_version_short}',
36 'platstdlib': '{platbase}/lib/python{py_version_short}',
37 'purelib': '{base}/lib/python{py_version_short}/site-packages',
38 'platlib': '{platbase}/lib/python{py_version_short}/site-packages',
39 'include': '{base}/include/python{py_version_short}',
40 'platinclude': '{platbase}/include/python{py_version_short}',
41 'scripts': '{base}/bin', 32 'scripts': '{base}/bin',
42 'data': '{base}', 33 'data': '{base}',
43 }, 34 },
44 'posix_home': { 35 'posix_home': {
45 'stdlib': '{base}/lib/python', 36 'stdlib': '{installed_base}/lib/python',
46 'platstdlib': '{base}/lib/python', 37 'platstdlib': '{base}/lib/python',
47 'purelib': '{base}/lib/python', 38 'purelib': '{base}/lib/python',
48 'platlib': '{base}/lib/python', 39 'platlib': '{base}/lib/python',
49 'include': '{base}/include/python', 40 'include': '{installed_base}/include/python',
50 'platinclude': '{base}/include/python', 41 'platinclude': '{installed_base}/include/python',
51 'scripts': '{base}/bin', 42 'scripts': '{base}/bin',
52 'data' : '{base}', 43 'data': '{base}',
53 }, 44 },
54 'nt': NT_SCHEME, 45 'nt': {
55 'os2': { 46 'stdlib': '{installed_base}/Lib',
56 'stdlib': '{base}/Lib',
57 'platstdlib': '{base}/Lib', 47 'platstdlib': '{base}/Lib',
58 'purelib': '{base}/Lib/site-packages', 48 'purelib': '{base}/Lib/site-packages',
59 'platlib': '{base}/Lib/site-packages', 49 'platlib': '{base}/Lib/site-packages',
60 'include': '{base}/Include', 50 'include': '{installed_base}/Include',
61 'platinclude': '{base}/Include', 51 'platinclude': '{installed_base}/Include',
62 'scripts': '{base}/Scripts', 52 'scripts': '{base}/Scripts',
63 'data' : '{base}', 53 'data': '{base}',
54 },
55 'os2': {
56 'stdlib': '{installed_base}/Lib',
57 'platstdlib': '{base}/Lib',
58 'purelib': '{base}/Lib/site-packages',
59 'platlib': '{base}/Lib/site-packages',
60 'include': '{installed_base}/Include',
61 'platinclude': '{installed_base}/Include',
62 'scripts': '{base}/Scripts',
63 'data': '{base}',
64 }, 64 },
65 'os2_home': { 65 'os2_home': {
66 'stdlib': '{userbase}/lib/python{py_version_short}', 66 'stdlib': '{userbase}/lib/python{py_version_short}',
67 'platstdlib': '{userbase}/lib/python{py_version_short}', 67 'platstdlib': '{userbase}/lib/python{py_version_short}',
68 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', 68 'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
69 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', 69 'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
70 'include': '{userbase}/include/python{py_version_short}', 70 'include': '{userbase}/include/python{py_version_short}',
71 'scripts': '{userbase}/bin', 71 'scripts': '{userbase}/bin',
72 'data' : '{userbase}', 72 'data': '{userbase}',
73 }, 73 },
74 'nt_user': { 74 'nt_user': {
75 'stdlib': '{userbase}/Python{py_version_nodot}', 75 'stdlib': '{userbase}/Python{py_version_nodot}',
76 'platstdlib': '{userbase}/Python{py_version_nodot}', 76 'platstdlib': '{userbase}/Python{py_version_nodot}',
77 'purelib': '{userbase}/Python{py_version_nodot}/site-packages', 77 'purelib': '{userbase}/Python{py_version_nodot}/site-packages',
78 'platlib': '{userbase}/Python{py_version_nodot}/site-packages', 78 'platlib': '{userbase}/Python{py_version_nodot}/site-packages',
79 'include': '{userbase}/Python{py_version_nodot}/Include', 79 'include': '{userbase}/Python{py_version_nodot}/Include',
80 'scripts': '{userbase}/Scripts', 80 'scripts': '{userbase}/Scripts',
81 'data' : '{userbase}', 81 'data': '{userbase}',
82 }, 82 },
83 'posix_user': { 83 'posix_user': {
84 'stdlib': '{userbase}/lib/python{py_version_short}', 84 'stdlib': '{userbase}/lib/python{py_version_short}',
85 'platstdlib': '{userbase}/lib/python{py_version_short}', 85 'platstdlib': '{userbase}/lib/python{py_version_short}',
86 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', 86 'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
87 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', 87 'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
88 'include': '{userbase}/include/python{py_version_short}', 88 'include': '{userbase}/include/python{py_version_short}',
89 'scripts': '{userbase}/bin', 89 'scripts': '{userbase}/bin',
90 'data' : '{userbase}', 90 'data': '{userbase}',
91 }, 91 },
92 'osx_framework_user': { 92 'osx_framework_user': {
93 'stdlib': '{userbase}/lib/python', 93 'stdlib': '{userbase}/lib/python',
94 'platstdlib': '{userbase}/lib/python', 94 'platstdlib': '{userbase}/lib/python',
95 'purelib': '{userbase}/lib/python/site-packages', 95 'purelib': '{userbase}/lib/python/site-packages',
96 'platlib': '{userbase}/lib/python/site-packages', 96 'platlib': '{userbase}/lib/python/site-packages',
97 'include': '{userbase}/include', 97 'include': '{userbase}/include',
98 'scripts': '{userbase}/bin', 98 'scripts': '{userbase}/bin',
99 'data' : '{userbase}', 99 'data': '{userbase}',
100 }, 100 },
101 } 101 }
102 102
103 _SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', 103 _SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include',
104 'scripts', 'data') 104 'scripts', 'data')
105
106 # FIXME don't rely on sys.version here, its format is an implementation detail
107 # of CPython, use sys.version_info or sys.hexversion
105 _PY_VERSION = sys.version.split()[0] 108 _PY_VERSION = sys.version.split()[0]
106 _PY_VERSION_SHORT = sys.version[:3] 109 _PY_VERSION_SHORT = sys.version[:3]
107 _PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2] 110 _PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2]
108 _PREFIX = os.path.normpath(sys.prefix) 111 _PREFIX = os.path.normpath(sys.prefix)
112 _BASE_PREFIX = os.path.normpath(sys.base_prefix)
109 _EXEC_PREFIX = os.path.normpath(sys.exec_prefix) 113 _EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
114 _BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix)
110 _CONFIG_VARS = None 115 _CONFIG_VARS = None
111 _USER_BASE = None 116 _USER_BASE = None
117
118
119 def _safe_realpath(path):
120 try:
121 return realpath(path)
122 except OSError:
123 return path
124
112 if sys.executable: 125 if sys.executable:
113 _PROJECT_BASE = os.path.dirname(realpath(sys.executable)) 126 _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable))
114 else: 127 else:
115 # sys.executable can be empty if argv[0] has been changed and Python is 128 # sys.executable can be empty if argv[0] has been changed and Python is
116 # unable to retrieve the real program name 129 # unable to retrieve the real program name
117 _PROJECT_BASE = realpath(os.getcwd()) 130 _PROJECT_BASE = _safe_realpath(os.getcwd())
118 131
119 if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): 132 if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower():
120 _PROJECT_BASE = realpath(os.path.join(_PROJECT_BASE, pardir)) 133 _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir))
121 # PC/VS7.1 134 # PC/VS7.1
122 if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): 135 if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower():
123 _PROJECT_BASE = realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) 136 _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))
124 # PC/AMD64 137 # PC/AMD64
125 if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): 138 if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower():
126 _PROJECT_BASE = realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) 139 _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))
127 140
128 def is_python_build(): 141 # set for cross builds
142 if "_PYTHON_PROJECT_BASE" in os.environ:
143 _PROJECT_BASE = _safe_realpath(os.environ["_PYTHON_PROJECT_BASE"])
144
145 def _is_python_source_dir(d):
129 for fn in ("Setup.dist", "Setup.local"): 146 for fn in ("Setup.dist", "Setup.local"):
130 if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): 147 if os.path.isfile(os.path.join(d, "Modules", fn)):
131 return True 148 return True
132 return False 149 return False
133 150
134 _PYTHON_BUILD = is_python_build() 151 _sys_home = getattr(sys, '_home', None)
152 if _sys_home and os.name == 'nt' and \
153 _sys_home.lower().endswith(('pcbuild', 'pcbuild\\amd64')):
154 _sys_home = os.path.dirname(_sys_home)
155 if _sys_home.endswith('pcbuild'): # must be amd64
156 _sys_home = os.path.dirname(_sys_home)
157 def is_python_build(check_home=False):
158 if check_home and _sys_home:
159 return _is_python_source_dir(_sys_home)
160 return _is_python_source_dir(_PROJECT_BASE)
161
162 _PYTHON_BUILD = is_python_build(True)
135 163
136 if _PYTHON_BUILD: 164 if _PYTHON_BUILD:
137 for scheme in ('posix_prefix', 'posix_home'): 165 for scheme in ('posix_prefix', 'posix_home'):
138 _INSTALL_SCHEMES[scheme]['include'] = '{srcdir}/Include' 166 _INSTALL_SCHEMES[scheme]['include'] = '{srcdir}/Include'
139 _INSTALL_SCHEMES[scheme]['platinclude'] = '{projectbase}/.' 167 _INSTALL_SCHEMES[scheme]['platinclude'] = '{projectbase}/.'
168
169 # GCC(mingw) use posix build system
170 if os.name == "nt" and sys.version.upper().find('GCC') >= 0:
171 _INSTALL_SCHEMES['nt']['include'] = '{srcdir}/Include'
172 _INSTALL_SCHEMES['nt']['platinclude'] = '{projectbase}/.'
140 173
141 def _subst_vars(s, local_vars): 174 def _subst_vars(s, local_vars):
142 try: 175 try:
143 return s.format(**local_vars) 176 return s.format(**local_vars)
144 except KeyError: 177 except KeyError:
145 try: 178 try:
146 return s.format(**os.environ) 179 return s.format(**os.environ)
147 except KeyError as var: 180 except KeyError as var:
148 raise AttributeError('{%s}' % var) 181 raise AttributeError('{%s}' % var)
149 182
150 def _extend_dict(target_dict, other_dict): 183 def _extend_dict(target_dict, other_dict):
151 target_keys = target_dict.keys() 184 target_keys = target_dict.keys()
152 for key, value in other_dict.items(): 185 for key, value in other_dict.items():
153 if key in target_keys: 186 if key in target_keys:
154 continue 187 continue
155 target_dict[key] = value 188 target_dict[key] = value
156 189
190
157 def _expand_vars(scheme, vars): 191 def _expand_vars(scheme, vars):
158 res = {} 192 res = {}
159 if vars is None: 193 if vars is None:
160 vars = {} 194 vars = {}
161 _extend_dict(vars, get_config_vars()) 195 _extend_dict(vars, get_config_vars())
162 196
163 for key, value in _INSTALL_SCHEMES[scheme].items(): 197 for key, value in _INSTALL_SCHEMES[scheme].items():
164 if os.name in ('posix', 'nt'): 198 if os.name in ('posix', 'nt'):
165 value = os.path.expanduser(value) 199 value = os.path.expanduser(value)
166 res[key] = os.path.normpath(_subst_vars(value, vars)) 200 res[key] = os.path.normpath(_subst_vars(value, vars))
167 return res 201 return res
168 202
203
169 def _get_default_scheme(): 204 def _get_default_scheme():
170 if os.name == 'posix': 205 if os.name == 'posix':
171 # the default scheme for posix is posix_prefix 206 # the default scheme for posix is posix_prefix
172 return 'posix_prefix' 207 return 'posix_prefix'
173 return os.name 208 return os.name
174 209
210
175 def _getuserbase(): 211 def _getuserbase():
176 env_base = os.environ.get("PYTHONUSERBASE", None) 212 env_base = os.environ.get("PYTHONUSERBASE", None)
213
177 def joinuser(*args): 214 def joinuser(*args):
178 return os.path.expanduser(os.path.join(*args)) 215 return os.path.expanduser(os.path.join(*args))
179 216
180 # what about 'os2emx', 'riscos' ? 217 # what about 'os2emx', 'riscos' ?
181 if os.name == "nt": 218 if os.name == "nt":
182 base = os.environ.get("APPDATA") or "~" 219 base = os.environ.get("APPDATA") or "~"
183 return env_base if env_base else joinuser(base, "Python") 220 if env_base:
221 return env_base
222 else:
223 return joinuser(base, "Python")
184 224
185 if sys.platform == "darwin": 225 if sys.platform == "darwin":
186 framework = get_config_var("PYTHONFRAMEWORK") 226 framework = get_config_var("PYTHONFRAMEWORK")
187 if framework: 227 if framework:
188 return env_base if env_base else joinuser("~", "Library", framework, "%d.%d"%( 228 if env_base:
189 sys.version_info[:2])) 229 return env_base
190 230 else:
191 return env_base if env_base else joinuser("~", ".local") 231 return joinuser("~", "Library", framework, "%d.%d" %
232 sys.version_info[:2])
233
234 if env_base:
235 return env_base
236 else:
237 return joinuser("~", ".local")
192 238
193 239
194 def _parse_makefile(filename, vars=None): 240 def _parse_makefile(filename, vars=None):
195 """Parse a Makefile-style file. 241 """Parse a Makefile-style file.
196 242
197 A dictionary containing name/value pairs is returned. If an 243 A dictionary containing name/value pairs is returned. If an
198 optional dictionary is passed in as the second argument, it is 244 optional dictionary is passed in as the second argument, it is
199 used instead of a new dictionary. 245 used instead of a new dictionary.
200 """ 246 """
201 import re
202 # Regexes needed for parsing Makefile (and similar syntaxes, 247 # Regexes needed for parsing Makefile (and similar syntaxes,
203 # like old-style Setup files). 248 # like old-style Setup files).
204 _variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") 249 _variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
205 _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") 250 _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
206 _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") 251 _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
207 252
208 if vars is None: 253 if vars is None:
209 vars = {} 254 vars = {}
210 done = {} 255 done = {}
211 notdone = {} 256 notdone = {}
212 257
213 with open(filename) as f: 258 with open(filename, errors="surrogateescape") as f:
214 lines = f.readlines() 259 lines = f.readlines()
215 260
216 for line in lines: 261 for line in lines:
217 if line.startswith('#') or line.strip() == '': 262 if line.startswith('#') or line.strip() == '':
218 continue 263 continue
219 m = _variable_rx.match(line) 264 m = _variable_rx.match(line)
220 if m: 265 if m:
221 n, v = m.group(1, 2) 266 n, v = m.group(1, 2)
222 v = v.strip() 267 v = v.strip()
223 # `$$' is a literal `$' in make 268 # `$$' is a literal `$' in make
(...skipping 29 matching lines...) Expand all
253 if n in done: 298 if n in done:
254 item = str(done[n]) 299 item = str(done[n])
255 elif n in notdone: 300 elif n in notdone:
256 # get it on a subsequent round 301 # get it on a subsequent round
257 found = False 302 found = False
258 elif n in os.environ: 303 elif n in os.environ:
259 # do it like make: fall back to environment 304 # do it like make: fall back to environment
260 item = os.environ[n] 305 item = os.environ[n]
261 306
262 elif n in renamed_variables: 307 elif n in renamed_variables:
263 if name.startswith('PY_') and name[3:] in renamed_variables: 308 if (name.startswith('PY_') and
309 name[3:] in renamed_variables):
264 item = "" 310 item = ""
265 311
266 elif 'PY_' + n in notdone: 312 elif 'PY_' + n in notdone:
267 found = False 313 found = False
268 314
269 else: 315 else:
270 item = str(done['PY_' + n]) 316 item = str(done['PY_' + n])
271 317
272 else: 318 else:
273 done[n] = item = "" 319 done[n] = item = ""
274 320
275 if found: 321 if found:
276 after = value[m.end():] 322 after = value[m.end():]
277 value = value[:m.start()] + item + after 323 value = value[:m.start()] + item + after
278 if "$" in after: 324 if "$" in after:
279 notdone[name] = value 325 notdone[name] = value
280 else: 326 else:
281 try: 327 try:
282 value = int(value) 328 value = int(value)
283 except ValueError: 329 except ValueError:
284 done[name] = value.strip() 330 done[name] = value.strip()
285 else: 331 else:
286 done[name] = value 332 done[name] = value
287 variables.remove(name) 333 variables.remove(name)
288 334
289 if name.startswith('PY_') \ 335 if name.startswith('PY_') \
290 and name[3:] in renamed_variables: 336 and name[3:] in renamed_variables:
291 337
292 name = name[3:] 338 name = name[3:]
293 if name not in done: 339 if name not in done:
294 done[name] = value 340 done[name] = value
295 341
296
297 else: 342 else:
298 # bogus variable reference; just drop it since we can't deal 343 # bogus variable reference (e.g. "prefix=$/opt/python");
344 # just drop it since we can't deal
345 done[name] = value
299 variables.remove(name) 346 variables.remove(name)
347
348 # strip spurious spaces
349 for k, v in done.items():
350 if isinstance(v, str):
351 done[k] = v.strip()
300 352
301 # save the results in the global dictionary 353 # save the results in the global dictionary
302 vars.update(done) 354 vars.update(done)
303 return vars 355 return vars
304 356
305 357
306 def _get_makefile_filename(): 358 def get_makefile_filename():
359 """Return the path of the Makefile."""
307 if _PYTHON_BUILD: 360 if _PYTHON_BUILD:
308 return os.path.join(_PROJECT_BASE, "Makefile") 361 return os.path.join(_sys_home or _PROJECT_BASE, "Makefile")
309 return os.path.join(get_path('stdlib'), "config", "Makefile") 362 if hasattr(sys, 'abiflags'):
310 363 config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags)
311 364 else:
312 def _init_posix(vars): 365 config_dir_name = 'config'
313 """Initialize the module as appropriate for POSIX systems.""" 366 return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile')
367
368 def _generate_posix_vars():
369 """Generate the Python module containing build-time variables."""
370 import pprint
371 vars = {}
314 # load the installed Makefile: 372 # load the installed Makefile:
315 makefile = _get_makefile_filename() 373 makefile = get_makefile_filename()
316 try: 374 try:
317 _parse_makefile(makefile, vars) 375 _parse_makefile(makefile, vars)
318 except IOError as e: 376 except IOError as e:
319 msg = "invalid Python installation: unable to open %s" % makefile 377 msg = "invalid Python installation: unable to open %s" % makefile
320 if hasattr(e, "strerror"): 378 if hasattr(e, "strerror"):
321 msg = msg + " (%s)" % e.strerror 379 msg = msg + " (%s)" % e.strerror
322 raise IOError(msg) 380 raise IOError(msg)
323 # load the installed pyconfig.h: 381 # load the installed pyconfig.h:
324 config_h = get_config_h_filename() 382 config_h = get_config_h_filename()
325 try: 383 try:
326 parse_config_h(open(config_h), vars) 384 with open(config_h) as f:
385 parse_config_h(f, vars)
327 except IOError as e: 386 except IOError as e:
328 msg = "invalid Python installation: unable to open %s" % config_h 387 msg = "invalid Python installation: unable to open %s" % config_h
329 if hasattr(e, "strerror"): 388 if hasattr(e, "strerror"):
330 msg = msg + " (%s)" % e.strerror 389 msg = msg + " (%s)" % e.strerror
331 raise IOError(msg) 390 raise IOError(msg)
332 # On MacOSX we need to check the setting of the environment variable
333 # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so
334 # it needs to be compatible.
335 # If it isn't set we set it to the configure-time value
336 if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in vars:
337 cfg_target = vars['MACOSX_DEPLOYMENT_TARGET']
338 cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '')
339 if cur_target == '':
340 cur_target = cfg_target
341 os.putenv('MACOSX_DEPLOYMENT_TARGET', cfg_target)
342 elif (list(map(int, cfg_target.split('.'))) >
343 list(map(int, cur_target.split('.')))):
344 msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" '
345 'during configure' % (cur_target, cfg_target))
346 raise IOError(msg)
347 # On AIX, there are wrong paths to the linker scripts in the Makefile 391 # On AIX, there are wrong paths to the linker scripts in the Makefile
348 # -- these paths are relative to the Python source, but when installed 392 # -- these paths are relative to the Python source, but when installed
349 # the scripts are in another directory. 393 # the scripts are in another directory.
350 if _PYTHON_BUILD: 394 if _PYTHON_BUILD:
351 vars['LDSHARED'] = vars['BLDSHARED'] 395 vars['LDSHARED'] = vars['BLDSHARED']
396
397 destfile = os.path.join(os.path.dirname(__file__), '_sysconfigdata.py')
398
399 with open(destfile, 'w', encoding='utf8') as f:
400 f.write('# system configuration generated and used by'
401 ' the sysconfig module\n')
402 f.write('build_time_vars = ')
403 pprint.pprint(vars, stream=f)
404
405 def _init_posix(vars):
406 """Initialize the module as appropriate for POSIX systems."""
407 # _sysconfigdata is generated at build time, see _generate_posix_vars()
408 from _sysconfigdata import build_time_vars
409 vars.update(build_time_vars)
352 410
353 def _init_non_posix(vars): 411 def _init_non_posix(vars):
354 """Initialize the module as appropriate for NT""" 412 """Initialize the module as appropriate for NT"""
355 # set basic install directories 413 # set basic install directories
356 vars['LIBDEST'] = get_path('stdlib') 414 vars['LIBDEST'] = get_path('stdlib')
357 vars['BINLIBDEST'] = get_path('platstdlib') 415 vars['BINLIBDEST'] = get_path('platstdlib')
358 vars['INCLUDEPY'] = get_path('include') 416 vars['INCLUDEPY'] = get_path('include')
359 vars['SO'] = '.pyd' 417 vars['SO'] = '.pyd'
360 vars['EXE'] = '.exe' 418 vars['EXE'] = '.exe'
361 vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT 419 vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT
362 vars['BINDIR'] = os.path.dirname(realpath(sys.executable)) 420 vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable))
363 421
364 # 422 #
365 # public APIs 423 # public APIs
366 # 424 #
367 425
368 426
369 def parse_config_h(fp, vars=None): 427 def parse_config_h(fp, vars=None):
370 """Parse a config.h-style file. 428 """Parse a config.h-style file.
371 429
372 A dictionary containing name/value pairs is returned. If an 430 A dictionary containing name/value pairs is returned. If an
373 optional dictionary is passed in as the second argument, it is 431 optional dictionary is passed in as the second argument, it is
374 used instead of a new dictionary. 432 used instead of a new dictionary.
375 """ 433 """
376 import re
377 if vars is None: 434 if vars is None:
378 vars = {} 435 vars = {}
379 define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") 436 define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
380 undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") 437 undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
381 438
382 while True: 439 while True:
383 line = fp.readline() 440 line = fp.readline()
384 if not line: 441 if not line:
385 break 442 break
386 m = define_rx.match(line) 443 m = define_rx.match(line)
387 if m: 444 if m:
388 n, v = m.group(1, 2) 445 n, v = m.group(1, 2)
389 try: v = int(v) 446 try:
390 except ValueError: pass 447 v = int(v)
448 except ValueError:
449 pass
391 vars[n] = v 450 vars[n] = v
392 else: 451 else:
393 m = undef_rx.match(line) 452 m = undef_rx.match(line)
394 if m: 453 if m:
395 vars[m.group(1)] = 0 454 vars[m.group(1)] = 0
396 return vars 455 return vars
397 456
457
398 def get_config_h_filename(): 458 def get_config_h_filename():
399 """Returns the path of pyconfig.h.""" 459 """Return the path of pyconfig.h."""
400 if _PYTHON_BUILD: 460 if _PYTHON_BUILD:
401 if os.name == "nt" and 'msys' not in sys.builtin_module_names: 461 # GCC(mingw): os.name is "nt" but build system is posix
402 inc_dir = os.path.join(_PROJECT_BASE, "PC") 462 if os.name == "nt" and sys.version.upper().find('GCC') < 0:
463 inc_dir = os.path.join(_sys_home or _PROJECT_BASE, "PC")
403 else: 464 else:
404 inc_dir = _PROJECT_BASE 465 inc_dir = _sys_home or _PROJECT_BASE
405 else: 466 else:
406 inc_dir = get_path('platinclude') 467 inc_dir = get_path('platinclude')
407 return os.path.join(inc_dir, 'pyconfig.h') 468 return os.path.join(inc_dir, 'pyconfig.h')
408 469
470
409 def get_scheme_names(): 471 def get_scheme_names():
410 """Returns a tuple containing the schemes names.""" 472 """Return a tuple containing the schemes names."""
411 schemes = list(_INSTALL_SCHEMES.keys()) 473 return tuple(sorted(_INSTALL_SCHEMES))
412 schemes.sort() 474
413 return tuple(schemes)
414 475
415 def get_path_names(): 476 def get_path_names():
416 """Returns a tuple containing the paths names.""" 477 """Return a tuple containing the paths names."""
417 return _SCHEME_KEYS 478 return _SCHEME_KEYS
418 479
480
419 def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): 481 def get_paths(scheme=_get_default_scheme(), vars=None, expand=True):
420 """Returns a mapping containing an install scheme. 482 """Return a mapping containing an install scheme.
421 483
422 ``scheme`` is the install scheme name. If not provided, it will 484 ``scheme`` is the install scheme name. If not provided, it will
423 return the default scheme for the current platform. 485 return the default scheme for the current platform.
424 """ 486 """
425 if expand: 487 if expand:
426 return _expand_vars(scheme, vars) 488 return _expand_vars(scheme, vars)
427 else: 489 else:
428 return _INSTALL_SCHEMES[scheme] 490 return _INSTALL_SCHEMES[scheme]
429 491
492
430 def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): 493 def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True):
431 """Returns a path corresponding to the scheme. 494 """Return a path corresponding to the scheme.
432 495
433 ``scheme`` is the install scheme name. 496 ``scheme`` is the install scheme name.
434 """ 497 """
435 return get_paths(scheme, vars, expand)[name] 498 return get_paths(scheme, vars, expand)[name]
436 499
500
437 def get_config_vars(*args): 501 def get_config_vars(*args):
438 """With no arguments, return a dictionary of all configuration 502 """With no arguments, return a dictionary of all configuration
439 variables relevant for the current platform. 503 variables relevant for the current platform.
440 504
441 On Unix, this means every variable defined in Python's installed Makefile; 505 On Unix, this means every variable defined in Python's installed Makefile;
442 On Windows and Mac OS it's a much smaller set. 506 On Windows it's a much smaller set.
443 507
444 With arguments, return a list of values that result from looking up 508 With arguments, return a list of values that result from looking up
445 each argument in the configuration variable dictionary. 509 each argument in the configuration variable dictionary.
446 """ 510 """
447 import re
448 global _CONFIG_VARS 511 global _CONFIG_VARS
449 if _CONFIG_VARS is None: 512 if _CONFIG_VARS is None:
450 _CONFIG_VARS = {} 513 _CONFIG_VARS = {}
451 # Normalized versions of prefix and exec_prefix are handy to have; 514 # Normalized versions of prefix and exec_prefix are handy to have;
452 # in fact, these are the standard versions used most places in the 515 # in fact, these are the standard versions used most places in the
453 # Distutils. 516 # Distutils.
454 _CONFIG_VARS['prefix'] = _PREFIX 517 _CONFIG_VARS['prefix'] = _PREFIX
455 _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX 518 _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX
456 _CONFIG_VARS['py_version'] = _PY_VERSION 519 _CONFIG_VARS['py_version'] = _PY_VERSION
457 _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT 520 _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT
458 _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2] 521 _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2]
522 _CONFIG_VARS['installed_base'] = _BASE_PREFIX
459 _CONFIG_VARS['base'] = _PREFIX 523 _CONFIG_VARS['base'] = _PREFIX
524 _CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX
460 _CONFIG_VARS['platbase'] = _EXEC_PREFIX 525 _CONFIG_VARS['platbase'] = _EXEC_PREFIX
461 _CONFIG_VARS['projectbase'] = _PROJECT_BASE 526 _CONFIG_VARS['projectbase'] = _PROJECT_BASE
462 527 try:
463 if os.name in ('nt', 'os2'): 528 _CONFIG_VARS['abiflags'] = sys.abiflags
529 except AttributeError:
530 # sys.abiflags may not be defined on all platforms.
531 _CONFIG_VARS['abiflags'] = ''
532
533 # GCC(mingw) use posix build system
534 posix_build = False
535 if os.name == 'posix':
536 posix_build = True
537 else:
538 if os.name == 'nt' and sys.version.upper().find('GCC') >= 0:
539 posix_build = True
540 if os.name in ('nt', 'os2') and not posix_build:
464 _init_non_posix(_CONFIG_VARS) 541 _init_non_posix(_CONFIG_VARS)
465 if os.name == 'posix' or 'msys' in sys.builtin_module_names: 542 if posix_build:
466 _init_posix(_CONFIG_VARS) 543 _init_posix(_CONFIG_VARS)
467 # Setting 'userbase' is done below the call to the 544 # Setting 'userbase' is done below the call to the
468 # init function to enable using 'get_config_var' in 545 # init function to enable using 'get_config_var' in
469 # the init-function. 546 # the init-function.
470 _CONFIG_VARS['userbase'] = _getuserbase() 547 _CONFIG_VARS['userbase'] = _getuserbase()
471 548
472 if 'srcdir' not in _CONFIG_VARS: 549 # Always convert srcdir to an absolute path
473 _CONFIG_VARS['srcdir'] = _PROJECT_BASE 550 srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE)
474 else: 551 if posix_build:
475 _CONFIG_VARS['srcdir'] = realpath(_CONFIG_VARS['srcdir']) 552 if _PYTHON_BUILD:
476 553 # If srcdir is a relative path (typically '.' or '..')
477 554 # then it should be interpreted relative to the directory
478 # Convert srcdir into an absolute path if it appears necessary. 555 # containing Makefile.
479 # Normally it is relative to the build directory. However, during 556 base = os.path.dirname(get_makefile_filename())
480 # testing, for example, we might be running a non-installed python 557 srcdir = os.path.join(base, srcdir)
481 # from a different directory. 558 else:
482 if _PYTHON_BUILD and os.name == "posix": 559 # srcdir is not meaningful since the installation is
483 base = _PROJECT_BASE 560 # spread about the filesystem. We choose the
484 if (not os.path.isabs(_CONFIG_VARS['srcdir']) and 561 # directory containing the Makefile since we know it
485 base != os.getcwd()): 562 # exists.
486 # srcdir is relative and we are not in the same directory 563 srcdir = os.path.dirname(get_makefile_filename())
487 # as the executable. Assume executable is in the build 564 _CONFIG_VARS['srcdir'] = _safe_realpath(srcdir)
488 # directory and make srcdir absolute. 565
489 srcdir = os.path.join(base, _CONFIG_VARS['srcdir']) 566 # OS X platforms require special customization to handle
490 _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir) 567 # multi-architecture, multi-os-version installers
491
492 if sys.platform == 'darwin': 568 if sys.platform == 'darwin':
493 kernel_version = os.uname()[2] # Kernel version (8.4.3) 569 import _osx_support
494 major_version = int(kernel_version.split('.')[0]) 570 _osx_support.customize_config_vars(_CONFIG_VARS)
495
496 if major_version < 8:
497 # On Mac OS X before 10.4, check if -arch and -isysroot
498 # are in CFLAGS or LDFLAGS and remove them if they are.
499 # This is needed when building extensions on a 10.3 system
500 # using a universal build of python.
501 for key in ('LDFLAGS', 'BASECFLAGS',
502 # a number of derived variables. These need to be
503 # patched up as well.
504 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
505 flags = _CONFIG_VARS[key]
506 flags = re.sub('-arch\s+\w+\s', ' ', flags)
507 flags = re.sub('-isysroot [^ \t]*', ' ', flags)
508 _CONFIG_VARS[key] = flags
509 else:
510 # Allow the user to override the architecture flags using
511 # an environment variable.
512 # NOTE: This name was introduced by Apple in OSX 10.5 and
513 # is used by several scripting languages distributed with
514 # that OS release.
515 if 'ARCHFLAGS' in os.environ:
516 arch = os.environ['ARCHFLAGS']
517 for key in ('LDFLAGS', 'BASECFLAGS',
518 # a number of derived variables. These need to be
519 # patched up as well.
520 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
521
522 flags = _CONFIG_VARS[key]
523 flags = re.sub('-arch\s+\w+\s', ' ', flags)
524 flags = flags + ' ' + arch
525 _CONFIG_VARS[key] = flags
526
527 # If we're on OSX 10.5 or later and the user tries to
528 # compiles an extension using an SDK that is not present
529 # on the current machine it is better to not use an SDK
530 # than to fail.
531 #
532 # The major usecase for this is users using a Python.org
533 # binary installer on OSX 10.6: that installer uses
534 # the 10.4u SDK, but that SDK is not installed by default
535 # when you install Xcode.
536 #
537 CFLAGS = _CONFIG_VARS.get('CFLAGS', '')
538 m = re.search('-isysroot\s+(\S+)', CFLAGS)
539 if m is not None:
540 sdk = m.group(1)
541 if not os.path.exists(sdk):
542 for key in ('LDFLAGS', 'BASECFLAGS',
543 # a number of derived variables. These need to be
544 # patched up as well.
545 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
546
547 flags = _CONFIG_VARS[key]
548 flags = re.sub('-isysroot\s+\S+(\s|$)', ' ', flags)
549 _CONFIG_VARS[key] = flags
550 571
551 if args: 572 if args:
552 vals = [] 573 vals = []
553 for name in args: 574 for name in args:
554 vals.append(_CONFIG_VARS.get(name)) 575 vals.append(_CONFIG_VARS.get(name))
555 return vals 576 return vals
556 else: 577 else:
557 return _CONFIG_VARS 578 return _CONFIG_VARS
558 579
580
559 def get_config_var(name): 581 def get_config_var(name):
560 """Return the value of a single variable using the dictionary returned by 582 """Return the value of a single variable using the dictionary returned by
561 'get_config_vars()'. 583 'get_config_vars()'.
562 584
563 Equivalent to get_config_vars().get(name) 585 Equivalent to get_config_vars().get(name)
564 """ 586 """
565 return get_config_vars().get(name) 587 return get_config_vars().get(name)
588
566 589
567 def get_platform(): 590 def get_platform():
568 """Return a string that identifies the current platform. 591 """Return a string that identifies the current platform.
569 592
570 This is used mainly to distinguish platform-specific build directories and 593 This is used mainly to distinguish platform-specific build directories and
571 platform-specific built distributions. Typically includes the OS name 594 platform-specific built distributions. Typically includes the OS name
572 and version and the architecture (as supplied by 'os.uname()'), 595 and version and the architecture (as supplied by 'os.uname()'),
573 although the exact information included depends on the OS; eg. for IRIX 596 although the exact information included depends on the OS; eg. for IRIX
574 the architecture isn't particularly important (IRIX only runs on SGI 597 the architecture isn't particularly important (IRIX only runs on SGI
575 hardware), but for Linux the kernel version isn't particularly 598 hardware), but for Linux the kernel version isn't particularly
576 important. 599 important.
577 600
578 Examples of returned values: 601 Examples of returned values:
579 linux-i586 602 linux-i586
580 linux-alpha (?) 603 linux-alpha (?)
581 solaris-2.6-sun4u 604 solaris-2.6-sun4u
582 irix-5.3 605 irix-5.3
583 irix64-6.2 606 irix64-6.2
584 607
585 Windows will return one of: 608 Windows will return one of:
586 win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) 609 win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
587 win-ia64 (64bit Windows on Itanium) 610 win-ia64 (64bit Windows on Itanium)
588 win32 (all others - specifically, sys.platform is returned) 611 win32 (all others - specifically, sys.platform is returned)
589 612
590 For other non-POSIX platforms, currently just returns 'sys.platform'. 613 For other non-POSIX platforms, currently just returns 'sys.platform'.
591 """ 614 """
592 import re
593 if os.name == 'nt': 615 if os.name == 'nt':
594 # sniff sys.version for architecture. 616 # sniff sys.version for architecture.
595 prefix = " bit (" 617 prefix = " bit ("
596 i = sys.version.find(prefix) 618 i = sys.version.find(prefix)
597 if i == -1: 619 if i == -1:
598 return sys.platform 620 return sys.platform
599 j = sys.version.find(")", i) 621 j = sys.version.find(")", i)
600 look = sys.version[i+len(prefix):j].lower() 622 look = sys.version[i+len(prefix):j].lower()
601 if look == 'amd64': 623 if look == 'amd64':
602 return 'win-amd64' 624 return 'win-amd64'
603 if look == 'itanium': 625 if look == 'itanium':
604 return 'win-ia64' 626 return 'win-ia64'
605 return sys.platform 627 return sys.platform
606 628
607 if os.name != "posix" or not hasattr(os, 'uname'): 629 if os.name != "posix" or not hasattr(os, 'uname'):
608 # XXX what about the architecture? NT is Intel or Alpha, 630 # XXX what about the architecture? NT is Intel or Alpha
609 # Mac OS is M68k or PPC, etc.
610 return sys.platform 631 return sys.platform
632
633 # Set for cross builds explicitly
634 if "_PYTHON_HOST_PLATFORM" in os.environ:
635 return os.environ["_PYTHON_HOST_PLATFORM"]
611 636
612 # Try to distinguish various flavours of Unix 637 # Try to distinguish various flavours of Unix
613 osname, host, release, version, machine = os.uname() 638 osname, host, release, version, machine = os.uname()
614 639
615 # Convert the OS name to lowercase, remove '/' characters 640 # Convert the OS name to lowercase, remove '/' characters
616 # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") 641 # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh")
617 osname = osname.lower().replace('/', '') 642 osname = osname.lower().replace('/', '')
618 machine = machine.replace(' ', '_') 643 machine = machine.replace(' ', '_')
619 machine = machine.replace('/', '-') 644 machine = machine.replace('/', '-')
620 645
621 if osname[:5] == "linux": 646 if osname[:5] == "linux":
622 # At least on Linux/Intel, 'machine' is the processor -- 647 # At least on Linux/Intel, 'machine' is the processor --
623 # i386, etc. 648 # i386, etc.
624 # XXX what about Alpha, SPARC, etc? 649 # XXX what about Alpha, SPARC, etc?
625 return "%s-%s" % (osname, machine) 650 return "%s-%s" % (osname, machine)
626 elif osname[:5] == "sunos": 651 elif osname[:5] == "sunos":
627 if release[0] >= "5": # SunOS 5 == Solaris 2 652 if release[0] >= "5": # SunOS 5 == Solaris 2
628 osname = "solaris" 653 osname = "solaris"
629 release = "%d.%s" % (int(release[0]) - 3, release[2:]) 654 release = "%d.%s" % (int(release[0]) - 3, release[2:])
655 # We can't use "platform.architecture()[0]" because a
656 # bootstrap problem. We use a dict to get an error
657 # if some suspicious happens.
658 bitness = {2147483647:"32bit", 9223372036854775807:"64bit"}
659 machine += ".%s" % bitness[sys.maxsize]
630 # fall through to standard osname-release-machine representation 660 # fall through to standard osname-release-machine representation
631 elif osname[:4] == "irix": # could be "irix64"! 661 elif osname[:4] == "irix": # could be "irix64"!
632 return "%s-%s" % (osname, release) 662 return "%s-%s" % (osname, release)
633 elif osname[:3] == "aix": 663 elif osname[:3] == "aix":
634 return "%s-%s.%s" % (osname, version, release) 664 return "%s-%s.%s" % (osname, version, release)
635 elif osname[:6] == "cygwin": 665 elif osname[:6] == "cygwin":
636 osname = "cygwin" 666 osname = "cygwin"
637 rel_re = re.compile (r'[\d.]+') 667 rel_re = re.compile(r'[\d.]+')
638 m = rel_re.match(release) 668 m = rel_re.match(release)
639 if m: 669 if m:
640 release = m.group() 670 release = m.group()
641 elif osname[:6] == "darwin": 671 elif osname[:6] == "darwin":
642 # 672 import _osx_support
643 # For our purposes, we'll assume that the system version from 673 osname, release, machine = _osx_support.get_platform_osx(
644 # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set 674 get_config_vars(),
645 # to. This makes the compatibility story a bit more sane because the 675 osname, release, machine)
646 # machine is going to compile and link as if it were
647 # MACOSX_DEPLOYMENT_TARGET.
648 cfgvars = get_config_vars()
649 macver = os.environ.get('MACOSX_DEPLOYMENT_TARGET')
650 if not macver:
651 macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET')
652
653 if 1:
654 # Always calculate the release of the running machine,
655 # needed to determine if we can build fat binaries or not.
656
657 macrelease = macver
658 # Get the system version. Reading this plist is a documented
659 # way to get the system version (see the documentation for
660 # the Gestalt Manager)
661 try:
662 f = open('/System/Library/CoreServices/SystemVersion.plist')
663 except IOError:
664 # We're on a plain darwin box, fall back to the default
665 # behaviour.
666 pass
667 else:
668 m = re.search(
669 r'<key>ProductUserVisibleVersion</key>\s*' +
670 r'<string>(.*?)</string>', f.read())
671 f.close()
672 if m is not None:
673 macrelease = '.'.join(m.group(1).split('.')[:2])
674 # else: fall back to the default behaviour
675
676 if not macver:
677 macver = macrelease
678
679 if macver:
680 release = macver
681 osname = "macosx"
682
683 if (macrelease + '.') >= '10.4.' and \
684 '-arch' in get_config_vars().get('CFLAGS', '').strip():
685 # The universal build will build fat binaries, but not on
686 # systems before 10.4
687 #
688 # Try to detect 4-way universal builds, those have machine-type
689 # 'universal' instead of 'fat'.
690
691 machine = 'fat'
692 cflags = get_config_vars().get('CFLAGS')
693
694 archs = re.findall('-arch\s+(\S+)', cflags)
695 archs = tuple(sorted(set(archs)))
696
697 if len(archs) == 1:
698 machine = archs[0]
699 elif archs == ('i386', 'ppc'):
700 machine = 'fat'
701 elif archs == ('i386', 'x86_64'):
702 machine = 'intel'
703 elif archs == ('i386', 'ppc', 'x86_64'):
704 machine = 'fat3'
705 elif archs == ('ppc64', 'x86_64'):
706 machine = 'fat64'
707 elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'):
708 machine = 'universal'
709 else:
710 raise ValueError(
711 "Don't know machine value for archs=%r"%(archs,))
712
713 elif machine == 'i386':
714 # On OSX the machine type returned by uname is always the
715 # 32-bit variant, even if the executable architecture is
716 # the 64-bit variant
717 if sys.maxsize >= 2**32:
718 machine = 'x86_64'
719
720 elif machine in ('PowerPC', 'Power_Macintosh'):
721 # Pick a sane name for the PPC architecture.
722 # See 'i386' case
723 if sys.maxsize >= 2**32:
724 machine = 'ppc64'
725 else:
726 machine = 'ppc'
727 676
728 return "%s-%s-%s" % (osname, release, machine) 677 return "%s-%s-%s" % (osname, release, machine)
729 678
730 679
731 def get_python_version(): 680 def get_python_version():
732 return _PY_VERSION_SHORT 681 return _PY_VERSION_SHORT
682
733 683
734 def _print_dict(title, data): 684 def _print_dict(title, data):
735 for index, (key, value) in enumerate(sorted(data.items())): 685 for index, (key, value) in enumerate(sorted(data.items())):
736 if index == 0: 686 if index == 0:
737 print('{0}: '.format(title)) 687 print('%s: ' % (title))
738 print('\t{0} = "{1}"'.format(key, value)) 688 print('\t%s = "%s"' % (key, value))
689
739 690
740 def _main(): 691 def _main():
741 """Displays all information sysconfig detains.""" 692 """Display all information sysconfig detains."""
742 print('Platform: "{0}"'.format(get_platform())) 693 if '--generate-posix-vars' in sys.argv:
743 print('Python version: "{0}"'.format(get_python_version())) 694 _generate_posix_vars()
744 print('Current installation scheme: "{0}"'.format(_get_default_scheme())) 695 return
745 print('') 696 print('Platform: "%s"' % get_platform())
697 print('Python version: "%s"' % get_python_version())
698 print('Current installation scheme: "%s"' % _get_default_scheme())
699 print()
746 _print_dict('Paths', get_paths()) 700 _print_dict('Paths', get_paths())
747 print('') 701 print()
748 _print_dict('Variables', get_config_vars()) 702 _print_dict('Variables', get_config_vars())
703
749 704
750 if __name__ == '__main__': 705 if __name__ == '__main__':
751 _main() 706 _main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+