如何将lto与静态库一起使用?

Tav*_*nes 18 c++ gcc lto

当我尝试使用构建静态库时-flto,我得到未定义的引用错误:

library.cpp:

#include <iostream>

void foo() {
  std::cout << "Test!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

main.cpp:

void foo();

int main() {
  foo();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译输出:

$ g++ -flto -c library.cpp
$ ar rcs library.a library.o
$ g++ -flto main.cpp library.a
/tmp/ccZIgxCY.ltrans0.ltrans.o: In function `main':
ccZIgxCY.ltrans0.o:(.text+0x5): undefined reference to `foo()'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

如果我链接library.o而不是,它工作正常library.a.我错过了什么?这与GCC 4.9.1和binutils 2.24有关.

Tav*_*nes 22

正如我在GCC开发人员HonzaHubička的这篇文章中发现的那样,答案是使用gcc-ar包装而不是单独使用ar:

$ gcc-ar rcs library.a library.o
Run Code Online (Sandbox Code Playgroud)

这会调用ar正确的插件参数,在我的例子中是

--plugin /usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.1/liblto_plugin.so
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,如果你需要它们,还有`gcc-ranlib`和`gcc-nm`. (7认同)
  • @rodrigo 确实-似乎`ar` 只是图片的一部分。我还需要用 `gcc-ranlib` 覆盖,因为系统默认无法处理 LTO 对象。所以,因为似乎很难找到任何接近单线解决方案的东西:我让 LTO 工作如下:`./configure --prefix=/opt/testmake AR=gcc-ar RANLIB=gcc-ranlib CXXFLAGS=' -O3 -flto'` (2认同)

RJV*_*JVB 5

作为一个免费的答案:使用 GCC 还可以使用-ffat-lto-objects它向存档中的文件添加经典目标代码。这使得在不使用 -flto 的情况下构建的代码中使用静态库成为可能。

  • 问题是,当使用胖对象时,很难发现 LTO 失败的地方 (3认同)