我正在尝试使用Boost.Python为模板库的某个实例化构建一个小的Python扩展。这个库广泛使用了CGAL库,它与CMake集成得非常好,因此我将其用于我的项目。
这是我模块的代码(python_export.cpp):
#include <boost/python.hpp>
#include <CGAL/Exact_spherical_kernel_3.h>
#include "Sphere_intersecter.h" // header-only
typedef CGAL::Exact_spherical_kernel_3 SK;
template class Sphere_intersecter<SK>; // explicit for "-fno-implicit-templates"
typedef Sphere_intersecter<SK> SI;
BOOST_PYTHON_MODULE(thickness_diag)
{
using namespace boost::python;
class_<SI>("SphereIntersecter", no_init)
.def("add_sphere", &SI::add_sphere)
;
}
和CMakeLists.txt:
cmake_minimum_required(VERSION 2.6.2)
project(ThicknessDiag-Python)
# CGAL
find_package(CGAL REQUIRED)
include(${CGAL_USE_FILE})
# Boost
find_package(Boost REQUIRED COMPONENTS python)
find_package(PythonLibs 2.7 REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${PYTHON_INCLUDE_DIRS})
# Shared library
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-implicit-templates")
set(ThicknessDiag-Python "thickness_diag")
add_library(${ThicknessDiag-Python} SHARED python_export.cpp)
set_target_properties(${ThicknessDiag-Python} PROPERTIES PREFIX "")
target_link_libraries(${ThicknessDiag-Python}
${PYTHON_LIBRARIES} ${Boost_LIBRARIES}
${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES})
编译命令的详细输出:
[100%] Building CXX object CMakeFiles/thickness_diag.dir/python_export.cpp.o
/usr/bin/c++ -Dthickness_diag_EXPORTS -DCGAL_USE_MPFR -DCGAL_USE_GMP -frounding-math -fno-implicit-templates -O3 -DNDEBUG -fPIC -isystem /usr/local/include -I/usr/include/python2.7 -o CMakeFiles/thickness_diag.dir/python_export.cpp.o -c /home/jmcomets/ThicknessDiag/tests/python_export.cpp
Linking CXX shared library thickness_diag.so
/usr/bin/c++ -fPIC -frounding-math -fno-implicit-templates -O3 -DNDEBUG -shared -Wl,-soname,thickness_diag.so -o thickness_diag.so CMakeFiles/thickness_diag.dir/python_export.cpp.o -L/usr/local/lib -lmpfr -lgmp /usr/local/lib/libCGAL.so /usr/local/lib/libboost_thread.so -lpthread /usr/local/lib/libboost_system.so -lpython2.7 /usr/local/lib/libboost_python.so /usr/local/lib/libCGAL.so /usr/local/lib/libboost_thread.so -lpthread /usr/local/lib/libboost_system.so -lpython2.7 /usr/local/lib/libboost_python.so -Wl,-rpath,/usr/local/lib
导入共享库的输出:
$ python -c 'import thickness_diag'
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: ./thickness_diag.so: undefined symbol: _ZN5boost6python9converter6detail15registered_baseIRVK18Sphere_intersecterIN4CGAL18Spherical_kernel_3INS5_9CartesianINS5_4GmpqEEENS5_32Algebraic_kernel_for_spheres_2_3IS8_EEEEEE10convertersE
$ nm thickness_diag.so | grep _ZN5boost6python9converter6detail15registered_baseIRVK18Sphere_intersecterIN4CGAL18Spherical_kernel_3INS5_9CartesianINS5_4GmpqEEENS5_32Algebraic_kernel_for_spheres_2_3IS8_EEEEEE10convertersE
U _ZN5boost6python9converter6detail15registered_baseIRVK18Sphere_intersecterIN4CGAL18Spherical_kernel_3INS5_9CartesianINS5_4GmpqEEENS5_32Algebraic_kernel_for_spheres_2_3IS8_EEEEEE10convertersE
过去两天我一直在努力解决这个问题,任何帮助都会很棒! :)
编辑:输出ldd
$ ldd thickness_diag.so
linux-vdso.so.1 => (0x00007fffdfdff000)
libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007fd91eadf000)
libCGAL.so.10 => /usr/local/lib/libCGAL.so.10 (0x00007fd91e8b4000)
libboost_thread.so.1.55.0 => /usr/local/lib/libboost_thread.so.1.55.0 (0x00007fd91e699000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd91e47c000)
libboost_system.so.1.55.0 => /usr/local/lib/libboost_system.so.1.55.0 (0x00007fd91e278000)
libpython2.7.so.1.0 => /usr/lib/libpython2.7.so.1.0 (0x00007fd91dd79000)
libboost_python.so.1.55.0 => /usr/local/lib/libboost_python.so.1.55.0 (0x00007fd91db2c000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fd91d829000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd91d612000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd91d253000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd91cf57000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fd91cd4e000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd91ef85000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fd91cb37000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd91c933000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fd91c72f000)
答案 0 :(得分:1)
$man nm
...
"U" The symbol is undefined.
这是什么意思?这是not there。
在ldd
上尝试so
。这将告诉您它使用的所有库。然后,您需要确保所有库都在LD_LIBRARY_PATH
答案 1 :(得分:1)
好吧我明白了。事实证明,选项-fno-implicit-templates
阻止了其正常模板实例化(这实际上是非常明显的)。
然后我又回到了我认为已修复的错误:undefined symbol: _ZN18Sphere_intersecterIN4CGAL18Spherical_kernel_3INS0_9CartesianINS0_4GmpqEEENS0_32Algebraic_kernel_for_spheres_2_3IS3_EEEEEC1ERKS8_ (./thickness_diag.so)
当通过c++filt翻译时,会给出:Sphere_intersecter<...> >::Sphere_intersecter(Sphere_intersecter<...> const&)
复制构造函数,未实现(不可复制的类)...
解决方案是删除将boost::noncopyable
参数添加到boost::python::class_
:
#include <boost/python.hpp>
#include <CGAL/Exact_spherical_kernel_3.h>
#include "Sphere_intersecter.h"
typedef CGAL::Exact_spherical_kernel_3 SK;
template class Sphere_intersecter<SK>;
typedef Sphere_intersecter<SK> SI;
BOOST_PYTHON_MODULE(thickness_diag)
{
using namespace boost::python;
class_<SI, boost::noncopyable>("SphereIntersecter")
.def("add_sphere", &SI::add_sphere)
;
}