无法加载 Boost.Python 模块 - 未定义的符号
Can't load Boost.Python module - undefined symbols
我有一个用 C 编写的库,需要从 Python 访问,所以我使用 Boost.Python 包装了它。我可以毫无问题地将我的库编译成 Boost .so 文件,但是当我尝试将它加载到 Python(使用 import tropmodboost
)时,出现以下错误:
ImportError: ./tropmodboost.so: undefined symbol: _Z12simplex_freeP7simplex
我 found out that this is a common 错误,它通常可以通过在我的 g++ 链接器调用中重新排序 -l
指令来修复,但据我所知,我的已经没问题了。
这是我的 Makefile 的文本,它是 Ubuntu 上的 运行:
# location of the Python header files
PYTHON_VERSION = 2.7
PY_VER2 = 27
# various include directories, used separately in different compiler tasks
PYN_INC = /usr/include/python$(PYTHON_VERSION)
IGH_INC = /usr/local/include/igraph
BST_INC = /usr/include
# library locations for linking
LS = -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -L/usr/lib/python$(PYTHON_VERSION)/config
lS = -lboost_python-py$(PY_VER2) -lpython$(PYTHON_VERSION)
# source files for different compiler tasks
CORE_SRC = permutation_src.c permutation_parity.c split.c simplex.c simplex_src.c build_complex.c
TEST_SRC = main.c tests/tests.c -ligraph -lm
# objects for linking the core to the boost module
CORE_OBJS = permutation_src.o permutation_parity.o split.o simplex.o simplex_src.o build_complex.o
.PHONY: clean tests
main: tropmod.boost.o
g++ -shared -Wl,--export-dynamic tropmod.boost.o $(LS) $(lS) $(CORE_OBJS) -o tropmodboost.so
tropmod.boost.o: tropmod.boost.cpp tmstuff
g++ -I$(PYN_INC) -I$(BST_INC) -I$(IGH_INC) -fPIC -c tropmod.boost.cpp
tmstuff: main.c permutation_src.c permutation_parity.c split.c simplex.c simplex_src.c tests/tests.c
gcc -I. -I=$(IGH_INC) -fPIC -c $(CORE_SRC)
debug: main.c permutation_src.c permutation_parity.c split.c simplex.c simplex_src.c tests/tests.c
gcc -I. -I=$(IGH_INC) -g -fPIC -c $(CORE_SRC)
tests:
gcc -I. -I=$(IGH_INC) -g -o tmtest $(CORE_SRC) $(TEST_SRC) -L/usr/local/lib -ligraph -lm
clean:
rm *.o *.so
调用ldd tropmodboost.so
输出:
linux-vdso.so.1 => (0x00007ffff79a3000)
libpython2.7.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0 (0x00007f34ea732000)
libboost_python-py27.so.1.58.0 => /usr/lib/x86_64-linux-gnu/libboost_python-py27.so.1.58.0 (0x00007f34ea4e6000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f34ea163000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f34e9f4d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f34e9b84000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f34e9966000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f34e974c000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f34e9548000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f34e9344000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f34e903b000)
/lib64/ld-linux-x86-64.so.2 (0x0000561fcfee3000)
这是 .hpp 文件中的一个例外,它显示了 Boost 包装器代码本身:
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/list.hpp>
#include <boost/python/object.hpp>
[...]
BOOST_PYTHON_MODULE(tropmodboost) {
using namespace boost::python;
class_<ConfigSpace>("ConfigSpace", init<int, int>())
.def("destroy", &ConfigSpace::destroy)
.def("getTraceOfPerm", &ConfigSpace::getTraceOfPerm)
;
}
在我的一些目标文件上 运行 nm
之后,我发现未定义的符号 _Z12simplex_freeP7simplex
在 simplex.o 中被定义为 simplex_free
,大概是因为它是使用 gcc 从 simplex.c 编译而来的。换句话说,我认为 gcc 和 g++ 的命名方式彼此不同,所以我将所有内容都切换为 g++ 并将我的 C 代码编译为 C++,这解决了这个问题。
我有一个用 C 编写的库,需要从 Python 访问,所以我使用 Boost.Python 包装了它。我可以毫无问题地将我的库编译成 Boost .so 文件,但是当我尝试将它加载到 Python(使用 import tropmodboost
)时,出现以下错误:
ImportError: ./tropmodboost.so: undefined symbol: _Z12simplex_freeP7simplex
我 found out that this is a common 错误,它通常可以通过在我的 g++ 链接器调用中重新排序 -l
指令来修复,但据我所知,我的已经没问题了。
这是我的 Makefile 的文本,它是 Ubuntu 上的 运行:
# location of the Python header files
PYTHON_VERSION = 2.7
PY_VER2 = 27
# various include directories, used separately in different compiler tasks
PYN_INC = /usr/include/python$(PYTHON_VERSION)
IGH_INC = /usr/local/include/igraph
BST_INC = /usr/include
# library locations for linking
LS = -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -L/usr/lib/python$(PYTHON_VERSION)/config
lS = -lboost_python-py$(PY_VER2) -lpython$(PYTHON_VERSION)
# source files for different compiler tasks
CORE_SRC = permutation_src.c permutation_parity.c split.c simplex.c simplex_src.c build_complex.c
TEST_SRC = main.c tests/tests.c -ligraph -lm
# objects for linking the core to the boost module
CORE_OBJS = permutation_src.o permutation_parity.o split.o simplex.o simplex_src.o build_complex.o
.PHONY: clean tests
main: tropmod.boost.o
g++ -shared -Wl,--export-dynamic tropmod.boost.o $(LS) $(lS) $(CORE_OBJS) -o tropmodboost.so
tropmod.boost.o: tropmod.boost.cpp tmstuff
g++ -I$(PYN_INC) -I$(BST_INC) -I$(IGH_INC) -fPIC -c tropmod.boost.cpp
tmstuff: main.c permutation_src.c permutation_parity.c split.c simplex.c simplex_src.c tests/tests.c
gcc -I. -I=$(IGH_INC) -fPIC -c $(CORE_SRC)
debug: main.c permutation_src.c permutation_parity.c split.c simplex.c simplex_src.c tests/tests.c
gcc -I. -I=$(IGH_INC) -g -fPIC -c $(CORE_SRC)
tests:
gcc -I. -I=$(IGH_INC) -g -o tmtest $(CORE_SRC) $(TEST_SRC) -L/usr/local/lib -ligraph -lm
clean:
rm *.o *.so
调用ldd tropmodboost.so
输出:
linux-vdso.so.1 => (0x00007ffff79a3000)
libpython2.7.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0 (0x00007f34ea732000)
libboost_python-py27.so.1.58.0 => /usr/lib/x86_64-linux-gnu/libboost_python-py27.so.1.58.0 (0x00007f34ea4e6000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f34ea163000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f34e9f4d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f34e9b84000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f34e9966000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f34e974c000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f34e9548000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f34e9344000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f34e903b000)
/lib64/ld-linux-x86-64.so.2 (0x0000561fcfee3000)
这是 .hpp 文件中的一个例外,它显示了 Boost 包装器代码本身:
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/list.hpp>
#include <boost/python/object.hpp>
[...]
BOOST_PYTHON_MODULE(tropmodboost) {
using namespace boost::python;
class_<ConfigSpace>("ConfigSpace", init<int, int>())
.def("destroy", &ConfigSpace::destroy)
.def("getTraceOfPerm", &ConfigSpace::getTraceOfPerm)
;
}
在我的一些目标文件上 运行 nm
之后,我发现未定义的符号 _Z12simplex_freeP7simplex
在 simplex.o 中被定义为 simplex_free
,大概是因为它是使用 gcc 从 simplex.c 编译而来的。换句话说,我认为 gcc 和 g++ 的命名方式彼此不同,所以我将所有内容都切换为 g++ 并将我的 C 代码编译为 C++,这解决了这个问题。