17

我是clang的新手,所以很可能我在做一些愚蠢的事情。但是我花了几个小时寻找解决方案,包括在这里搜索,在那里我没有找到解决 -flto 与发行版提供的软件包的问题。此描述的详细信息特定于 Fedora 18,但我在 Ubuntu 13.04 上遇到了类似的问题,因此问题并非特定于 Fedora。要么是我,要么是铿锵。

问题:我正在尝试编译一个简单的 hello-world 程序,clang++ -flto以获取链接时间优化的好处。没有 -flto 它工作正常。使用 -flto 无法链接。调用clang -flto -o hello hello.o -v以查看完整的链接器命令行,我得到:

$ clang++ -flto -o hello hello.o -v
clang version 3.2 (tags/RELEASE_32/final)
Target: x86_64-redhat-linux-gnu
Thread model: posix
 "/usr/bin/ld" --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o hello /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2 -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../.. -L/lib -L/usr/lib -plugin /usr/bin/../lib/LLVMgold.so hello.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crtn.o
/usr/bin/ld: /usr/bin/../lib/LLVMgold.so: error loading plugin
/usr/bin/ld: /usr/bin/../lib/LLVMgold.so: error in plugin cleanup (ignored)
clang: error: linker command failed with exit code 1 (use -v to see invocation)

似乎有两个问题:

  1. clang++ 将链接器调用为/usr/bin/ld,这不是黄金链接器。Fedora18 将黄金安装为/usr/bin/ld.gold. 我试过从/usr/local/bin/ldto创建一个符号链接/usr/bin/ld.gold,验证which ld/usr/local/bin/ld,但 clang++ 不使用它。它似乎是硬连线到/usr/bin/ld。

  2. clang++ 使用-plugin /usr/bin/../lib/LLVMgold.so. 这是错误的,因为铿锵的 Fedora 发行版将它放在/usr/lib64/llvm/LLVMgold.so.

我尝试通过以下调整手动调用上面的链接器行:

  • 替换-plugin /usr/bin/../lib/LLVMgold.so-plugin /usr/lib64/llvm/LLVMgold.so。这会产生错误消息hello.o: file not recognized: File format not recognized。因此,非黄金链接器似乎了解插件,但不会采用包含 LLVM 位码的 .o。

  • 替换/usr/bin/ld/usr/bin/ld.gold。这有效,生成按预期运行的可执行文件。

  • 以上两者都用--plugin而不是-plugin。这种变化没有任何区别。

那么对于喜欢坚持使用系统提供的软件包来使用 clang -flto 的人来说,最好的方法是什么?我希望有一个配置文件,或未记录的选项或环境变量可以让我覆盖这些。或者更好的是,我缺少一个包,“yum install ...”将修复它。

我不希望直接调用链接器,因为这样我的 makefile 需要知道他们应该不知道的系统对象和库(例如 crt1.o、crtbegin.o、crtend.o)。我也可以自己构建 clang,但我在它的配置脚本中没有看到任何可以让我配置链接器和插件路径的东西。

我正在运行 Fedora 18。计算机上唯一的非发行版软件包是 google chrome 和 VMware Tools(它是 VMWare Fusion 中的访客)。相关 Fedora 软件包的版本(截至今天,2013 年 4 月 29 日,整台计算机已“yum 更新”):

$ yum list --noplugins installed binutils* clang* llvm* gcc*
Installed Packages
binutils.x86_64                      2.23.51.0.1-6.fc18                 @updates
binutils-devel.x86_64                2.23.51.0.1-6.fc18                 @updates
clang.x86_64                         3.2-2.fc18                         @updates
clang-devel.x86_64                   3.2-2.fc18                         @updates
clang-doc.noarch                     3.2-2.fc18                         @updates
gcc.x86_64                           4.7.2-8.fc18                       @fedora 
gcc-c++.x86_64                       4.7.2-8.fc18                       @fedora 
llvm.x86_64                          3.2-2.fc18                         @updates
llvm-libs.x86_64                     3.2-2.fc18                         @updates
4

1 回答 1

8

Fedora 中有一个实用程序alternatives- 它允许在系统级别用另一个链接器替换一个链接器:

$ sudo alternatives --display ld
ld - status is auto.
link currently points to /usr/bin/ld.bfd
/usr/bin/ld.bfd - priority 50
/usr/bin/ld.gold - priority 30
Current `best' version is /usr/bin/ld.bfd.
$ sudo alternatives --set ld /usr/bin/ld.gold

关于 LLVMgold.so 位置,您只能在 Fedora Bugzilla 中报告错误,因为路径是内置在 clang 源中的:

lib/Driver/Tools.cpp: std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so";

Fedora 的家伙可能会为 Clang 的源代码包应用补丁,或者创建到 LLVMgold.so 的符号链接。即使在 Fedora 20 中也没有任何变化。

于 2013-11-11T06:25:21.693 回答