diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py index c625c95bf7e8cf..f86d2220bd609a 100644 --- a/Lib/distutils/command/install.py +++ b/Lib/distutils/command/install.py @@ -30,7 +30,7 @@ INSTALL_SCHEMES = { 'unix_prefix': { 'purelib': '$base/lib/python$py_version_short/site-packages', - 'platlib': '$platbase/lib/python$py_version_short/site-packages', + 'platlib': '$platbase/$platlibdir/python$py_version_short/site-packages', 'headers': '$base/include/python$py_version_short$abiflags/$dist_name', 'scripts': '$base/bin', 'data' : '$base', @@ -281,7 +281,7 @@ def finalize_options(self): # about needing recursive variable expansion (shudder). py_version = sys.version.split()[0] - (prefix, exec_prefix) = get_config_vars('prefix', 'exec_prefix') + (prefix, exec_prefix, platlibdir) = get_config_vars('prefix', 'exec_prefix', 'platlibdir') try: abiflags = sys.abiflags except AttributeError: @@ -298,6 +298,7 @@ def finalize_options(self): 'sys_exec_prefix': exec_prefix, 'exec_prefix': exec_prefix, 'abiflags': abiflags, + 'platlibdir': platlibdir, } if HAS_USER_SITE: diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py index b51629eb94f825..e22d3ada610ff5 100644 --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -146,8 +146,9 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): prefix = plat_specific and EXEC_PREFIX or PREFIX if os.name == "posix": + libdir = plat_specific and get_config_var("platlibdir") or "lib" libpython = os.path.join(prefix, - "lib", "python" + get_python_version()) + libdir, "python" + get_python_version()) if standard_lib: return libpython else: diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 86ccfe041f6675..c55a94b8842a48 100644 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -66,6 +66,7 @@ class or function within a module or module in a package. If the import platform import re import sys +import sysconfig import time import tokenize import urllib.parse @@ -392,9 +393,7 @@ def fail(self, object, name=None, *args): docmodule = docclass = docroutine = docother = docproperty = docdata = fail - def getdocloc(self, object, - basedir=os.path.join(sys.base_exec_prefix, "lib", - "python%d.%d" % sys.version_info[:2])): + def getdocloc(self, object, basedir=sysconfig.get_path('stdlib')): """Return the location of module docs or None""" try: diff --git a/Lib/site.py b/Lib/site.py index ad1146332b0ab7..53b2dfa938c29f 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -334,9 +334,15 @@ def getsitepackages(prefixes=None): seen.add(prefix) if os.sep == '/': - sitepackages.append(os.path.join(prefix, "lib", + from sysconfig import get_config_var + platlibdir = get_config_var("platlibdir") + sitepackages.append(os.path.join(prefix, platlibdir, "python%d.%d" % sys.version_info[:2], "site-packages")) + if platlibdir != "lib": + sitepackages.append(os.path.join(prefix, "lib", + "python%d.%d" % sys.version_info[:2], + "site-packages")) else: sitepackages.append(prefix) sitepackages.append(os.path.join(prefix, "lib", "site-packages")) diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index 8446c8deb2427e..7995f362f40859 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -20,10 +20,10 @@ _INSTALL_SCHEMES = { 'posix_prefix': { - 'stdlib': '{installed_base}/lib/python{py_version_short}', - 'platstdlib': '{platbase}/lib/python{py_version_short}', + 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', + 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', 'purelib': '{base}/lib/python{py_version_short}/site-packages', - 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', + 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', 'include': '{installed_base}/include/python{py_version_short}{abiflags}', 'platinclude': diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 41c4229919507b..113023e6651c7a 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -266,8 +266,9 @@ def test_getsitepackages(self): dirs = site.getsitepackages() if os.sep == '/': # OS X, Linux, FreeBSD, etc - self.assertEqual(len(dirs), 1) - wanted = os.path.join('xoxo', 'lib', + platlibdir = sysconfig.get_config_var('platlibdir') + self.assertTrue(len(dirs) in (1,2)) + wanted = os.path.join('xoxo', platlibdir, 'python%d.%d' % sys.version_info[:2], 'site-packages') self.assertEqual(dirs[0], wanted) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 1b1929885edd6b..087e7df96f5d94 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -271,6 +271,7 @@ def test_user_similar(self): # is similar to the global posix_prefix one base = get_config_var('base') user = get_config_var('userbase') + platlibdir = get_config_var("platlibdir") # the global scheme mirrors the distinction between prefix and # exec-prefix but not the user scheme, so we have to adapt the paths # before comparing (issue #9100) @@ -285,8 +286,19 @@ def test_user_similar(self): # before comparing global_path = global_path.replace(sys.base_prefix, sys.prefix) base = base.replace(sys.base_prefix, sys.prefix) + + if platlibdir != "lib": + platbase = os.path.join(base, platlibdir) + purebase = os.path.join(base, "lib") + userlib = os.path.join(user, "lib") + # replace platbase first because usually purebase is a prefix of platbase + # /usr/lib is prefix of /usr/lib64 and would get replaced first + modified_path = global_path.replace(platbase, userlib, 1).replace(purebase, userlib, 1) + else: + modified_path = global_path.replace(base, user, 1) + user_path = get_path(name, 'posix_user') - self.assertEqual(user_path, global_path.replace(base, user, 1)) + self.assertEqual(user_path, modified_path) def test_main(self): # just making sure _main() runs and returns things in the stdout diff --git a/Lib/trace.py b/Lib/trace.py index 63008a134a8aec..5835b4224e43ed 100755 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -52,6 +52,7 @@ import linecache import os import sys +import sysconfig import token import tokenize import inspect @@ -674,9 +675,8 @@ def main(): opts = parser.parse_args() if opts.ignore_dir: - rel_path = 'lib', 'python{0.major}.{0.minor}'.format(sys.version_info) - _prefix = os.path.join(sys.base_prefix, *rel_path) - _exec_prefix = os.path.join(sys.base_exec_prefix, *rel_path) + _prefix = sysconfig.get_path("stdlib") + _exec_prefix = sysconfig.get_path("platstdlib") def parse_ignore_dir(s): s = os.path.expanduser(os.path.expandvars(s)) diff --git a/Makefile.pre.in b/Makefile.pre.in index 12891e938236a4..86868a21e85d7a 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -137,13 +137,16 @@ exec_prefix= @exec_prefix@ # Install prefix for data files datarootdir= @datarootdir@ +# Name of "lib" directory under prefix +platlibdir= @platlibdir@ + # Expanded directories BINDIR= @bindir@ LIBDIR= @libdir@ MANDIR= @mandir@ INCLUDEDIR= @includedir@ CONFINCLUDEDIR= $(exec_prefix)/include -SCRIPTDIR= $(prefix)/lib +SCRIPTDIR= @libdir@ ABIFLAGS= @ABIFLAGS@ # Detailed destination directories @@ -751,6 +754,7 @@ Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile -DEXEC_PREFIX='"$(exec_prefix)"' \ -DVERSION='"$(VERSION)"' \ -DVPATH='"$(VPATH)"' \ + -DPLATLIBDIR='"$(platlibdir)"' \ -o $@ $(srcdir)/Modules/getpath.c Programs/python.o: $(srcdir)/Programs/python.c diff --git a/Misc/NEWS.d/next/Build/2018-07-03-18-36-35.bpo-34032.bSAQzz.rst b/Misc/NEWS.d/next/Build/2018-07-03-18-36-35.bpo-34032.bSAQzz.rst new file mode 100644 index 00000000000000..7a1058e7c8893a --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-07-03-18-36-35.bpo-34032.bSAQzz.rst @@ -0,0 +1,3 @@ +Build system has been modified to allow /usr/lib64 as well as /usr/lib into +install path as well as to the search path for the Linux distributions which +distinguish between 32bit and 64bit libraries. diff --git a/Modules/getpath.c b/Modules/getpath.c index 3dcfcef7bd7856..75015a14e56439 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -55,9 +55,10 @@ * pybuilddir.txt. If the landmark is found, we're done. * * For the remaining steps, the prefix landmark will always be - * lib/python$VERSION/os.py and the exec_prefix will always be - * lib/python$VERSION/lib-dynload, where $VERSION is Python's version - * number as supplied by the Makefile. Note that this means that no more + * $lib/python$VERSION/os.py and the exec_prefix will always be + * $lib/python$VERSION/lib-dynload, where $VERSION is Python's version + * number and $lib is PLATLIBDIR as supplied by the Makefile. (usually + * "lib", "lib32" or "lib64"). Note that this means that no more * build directory checking is performed; if the first step did not find * the landmarks, the assumption is that python is running from an * installed setup. @@ -86,7 +87,7 @@ * containing the shared library modules is appended. The environment * variable $PYTHONPATH is inserted in front of it all. Finally, the * prefix and exec_prefix globals are tweaked so they reflect the values - * expected by other code, by stripping the "lib/python$VERSION/..." stuff + * expected by other code, by stripping the "$lib/python$VERSION/..." stuff * off. If either points to the build directory, the globals are reset to * the corresponding preprocessor variables (so sys.prefix will reflect the * installation location, even though sys.path points into the build @@ -105,8 +106,8 @@ extern "C" { #endif -#if !defined(PREFIX) || !defined(EXEC_PREFIX) || !defined(VERSION) || !defined(VPATH) -#error "PREFIX, EXEC_PREFIX, VERSION, and VPATH must be constant defined" +#if !defined(PREFIX) || !defined(EXEC_PREFIX) || !defined(VERSION) || !defined(VPATH) || !defined(PLATLIBDIR) +#error "PREFIX, EXEC_PREFIX, VERSION, VPATH and PLATLIBDIR must be constant defined" #endif #ifndef LANDMARK @@ -1145,7 +1146,7 @@ calculate_init(PyCalculatePath *calculate, if (!calculate->prefix) { return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); } - calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len); + calculate->lib_python = Py_DecodeLocale(PLATLIBDIR "/python" VERSION, &len); if (!calculate->lib_python) { return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); } diff --git a/configure.ac b/configure.ac index 0baf0d6660aafe..3852bf76484afc 100644 --- a/configure.ac +++ b/configure.ac @@ -4628,12 +4628,26 @@ else LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" fi +# platlibdir must be defined before LIBPL definition +AC_MSG_CHECKING(for custom platlibdir) +AC_ARG_WITH(custom-platlibdir, + [AS_HELP_STRING([--with-custom-platlibdir=], + [set the platlibdir name to a custom string])], + [], + [with_custom_platlibdir=yes]) +AS_CASE($with_custom_platlibdir, + [yes],[platlibdir=`basename ${libdir}`], + [no],[platlibdir=lib], + [platlibdir=$with_custom_platlibdir]) +AC_MSG_RESULT($platlibdir) +AC_SUBST(platlibdir) + dnl define LIBPL after ABIFLAGS and LDVERSION is defined. AC_SUBST(PY_ENABLE_SHARED) if test x$PLATFORM_TRIPLET = x; then - LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}" + LIBPL='$(prefix)'"/${platlibdir}/python${VERSION}/config-${LDVERSION}" else - LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}" + LIBPL='$(prefix)'"/${platlibdir}/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}" fi AC_SUBST(LIBPL)