【问题标题】:Cmake could not find boost_pythonCmake 找不到 boost_python
【发布时间】:2023-03-28 03:05:02
【问题描述】:

我正在尝试在我的 MacOS High Sierra 上从 this link 构建这个简单的 boost python 演示。

下面是hello_ext.cpp

#include <boost/python.hpp>

char const* greet()
{
  return "hello, world";
}

BOOST_PYTHON_MODULE(hello_ext)
{
  using namespace boost::python;
  def("greet", greet);
}

下面是CmakeLists.txt

cmake_minimum_required(VERSION 3.5)

# Find python and Boost - both are required dependencies
find_package(PythonLibs 2.7 REQUIRED)
find_package(Boost COMPONENTS python REQUIRED)

# Without this, any build libraries automatically have names "lib{x}.so"
set(CMAKE_SHARED_MODULE_PREFIX "")

# Add a shared module - modules are intended to be imported at runtime.
# - This is where you add the source files
add_library(hello_ext MODULE hello_ext.cpp)

# Set up the libraries and header search paths for this target
target_link_libraries(hello_ext ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
target_include_directories(hello_ext PRIVATE ${PYTHON_INCLUDE_DIRS})

我想我需要安装 python。 Boost 1.69 已经安装,我做了brew install boost-python,效果很好。执行brew list | grep 'boost' 会列出boostboost-python

但是,从build 目录执行cmake .. 会报错:

Could not find the following Boost libraries:

      boost_python

No Boost libraries were found.  You may need to set BOOST_LIBRARYDIR to 
the directory containing Boost libraries or BOOST_ROOT to the location 
of Boost.

我在这里错过了什么?

【问题讨论】:

  • 也许在您的 CMakeList.txt 中发布与 boost_python 相关的部分,以便我们仔细查看?我怀疑 boost_python 库不在 LD_LIBRARY_PATH 或您的 MacOS 版本中。
  • 代码取自我提到的链接。我现在发布了问题中的所有代码,从而使其成为一个完整的代码示例。
  • 运行 cmake --trace--trace-expand 对于调试 CMake 逻辑非常有用。在 CMake 库存脚本中找到错误消息,然后将代码与跟踪中的相应位置进行比较,看看发生了什么。
  • 您可以尝试改用find_package(Boost COMPONENTS python27 REQUIRED) 吗?
  • find_package(Boost COMPONENTS python27 REQUIRED) 修复了它:D。伟大的。谢谢。看起来我应该在要求 cmake 定位 python 时编写正确的 python 版本

标签: python c++ boost-python


【解决方案1】:

来自this document

请注意,Boost Python 组件需要 Python 版本后缀(Boost 1.67 及更高版本),例如python36 或 python27 分别用于针对 Python 3.6 和 2.7 构建的版本。这也适用于使用 Python 的其他组件,包括 mpi_python 和 numpy。较早的 Boost 版本可能使用特定于发行版的后缀,例如 2、3 或 2.7。这些也可以用作后缀,但请注意它们不可移植。

您发现的示例可能使用的是旧版本的 Boost。因此,您可能需要更改此行:

find_package(Boost COMPONENTS python27 REQUIRED)

【讨论】:

  • 这不是一个非常通用的解决方案。如果我想使用默认的 python 3 库,但不介意 Python 的次要版本怎么办?
  • @AndréOffringa 也许您可以通过提供另一个指向库的符号链接来摆脱困境。但这可能属于“不可移植”的范畴。
  • 对于要在多个平台上发布的软件包,这不是一个选项。一个可移植的解决方案仍然非常有用,但据我所知,Boost Python 似乎没有提供它,这是不幸的。
  • 也许您可以在他们的邮件列表或问题跟踪器上找到有关此内容的信息。否则你可以考虑发布一个新问题...
【解决方案2】:

要将正确的python版本传递给find_package(Boost),我建议从系统上找到的python版本中提取它。

find_package(PythonLibs 3.6 REQUIRED)
# Extract major/minor python version
string(REPLACE "." ";" VERSION_LIST ${PYTHONLIBS_VERSION_STRING})
list(GET VERSION_LIST 0 PYTHONLIBS_VERSION_MAJOR)                                                                                                                             
list(GET VERSION_LIST 1 PYTHONLIBS_VERSION_MINOR)
find_package(Boost COMPONENTS python${PYTHONLIBS_VERSION_MAJOR}${PYTHONLIBS_VERSION_MINOR} REQUIRED)

第一行的3.6是最低版本,由于/usr/lib64/libpython3.8.so在我的机器上找到了python38 boost模块。

【讨论】: