Cmake 无法找到 Python 库

得到这个错误:

sudo: unable to resolve host coderw@ll
-- Could NOT find PythonLibs (missing:  PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS)
CMake Error at /usr/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:108
(message):
Could NOT find PythonInterp (missing: PYTHON_EXECUTABLE)
Call Stack (most recent call first):
/usr/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:315
(_FPHSA_FAILURE_MESSAGE)
/usr/share/cmake-2.8/Modules/FindPythonInterp.cmake:139
(FIND_PACKAGE_HANDLE_STANDARD_ARGS)
Code/cmake/Modules/FindNumPy.cmake:10 (find_package)
CMakeLists.txt:114 (find_package)






-- Configuring incomplete, errors occurred!
See also "/home/coderwall/Desktop/rdkit/build/CMakeFiles/CMakeOutput.log".
See also "/home/coderwall/Desktop/rdkit/build/CMakeFiles/CMakeError.log".

我已经安装了:

  1. Sudo apt-get install python-dev
  2. 环境变量如下:

    PYTHON_INCLUDE_DIRS=/usr/include/python2.7
    PYTHON_LIBRARIES=/usr/lib/python2.7/config/libpython2.7.so
    

Location of python.h : /usr/lib/include/python2.7/python.h

Location of python libs: /usr/lib/python2.7/ How to solve this?

154064 次浏览

Ubuntu 的某些最新版本默认安装 Python 3.4,而 Ubuntu (2.8)的 CMake 版本只能搜索到 Python 3.3。

尝试在 find_package语句之前添加 set(Python_ADDITIONAL_VERSIONS 3.4)

记得把 CMakeCache.txt也清洗干净。

对我来说,这是有帮助的:

# if using python2
apt-get install python-dev


# if using python3
apt-get install python3-dev

我碰到了同样的问题,发现错误消息给出了误导性的变量名。尝试设置以下内容(单数代替复数) :

PYTHON_INCLUDE_DIR=/usr/include/python2.7
PYTHON_LIBRARY=/usr/lib/python2.7/config/libpython2.7.so

您看到的关于错误消息的(复数)变量是 PythonLibs 在正确初始化时设置的值。

当我在 Xubuntu 14.04 Thrusty Tahr 系统上编译 OpenCV 3时遇到了这个问题。 在安装了所有 Python 的 dev 包之后,配置过程总是返回消息:

Could NOT found PythonInterp: /usr/bin/python2.7 (found suitable version "2.7.6", minimum required is "2.7")
Could NOT find PythonLibs (missing: PYTHON_INCLUDE_DIRS) (found suitable exact version "2.7.6")
Found PythonInterp: /usr/bin/python3.4 (found suitable version "3.4", minimum required is "3.4")
Could NOT find PythonLibs (missing: PYTHON_LIBRARIES) (Required is exact version "3.4.0")

Thrusty Tahr 仓库上的 CMake 版本是2.8。 一些帖子激励我升级 CMake。 我已经添加了一个 PPA CMake 存储库,它安装了 CMake 3.2版本。

升级后一切顺利,编译成功。

这个问题也可能发生在 Windows 中。Cmake 查看注册表,有时没有设置 python 值。对于那些有类似问题的人:

Http://ericsilva.org/2012/10/11/restoring-your-python-registry-in-windows/

只需创建一个. reg 文件来设置必要的密钥,并相应地进行编辑以匹配您的设置。

Windows Registry Editor Version 5.00


[HKEY_CURRENT_USER\Software\Python]


[HKEY_CURRENT_USER\Software\Python\Pythoncore]


[HKEY_CURRENT_USER\Software\Python\Pythoncore\2.6]


[HKEY_CURRENT_USER\Software\Python\Pythoncore\2.6\InstallPath]
@="C:\\python26"


[HKEY_CURRENT_USER\Software\Python\Pythoncore\2.6\PythonPath]
@="C:\\python26;C:\\python26\\Lib\\;C:\\python26\\DLLs\\"


[HKEY_CURRENT_USER\Software\Python\Pythoncore\2.7]


[HKEY_CURRENT_USER\Software\Python\Pythoncore\2.7\InstallPath]
@="C:\\python27"


[HKEY_CURRENT_USER\Software\Python\Pythoncore\2.7\PythonPath]
@="C:\\python27;C:\\python27\\Lib\\;C:\\python27\\DLLs\\"

可以通过在 cmake命令后面添加用各个文件夹填充的 -DPYTHON_LIBRARY-DPYTHON_INCLUDE_DIR标志来修复这些错误。

因此,技巧是用来自 python 解释器的返回信息填充这些参数,这是最可靠的。这可能独立于您的 python 位置/版本(也适用于 Anaconda 用户) :

$ cmake .. \
-DPYTHON_INCLUDE_DIR=$(python -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())")  \
-DPYTHON_LIBRARY=$(python -c "import distutils.sysconfig as sysconfig; print(sysconfig.get_config_var('LIBDIR'))")

