Linking Python and C++ with Boost.python

Introduction to Boost

Boost is a project to create open-source libraries for C++. There are a lot of nice tools available through Boost, one of which is Boost.python. Boost.Python provides seamless interoperability between C++ and Python. I have found it to be an extremely useful tool for scientific programming. Parts of a program that require more flexibility than speed can be written in Python, and critical portions can be coded in C++.

Tutorials and Examples

Unfortunately, the Boost.Python documentation is not written for beginners, and there is not a lot of help on other web sites. The mailing list is great, but a good mailing list does not replace good introductory documentation.

Hello World

Here is the “hello world” example from the Boost.python tutorial. I found that attempting to configure the Boost.jam build system is far more confusing than using GNU make to build the examples. The following presentation should be much easier to understand. All files to build this example can be found in the Shocksolution_Examples repo on GitHub.
Save the following as hello_ext.C

char const* greet()
{
   return "hello, world";
}
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(hello_ext)
{
    using namespace boost::python;
    def("greet", greet);
}

Save the following as Makefile:

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

Save the following as test_hello.py

import hello_ext
print(hello_ext.greet())

That’s it.

Other Examples

37 thoughts on “Linking Python and C++ with Boost.python”

  1. Pingback: Configuring Boost::Python and Hello Boost « Paranoid Android

  2. You saved me from the horrible hellhole this BoostJam is. It almost feels like it was crafted not to be used by anyone but the core developers. Thanks 🙂

  3. Craig, I expect you will get lots of traffic with your solution. I’ve been trying to get your files to compile, but I’m having a few Makefile issues. After editing with Nano to confirm tabs rather than spaces and converting to unix lifefeeds, I’m getting an error: make: hello_ext.o: Command not found. Any idea why make is viewing $(TARGET).o as a command?

  4. Ross, the formatting of the Makefile in this post was causing a lot of problems. I have refomatted the Makefile in the post and added all necessary files for the example to my repo on GitHub (link is near the top of the post).
    Also, the version of Boost on my workstation now has separate library files for each Python version, so I modified the Makefile accordingly. Let me know if there are any further problems.

  5. Craig, brilliant work. After a few mods to my own python and boost lib paths, and checking the whitespace/tabs formatting, your Makefile worked like a charm. With no disrespect to the bjam fellows, I worked on bjam until I was about to pass out and realized I could probably build using good-old-fashioned make (with a little help). That’s when a search took me to your site. Thanks for unblocking the road.

  6. I am getting error /usr/local/include/boost/python/detail/wrap_python.hpp:50:23: fatal error: pyconfig.h: No such file or directory
    # include
    Any idea what could be the problem here?

    1. There is probably a problem with the configuration of your include paths. I suspect that the compiler cannot find the source directory with the Python header files, so you may need to set an environment variable or use a command-line flag to tell it where to find the header files.

  7. hi! I get this error when i try to make it.
    g++ -shared -Wl,–export-dynamic hello_ext.o -L/usr/lib -lboost_python-2.7 -L/usr/lib/python2.7/config -lpython2.7 -o hello_ext.so
    /usr/bin/ld: cannot find -lboost_python-2.7
    collect2: ld returned 1 exit status
    make: *** [hello_ext.so] Error 1
    please help me! thanks in advance.

    1. The linker cannot find the library called boost_python-2.7. You should find the path to this library on your system and provide that path to the linker with a -L flag as you have done with the other library paths. If that library doesn’t exist, it may need to be installed, or you may have specified its name incorrectly.

    2. in the Makefile try -lboost_python instead of -lboost_python-$(PYTHON_VERSION)
      In my case the boost_python library name does not have the python version as a suffix.

    1. Make sure your Makefile is identical to the one I posted on GitHub. Note that spaces and tabs are critical! The –export-dynamic option is a linker (LD) flag, NOT a compiler (GCC) flag. You pass flags to the linker by giving GCC the flag “-Wl,” followed by the desired linker flag. There cannot be a space between the comma and the linker flag.

  8. This is great, thank you for taking the time to make a walk through. The Boost documentation is cryptic for those attempting to use the libraries for the first time.
    I’ve made it past a few of the common errors that I’m seeing on this thread and elsewhere, but I’m getting this error:
    g++ -I/Users/tomconlin/anaconda/pkgs/python-2.7.11-0/include/python2.7 -I/usr/include -fPIC -c hello_ext.C
    g++ -shared -Wl,–export-dynamic hello_ext.o -L/usr/lib -lboost_python -L/usr/lib/python2.7/config -lpython2.7 -o hello_ext.so
    ld: unknown option: –export-dynamic
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    make: *** [hello_ext.so] Error 1
    Has anyone seen anything like this before? Any insights would be greatly appreciated!!
    Thanks again for the tutorial, simple and to the point!

  9. HARIHARAN RAGOTHAMAN

    I am getting the following. It would be great if you could tell me what happens here.
    ImportError: /scratch/Python_stuff/Python_Boost/hello_ext.so: undefined symbol: _ZN5boost6python6detail11init_mod uleEPKcPFvvE

  10. Hi
    I downloaded all the files and tried to run the python file. But it is giving me following error:
    ImportError: No module named hello_ext
    I am not sure whether Boost Python is installed on my system. I tried to install it using BoostPython website but it did not work. Can someone tell me about the installtion of boost python library for python 2.7? It would be great if you could also help me in troublehooting this error.
    Thanks in anticipation.

  11. I had the same issue with “ImportError” (working on the new windows subsystem for Linux for Windows 10). It was related to not linking the correct library name (boost_python-py27 not boost_python-2.7 per the Makefile example above) and the fact that my boost-python link path was set incorrectly (ie not -L/usr/lib but -L/usr/lib/x86_64-linux-gnu). Hope this helps Hari and Alam…

  12. Hi,
    I tried running your files in git. But its giving me an error.
    ImportError: No module named hello_ext. I have boost installed on my system and I am trying to run this program on Windows 7. Any help will be appreciated

    1. Problems like this are very specific to the way that libraries are installed and configured on your particular system, so I can’t help with this type of problem. Also, I have never done this on a Windows system.

  13. WOW, Thank you big time
    I cant believe that it says hello :V
    It’s 3 days that I’m trying to make the boost_python works, I was giving up on it !

  14. Thank you for this great blog post. It was a huge help in getting my build environment setup.
    It took the better part of a day but I at least got “hello world” from C++ into Python.

  15. On Ubuntu 14.04LTS, I had to change the descriptor for boost_python and remove the following:
    -L/usr/lib/python$(PYTHON_VERSION)/config -lpython$(PYTHON_VERSION)
    as my installation on Ubuntu 14.04LTS has no such config directory

    The result that works for me looks like this (python3.4 and my source has .cpp extension):
    $(TARGET).so: $(TARGET).o
    g++ -shared -Wl,–export-dynamic $(TARGET).o -L$(BOOST_LIB) -lboost_python-py34 -o $(TARGET).so
    $(TARGET).o: $(TARGET).cpp
    g++ -I$(PYTHON_INCLUDE) -I$(BOOST_INC) -fPIC -c $(TARGET).cpp

    Thank you for the post, was getting frustrated with bjam.

  16. Its an old tutorial, and it seems to not wor with current boost python any more. However the official documentation has not updated there hellow world either and now im stuck with either:

    g++ -I/usr/include/python3.9 -I/usr/include -fPIC -c hello_ext.C
    In file included from /usr/include/boost/smart_ptr/detail/sp_thread_sleep.hpp:22,
    from /usr/include/boost/smart_ptr/detail/yield_k.hpp:23,
    from /usr/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp:14,
    from /usr/include/boost/smart_ptr/detail/spinlock.hpp:42,
    from /usr/include/boost/smart_ptr/detail/spinlock_pool.hpp:25,
    from /usr/include/boost/smart_ptr/shared_ptr.hpp:29,
    from /usr/include/boost/shared_ptr.hpp:17,
    from /usr/include/boost/python/converter/shared_ptr_to_python.hpp:12,
    from /usr/include/boost/python/converter/arg_to_python.hpp:15,
    from /usr/include/boost/python/call.hpp:15,
    from /usr/include/boost/python/object_core.hpp:14,
    from /usr/include/boost/python/args.hpp:22,
    from /usr/include/boost/python.hpp:11,
    from hello_ext.C:5:
    /usr/include/boost/bind.hpp:36:1: note: ‘#pragma message: The practice of declaring the Bind placeholders (_1, _2, …) in the global namespace is deprecated. Please use + using namespace boost::placeholders, or define BOOST_BIND_GLOBAL_PLACEHOLDERS to retain the current behavior.’
    36 | BOOST_PRAGMA_MESSAGE(
    | ^~~~~~~~~~~~~~~~~~~~
    /usr/include/boost/detail/iterator.hpp:13:1: note: ‘#pragma message: This header is deprecated. Use instead.’
    13 | BOOST_HEADER_DEPRECATED(“”)
    | ^~~~~~~~~~~~~~~~~~~~~~~
    g++ -shared -Wl,–export-dynamic hello_ext.o -L/usr/lib -lboost_python-3.9 -L/usr/lib/python3.9/config -lpython3.9 -o hello_ext.so
    /usr/bin/ld: cannot find -lboost_python-3.9
    collect2: error: ld returned 1 exit status
    make: *** [Makefile:10: hello_ext.so] Error 1

    and if I follow the advice of using instead of the error changes to:

    g++ -I/usr/include/python3.9 -I/usr/include -fPIC -c hello_ext.C
    hello_ext.C:6:20: error: expected constructor, destructor, or type conversion before ‘(’ token
    6 | BOOST_PYTHON_MODULE(hello_ext)
    | ^
    make: *** [Makefile:12: hello_ext.o] Error 1

    what is less verbose but doesnt work either 🙁

    1. You are correct-this is a very old tutorial. I haven’t used Boost.python in at least 10 years. From its web page, I can’t tell if it’s even maintained anymore. Good luck!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.