将 CUDA 编译与使用 Boost 的代码链接起来的问题

Problems linking CUDA-compiled with Boost-using code

关于 CUDA-cum-Boost 交互的问题偶尔会在 SO 上弹出,但它们总是(?)关于 编译:CUDA 在 Boost 的巫术技巧方面遇到了麻烦。常识是将使用 Boost 的代码与 CUDA 编译的代码隔离。

所以,我这样做了:我正在编写一个小型 CUDA 实用程序,boost::program_options 很好地限制在单个 class 的实现中使用。我的问题在 linking.

我正在开发 Debian Stretch(64 位),它是用 GCC 5.x 构建的(这包括它的 Boost 1.58 软件包)。但是,我在本地安装的 CUDA 7.5 只能支持我使用的 gcc 4.9.x 或更早版本。编译所有内容后,未定义的引用仍然存在。也就是说,在我这样做之后:

/usr/bin/g++-4.9   -Wall -std=c++11  originally_cu.o originaly_cpp.o weird_cmake_generated_intermediate_link.o -o foo_app -rdynamic /usr/local/cuda/lib64/libcudart_static.a -lpthread -lrt -ldl -lboost_log -lboost_system -lboost_program_options /usr/local/cuda/lib64/libcudart_static.a -lpthread -lrt -ldl -lboost_log -lboost_system -lboost_program_options 

(CMake 生成的,我不确定为什么我会看到双 -ls)

我得到:

originally_cpp.o: In function `FooConfiguration::getFromProgramArguments(int, char**)':
FooConfiguration.cpp:(.text+0x5d4): undefined reference to `boost::program_options::options_description::options_description(std::string const&, unsigned int, unsigned int)'
FooConfiguration.cpp:(.text+0x6ca): undefined reference to `boost::program_options::options_description::options_description(std::string const&, unsigned int, unsigned int)'
FooConfiguration.cpp.o: In function `boost::program_options::validation_error::validation_error(boost::program_options::validation_error::kind_t, std::string const&, std::string const&, int)':
FooConfiguration.cpp:(.text._ZN5boost15program_options16validation_errorC2ENS1_6kind_tERKSsS4_i[_ZN5boost15program_options16validation_errorC5ENS1_6kind_tERKSsS4_i]+0x2e): undefined reference to `boost::program_options::validation_error::get_template(boost::program_options::validation_error::kind_t)'

等等。

我认为这可能与 Boost 是用 gcc 构建的事实有关 5.x ;所以,我下载了 Boost 1.60,用 gcc 4.9 构建它,并将它安装在 /opt/boost 下(编辑: 并将 /opt/boost/lib 添加到 `LD_LIBRARY_PATH) .但是当我尝试使用它时,好吧 - 它构建了,但是我在 Boost 中遇到了分段违规(而且我知道我不应该,因为相同的代码在另一台机器上运行,至少在解析命令行参数的时候) .这是来自 gdb 的回溯:

