PageRenderTime 45ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/lib-python/2.7/sysconfig.py

https://bitbucket.org/pwaller/pypy
Python | 583 lines | 550 code | 6 blank | 27 comment | 16 complexity | 951d48e8aba57637c45fcfb4df4959ed MD5 | raw file
  1. """Provide access to Python's configuration information.
  2. """
  3. import sys
  4. import os
  5. from os.path import pardir, realpath
  6. _INSTALL_SCHEMES = {
  7. 'posix_prefix': {
  8. 'stdlib': '{base}/lib/python{py_version_short}',
  9. 'platstdlib': '{platbase}/lib/python{py_version_short}',
  10. 'purelib': '{base}/lib/python{py_version_short}/site-packages',
  11. 'platlib': '{platbase}/lib/python{py_version_short}/site-packages',
  12. 'include': '{base}/include/python{py_version_short}',
  13. 'platinclude': '{platbase}/include/python{py_version_short}',
  14. 'scripts': '{base}/bin',
  15. 'data': '{base}',
  16. },
  17. 'posix_home': {
  18. 'stdlib': '{base}/lib/python',
  19. 'platstdlib': '{base}/lib/python',
  20. 'purelib': '{base}/lib/python',
  21. 'platlib': '{base}/lib/python',
  22. 'include': '{base}/include/python',
  23. 'platinclude': '{base}/include/python',
  24. 'scripts': '{base}/bin',
  25. 'data' : '{base}',
  26. },
  27. 'pypy': {
  28. 'stdlib': '{base}/lib-python',
  29. 'platstdlib': '{base}/lib-python',
  30. 'purelib': '{base}/lib-python',
  31. 'platlib': '{base}/lib-python',
  32. 'include': '{base}/include',
  33. 'platinclude': '{base}/include',
  34. 'scripts': '{base}/bin',
  35. 'data' : '{base}',
  36. },
  37. 'nt': {
  38. 'stdlib': '{base}/Lib',
  39. 'platstdlib': '{base}/Lib',
  40. 'purelib': '{base}/Lib/site-packages',
  41. 'platlib': '{base}/Lib/site-packages',
  42. 'include': '{base}/Include',
  43. 'platinclude': '{base}/Include',
  44. 'scripts': '{base}/Scripts',
  45. 'data' : '{base}',
  46. },
  47. 'os2': {
  48. 'stdlib': '{base}/Lib',
  49. 'platstdlib': '{base}/Lib',
  50. 'purelib': '{base}/Lib/site-packages',
  51. 'platlib': '{base}/Lib/site-packages',
  52. 'include': '{base}/Include',
  53. 'platinclude': '{base}/Include',
  54. 'scripts': '{base}/Scripts',
  55. 'data' : '{base}',
  56. },
  57. 'os2_home': {
  58. 'stdlib': '{userbase}/lib/python{py_version_short}',
  59. 'platstdlib': '{userbase}/lib/python{py_version_short}',
  60. 'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
  61. 'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
  62. 'include': '{userbase}/include/python{py_version_short}',
  63. 'scripts': '{userbase}/bin',
  64. 'data' : '{userbase}',
  65. },
  66. 'nt_user': {
  67. 'stdlib': '{userbase}/Python{py_version_nodot}',
  68. 'platstdlib': '{userbase}/Python{py_version_nodot}',
  69. 'purelib': '{userbase}/Python{py_version_nodot}/site-packages',
  70. 'platlib': '{userbase}/Python{py_version_nodot}/site-packages',
  71. 'include': '{userbase}/Python{py_version_nodot}/Include',
  72. 'scripts': '{userbase}/Scripts',
  73. 'data' : '{userbase}',
  74. },
  75. 'posix_user': {
  76. 'stdlib': '{userbase}/lib/python{py_version_short}',
  77. 'platstdlib': '{userbase}/lib/python{py_version_short}',
  78. 'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
  79. 'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
  80. 'include': '{userbase}/include/python{py_version_short}',
  81. 'scripts': '{userbase}/bin',
  82. 'data' : '{userbase}',
  83. },
  84. 'osx_framework_user': {
  85. 'stdlib': '{userbase}/lib/python',
  86. 'platstdlib': '{userbase}/lib/python',
  87. 'purelib': '{userbase}/lib/python/site-packages',
  88. 'platlib': '{userbase}/lib/python/site-packages',
  89. 'include': '{userbase}/include',
  90. 'scripts': '{userbase}/bin',
  91. 'data' : '{userbase}',
  92. },
  93. }
  94. _SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include',
  95. 'scripts', 'data')
  96. _PY_VERSION = sys.version.split()[0]
  97. _PY_VERSION_SHORT = sys.version[:3]
  98. _PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2]
  99. _PREFIX = os.path.normpath(sys.prefix)
  100. _EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
  101. _CONFIG_VARS = None
  102. _USER_BASE = None
  103. def _safe_realpath(path):
  104. try:
  105. return realpath(path)
  106. except OSError:
  107. return path
  108. if sys.executable:
  109. _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable))
  110. else:
  111. # sys.executable can be empty if argv[0] has been changed and Python is
  112. # unable to retrieve the real program name
  113. _PROJECT_BASE = _safe_realpath(os.getcwd())
  114. if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower():
  115. _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir))
  116. # PC/VS7.1
  117. if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower():
  118. _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))
  119. # PC/AMD64
  120. if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower():
  121. _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir))
  122. def is_python_build():
  123. for fn in ("Setup.dist", "Setup.local"):
  124. if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)):
  125. return True
  126. return False
  127. _PYTHON_BUILD = is_python_build()
  128. if _PYTHON_BUILD:
  129. for scheme in ('posix_prefix', 'posix_home'):
  130. _INSTALL_SCHEMES[scheme]['include'] = '{projectbase}/Include'
  131. _INSTALL_SCHEMES[scheme]['platinclude'] = '{srcdir}'
  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. def _extend_dict(target_dict, other_dict):
  141. target_keys = target_dict.keys()
  142. for key, value in other_dict.items():
  143. if key in target_keys:
  144. continue
  145. target_dict[key] = value
  146. def _expand_vars(scheme, vars):
  147. res = {}
  148. if vars is None:
  149. vars = {}
  150. _extend_dict(vars, get_config_vars())
  151. for key, value in _INSTALL_SCHEMES[scheme].items():
  152. if os.name in ('posix', 'nt'):
  153. value = os.path.expanduser(value)
  154. res[key] = os.path.normpath(_subst_vars(value, vars))
  155. return res
  156. def _get_default_scheme():
  157. if '__pypy__' in sys.builtin_module_names:
  158. return 'pypy'
  159. elif os.name == 'posix':
  160. # the default scheme for posix is posix_prefix
  161. return 'posix_prefix'
  162. return os.name
  163. def _getuserbase():
  164. env_base = os.environ.get("PYTHONUSERBASE", None)
  165. def joinuser(*args):
  166. return os.path.expanduser(os.path.join(*args))
  167. # what about 'os2emx', 'riscos' ?
  168. if os.name == "nt":
  169. base = os.environ.get("APPDATA") or "~"
  170. return env_base if env_base else joinuser(base, "Python")
  171. if sys.platform == "darwin":
  172. framework = get_config_var("PYTHONFRAMEWORK")
  173. if framework:
  174. return joinuser("~", "Library", framework, "%d.%d"%(
  175. sys.version_info[:2]))
  176. return env_base if env_base else joinuser("~", ".local")
  177. def _init_posix(vars):
  178. """Initialize the module as appropriate for POSIX systems."""
  179. return
  180. def _init_non_posix(vars):
  181. """Initialize the module as appropriate for NT"""
  182. # set basic install directories
  183. vars['LIBDEST'] = get_path('stdlib')
  184. vars['BINLIBDEST'] = get_path('platstdlib')
  185. vars['INCLUDEPY'] = get_path('include')
  186. vars['SO'] = '.pyd'
  187. vars['EXE'] = '.exe'
  188. vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT
  189. vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable))
  190. #
  191. # public APIs
  192. #
  193. def parse_config_h(fp, vars=None):
  194. """Parse a config.h-style file.
  195. A dictionary containing name/value pairs is returned. If an
  196. optional dictionary is passed in as the second argument, it is
  197. used instead of a new dictionary.
  198. """
  199. import re
  200. if vars is None:
  201. vars = {}
  202. define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
  203. undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
  204. while True:
  205. line = fp.readline()
  206. if not line:
  207. break
  208. m = define_rx.match(line)
  209. if m:
  210. n, v = m.group(1, 2)
  211. try: v = int(v)
  212. except ValueError: pass
  213. vars[n] = v
  214. else:
  215. m = undef_rx.match(line)
  216. if m:
  217. vars[m.group(1)] = 0
  218. return vars
  219. def get_config_h_filename():
  220. """Returns the path of pyconfig.h."""
  221. if _PYTHON_BUILD:
  222. if os.name == "nt":
  223. inc_dir = os.path.join(_PROJECT_BASE, "PC")
  224. else:
  225. inc_dir = _PROJECT_BASE
  226. else:
  227. inc_dir = get_path('platinclude')
  228. return os.path.join(inc_dir, 'pyconfig.h')
  229. def get_scheme_names():
  230. """Returns a tuple containing the schemes names."""
  231. schemes = _INSTALL_SCHEMES.keys()
  232. schemes.sort()
  233. return tuple(schemes)
  234. def get_path_names():
  235. """Returns a tuple containing the paths names."""
  236. return _SCHEME_KEYS
  237. def get_paths(scheme=_get_default_scheme(), vars=None, expand=True):
  238. """Returns a mapping containing an install scheme.
  239. ``scheme`` is the install scheme name. If not provided, it will
  240. return the default scheme for the current platform.
  241. """
  242. if expand:
  243. return _expand_vars(scheme, vars)
  244. else:
  245. return _INSTALL_SCHEMES[scheme]
  246. def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True):
  247. """Returns a path corresponding to the scheme.
  248. ``scheme`` is the install scheme name.
  249. """
  250. return get_paths(scheme, vars, expand)[name]
  251. def get_config_vars(*args):
  252. """With no arguments, return a dictionary of all configuration
  253. variables relevant for the current platform.
  254. On Unix, this means every variable defined in Python's installed Makefile;
  255. On Windows and Mac OS it's a much smaller set.
  256. With arguments, return a list of values that result from looking up
  257. each argument in the configuration variable dictionary.
  258. """
  259. import re
  260. global _CONFIG_VARS
  261. if _CONFIG_VARS is None:
  262. _CONFIG_VARS = {}
  263. # Normalized versions of prefix and exec_prefix are handy to have;
  264. # in fact, these are the standard versions used most places in the
  265. # Distutils.
  266. _CONFIG_VARS['prefix'] = _PREFIX
  267. _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX
  268. _CONFIG_VARS['py_version'] = _PY_VERSION
  269. _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT
  270. _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2]
  271. _CONFIG_VARS['base'] = _PREFIX
  272. _CONFIG_VARS['platbase'] = _EXEC_PREFIX
  273. _CONFIG_VARS['projectbase'] = _PROJECT_BASE
  274. if os.name in ('nt', 'os2'):
  275. _init_non_posix(_CONFIG_VARS)
  276. if os.name == 'posix':
  277. _init_posix(_CONFIG_VARS)
  278. # Setting 'userbase' is done below the call to the
  279. # init function to enable using 'get_config_var' in
  280. # the init-function.
  281. _CONFIG_VARS['userbase'] = _getuserbase()
  282. if 'srcdir' not in _CONFIG_VARS:
  283. _CONFIG_VARS['srcdir'] = _PROJECT_BASE
  284. # Convert srcdir into an absolute path if it appears necessary.
  285. # Normally it is relative to the build directory. However, during
  286. # testing, for example, we might be running a non-installed python
  287. # from a different directory.
  288. if _PYTHON_BUILD and os.name == "posix":
  289. base = _PROJECT_BASE
  290. try:
  291. cwd = os.getcwd()
  292. except OSError:
  293. cwd = None
  294. if (not os.path.isabs(_CONFIG_VARS['srcdir']) and
  295. base != cwd):
  296. # srcdir is relative and we are not in the same directory
  297. # as the executable. Assume executable is in the build
  298. # directory and make srcdir absolute.
  299. srcdir = os.path.join(base, _CONFIG_VARS['srcdir'])
  300. _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir)
  301. if sys.platform == 'darwin':
  302. kernel_version = os.uname()[2] # Kernel version (8.4.3)
  303. major_version = int(kernel_version.split('.')[0])
  304. if major_version < 8:
  305. # On Mac OS X before 10.4, check if -arch and -isysroot
  306. # are in CFLAGS or LDFLAGS and remove them if they are.
  307. # This is needed when building extensions on a 10.3 system
  308. # using a universal build of python.
  309. for key in ('LDFLAGS', 'BASECFLAGS',
  310. # a number of derived variables. These need to be
  311. # patched up as well.
  312. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
  313. flags = _CONFIG_VARS[key]
  314. flags = re.sub('-arch\s+\w+\s', ' ', flags)
  315. flags = re.sub('-isysroot [^ \t]*', ' ', flags)
  316. _CONFIG_VARS[key] = flags
  317. else:
  318. # Allow the user to override the architecture flags using
  319. # an environment variable.
  320. # NOTE: This name was introduced by Apple in OSX 10.5 and
  321. # is used by several scripting languages distributed with
  322. # that OS release.
  323. if 'ARCHFLAGS' in os.environ:
  324. arch = os.environ['ARCHFLAGS']
  325. for key in ('LDFLAGS', 'BASECFLAGS',
  326. # a number of derived variables. These need to be
  327. # patched up as well.
  328. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
  329. if key in _CONFIG_VARS:
  330. flags = _CONFIG_VARS[key]
  331. flags = re.sub('-arch\s+\w+\s', ' ', flags)
  332. flags = flags + ' ' + arch
  333. _CONFIG_VARS[key] = flags
  334. # If we're on OSX 10.5 or later and the user tries to
  335. # compiles an extension using an SDK that is not present
  336. # on the current machine it is better to not use an SDK
  337. # than to fail.
  338. #
  339. # The major usecase for this is users using a Python.org
  340. # binary installer on OSX 10.6: that installer uses
  341. # the 10.4u SDK, but that SDK is not installed by default
  342. # when you install Xcode.
  343. #
  344. CFLAGS = _CONFIG_VARS.get('CFLAGS', '')
  345. m = re.search('-isysroot\s+(\S+)', CFLAGS)
  346. if m is not None:
  347. sdk = m.group(1)
  348. if not os.path.exists(sdk):
  349. for key in ('LDFLAGS', 'BASECFLAGS',
  350. # a number of derived variables. These need to be
  351. # patched up as well.
  352. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
  353. flags = _CONFIG_VARS[key]
  354. flags = re.sub('-isysroot\s+\S+(\s|$)', ' ', flags)
  355. _CONFIG_VARS[key] = flags
  356. if args:
  357. vals = []
  358. for name in args:
  359. vals.append(_CONFIG_VARS.get(name))
  360. return vals
  361. else:
  362. return _CONFIG_VARS
  363. def get_config_var(name):
  364. """Return the value of a single variable using the dictionary returned by
  365. 'get_config_vars()'.
  366. Equivalent to get_config_vars().get(name)
  367. """
  368. return get_config_vars().get(name)
  369. def get_platform():
  370. """Return a string that identifies the current platform.
  371. This is used mainly to distinguish platform-specific build directories and
  372. platform-specific built distributions. Typically includes the OS name
  373. and version and the architecture (as supplied by 'os.uname()'),
  374. although the exact information included depends on the OS; eg. for IRIX
  375. the architecture isn't particularly important (IRIX only runs on SGI
  376. hardware), but for Linux the kernel version isn't particularly
  377. important.
  378. Examples of returned values:
  379. linux-i586
  380. linux-alpha (?)
  381. solaris-2.6-sun4u
  382. irix-5.3
  383. irix64-6.2
  384. Windows will return one of:
  385. win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
  386. win-ia64 (64bit Windows on Itanium)
  387. win32 (all others - specifically, sys.platform is returned)
  388. For other non-POSIX platforms, currently just returns 'sys.platform'.
  389. """
  390. import re
  391. if os.name == 'nt':
  392. # sniff sys.version for architecture.
  393. prefix = " bit ("
  394. i = sys.version.find(prefix)
  395. if i == -1:
  396. return sys.platform
  397. j = sys.version.find(")", i)
  398. look = sys.version[i+len(prefix):j].lower()
  399. if look == 'amd64':
  400. return 'win-amd64'
  401. if look == 'itanium':
  402. return 'win-ia64'
  403. return sys.platform
  404. if os.name != "posix" or not hasattr(os, 'uname'):
  405. # XXX what about the architecture? NT is Intel or Alpha,
  406. # Mac OS is M68k or PPC, etc.
  407. return sys.platform
  408. # Try to distinguish various flavours of Unix
  409. osname, host, release, version, machine = os.uname()
  410. # Convert the OS name to lowercase, remove '/' characters
  411. # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh")
  412. osname = osname.lower().replace('/', '')
  413. machine = machine.replace(' ', '_')
  414. machine = machine.replace('/', '-')
  415. if osname[:5] == "linux":
  416. # At least on Linux/Intel, 'machine' is the processor --
  417. # i386, etc.
  418. # XXX what about Alpha, SPARC, etc?
  419. return "%s-%s" % (osname, machine)
  420. elif osname[:5] == "sunos":
  421. if release[0] >= "5": # SunOS 5 == Solaris 2
  422. osname = "solaris"
  423. release = "%d.%s" % (int(release[0]) - 3, release[2:])
  424. # fall through to standard osname-release-machine representation
  425. elif osname[:4] == "irix": # could be "irix64"!
  426. return "%s-%s" % (osname, release)
  427. elif osname[:3] == "aix":
  428. return "%s-%s.%s" % (osname, version, release)
  429. elif osname[:6] == "cygwin":
  430. osname = "cygwin"
  431. rel_re = re.compile (r'[\d.]+')
  432. m = rel_re.match(release)
  433. if m:
  434. release = m.group()
  435. elif osname[:6] == "darwin":
  436. #
  437. # For our purposes, we'll assume that the system version from
  438. # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set
  439. # to. This makes the compatibility story a bit more sane because the
  440. # machine is going to compile and link as if it were
  441. # MACOSX_DEPLOYMENT_TARGET.
  442. cfgvars = get_config_vars()
  443. macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET')
  444. if 1:
  445. # Always calculate the release of the running machine,
  446. # needed to determine if we can build fat binaries or not.
  447. macrelease = macver
  448. # Get the system version. Reading this plist is a documented
  449. # way to get the system version (see the documentation for
  450. # the Gestalt Manager)
  451. try:
  452. f = open('/System/Library/CoreServices/SystemVersion.plist')
  453. except IOError:
  454. # We're on a plain darwin box, fall back to the default
  455. # behaviour.
  456. pass
  457. else:
  458. try:
  459. m = re.search(
  460. r'<key>ProductUserVisibleVersion</key>\s*' +
  461. r'<string>(.*?)</string>', f.read())
  462. if m is not None:
  463. macrelease = '.'.join(m.group(1).split('.')[:2])
  464. # else: fall back to the default behaviour
  465. finally:
  466. f.close()
  467. if not macver:
  468. macver = macrelease
  469. if macver:
  470. release = macver
  471. osname = "macosx"
  472. if (macrelease + '.') >= '10.4.' and \
  473. '-arch' in get_config_vars().get('CFLAGS', '').strip():
  474. # The universal build will build fat binaries, but not on
  475. # systems before 10.4
  476. #
  477. # Try to detect 4-way universal builds, those have machine-type
  478. # 'universal' instead of 'fat'.
  479. machine = 'fat'
  480. cflags = get_config_vars().get('CFLAGS')
  481. archs = re.findall('-arch\s+(\S+)', cflags)
  482. archs = tuple(sorted(set(archs)))
  483. if len(archs) == 1:
  484. machine = archs[0]
  485. elif archs == ('i386', 'ppc'):
  486. machine = 'fat'
  487. elif archs == ('i386', 'x86_64'):
  488. machine = 'intel'
  489. elif archs == ('i386', 'ppc', 'x86_64'):
  490. machine = 'fat3'
  491. elif archs == ('ppc64', 'x86_64'):
  492. machine = 'fat64'
  493. elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'):
  494. machine = 'universal'
  495. else:
  496. raise ValueError(
  497. "Don't know machine value for archs=%r"%(archs,))
  498. elif machine == 'i386':
  499. # On OSX the machine type returned by uname is always the
  500. # 32-bit variant, even if the executable architecture is
  501. # the 64-bit variant
  502. if sys.maxint >= 2**32:
  503. machine = 'x86_64'
  504. elif machine in ('PowerPC', 'Power_Macintosh'):
  505. # Pick a sane name for the PPC architecture.
  506. # See 'i386' case
  507. if sys.maxint >= 2**32:
  508. machine = 'ppc64'
  509. else:
  510. machine = 'ppc'
  511. return "%s-%s-%s" % (osname, release, machine)
  512. def get_python_version():
  513. return _PY_VERSION_SHORT