Cmake could not find boost_python
Asked Answered
T

2

11

I am trying to build this simple boost python demo from this link on my MacOS High Sierra.

Following is the 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);
}

Following is the 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})

I figured I need to install python. Boost 1.69 was already installed and I did brew install boost-python which worked fine. Doing a brew list | grep 'boost' lists out boost and boost-python.

But, doing a cmake .. from a build directory complains the following:

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.

What am I missing here?

Thicket answered 9/5, 2019 at 21:1 Comment(5)
Maybe post the section in your CMakeList.txt that is related to boost_python so that we can take a closer look? I suspect the boost_python library is not in the LD_LIBRARY_PATH or the equivalent of your version of MacOS.Claw
The code is taken from the link I mentioned. I posted all the code in the question now thus making it a complete code example.Thicket
Running cmake --trace or --trace-expand is very useful for debugging CMake logic. Find the error message in CMake stock scripts, then compare the code with the corresponding place in the trace to see what's happening.Mercerize
Can you try to use find_package(Boost COMPONENTS python27 REQUIRED) instead?Albigenses
find_package(Boost COMPONENTS python27 REQUIRED) fixed it :D. Great. Thanks. Looks like I should write the correct python version while asking cmake to locate pythonThicket
A
10

From this document:

Note that Boost Python components require a Python version suffix (Boost 1.67 and later), e.g. python36 or python27 for the versions built against Python 3.6 and 2.7, respectively. This also applies to additional components using Python including mpi_python and numpy. Earlier Boost releases may use distribution-specific suffixes such as 2, 3 or 2.7. These may also be used as suffixes, but note that they are not portable.

The example you found was probably using an older version of Boost. So, you may need to change this line:

find_package(Boost COMPONENTS python27 REQUIRED)
Albigenses answered 10/5, 2019 at 6:58 Comment(4)
This is not a very generic solution. What if I want to use the default python 3 library, but do not mind which minor version of Python?Corbicula
@AndréOffringa Maybe you can get away with providing another symlink to the library. But this will probably fall under the realm of "not portable".Albigenses
For packages that are to be released on several platforms, that's not an option. A portable solution for this would still be very useful, but as far as I can tell it seems that Boost Python doesn't provide it, which is unfortunate.Corbicula
Maybe you can find something about this on their mailing lists or the issue tracker. Otherwise you may consider to post a new issue...Albigenses
E
3

To pass the right python version to find_package(Boost), I suggest to extract it from the version of python found on the system.

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)

The 3.6 on the first line is a minimum version, it finds the python38 boost module on my machine due to /usr/lib64/libpython3.8.so.

Evanston answered 13/12, 2020 at 20:7 Comment(1)
Please don't use this. FindPythonLibs has been deprecated long time ago.Mckown

© 2022 - 2024 — McMap. All rights reserved.