(gdb) bt
#0  0x00007fe9b8362880 in boost::program_options::validators::check_first_occurrence(boost::any const&) () from /opt/boost/lib/libboost_program_options.so.1.60.0
#1  0x000000000046c9d8 in void boost::program_options::validate<int, char>(boost::any&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, int*, long) ()
#2  0x000000000046be44 in boost::program_options::typed_value<int, char>::xparse(boost::any&, std::vector<std::string, std::allocator<std::string> > const&) const ()
#3  0x00007fe9b8347cda in boost::program_options::option_description::~option_description() () from /opt/boost/lib/libboost_program_options.so.1.60.0
#4  0x00007fe9b834d2b5 in boost::detail::sp_counted_impl_p<boost::program_options::option_description>::dispose() () from /opt/boost/lib/libboost_program_options.so.1.60.0
#5  0x00000000004616d4 in boost::detail::sp_counted_base::release() ()
#6  0x0000000000461763 in boost::detail::shared_count::~shared_count() ()
#7  0x0000000000468c4c in boost::shared_ptr<boost::program_options::option_description>::~shared_ptr() ()
#8  0x0000000000468c66 in void std::_Destroy<boost::shared_ptr<boost::program_options::option_description> >(boost::shared_ptr<boost::program_options::option_description>*) ()
#9  0x0000000000467c05 in void std::_Destroy_aux<false>::__destroy<boost::shared_ptr<boost::program_options::option_description>*>(boost::shared_ptr<boost::program_options::option_description>*, boost::shared_ptr<boost::program_options::option_description>*) ()
#10 0x0000000000465eeb in void std::_Destroy<boost::shared_ptr<boost::program_options::option_description>*>(boost::shared_ptr<boost::program_options::option_description>*, boost::shared_ptr<boost::program_options::option_description>*) ()
#11 0x0000000000464337 in void std::_Destroy<boost::shared_ptr<boost::program_options::option_description>*, boost::shared_ptr<boost::program_options::option_description> >(boost::shared_ptr<boost::program_options::option_description>*, boost::shared_ptr<boost::program_options::option_description>*, std::allocator<boost::shared_ptr<boost::program_options::option_description> >&) ()
#12 0x0000000000462ee3 in std::vector<boost::shared_ptr<boost::program_options::option_description>, std::allocator<boost::shared_ptr<boost::program_options::option_description> > >::~vector() ()
#13 0x0000000000461ccc in boost::program_options::options_description::~options_description() ()
#14 0x000000000045fb88 in FooConfiguration::getFromProgramArguments(int, char**) ()
#15 0x00000000004710e1 in get_configuration (argc=1, argv=0x7fff61fcb398) at /home/joeuser/foo_app/src/main.cu:257
#16 0x00000000004711f7 in main (argc=1, argv=0x7fff61fcb398) at /home/joeuser/foo_app/src/main.cu:269

这是本例中的 ldd 输出:

linux-vdso.so.1 (0x00007ffd4912f000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f06496e6000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f06494de000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f06492d9000)
libboost_log.so.1.60.0 => /opt/boost/lib/libboost_log.so.1.60.0 (0x00007f064901e000)
libboost_system.so.1.60.0 => /opt/boost/lib/libboost_system.so.1.60.0 (0x00007f0648e1b000)
libboost_program_options.so.1.60.0 => /opt/boost/lib/libboost_program_options.so.1.60.0 (0x00007f0648ba3000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f0648828000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0648523000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f064830c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0647f68000)
/lib64/ld-linux-x86-64.so.2 (0x000055a192443000)
libboost_atomic.so.1.60.0 => /opt/boost/lib/libboost_atomic.so.1.60.0 (0x00007f0647d66000)
libboost_date_time.so.1.60.0 => /opt/boost/lib/libboost_date_time.so.1.60.0 (0x00007f0647b54000)
libboost_filesystem.so.1.60.0 => /opt/boost/lib/libboost_filesystem.so.1.60.0 (0x00007f064793b000)
libboost_regex.so.1.60.0 => /opt/boost/lib/libboost_regex.so.1.60.0 (0x00007f064761e000)
libboost_thread.so.1.60.0 => /opt/boost/lib/libboost_thread.so.1.60.0 (0x00007f06473f9000)
libboost_chrono.so.1.60.0 => /opt/boost/lib/libboost_chrono.so.1.60.0 (0x00007f06471f3000)
libicudata.so.55 => /usr/lib/x86_64-linux-gnu/libicudata.so.55 (0x00007f064573c000)
libicui18n.so.55 => /usr/lib/x86_64-linux-gnu/libicui18n.so.55 (0x00007f06452d9000)
libicuuc.so.55 => /usr/lib/x86_64-linux-gnu/libicuuc.so.55 (0x00007f0644f45000)

所以:

显然这与 CUDA 无关,我可以通过 Boost 来解决问题。跟进 pertinent non-CUDA-related question。谢谢@Drop.