Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BoostPython and CMake

I have successfully followed this example for how to connect C++ and python. It works fine when I use the given Makefile. When I try to use cmake instead, it does not go as well.

C++ Code:

#include <boost/python.hpp>
#include <iostream>
extern "C"
char const* greet()
{
   return "hello, world";
}

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

int main(){
    std::cout<<greet()<<std::endl;
    return 0;
}

Makefile:

# location of the Python header files
PYTHON_VERSION = 27
PYTHON_DOT_VERSION = 2.7
PYTHON_INCLUDE = /usr/include/python$(PYTHON_DOT_VERSION)
# location of the Boost Python include files and library
BOOST_INC = /usr/include
BOOST_LIB = /usr/lib/x86_64-linux-gnu/
# compile mesh classes
TARGET = hello_ext
$(TARGET).so: $(TARGET).o
    g++ -shared -Wl,--export-dynamic $(TARGET).o -L$(BOOST_LIB) -lboost_python-py$(PYTHON_VERSION) -L/usr/lib/python$(PYTHON_DOT_VERSION)/config-x86_64-linux-gnu -lpython$(PYTHON_DOT_VERSION) -o $(TARGET).so
$(TARGET).o: $(TARGET).cpp
    g++ -I$(PYTHON_INCLUDE) -I$(BOOST_INC) -fPIC -c $(TARGET).cpp

When I compile this I get a .so file that can be included in the script

import sys
sys.path.append('/home/myname/Code/Trunk/TestBoostPython/build/')
import libhello_ext_lib as hello_ext

print(hello_ext.greet())

I really want to use cmake instead of a manually written Makefile so I wrote this:

cmake_minimum_required(VERSION 3.6)
PROJECT(hello_ext)

# Find Boost
find_package(Boost REQUIRED COMPONENTS python-py27)

set(PYTHON_DOT_VERSION 2.7)
set(PYTHON_INCLUDE /usr/include/python2.7)
set(PYTHON_LIBRARY /usr/lib/python2.7/config-x86_64-linux-gnu)

include_directories(${PYTHON_INCLUDE} ${Boost_INCLUDE_DIRS})

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -lrt -O3")

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
SET(LIBNAME hello_ext_lib)

add_library(${LIBNAME} SHARED src/hello_ext.cpp)
add_executable(${PROJECT_NAME} src/hello_ext.cpp)

TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${Boost_LIBRARIES} -lpython2.7 -fPIC)
TARGET_LINK_LIBRARIES(${LIBNAME} ${Boost_LIBRARIES} -lpython2.7 -fPIC -shared)

Here I currently type the Python-paths by hand but I have also tried using fin_package(PythonLibs) without success.

The program compiles fine and executes when I run the executable file in ../bin/. However, when I run the python script I get always:

ImportError: dynamic module does not define init function (initlibhello_ext_lib)

I found this which says this can happen if the lib and the executable have different names. Which indeed is the case, but how can I obtain the .so with correct name?

I also tried to not compile the executable but only the library. That did also not work.

like image 227
El_Loco Avatar asked Oct 22 '18 12:10

El_Loco


People also ask

Can I build boost with CMake?

However, this Infrastructure does setup more granular targets (like Boost::signals2 instead of Boost::headers ) and provide the ability to build compile-necessary targets too (like filesystem). That infrastructure does warn in their README that building Boost with CMake does not work yet and is not supported .

Can you use CMake with Python?

CMake, the cross-platform build system generator, is now easily installable in Python distributions! This makes creation of cross-platform C/C++ CPython extension modules accessible to many more developers.

What is boost :: Python?

Welcome to Boost. Python, a C++ library which enables seamless interoperability between C++ and the Python programming language. The library includes support for: References and Pointers.


1 Answers

BOOST_PYTHON_MODULE(hello_ext) creates an init function "inithello_ext", which should correspond to a module "hello_ext". But you are trying to import "libhello_ext_lib".

Give the module the same name as the filename. E.g. BOOST_PYTHON_MODULE(libhello_ext_lib).

like image 85
Ghpst Avatar answered Nov 02 '22 02:11

Ghpst