Pybind11: `pybind11` doesn't integrate shared objects (`.so`) files from `CMakeLists.txt`

Created on 16 Sep 2019  路  5Comments  路  Source: pybind/pybind11

Issue description

Hi There, I'm having trouble using pybind11 with an existing shared object library .so. What would be the proper way to import and combine in a CMakeLists.txt file?

Ultimately, I'm able to compile and create a build folder with the final .so, but the library fails as I import:

ImportError: dlopen(~/project/build/example.cpython-37m-darwin.so, 2): Symbol not found: __Z8hellosumxx

This is definitely related to pybind11, because I'm able to compile the shared library no problem and use its functions in a C++ file.

Reproducible example code

My CMakeLists.txt file looks like so:

cmake_minimum_required(VERSION 2.8.12)
project(example)

find_package(PythonLibs)
include_directories(${PYTHON_INCLUDE_DIRS})

include_directories(.)
link_directories(${PWD})

add_library(myclass SHARED IMPORTED)
set_property(TARGET myclass PROPERTY IMPORTED_LOCATION "./myclass.so")

add_subdirectory(pybind11)
pybind11_add_module(example example.cpp)

example.cpp:

#include <pybind11/pybind11.h>
#include "myclass.h"


int add(int i, int j) {
    return hellosum(2, 3);
}


namespace py = pybind11;

PYBIND11_MODULE(example, m) {
    // optional module docstring
    m.doc() = "pybind11 example plugin";

    // define add function
    m.def("add", &add, "A function which adds two numbers");
}

myclass.cc:

#include "myclass.h"

long long hellosum(long long a, long long b) {
    return a + b;
}

myclass.h:

#ifndef __MYCLASS_H__
#define __MYCLASS_H__

long long hellosum(long long a, long long b);

#endif

The failing Python import is simply:

from example import add

Most helpful comment

In that case, you need to either have cmake understand how to create and export the go library, or, if it is a 3rd-party dependency, simply link to it via target_link_libraries.

In either case, this is no longer an issue with pybind11, but rather with setting up your build system. As such, it may be a good idea to close this issue.

All 5 comments

Update: Running Python with DYLD_INSERT_LIBRARIES=../myclass.so python3 fixes it by linking at runtime, but I'm ultimately looking for a CMake based solution.

I had to modify your CMakeLists.txt a bit to get it to work. I changed it to use my installed pybind11, which is the current release.

I didn't test if this works after an installation of the package using something like pip:

cmake_minimum_required(VERSION 2.8.12)
project(example)

find_package(pybind11)

include_directories(.)
link_directories(${PWD})

add_library(myclass SHARED myclass.cc)
set_property(TARGET myclass PROPERTY IMPORTED_LOCATION "./myclass.so")

pybind11_add_module(example example.cpp)
target_link_libraries(example PRIVATE myclass)

Thanks a lot @molpopgen!

P.S. Do you know how I would modify that to use a .so library myclass.so without additional source code? (That's my use case and this example was designed to hide some of that complexity). The challenge I'm working with is that I have myclass.so exported from Go using cgo and it has no associated source code beyond the header. Could I pass the header instead?

add_library(myclass SHARED myclass.h)

In that case, you need to either have cmake understand how to create and export the go library, or, if it is a 3rd-party dependency, simply link to it via target_link_libraries.

In either case, this is no longer an issue with pybind11, but rather with setting up your build system. As such, it may be a good idea to close this issue.

Thank you!

Was this page helpful?
0 / 5 - 0 ratings