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.
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
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!
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.