为什么在Python2和Python3中包括路径不同



试图使我的基于SCONS的构建系统尽可能独立时,我想知道以下几点:

为什么python2返回包含路径/usr/local/include/python2.7?此路径不包含Python.h,如果我依靠那条路径,则建筑物会失败。

python2

在python2中使用sysconfig:

$ /usr/bin/python2
Python 2.7.13 (default, Nov 23 2017, 15:37:09) 
[GCC 6.3.0 20170406] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sysconfig
>>> sysconfig.get_path('include')
'/usr/local/include/python2.7'

给出/usr/local/include/python2.7。这是一个空文件夹。

shell呼叫python2-config:

$ /usr/bin/python2-config --includes
-I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7

这给出了不同的路径。我能够在/usr/include/python2.7中找到Python.h

python3

在python3中使用sysconfig:

$ /usr/bin/python3
Python 3.5.3 (default, Nov 23 2017, 11:34:05) 
[GCC 6.3.0 20170406] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sysconfig
>>> sysconfig.get_path('include')
'/usr/include/python3.5m'

shell呼叫python3-config:

/usr/bin/python3-config --includes
-I/usr/include/python3.5m -I/usr/include/python3.5m

所得路径/usr/include/python3.5m对于Boath方法是相同的。Python.h位于这里。

anaconda

如果我使用anaconda python(2或3(路径也是一致的(与python3一样(。

我已经找到了一些解决方法,例如将软链接放在usr/local/include中的usr/include或只是将local/扔掉在路径中,但是两者看起来都不像一个不错的解决方案。

编辑:

当前不正确的python2中的路径使我的构建系统不像我想要的那样独立。如果使用Python2,则添加(可选(环境变量PYTHON_INCLUDE_PATH使我有可能定义正确的路径。但是,始终返回正确路径的解决方案将对我有很大帮助(在Python侧或使用SCONS特定功能(。因为我的构建系统基于SCON

python使用的安装方案根据 平台和安装选项。

https://docs.python.org/2/library/sysconfig.html#installation-paths

有各种方案,包括posix_localposix_prefix,这些方案确定了各种安装目录的位置。sysconfig似乎实际上并未记录使用哪种方案来安装Python的特定构建 - 它只有构建信息。

因此,当您调用sysconfig.get_path()时,它会根据当前平台的默认值猜测该方案[1]。Python2.7 sysconfig猜测posix_local时Python3 sysconfig猜测posix_prefix [2]。

看起来两个版本的Python都使用posix_prefix方案安装,因此您可以指定调用sysconfig.get_path

$ python -c "import sysconfig; print(sysconfig.get_path('include', 'posix_prefix'))"
/usr/include/python2.7
$ python3 -c "import sysconfig; print(sysconfig.get_path('include', 'posix_prefix'))"
/usr/include/python3.5m

[1] https://github.com/python/cpython/blob/2.7/lib/sysconfig.py#l169

[2]将sysconfig作为脚本运行:

$ python -m sysconfig | head
Platform: "linux-x86_64"
Python version: "2.7"
Current installation scheme: "posix_local"
$ python3 -m sysconfig | head
Platform: "linux-x86_64"
Python version: "3.5"
Current installation scheme: "posix_prefix"

我实际上无法在sysconfig源中找到posix_local,因此不确定它来自何处。

编辑

我进一步研究了这一点,并了解到它特定于Debian/Ubuntu版本的Python。上游Python不使用/usr/local/或具有posix_local方案。Debian软件包使用一种与posix_prefix相同的混合方法,并在模块中添加/usr/local/

我尚未在线找到链接,但是我的本地系统在其python2.7 sysconfig.py中具有此链接(请注意FIXME(:

def _get_default_scheme():
    if os.name == 'posix':
        # the default scheme for posix on Debian/Ubuntu is posix_local
        # FIXME: return dist-packages/posix_prefix only for
        #   is_default_prefix and 'PYTHONUSERBASE' not in os.environ and 'real_prefix' not in sys.__dict__
        # is_default_prefix = not prefix or os.path.normpath(prefix) in ('/usr', '/usr/local')
        return 'posix_local'
    return os.name

debian python3 sysconfig.py删除了posix_local,并使用与上游python相同的默认值:

def _get_default_scheme():
    if os.name == 'posix':
        # the default scheme for posix is posix_prefix
        return 'posix_prefix'
    return os.name

您可能需要复制它与Mac或Windows兼容:

sysconfig.get_path('include', 'posix_prefix' if os.name == 'posix' else os.name)

https://wiki.debian.org/python#deviations_from_upstream
https://www.debian.org/doc/packaging-manuals/python-policy/python.html#paths

最新更新