Boost.Python模块中未定义的符号

时间:2013-07-23 09:22:37

标签: c++ cmake boost-python

我正在尝试使用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)

2 个答案:

答案 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)
    ;
}