2015-11-04 70 views
3

初始状态:如何从Python中得到Python库的路径

我有一个C/C++库,并提供不同的目标语言绑定。其中一种语言是Python。我决定使用Swig,因为它为很多语言提供了很好的支持,并且它与CMake的集成非常简单。

为了提高Python绑定的可用性和它的安装,我想提供一个setup.py。这个想法是从setup.py文件中运行CMake,因为CMake包含了如何正确创建绑定的所有逻辑。

我目前有:

我能够运行CMake和建设的Python从setup.py内粘合的目标。

通过Swig的设计,CMake文件需要区分Python 2和Python 3.在运行CMake时,它会检测Python安装的位置并配置环境。如果用户安装了这两个,Python 2和Python 3中(与他们开发包)的CMake始终把Python 3的

据:https://cmake.org/cmake/help/v3.0/module/FindPythonLibs.html实际使用Python版本可以通过设置PYTHON_LIBRARY和PYTHON_INCLUDE_DIR指定。比如我要运行:如果用户执行

cmake -DPYTHON_INCLUDE_DIR=/usr/include/python2.7 -DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython2.7.so 

什么问题

python setup.py build 

可执行 '巨蟒' 的Python版本可能是2,但CMake使用版本3构建绑定(参见上文)。

根据Find python header path from within python?我能够用得到的头文件的位置:

from distutils.sysconfig import get_python_inc 
get_python_inc() 

不幸的是,我不知道如何让Python库的路径。通过提供的解决方案:Distribution independent libpython path不为我工作,因为它总是返回“/ usr/lib目录”,而不是“/usr/lib/x86_64-linux-gnu/libpython2.7.so”

的问题:

如何从Python中获取Python库的位置(完整路径)。

+0

[获取Python的LIB路径]的可能重复(https://stackoverflow.com/questions/47423246/get-pythons-lib-path) –

回答

-1

我用解决方法自己解决了问题。也许它可以帮助其他人面对相同或至少类似的问题。

首先,我介绍了环境变量PYTHON_INCLUDE_DIR和PYTHON_LIBRARY,它们的名称与用于配置python路径的参数CMake相同:-DPYTHON_INCLUDE_DIR和-DPYTHON_LIBRARY。此外,我将下面的代码添加到我的CMake文件

if(DEFINED ENV{PYTHON_LIBRARY} AND DEFINED ENV{PYTHON_INCLUDE_DIR}) 
    message(STATUS "Using environment variables PYTHON_LIBRARY and PYTHON_INCLUDE_DIR") 
    set(PYTHON_LIBRARY $ENV{PYTHON_LIBRARY}) 
    set(PYTHON_INCLUDE_DIR $ENV{PYTHON_INCLUDE_DIR}) 
endif() 

它只是将环境变量包装到CMake参数中。现在用户可以在运行CMake之前定义这些变量而不是参数。

PYTHON_INCLUDE_DIR=/usr/include/python2.7 PYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython2.7.so cmake 

由于我的setup.py只是调用CMake和现在的CMake之所以能够抓住环境变量,并将它们运行setup.py前分别换到的参数,用户还可以配置变量(或点子等)。

PYTHON_INCLUDE_DIR=/usr/include/python2.7 PYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython2.7.so pip install tinyspline 

说实话,用户仍然需要配置一些路径,但最终他/她能够这样做。

+1

这并没有真正解决找出路径的问题。你仍然需要手工指定,只是在另一个地方。 –

+0

Thist doensn't回答你的问题:“如何从Python中获取Python库的位置(完整路径)” – olivecoder

1

问题:

如何从内Python中得到Python库的位置(完整路径)。

答案:

在Makefile中寻找INSTALL_SHARED为Python: https://github.com/python/cpython/blob/3.5/Makefile.pre.in

我们可以发现:

$(INSTALL_SHARED) libpython$(VERSION)$(SO) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \ 

我们可以看到,没有一个统一的变量与询问信息。你需要从两个人建立它:

from distutils.sysconfig import get_config_var 
libpython = "%s/%s" % (get_config_var("LIBDIR"), get_config_var("INSTSONAME")) 

测试在Python 2.7:

Python 2.7.13 (default, Nov 20 2017, 02:33:01) 
[GCC 4.7.2 20121109 (Red Hat 4.7.2-8)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from distutils.sysconfig import get_config_var 
>>> "%s/%s" % (get_config_var("LIBDIR"), get_config_var("INSTSONAME")) 
'/usr/lib64/libpython2.7.so.1.0' 

测试在Python 3.3:

Python 3.3.0 (default, Nov 11 2013, 09:56:47) 
[GCC 4.7.2 20121109 (Red Hat 4.7.2-8)] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from distutils.sysconfig import get_config_var 
>>> "%s/%s" % (get_config_var("LIBDIR"), get_config_var("INSTSONAME")) 
'/usr/lib64/libpython3.3m.so.1.0' 

所以,它只是适用于CPython的(> = 2.3)在Linux中,你可以在python Makefile中看到,并且不能保证它可以在未来工作,无论如何,在过去的14年里,这并没有改变,从2003年5月11日开始。

您可以使用的Windows BINDIR和DLLLIBRARY变量来代替,因为你可以从Makefile中看到:

$(INSTALL_SHARED) libpython$(VERSION)$(SO) $(DESTDIR)$(BINDIR); \ 

不过,我也没办法在Windows中进行测试。

+1

sysconfig.get_python_lib()返回'/usr/lib/python2.7/ dist-packages'不包含文件'libpython2.7.so' – Marcel

+0

对不起@Marcel,我没有给予足够的关注。现在应该可以。 – olivecoder

+2

sysconfig.get_config_var(“LDLIBRARY”)仅返回库的名称,但不返回完整路径。我期待的是:'/usr/lib/x86_64-linux-gnu/libpython2.7.so' – Marcel