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