Building Boost.Python with Python 3 on MacOS X

5 Janvier 2014

This assumes you’re using the official Python 3.x.y releases, installed in: /Library/Frameworks/Python.framework/. I’m using OSX 10.9 “Mavericks”, with latest XCode command-line tools. Most notably:

% clang++ --version
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix

Boost version is 1.55, but it may work with others. At the root of the Boost source tree, do:

# Linebreaks added for legibility
./bootstrap.sh
    --with-python-version=3.3 
    --with-python-root=/Library/Frameworks/Python.framework/Versions/3.3
    --with-python=/Library/Frameworks/Python.framework/Versions/3.3/bin/python3.3

# then

./b2 
    include="/Library/Frameworks/Python.framework/Versions/3.3/include/python3.3m"

Let’s try it with a simple Hello world:

/* hellopython.cpp */

#include <iostream>

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

using namespace boost::python;

void greet() {
	// Retrieve the main module.
	object main = import("__main__");

	// Retrieve the main module's namespace
	object global(main.attr("__dict__"));

	// Define greet function in Python.
	object result = exec("def greet():                   \n"
			"\timport sys \n"
			"\tprint(sys.version_info)\n"
			"\treturn 'Hello from Python 3!' \n", global, global);

	// Create a reference to it.
	object greet = global["greet"];

	// Call it.
	std::string message = extract < std::string > (greet());
	std::cout << message << std::endl;
}

int main(int argc, char* argv[]) {
	Py_Initialize();
	greet();
	Py_Finalize();
	return 0;
}

(I’ve found the void greet() function somewhere, and can’t remember where it was — maybe in the Boost docs. Anyway, this code isn’t mine.)

This should build correctly (you need to fix the path to Boost to match your own setup, of course):

# Linebreaks added for legibility
clang++ hellopython.cpp 
    -I /Users/thblt/Documents/Coderies/boost_1_55_0 
    -I /Library/Frameworks/Python.framework/Versions/3.3/include/python3.3m 
    -L /Users/thblt/Documents/Coderies/boost_1_55_0/stage/lib/ 
    -L /Library/Frameworks/Python.framework/Versions/3.3/lib/ 
    -lboost_python3 
    -lpython3.3

Notice that you must link with boost_python3 and python3.3 itself. Of course, you should (maybe must?) link with the same Python library you’ve used to build Boost.

Running a.out should print:

sys.version_info(major=3, minor=3, micro=2, releaselevel='final', serial=0)
Hello from Python 3!

If it complains about missing dylibs, just copy them to your executable’s (a.out) directory. It’ll probably be libboost_python3.dylib, to be found in $BOOST_ROOT/stage/lib.