PageRenderTime 485ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/lib-python/2.7/sysconfig.py

https://bitbucket.org/quangquach/pypy
Python | 589 lines | 551 code | 6 blank | 32 comment | 21 complexity | eaacadda82d52f4ec0cb7153983ab79f 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 env_base if env_base else \
  175. joinuser("~", "Library", framework, "%d.%d"
  176. % (sys.version_info[:2]))
  177. return env_base if env_base else joinuser("~", ".local")
  178. def _init_posix(vars):
  179. """Initialize the module as appropriate for POSIX systems."""
  180. return
  181. def _init_non_posix(vars):
  182. """Initialize the module as appropriate for NT"""
  183. # set basic install directories
  184. vars['LIBDEST'] = get_path('stdlib')
  185. vars['BINLIBDEST'] = get_path('platstdlib')
  186. vars['INCLUDEPY'] = get_path('include')
  187. vars['SO'] = '.pyd'
  188. vars['EXE'] = '.exe'
  189. vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT
  190. vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable))
  191. #
  192. # public APIs
  193. #
  194. def parse_config_h(fp, vars=None):
  195. """Parse a config.h-style file.
  196. A dictionary containing name/value pairs is returned. If an
  197. optional dictionary is passed in as the second argument, it is
  198. used instead of a new dictionary.
  199. """
  200. import re
  201. if vars is None:
  202. vars = {}
  203. define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
  204. undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
  205. while True:
  206. line = fp.readline()
  207. if not line:
  208. break
  209. m = define_rx.match(line)
  210. if m:
  211. n, v = m.group(1, 2)
  212. try: v = int(v)
  213. except ValueError: pass
  214. vars[n] = v
  215. else:
  216. m = undef_rx.match(line)
  217. if m:
  218. vars[m.group(1)] = 0
  219. return vars
  220. def get_config_h_filename():
  221. """Returns the path of pyconfig.h."""
  222. if _PYTHON_BUILD:
  223. if os.name == "nt":
  224. inc_dir = os.path.join(_PROJECT_BASE, "PC")
  225. else:
  226. inc_dir = _PROJECT_BASE
  227. else:
  228. inc_dir = get_path('platinclude')
  229. return os.path.join(inc_dir, 'pyconfig.h')
  230. def get_scheme_names():
  231. """Returns a tuple containing the schemes names."""
  232. schemes = _INSTALL_SCHEMES.keys()
  233. schemes.sort()
  234. return tuple(schemes)
  235. def get_path_names():
  236. """Returns a tuple containing the paths names."""
  237. return _SCHEME_KEYS
  238. def get_paths(scheme=_get_default_scheme(), vars=None, expand=True):
  239. """Returns a mapping containing an install scheme.
  240. ``scheme`` is the install scheme name. If not provided, it will
  241. return the default scheme for the current platform.
  242. """
  243. if expand:
  244. return _expand_vars(scheme, vars)
  245. else:
  246. return _INSTALL_SCHEMES[scheme]
  247. def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True):
  248. """Returns a path corresponding to the scheme.
  249. ``scheme`` is the install scheme name.
  250. """
  251. return get_paths(scheme, vars, expand)[name]
  252. def get_config_vars(*args):
  253. """With no arguments, return a dictionary of all configuration
  254. variables relevant for the current platform.
  255. On Unix, this means every variable defined in Python's installed Makefile;
  256. On Windows and Mac OS it's a much smaller set.
  257. With arguments, return a list of values that result from looking up
  258. each argument in the configuration variable dictionary.
  259. """
  260. import re
  261. global _CONFIG_VARS
  262. if _CONFIG_VARS is None:
  263. _CONFIG_VARS = {}
  264. # Normalized versions of prefix and exec_prefix are handy to have;
  265. # in fact, these are the standard versions used most places in the
  266. # Distutils.
  267. _CONFIG_VARS['prefix'] = _PREFIX
  268. _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX
  269. _CONFIG_VARS['py_version'] = _PY_VERSION
  270. _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT
  271. _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2]
  272. _CONFIG_VARS['base'] = _PREFIX
  273. _CONFIG_VARS['platbase'] = _EXEC_PREFIX
  274. _CONFIG_VARS['projectbase'] = _PROJECT_BASE
  275. if os.name in ('nt', 'os2'):
  276. _init_non_posix(_CONFIG_VARS)
  277. if os.name == 'posix':
  278. _init_posix(_CONFIG_VARS)
  279. # Setting 'userbase' is done below the call to the
  280. # init function to enable using 'get_config_var' in
  281. # the init-function.
  282. _CONFIG_VARS['userbase'] = _getuserbase()
  283. if 'srcdir' not in _CONFIG_VARS:
  284. _CONFIG_VARS['srcdir'] = _PROJECT_BASE
  285. # Convert srcdir into an absolute path if it appears necessary.
  286. # Normally it is relative to the build directory. However, during
  287. # testing, for example, we might be running a non-installed python
  288. # from a different directory.
  289. if _PYTHON_BUILD and os.name == "posix":
  290. base = _PROJECT_BASE
  291. try:
  292. cwd = os.getcwd()
  293. except OSError:
  294. cwd = None
  295. if (not os.path.isabs(_CONFIG_VARS['srcdir']) and
  296. base != cwd):
  297. # srcdir is relative and we are not in the same directory
  298. # as the executable. Assume executable is in the build
  299. # directory and make srcdir absolute.
  300. srcdir = os.path.join(base, _CONFIG_VARS['srcdir'])
  301. _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir)
  302. if sys.platform == 'darwin':
  303. kernel_version = os.uname()[2] # Kernel version (8.4.3)
  304. major_version = int(kernel_version.split('.')[0])
  305. if major_version < 8:
  306. # On Mac OS X before 10.4, check if -arch and -isysroot
  307. # are in CFLAGS or LDFLAGS and remove them if they are.
  308. # This is needed when building extensions on a 10.3 system
  309. # using a universal build of python.
  310. for key in ('LDFLAGS', 'BASECFLAGS',
  311. # a number of derived variables. These need to be
  312. # patched up as well.
  313. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
  314. flags = _CONFIG_VARS[key]
  315. flags = re.sub('-arch\s+\w+\s', ' ', flags)
  316. flags = re.sub('-isysroot [^ \t]*', ' ', flags)
  317. _CONFIG_VARS[key] = flags
  318. else:
  319. # Allow the user to override the architecture flags using
  320. # an environment variable.
  321. # NOTE: This name was introduced by Apple in OSX 10.5 and
  322. # is used by several scripting languages distributed with
  323. # that OS release.
  324. if 'ARCHFLAGS' in os.environ:
  325. arch = os.environ['ARCHFLAGS']
  326. for key in ('LDFLAGS', 'BASECFLAGS',
  327. # a number of derived variables. These need to be
  328. # patched up as well.
  329. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
  330. if key in _CONFIG_VARS:
  331. flags = _CONFIG_VARS[key]
  332. flags = re.sub('-arch\s+\w+\s', ' ', flags)
  333. flags = flags + ' ' + arch
  334. _CONFIG_VARS[key] = flags
  335. # If we're on OSX 10.5 or later and the user tries to
  336. # compiles an extension using an SDK that is not present
  337. # on the current machine it is better to not use an SDK
  338. # than to fail.
  339. #
  340. # The major usecase for this is users using a Python.org
  341. # binary installer on OSX 10.6: that installer uses
  342. # the 10.4u SDK, but that SDK is not installed by default
  343. # when you install Xcode.
  344. #
  345. CFLAGS = _CONFIG_VARS.get('CFLAGS', '')
  346. m = re.search('-isysroot\s+(\S+)', CFLAGS)
  347. if m is not None:
  348. sdk = m.group(1)
  349. if not os.path.exists(sdk):
  350. for key in ('LDFLAGS', 'BASECFLAGS',
  351. # a number of derived variables. These need to be
  352. # patched up as well.
  353. 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
  354. flags = _CONFIG_VARS[key]
  355. flags = re.sub('-isysroot\s+\S+(\s|$)', ' ', flags)
  356. _CONFIG_VARS[key] = flags
  357. if args:
  358. vals = []
  359. for name in args:
  360. vals.append(_CONFIG_VARS.get(name))
  361. return vals
  362. else:
  363. return _CONFIG_VARS
  364. def get_config_var(name):
  365. """Return the value of a single variable using the dictionary returned by
  366. 'get_config_vars()'.
  367. Equivalent to get_config_vars().get(name)
  368. """
  369. return get_config_vars().get(name)
  370. def get_platform():
  371. """Return a string that identifies the current platform.
  372. This is used mainly to distinguish platform-specific build directories and
  373. platform-specific built distributions. Typically includes the OS name
  374. and version and the architecture (as supplied by 'os.uname()'),
  375. although the exact information included depends on the OS; eg. for IRIX
  376. the architecture isn't particularly important (IRIX only runs on SGI
  377. hardware), but for Linux the kernel version isn't particularly
  378. important.
  379. Examples of returned values:
  380. linux-i586
  381. linux-alpha (?)
  382. solaris-2.6-sun4u
  383. irix-5.3
  384. irix64-6.2
  385. Windows will return one of:
  386. win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
  387. win-ia64 (64bit Windows on Itanium)
  388. win32 (all others - specifically, sys.platform is returned)
  389. For other non-POSIX platforms, currently just returns 'sys.platform'.
  390. """
  391. import re
  392. if os.name == 'nt':
  393. # sniff sys.version for architecture.
  394. prefix = " bit ("
  395. i = sys.version.find(prefix)
  396. if i == -1:
  397. return sys.platform
  398. j = sys.version.find(")", i)
  399. look = sys.version[i+len(prefix):j].lower()
  400. if look == 'amd64':
  401. return 'win-amd64'
  402. if look == 'itanium':
  403. return 'win-ia64'
  404. return sys.platform
  405. if os.name != "posix" or not hasattr(os, 'uname'):
  406. # XXX what about the architecture? NT is Intel or Alpha,
  407. # Mac OS is M68k or PPC, etc.
  408. return sys.platform
  409. # Try to distinguish various flavours of Unix
  410. osname, host, release, version, machine = os.uname()
  411. # Convert the OS name to lowercase, remove '/' characters
  412. # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh")
  413. osname = osname.lower().replace('/', '')
  414. machine = machine.replace(' ', '_')
  415. machine = machine.replace('/', '-')
  416. if osname[:5] == "linux":
  417. # At least on Linux/Intel, 'machine' is the processor --
  418. # i386, etc.
  419. # XXX what about Alpha, SPARC, etc?
  420. return "%s-%s" % (osname, machine)
  421. elif osname[:5] == "sunos":
  422. if release[0] >= "5": # SunOS 5 == Solaris 2
  423. osname = "solaris"
  424. release = "%d.%s" % (int(release[0]) - 3, release[2:])
  425. # We can't use "platform.architecture()[0]" because a
  426. # bootstrap problem. We use a dict to get an error
  427. # if some suspicious happens.
  428. bitness = {2147483647:"32bit", 9223372036854775807:"64bit"}
  429. machine += ".%s" % bitness[sys.maxint]
  430. # fall through to standard osname-release-machine representation
  431. elif osname[:4] == "irix": # could be "irix64"!
  432. return "%s-%s" % (osname, release)
  433. elif osname[:3] == "aix":
  434. return "%s-%s.%s" % (osname, version, release)
  435. elif osname[:6] == "cygwin":
  436. osname = "cygwin"
  437. rel_re = re.compile (r'[\d.]+')
  438. m = rel_re.match(release)
  439. if m:
  440. release = m.group()
  441. elif osname[:6] == "darwin":
  442. #
  443. # For our purposes, we'll assume that the system version from
  444. # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set
  445. # to. This makes the compatibility story a bit more sane because the
  446. # machine is going to compile and link as if it were
  447. # MACOSX_DEPLOYMENT_TARGET.
  448. cfgvars = get_config_vars()
  449. macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET')
  450. if 1:
  451. # Always calculate the release of the running machine,
  452. # needed to determine if we can build fat binaries or not.
  453. macrelease = macver
  454. # Get the system version. Reading this plist is a documented
  455. # way to get the system version (see the documentation for
  456. # the Gestalt Manager)
  457. try:
  458. f = open('/System/Library/CoreServices/SystemVersion.plist')
  459. except IOError:
  460. # We're on a plain darwin box, fall back to the default
  461. # behaviour.
  462. pass
  463. else:
  464. try:
  465. m = re.search(
  466. r'<key>ProductUserVisibleVersion</key>\s*' +
  467. r'<string>(.*?)</string>', f.read())
  468. if m is not None:
  469. macrelease = '.'.join(m.group(1).split('.')[:2])
  470. # else: fall back to the default behaviour
  471. finally:
  472. f.close()
  473. if not macver:
  474. macver = macrelease
  475. if macver:
  476. release = macver
  477. osname = "macosx"
  478. if (macrelease + '.') >= '10.4.' and \
  479. '-arch' in get_config_vars().get('CFLAGS', '').strip():
  480. # The universal build will build fat binaries, but not on
  481. # systems before 10.4
  482. #
  483. # Try to detect 4-way universal builds, those have machine-type
  484. # 'universal' instead of 'fat'.
  485. machine = 'fat'
  486. cflags = get_config_vars().get('CFLAGS')
  487. archs = re.findall('-arch\s+(\S+)', cflags)
  488. archs = tuple(sorted(set(archs)))
  489. if len(archs) == 1:
  490. machine = archs[0]
  491. elif archs == ('i386', 'ppc'):
  492. machine = 'fat'
  493. elif archs == ('i386', 'x86_64'):
  494. machine = 'intel'
  495. elif archs == ('i386', 'ppc', 'x86_64'):
  496. machine = 'fat3'
  497. elif archs == ('ppc64', 'x86_64'):
  498. machine = 'fat64'
  499. elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'):
  500. machine = 'universal'
  501. else:
  502. raise ValueError(
  503. "Don't know machine value for archs=%r"%(archs,))
  504. elif machine == 'i386':
  505. # On OSX the machine type returned by uname is always the
  506. # 32-bit variant, even if the executable architecture is
  507. # the 64-bit variant
  508. if sys.maxint >= 2**32:
  509. machine = 'x86_64'
  510. elif machine in ('PowerPC', 'Power_Macintosh'):
  511. # Pick a sane name for the PPC architecture.
  512. # See 'i386' case
  513. if sys.maxint >= 2**32:
  514. machine = 'ppc64'
  515. else:
  516. machine = 'ppc'
  517. return "%s-%s-%s" % (osname, release, machine)
  518. def get_python_version():
  519. return _PY_VERSION_SHORT