Search code examples
shared-librariesstatic-librariesboost-python

Linking static library Vs. shared library in Linux


I am reading a book about Raspberry Pi to understand Raspberry Pi.

One of the projects in the book shows a C++ class that provides methods that access the GPIO on the Raspberry Pi; the class name is "gpio".

The book tells two methods of using this class:

  1. To write C++ code, simple.cpp: In simple.cpp, main method instantiates gpio class and calls its public methods.

  2. To write Python code: gpio.so must be created using Boost.python. Then simple.py is written in which gpio is imported and its public methods will be called.

The first method is simple: simple.cpp and gpio.cpp are linked together to create a single exe.

To do the latter, the book recommends to use Boost.Python.

I downloaded Boost package and called bootstrap.sh and b2 as follows:

$ sudo ./bootstrap.sh --with-libraries=python --with-python-version=3.7
$ sudo ./b2 cxxflags=-fPIC -link=shared install

These created libboost_python37.so.1.73.0.

And I try to build gpio.so as follows:


PROG = gpio.so
CC = g++
CPPFLAGS = -c -fPIC -I/usr/include/python3.7m/ -I/usr/local/boost_1_73_0
LDFLAGS = -shared -pthread -L/usr/local/boost_1_73_0/bin.v2/libs/python/build/gcc- 
          8/release/python-3.7/threading-multi/visibility-hidden
LLIBS = -lboost_python37
OBJS = gpio.o

$(PROG) : $(OBJS)
  $(CC) $(LDFLAGS) -o $(PROG) $(OBJS) $(LLIBS)
gpio.o : gpio.h
  $(CC) $(CPPFLAGS) -c gpio.cpp

The above creates gpio.so without any fatal errors.

But if I do 'ldd gpio.so' its output shows "libboost_python37.so.1.73.0 => not found".

And if I run simple.py, its output shows "ImportError: libboost_python37.so.1.73.0: cannot open shared object file: No such file or directory".

When I used the static boost python library, I could accomplish the second method above: calling C++ methods from python code.

My development environment is on the Raspberry Pi 4 model B with 4GB memory. The OS is Raspbian GNU/Linux 10 (buster). The development software includes:

  1. Boost package as of July 15, 2020: Rev 1.73.0.
  2. Python 3.7.3 (32-bit)
  3. g++ (Raspbian 8.3.0-6+rpi1) 8.3.0

Solution

  • And I try to build gpio.so as follows:

    Your command line tells the linker how to find libboost_python3.7.so at link time. But it does not tell the runtime loader how to find that library at runtime.

    To tell the runtime loader, use -rpath /path/to/library linker flag. That is:

    BOOST_LIB_PATH = /usr/local/boost_1_73_0/bin.v2/libs/python/build/gcc-8/release/python-3.7/threading-multi/visibility-hidden
    
    LDFLAGS = ... -L ${BOOST_LIB_PATH} -Wl,-rpath,${BOOST_LIB_PATH} ...
    

    It may actually be better to install libbost... into system directory instead of loading it from the build tree.