【问题标题】:Problems linking CUDA-compiled with Boost-using code将 CUDA 编译的代码与使用 Boost 的代码链接的问题
【发布时间】:2016-01-23 23:57:09
【问题描述】:

关于 CUDA-cum-Boost 交互的问题偶尔会出现在她的 SO 上,但它们总是(?)关于编译:CUDA 在 Boost 的巫术技巧上遇到了麻烦。普遍的看法是将使用 Boost 的代码与 CUDA 编译的代码隔离开来。

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

我正在开发使用 GCC 5.x 构建的 Debian Stretch(64 位)(其中包括其 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)

所以:

  • 是什么导致了这些问题?
  • 除了不使用 Boost,我还能做些什么来解决或规避它们?

【问题讨论】:

  • 真的和CUDA没有关系。如果您动态链接 boost,它可能仍会在运行时使用 GCC5 .so 库(如果它在您的 GCC4 库之前找到 ldpath 中的库)。从而崩溃。 debian 上的 CUDA 也是 Nvidia 的not officially supported。您可以获得的最佳支持配置是 Fedora 21 上的 4.9.2。
  • 最好提供MCVE(即使没有CUDA)。 “它在另一台机器上运行”一点也不令人信服,你的程序中仍然可以有 UB。
  • ldd 告诉你什么?这听起来像是一个可以用 LD_LIBRARY_PATH 解决的问题,与 CUDA 无关。完全没有。
  • @talonmies:见编辑。
  • @Drop:我知道切换发行版是一种选择,但你会同意这是一个非常糟糕的选择......另外,当使用系统库时,静态链接器是失败的是什么,而不是动态的。至于 Boost 1.60 的案例 - 您可以从回溯中看到 Boost 编译的文本 is 被发现并使用,但由于某种原因崩溃。

标签: c++ boost cuda static-linking abi


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-31
    • 2011-06-03
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    相关资源
    最近更新 更多