Airfield20
Airfield20

Reputation: 294

How do I import a module created with pybind11 on Ubuntu

I am trying to setup a CMake project that creates python bindings for its c++ functions using pybind11 on Ubuntu.

The directory structure is:

pybind_test
    arithmetic.cpp
    arithmetic.h
    bindings.h
    CMakeLists.txt
    main.cpp
    pybind11 (github repo clone)
        Repo contents (https://github.com/pybind/pybind11)

The CMakeLists.txt file:

cmake_minimum_required(VERSION 3.10)
project(pybind_test)

set(CMAKE_CXX_STANDARD 17)

find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
include_directories(pybind11/include/pybind11)

add_executable(pybind_test main.cpp arithmetic.cpp)

add_subdirectory(pybind11)
pybind11_add_module(arithmetic arithmetic.cpp)

target_link_libraries(pybind_test ${PYTHON_LIBRARIES})

The repository builds successfully and the file arithmetic.cpython-36m-x86_64-linux-gnu.so is produced. How do I import this shared object file into python?

The documentation in the pybind11 docs has this line

$ c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example`python3-config --extension-suffix`

but I want to build using CMake and I also don't want to have to specify extra include directories every time I run python to use this module.

How would I import this shared object file into python like a normal python module?

I am using Ubuntu 16.04.

Upvotes: 4

Views: 12582

Answers (2)

Tom de Geus
Tom de Geus

Reputation: 5985

Besides the solution of setting the path in the Python script that is presented by @super, you have two more generic solutions.

Setting PYTHONPATH

There is an environment variable in Linux (and macOS) called PYTHONPATH. If you add the path that contains your *.so to the PYTHONPATH before you call Python, Python will be able to find your library.

To do this:

export PYTHONPATH="/path/that/contains/your/so":"${PYTHONPATH}"

To apply this 'automatically' for every session you can add this line to ~/.bash_profile or ~/.bashrc (see the same reference). In that case, Python will always be able to find your library.

Copying your to a path already in Python's path

You can also 'install' the library. The usual way to do this is to create a setup.py file. If set up correctly you can build and install your library using

python setup.py build
python setup.py install

(Python will know where to put your library. You can 'customize' a bit with an option like --user to use your home-folder, but this doesn't seems to be of particular interest to you.)

The question remains: How to write setup.py? For your case you can actually call CMake. In fact there exists an example that does exactly that: pybind/cmake_example. You can basically copy-paste from there.

Upvotes: 1

super
super

Reputation: 12978

If you open a terminal, go to the directory where arithmetic.cpython-36m-x86_64-linux-gnu.so is located and run python followed by import arithmetic the module will get imported just like any other module.

Another options is to use the method of

import sys

sys.path.insert(0, 'path/to/directory/where/so-file/is')
import arithmetic

With this method you can use both relative and absolute path.

Upvotes: 7

Related Questions