如果您想要链接到 cmake 的 python 版本是 Python 3.X,并且缺省的 python 符号链接指向 Python 2.X,那么可以使用 python3 -c ...代替 python -c ...

如果错误仍然存在,您可能需要将 cmake更新到@pdpcosta 所述的更高版本,然后再次重复该过程。

即使按照上面的建议添加了 -DPYTHON_INCLUDE_DIR-DPYTHON_LIBRARY,我仍然面临着 Could NOT find PythonInterp错误。解决这个问题的方法是按照 https://github.com/pybind/pybind11/issues/99#issuecomment-182071479的建议将 -DPYTHON_EXECUTABLE:FILEPATH=加入到 cmake中:

cmake .. \
-DPYTHON_INCLUDE_DIR=$(python -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())")  \
-DPYTHON_LIBRARY=$(python -c "import distutils.sysconfig as sysconfig; print(sysconfig.get_config_var('LIBDIR'))") \
-DPYTHON_EXECUTABLE:FILEPATH=`which python`

粘贴到 CMakeLists.txt:

# find python
execute_process(COMMAND python-config --prefix OUTPUT_VARIABLE PYTHON_SEARCH_PATH)
string(REGEX REPLACE "\n$" "" PYTHON_SEARCH_PATH "${PYTHON_SEARCH_PATH}")
file(GLOB_RECURSE PYTHON_DY_LIBS ${PYTHON_SEARCH_PATH}/lib/libpython*.dylib ${PYTHON_SEARCH_PATH}/lib/libpython*.so)
if (PYTHON_DY_LIBS)
list(GET PYTHON_DY_LIBS 0 PYTHON_LIBRARY)
message("-- Find shared libpython: ${PYTHON_LIBRARY}")
else()
message(WARNING "Cannot find shared libpython, try find_package")
endif()


find_package(PythonInterp)
find_package(PythonLibs ${PYTHON_VERSION_STRING} EXACT)

请注意,如果使用 cMake version 3.12或更高版本,变量 PythonInterpPythonLibs已被更改为 Python

因此,我们使用:

find_package(Python ${PY_VERSION} REQUIRED)

而不是:

find_package(PythonInterp ${PY_VERSION} REQUIRED) find_package(PythonLibs ${PY_VERSION} REQUIRED)

详情请参阅 https://cmake.org/cmake/help/v3.12/module/FindPython.html

为了防止这种情况发生,我找到了一个类似问题的解决方案,查看 cmake 文档: Https://cmake.org/cmake/help/v3.0/module/findpythonlibs.html

必须为 cmake 设置两个 env var 才能找到连贯的版本。 不幸的是,这不是一个通用的解决方案..。

cmake -DPYTHON_LIBRARY=${HOME}/.pyenv/versions/3.8.0/lib/libpython3.8.a -DPYTHON_INCLUDE_DIR=${HOME}/.pyenv/versions/3.8.0/include/python3.8/ cern_root/

如果上述所有方法都不能工作,那么下面的命令行可能对您有用。

sudo apt-get install cython cython3

我已经在系统上升级到 python3.8,并且没有完成安装。通过安装剩下的3.8软件包成功地解决了这个问题:

sudo apt-get install python3.8 python3.8-dev python3.8-distutils python3.8-venv

至少在 Ubuntu 20上,因为 Python 2.7已经过时了,你可以:

sudo apt install python2.7-dev

然后可以将 PYTHON_INCLUDE_DIR设置为 /usr/include/python2.7

在 Python 3.2及以后的版本中,不推荐使用 distutils.sysconfig,而青睐于 sysconfig

为了得到数据结构中所有的变量名并检查情况,我们可以使用 获取路径函数

import sysconfig
sysconfig.get_paths()

它将返回一个 dict,其中所有相关的变量名称作为键,相应的路径作为值。 当我们知道了键,我们就可以动态地得到值,

>>> sysconfig.get_path("include")
'C:\\Program Files\\Python310\\Include'

然而,对于这种情况,sysutils最方便的特性是它可以通过调用 python -m sysconfig从命令提示符一次列出所有变量:

$ python -m sysconfig


Platform: "macosx-10.4-i386"
Python version: "3.2"
Current installation scheme: "posix_prefix"


Paths:
data = "/usr/local"
include = "/Users/tarek/Dev/svn.python.org/py3k/Include"
platinclude = "."
platlib = "/usr/local/lib/python3.2/site-packages"
platstdlib = "/usr/local/lib/python3.2"
purelib = "/usr/local/lib/python3.2/site-packages"
scripts = "/usr/local/bin"
stdlib = "/usr/local/lib/python3.2"


Variables:
AC_APPLE_UNIVERSAL_BUILD = "0"
AIX_GENUINE_CPLUSPLUS = "0"
AR = "ar"
ARFLAGS = "rc"
...