Celdor
Celdor

Reputation: 2617

Boost.Python and C++ compiled library error while importing to Python 3

In Python 3, I am trying to import a shared library compiled in C++. Currently, I have these packages installed on CentOS 7:

A simple file in C++ greet.cpp is compiled into a shared library greet.so with Boost.Python. I followed a video on youtube Simple Demo of Boost Python of Python calling C++ library but it failed to find Python.h for some reasons. I had to changed a few things in makefile and eventually I compiled all with no errors. However, when I try to import the shared library pygreet.so in Python interpreter as a module: import pygreet, I get this error:

ImportError: /home/.../cpp/code/pygreet.so: undefined symbol: _ZN5boost6python6detail11init_moduleER11PyModuleDefPFvvE

I tried to see what this thing is: nm pygreet.so | less -p "_ZN5boost6python6detail11init_moduleER11PyModuleDefPFvvE" and found these line:

0000000000008916 W _ZN5boost6python3da simpleefIPFSsvEEEvPKcT_
                 U _ZN5boost6python6detail11init_moduleER11PyModuleDefPFvvE

I am rather a beginner at using shared libraries and I really don't know how to proceed. Below, I am showing the files in case someone can see I missed something important.

Thanks.


greet.cpp:

#include <string>
#include <boost/python.hpp>


namespace py = boost::python;


std::string greet() {
    return "hello, world";
}


int square(int number) {
    return number * number;
}


BOOST_PYTHON_MODULE(pygreet)
{
    // Add regular functions to the module.
    py::def("greet", greet);
    py::def("square", square);
}

makefile:

CXX = g++
PYLIBPATH = $(shell python3-config --exec-prefix)/lib
LDFLAGS = -L$(PYLIBPATH)
LFLAGS = $(shell python3-config --libs) -lboost_python
CFLAGS = -Wall -Werror
INCLUDES = $(shell python3-config --includes)

SOURCE = greet.cpp
TARGET = pygreet.so
OBJ = $(SOURCE:.cpp=.o)

default: $(TARGET)
    @echo $(TARGET) compiled!

$(TARGET): $(OBJ)
    $(CXX) $(CFLAGS) $(LDFLAGS) $(LFLAGS) -Wl,-rpath,$(PYLIBPATH) -shared $< -o $@

greet.o: $(SOURCE)
    $(CXX) $(CFLAGS) $(INCLUDES) -fpic -c $< -o $@

clean:
    rm -rf *.so *.o

.PHONY: deafult clean

Edit.

As suggested in comment, I changed the line in makefile:

PYLIBPATH = $(shell python3-config --exec-prefix)/lib
LDFLAGS = -L$(PYLIBPATH)
LFLAGS = $(shell python3-config --libs) -lboost_python

to

PYLIBPATH = $(shell python3-config --exec-prefix)
LDFLAGS = $(shell python3-config --ldflags) -lboost_python

and then

$(CXX) $(CFLAGS) $(LDFLAGS) $(LFLAGS) -Wl,-rpath,$(PYLIBPATH) -shared $< -o $@

to

$(CXX) $(CFLAGS) $(LDFLAGS) -Wl,-rpath,$(LDFLAGS) -shared $< -o $@

but still have the same error.

Upvotes: 0

Views: 1122

Answers (1)

n. m. could be an AI
n. m. could be an AI

Reputation: 120059

Boost provides separate libraries for Python 2 and Python 3. If you are using Python 3, you need to link with the Python 3 specific library, otherwise you will get undefined symbol errors at module loading time.

On Ubuntu, the library may be called libboost_python-py35.so. I'm pretty sure (but didn't verify) that different minor versions of the boost.python library are upwards compatible, so you may use libboost_python-py35.so with Python 3.6.

If such library is not present on your system, chances are your distro doesn't ship it, in which case you need to build boost.python from sources.

Upvotes: 1

Related Questions