百度Apollo使用bazel编译C++ Boost依赖出现undefined reference to `boost::python::api::object::object(boost::pyth

7 篇文章 0 订阅
3 篇文章 0 订阅

因为一些原因,楼主想在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的两个依赖,导致出现

external/boost/boost/python/detail/wrap_python.hpp:50:11: fatal error: 'pyconfig.h' file not found

去掉注释后就好了。 

然后使用bazel编译这个模块时出现了报错信息

(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

看报错信息大概意思是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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值