Introduced Boost.python with homebrew

When I introduced it with homebrew to try Boost.python, I was a little addicted to it. I'll make a note of it.

environment

Usage example (C ++)

Let's call a function that returns the square of c ++ from python.

hello_ext.cpp


#include <boost/python/module.hpp>
#include <boost/python/def.hpp>

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

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

Makefile for building hello_ext.so.

all: hello_ext.so

CC = g++

FRAMEWORK_PATH=/usr/local/opt/python/Frameworks
INCLUDE_PATH=$(FRAMEWORK_PATH)/Python.framework/Versions/2.7/include/python2.7

hello_ext.o: hello_ext.cpp
    $(CC) -Wall -O2 -fPIC -c $< -I$(INCLUDE_PATH)

hello_ext.so: hello_ext.o
    $(CC) -shared  -o $@ $< -lboost_python -F$(FRAMEWORK_PATH) -framework Python

The caller of python.

hello.py


#!/usr/bin/env python
import hello_ext
print hello_ext.square(2)

Build and execution results.

$ make
g++ -shared  -o hello_ext.so -I/usr/local/opt/python/Frameworks/Python.framework/Versions/2.7/include/python2.7 hello_ext.o -lboost_python -F/usr/local/opt/python/Frameworks -framework Python
$ python hello.py
4

Well, the code should be cleaner than the old-fashioned Python extensions.

Usage example (Objective-C ++)

You should use Objective-C ++ to mix Objective-C, for example because you want to use an existing framework. Create the following as hello_ext.mm.

#include <boost/python/module.hpp>
#include <boost/python/def.hpp>

#import <Foundation/Foundation.h>

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

void nslog(void)
{
    NSLog(@"Hello");
}

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

The Makefile is below. Add -x objective-c ++ when compiling, and the framework path and framework name when linking.

all: hello_ext.so

CC =clang++

FRAMEWORK_PATH=/usr/local/opt/python/Frameworks
INCLUDE_PATH=$(FRAMEWORK_PATH)/Python.framework/Versions/2.7/include/python2.7
FRAMEWORK_PATH2=/System/Library/Frameworks

STD_CPP_PATH = /usr/include/c++/4.2.1/

FRAMEWORK_OPTIONS=-F$(FRAMEWORK_PATH) -framework Python -F$(FRAMEWORK_PATH2) -framework Foundation

hello_ext.o: hello_ext.mm
	$(CC) -x objective-c++ -Wall -O2 -fPIC -c $< -I$(INCLUDE_PATH) -I$(STD_CPP_PATH)

hello_ext.so: hello_ext.o
	$(CC) -shared -o $@  $< -lboost_python $(FRAMEWORK_OPTIONS)

.PHONY: clean
clean:
	rm *.so *.o

You can call it below.

import hello_ext

hello_ext.nslog()
print hello_ext.square(2)

The execution result is as follows.

2017-04-09 11:45:29.818 Python[7710:333116] Hello
4

What I was addicted to and how it was resolved

First, the Official Tutorial says that you can use bjam. bjam can be installed by installing homebrew boost-build, but I was asked to specify the path such as Jamfile, so I gave up because I did not know where to install with homebrew.

Next, I tried to build with g ++ by learning from my predecessors such as I will briefly introduce the functions of Boost.Python. But when I tried to pass the arguments,

Segmentation fault: 11

But

Fatal Python error: PyEval_SaveThread: NULL tstate

It was terrible to say that.

The latter error message got stuck in the search and StackOverflow article Has arrived.

Mostly this is when you have multiple versions of python mixed together, right? If you look at the dependencies with otool -L or something;)

The comment is exactly bingo. Certainly there was a mix of OS X native paths and homebrew paths.

So I solved it by replacing the framework path with homebrew's instead of OSX native with the -F option.

I arrived at the -F option with man ld. I'm ashamed to say that I don't even understand the -framework option. I didn't study enough, but I managed to get it.

Reference link

Recommended Posts

Introduced Boost.python with homebrew
Stumble with homebrew opencv3
Setup modern Python environment with Homebrew
Introducing OpenCV on Mac with homebrew
Manage each Python version with Homebrew
"How to pass PATH" to learn with homebrew
Publish your own Python library with Homebrew
Introduced sip-4.14 in python3.2.2 environment with MacOS 10.7.4