有关CUDA-cum-Boost交互的问题偶尔会出现在SO上,但它们总是(?)关于编译:CUDA在使用Boost的巫术技巧方面遇到了麻烦。常识是使用Boost从CUDA编译的代码中隔离代码。
所以,我已经做到了这一点:我正在编写一个小型CUDA实用程序,其中boost::program_options
很有限地用于实现单个类。我的问题在于链接。
我正在使用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产生了这一点,我不确定为什么我会看到双-l
s)
我明白了:
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)
所以: