【问题标题】:NVCC attempting to link unnecessary objectsNVCC 试图链接不必要的对象
【发布时间】:2014-12-25 17:08:26
【问题描述】:

我有一个正在使用 CUDA 运行的项目。由于各种原因,它需要在有或没有 GTK 支持的情况下编译可执行文件,而不重新编译所有相关文件。在 C 语言下,我通过将对象的基本版本编译为 *.o 并将对象的 GTK 版本编译为 *.gtk.o 来实现这一点。因此,我可以链接到该库,如果它需要使用 GTK,它将引入这些功能(及其要求);如果不是,它就不会接触那些物体。

转换为nvcc 导致了一些问题:它在始终或从不 GTK 模式下工作;但是如果我用额外的 GTK 对象编译库,它会拒绝忽略它们并链接一个 GTKless 可执行文件。 (它因无法找到我调用的 cairo 函数而失败。)

我猜nvcc 正在链接到(至少一个)嵌入在对象中的辅助函数,这导致链接器解析整个对象。

运行ar d <lib> <objects.gtk.o> 以手动从库中删除它们将“修复”问题,因此那里没有真正的依赖关系。

我正在编译/链接

/usr/local/cuda/bin/nvcc --compiler-options -Wall --compiler-options -pipe 
        -rdc=true -O0 -g -G -I inc -I inc/ext -arch compute_20 -o program 
        program.cu obs/external.o libs/base.a libs/extra.a libs/core.a -lm

如何让 nvcc 忽略不需要的对象?

【问题讨论】:

  • 我对这个问题感到困惑。您的既定目标是在有或没有 GTK 支持的情况下编译应用程序。您还说,“它在始终或从不 GTK 模式下工作”,这向我表明您已经实现了目标。所以我不确定你在问什么。实际上,一种方便的方法是将所有引用 GTK 的对象文件收集到 mylib_GTK.a 中,将所有不引用 GTK 的对象文件收集到 mylib.a 中,然后将您的应用程序与两个库中的相应库链接。
  • 就像,如果我用 GTK 编译库,然后用它们在 GTK 模式下编译,它就可以工作。同样,如果两者都没有编译,它就可以工作。但是,如果库是用 GTK 编译的,没有它我就无法编译我的应用程序。是的,将两个分开在技术上是可行的,但强烈不推荐。我已经证明,当使用 gcc(无 CUDA)完成此操作时,这是有效的,因为未使用的代码不包含在最终的可执行文件中。
  • 如果我理解正确,您正在寻找一种在链接静态库时积极删除未使用的对象模块的链接器优化?除了膨胀的可执行文件大小之外,在可执行文件中包含未使用的目标代码是否存在问题(我想不出任何代码,因为应用程序不使用该代码)。考虑向 NVIDIA 提交增强请求,以使 nvcc 的行为更类似于 gcc。

标签: c++ linux cuda linker nvcc


【解决方案1】:

如何让 nvcc 忽略不需要的对象?

在实现这一目标之前,您需要了解是哪个符号导致 *.gtk.o 对象在不应该被从库中拉入时。

这样做的方法是使用-Wl,--print-map 运行链接,并查找链接器消息,例如:

Archive member included because of file (symbol)
libfoo.a(foo.o)               main.o (foo)

上面,main.o 引用了foo,它在libfoo.a(foo.o) 中定义,导致foo.o 被拉入主二进制文件。

一旦您知道哪些符号会导致xxxx.gtk.o 被拉入链接,搜索网络和/或 NVidia 文档可能会找到摆脱它们的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 2014-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多