0

I'm trying to create a shared object using boost::python (installed through homebrew) that's loadable in Python on OS X using the Python 2.7 that ships with the OS. What libraries do I have to link in to get a usable shared object?

Here's hello_ext.cpp, taken from the tutorial

// hello_ext.cpp
char const* greet() {
  return "hello, world";
}

#include <boost/python.hpp>

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

I can compile the example like this, although it takes a while.

$ clang++ -fPIC -c -I/usr/include/python2.7 hello_ext.cpp

However, when I attempt to link it and produce an so I get a bunch of undefined symbols:

$ clang++ -shared -o hello_ext.so hello_ext.o | & head -n 7
Undefined symbols for architecture x86_64:
  "_PyString_Type", referenced from:
      boost::python::to_python_value<char const* const&>::get_pytype() const in hello_ext.o
  "__Py_NoneStruct", referenced from:
      boost::python::api::object::object() in hello_ext.o
  "boost::python::detail::init_module(char const*, void (*)())", referenced from:
      _inithello_ext in hello_ext.o

Some of them clearly come from the Python interpreter, and indeed -lpython solves some of the unresolved symbol errors:

$ clang++ -shared -o hello_ext.so hello_ext.o -lpython | & head -n 7
Undefined symbols for architecture x86_64:
  "boost::python::detail::init_module(char const*, void (*)())", referenced from:
      _inithello_ext in hello_ext.o
  "boost::python::detail::gcc_demangle(char const*)", referenced from:
      boost::python::type_info::name() const in hello_ext.o
  "boost::python::detail::scope_setattr_doc(char const*, boost::python::api::object const&, char const*)", referenced from:
      void boost::python::def<char const* (*)()>(char const*, char const* (*)()) in hello_ext.o

The documentation here for boost::python goes into some detail about how to use the library in conjunction with cmake, but doesn't say much about what libraries are required at link time.

7
  • 1
    You need to link with the boost_python library, normally that would be libboost_python* or libboost_python3* depending on whether you want python2 or python3 (the exact name is system-dependent). Commented Feb 22, 2018 at 7:13
  • brew does not seem to have installed a library with that name as part of the boost package itself, although the headers are included in the boost package. libboost_python.{a,dylib} does appear to be part of boost-python. Commented Feb 22, 2018 at 7:26
  • 1
    Headers are not enough for boost::python, you need binary libraries. Your installation is either broken or uses unusual names for libraries. Or perhaps you are supposed to build them yourself (check if there is a large bunch of .cpp files that came with the installation). Commented Feb 22, 2018 at 7:41
  • 1
    Aw sorry didn't see it (it's kinda hard to read on the phone). So you probably need to link with one of these libraries. Commented Feb 22, 2018 at 8:54
  • 1
    Sorry, thank you for answering. Your recommendation worked and clang++ -shared -o hello_ext.so hello_ext.o -lpython -lboost_python produced a loadable native Python module. If I could accept your comment I would. Commented Feb 22, 2018 at 9:12

1 Answer 1

1

boost::python is not a header-only library, it includes a binary component. You need to link with it, for example

clang++ ... -I/usr/include/python2.7 -lboost_python -lpython2.7  

The library is apparently installed by the homebrew package boost-python, not boost.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.