CSDN搬家失败,手动导出markdown后再导入博客园
因为一些原因,楼主想在 Apollo 自动驾驶框架里使用 Boost.python 工具来用 C++ 调用 Python,从网上找了个例子想编译下试试。
C++ 代码如下(boost.python/EmbeddingPython - Python Wiki):
#include <boost/python.hpp>
using namespace boost::python;
int main( int argc, char ** argv ) {
try {
Py_Initialize();
object main_module((
handle<>(borrowed(PyImport_AddModule("__main__")))));
object main_namespace = main_module.attr("__dict__");
handle<> ignored(( PyRun_String( "print (\"Hello, World\")",
Py_file_input,
main_namespace.ptr(),
main_namespace.ptr() ) ));
} catch( error_already_set ) {
PyErr_Print();
}
}
BUILD 文件如下:
cc_binary(
name = "hello",
srcs = [
"hello.cc",
],
deps = [
#"@local_config_python//:python_headers",
#"@local_config_python//:python_lib",
"@boost",
],
)
一开始没有引入 local_config_python 的两个依赖,导致出现
(01:50:17) ERROR: /apollo/modules/zj_prediction/BUILD:52:10: Linking of rule '//modules/zj_prediction:hello' failed (Exit 1): crosstool_wrapper_driver_is_not_gcc failed: error executing command external/local_config_cuda/crosstool/clang/bin/crosstool_wrapper_driver_is_not_gcc @bazel-out/k8-opt/bin/modules/zj_prediction/hello-2.params
bazel-out/k8-opt/bin/modules/zj_prediction/_objs/hello/hello.o: In function `main':
hello.cc:(.text.startup.main+0x3c): undefined reference to `boost::python::api::object::object(boost::python::handle<_object> const&)'
hello.cc:(.text.startup.main+0x75): undefined reference to `boost::python::api::getattr(boost::python::api::object const&, char const*)'
hello.cc:(.text.startup.main+0xe8): undefined reference to `boost::python::throw_error_already_set()'
hello.cc:(.text.startup.main+0xf2): undefined reference to `boost::python::throw_error_already_set()'
hello.cc:(.text.startup.main+0x126): undefined reference to `vtable for boost::python::error_already_set'
hello.cc:(.text.startup.main+0x141): undefined reference to `boost::python::error_already_set::~error_already_set()'
hello.cc:(.text.startup.main+0x15f): undefined reference to `boost::python::error_already_set::~error_already_set()'
bazel-out/k8-opt/bin/modules/zj_prediction/_objs/hello/hello.o:(.data.rel.local.DW.ref._ZTIN5boost6python17error_already_setE[DW.ref._ZTIN5boost6python17error_already_setE]+0x0): undefined reference to `typeinfo for boost::python::error_already_set'
collect2: error: ld returned 1 exit status
去掉注释后就好了。
然后使用 bazel 编译这个模块时出现了报错信息
load("@rules_cc//cc:defs.bzl", "cc_library")
licenses(["notice"])
package(default_visibility = ["//visibility:public"])
# TODO(all): May use rules_boost.
cc_library(
name = "boost",
includes = ["."],
linkopts = [
"-L/opt/apollo/sysroot/lib",
"-lboost_filesystem",
"-lboost_program_options",
"-lboost_regex",
"-lboost_system",
"-lboost_thread",
# "-lboost_python36", 一开始没有
],
)
看报错信息大概意思是 boost 找不到包里的 Python 库,为此上网找了一下午都没解决,后来突然发现是因为楼主的环境配置跟别人不一样,lib 的名字不同当然不能直接复制解决了,下面说一下解决思路。
主要参考的是 Add boost library as Bazel dependency c++ - Stack Overflow
Since you're linking your executable to Boost Python/Numpy, you also need to provide Python symbols.
If you don't need Python, the easiest solution is add libboost_numpy.so
to exclude
in your glob. If you actually need Python, a quick fix would be to add -lpython
to linkopts
in BOOST.build
(this is not a solution that I would recommend for production, since you have no control over Python versions, etc..)
里面提到要在 BOOST.build里面加入-lpython,
还有對 boost::python::detail::init_module 和 friend 的 undefined reference - C++ _程式人
我添加了兩個額外的標誌來增強效果,然後就可以了!
-lboost_python -lboost_system
里面提到加入的是 - lboost_python,我两种都试了一下发现不行,于是开始思考人生。
先看下我的 boost.BUILD 文件是什么样的:
load("@rules_cc//cc:defs.bzl", "cc_library")
licenses(["notice"])
package(default_visibility = ["//visibility:public"])
# TODO(all): May use rules_boost.
cc_library(
name = "boost",
includes = ["."],
linkopts = [
"-L/opt/apollo/sysroot/lib",
"-lboost_filesystem",
"-lboost_program_options",
"-lboost_regex",
"-lboost_system",
"-lboost_thread",
# "-lboost_python36", 一开始没有
],
)
直接在 linkopts 里面加上这两种 - l 都没用,于是急需谷歌搜 bazel cannot find -lboost_python,然后出现这一条:
https://stackoverflow.com/questions/65675412/bazel-build-cannot-find-shared-library,里面提到了-L/usr/local/lib
Bazel likes to use the gold linker instead of GNU ld by default. gold, unlike GNU ld, doesn't put /usr/local/lib
on the default library search path. This can be remediated by passing --linkopt=-L/usr/local/lib
to Bazel.
然后猛然发现自己的 boost.BUILD 文件里面有一行 "-L/opt/apollo/sysroot/lib", 这明显是跟上面提到的-L/usr/local/lib
起相同的作用,于是
ll /opt/apollo/sysroot/lib/
发现下面有很多 libboost***,然后果然找到了一个
/opt/apollo/sysroot/lib/libboost_python36.so -> libboost_python36.so.1.74.0*
所以合理猜测在我的环境里,并不是 -lboost_python,而应该是 -lboost_python36!!!
在 boost.BUILD 文件里加入这行后,顺利编译成功,实现了 C++ 调用 Python 输出
Hello, World
标签:lboost,undefined,reference,python,cc,main,boost,hello
From: https://www.cnblogs.com/algorithmSpace/p/18200242