我是 clang 的新手,所以很可能我在做一些愚蠢的事情。但我花了几个小时寻找解决方案,包括在这里搜索,我没有找到使用发行版提供的软件包解决 -flto 问题的问题。此描述的详细信息特定于 Fedora 18,但我在 Ubuntu 13.04 上遇到类似的问题,因此该问题并非特定于 Fedora。要么是我,要么是 clang。
问题:我正在尝试使用 clang++ -flto
编译一个简单的 hello-world 程序,以获得链接时间优化的好处。没有 -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)
似乎有两个问题:
clang++ 将链接器调用为
/usr/bin/ld
,但这不是黄金链接器。 Fedora18 将 gold 安装为/usr/bin/ld.gold
。我尝试创建从/usr/local/bin/ld
到/usr/bin/ld.gold
的符号链接(symbolic link),并验证了which ld
> 表示/usr/local/bin/ld
,但 clang++ 不使用它。它似乎硬连线到/usr/bin/ld。clang++ 使用
-plugin/usr/bin/../lib/LLVMgold.so
调用链接器。这是错误的,因为 clang 的 Fedora 发行版将其放置在/usr/lib64/llvm/LLVMgold.so
。
我尝试通过以下调整手动调用上面的链接器行:
将
-plugin/usr/bin/../lib/LLVMgold.so
替换为-plugin/usr/lib64/llvm/LLVMgold.so
。这会产生错误消息hello.o:文件无法识别:文件格式无法识别
。因此,非黄金链接器似乎了解插件,但不会采用包含 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 中的 guest )。相关 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
最佳答案
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 的符号链接(symbolic link)。 即使在 Fedora 20 中也没有任何变化。
关于linker - Clang 链接时优化在 Fedora 18 上无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16290952/