7

Recently, I am learning boost C++ library. I want to use python to call exist C++ project. I have install boost under OSX 10.11 using brew install boost. My python version 2.7.

I make a hello.c:

char const* greet()
{
    return "hello, world";
}

#include <boost/python.hpp>

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

and Makefile:

PYTHON_VERSION = 2.7
PYTHON_INCLUDE = /usr/include/python$(PYTHON_VERSION)

# location of the Boost Python include files and library
#  
BOOST_INC = /usr/local/include
BOOST_LIB = /usr/local/lib
#   
# compile mesh classes
TARGET = hello

$(TARGET).so: $(TARGET).o
    g++ -shared -Wl $(TARGET).o -L$(BOOST_LIB) -lboost_python -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

However, after I run make and got hello.so. I met following error when I run python code:

import hello
print hello.greet()

error:

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    import hello
ImportError: dlopen(/Users/einverne/boost_test/hello.so, 2): Library not loaded: libboost_python.dylib
  Referenced from: /Users/einverne/boost_test/hello.so
  Reason: unsafe use of relative rpath libboost_python.dylib in /Users/einverne/boost_test/hello.so with restricted binary
Randall
  • 2,859
  • 1
  • 21
  • 24
einverne
  • 6,454
  • 6
  • 45
  • 91

2 Answers2

18

Take this link as a reference.

To my problem, use otool -L hello.so:

hello.so:
    hello.so (compatibility version 0.0.0, current version 0.0.0)
    libboost_python.dylib (compatibility version 0.0.0, current version 0.0.0)
    /System/Library/Frameworks/Python.framework/Versions/2.7/Python (compatibility version 2.7.0, current version 2.7.10)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1)

you can see that libboost_python.dylib is not point to the really exist path.

so use this command:

install_name_tool -change libboost_python.dylib /usr/local/lib/libboost_python.dylib hello.so 

and run otool -L hello.so again:

hello.so:
    hello.so (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/lib/libboost_python.dylib (compatibility version 0.0.0, current version 0.0.0)
    /System/Library/Frameworks/Python.framework/Versions/2.7/Python (compatibility version 2.7.0, current version 2.7.10)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1)

and finally run python test.py, I get the result.

Community
  • 1
  • 1
einverne
  • 6,454
  • 6
  • 45
  • 91
  • 1
    sometimes you want use sudo `sudo install_name_tool -change libboost_python.dylib /usr/local/lib/libboost_python.dylib some.so` – sharma sk Apr 02 '16 at 10:46
  • This saved me *hours*. Thank you!! – Alex Weinstein May 25 '16 at 03:32
  • @sharmask: When would I want to do that instead? Would it give errors, or would it silently fail without `sudo`? – jvriesem Aug 24 '16 at 17:18
  • @jvriesem: When the file (given in the last argument, ie `some.so`) is only writable by root. Generally, yes, that should give an error if `install_name_tool` can't write to it. – Randall Jul 25 '18 at 19:25
3

It is advisable to change the Boost dynamic libraries themselves on MacOS instead of changing the executables or other dynamic libraries linked against them. Run the bash script given below in the directory that contains your libboost_XXX.dylib libraries:

#!/bin/bash

# Modify the absolute dylib paths baked into the libraries
for i in *.dylib
do
    FULLPATH=`pwd`/$i
    install_name_tool -id $FULLPATH $i
    echo -change $i $FULLPATH
    done > changes
for i in *.dylib
do
    install_name_tool `cat changes` $i
done
rm changes

You will need to do this only once after you built the Boost libraries. No mucking around with the executables linking against them is needed.

András Aszódi
  • 8,948
  • 5
  • 48
  • 51