LLVM gold 插件

简介

使用链接时优化构建需要系统链接器的配合。Linux 系统上的 LTO 支持通过 gold 链接器 提供,它通过插件支持 LTO。这与 GCC LTO 项目使用的机制相同。

LLVM gold 插件在 libLTO 之上实现了 gold 插件接口。相同的插件也可以被其他工具使用,例如 arnm。请注意,来自 binutils 版本 2.21.51.0.2 及更高版本的 ld.bfd 也通过插件支持 LTO。但是,LLVM gold 插件与 ld.bfd 的使用未经测试,因此未获得官方支持或推荐。

从 LLVM 15 开始,gold 插件将忽略来自 ELF 目标文件内部 .llvmbc 区段的位代码。但是,仍然支持使用位代码文件的 LTO。

如何构建它

你需要拥有带有插件支持的 gold 并构建 LLVMgold 插件。gold 链接器安装为 ld.gold。要查看 gold 是否是系统上的默认链接器,请运行 /usr/bin/ld -v。如果不是,它将报告 “GNU gold”,否则报告 “GNU ld”。如果 gold 已经安装在 /usr/bin/ld.gold,一种选择是简单地将其设为默认链接器,方法是备份你现有的 /usr/bin/ld 并使用 ln -s /usr/bin/ld.gold /usr/bin/ld 创建一个符号链接。或者,你可以使用 clang 的 -fuse-ld=gold 构建,或将 -fuse-ld=gold 添加到 LDFLAGS,这将导致 clang 驱动程序直接调用 /usr/bin/ld.gold

如果你已安装 gold,请通过运行 /usr/bin/ld.gold -plugin 检查插件支持。如果它提示 “missing argument”(缺少参数),则你具有插件支持。如果不是,并且你收到诸如 “unknown option”(未知选项)之类的错误,那么你需要构建 gold 或安装具有插件支持的版本。

  • 下载、配置和构建带有插件支持的 gold

    $ git clone --depth 1 git://sourceware.org/git/binutils-gdb.git binutils
    $ mkdir build
    $ cd build
    $ ../binutils/configure --enable-gold --enable-plugins --disable-werror
    $ make all-gold
    

    这应该会给你留下 build/gold/ld-new,它支持 -plugin 选项。运行 make 还会额外构建支持插件的 build/binutils/arnm-new 二进制文件。

    一旦你准备好切换到使用 gold,备份你现有的 /usr/bin/ld,然后用 ld-new 替换它。或者,安装在 /usr/bin/ld.gold 中,并使用 -fuse-ld=gold,如前所述。

    可选地,将 --enable-gold=default 添加到上面的配置调用中,以使用 make install 自动安装新构建的 gold 作为默认链接器。

  • 构建 LLVMgold 插件。运行带有 -DLLVM_BINUTILS_INCDIR=/path/to/binutils/include 的 CMake。正确的包含路径将包含文件 plugin-api.h

用法

你应该使用选项 -fltoclang 生成位代码文件。此标志还将导致 clang 在其前缀下的 lib 目录中查找 gold 插件,并将 -plugin 选项传递给 ld。如果没有 -fuse-ld=gold,它将不会查找备用链接器,这就是为什么你还需要 gold 成为路径中已安装的系统链接器的原因。

arnm 也接受 -plugin 选项,并且可以将 LLVMgold.so 安装到 /usr/lib/bfd-plugins 以实现无缝设置。如果你构建了自己的 gold,请务必将你构建的 arnm-new 安装到 /usr/bin

快速入门:将 LTO 用于 autotooled 项目

一旦你的系统 ldarnm 都支持 LLVM 位代码,一切都已就绪,可以轻松构建 autotooled 项目的 LTO

  • 按照 关于如何构建 LLVMgold.so 的说明进行操作。

  • 将新构建的 binutils 安装到 $PREFIX

  • Release/lib/LLVMgold.so 复制到 $PREFIX/lib/bfd-plugins/

  • 设置环境变量($PREFIX 是你安装 clang 和 binutils 的位置)

    export CC="$PREFIX/bin/clang -flto"
    export CXX="$PREFIX/bin/clang++ -flto"
    export AR="$PREFIX/bin/ar"
    export NM="$PREFIX/bin/nm"
    export RANLIB=/bin/true #ranlib is not needed, and doesn't support .bc files in .a
    
  • 或者你可以直接设置你的路径

    export PATH="$PREFIX/bin:$PATH"
    export CC="clang -flto"
    export CXX="clang++ -flto"
    export RANLIB=/bin/true
    
  • 像往常一样配置和构建项目

    % ./configure && make && make check
    

环境变量设置也可能适用于非 autotooled 项目,但你可能还需要设置 LD 环境变量。

许可

Gold 在 GPLv3 许可下获得许可。LLVMgold 使用来自 gold 的接口文件 plugin-api.h,这意味着生成的 LLVMgold.so 二进制文件也受 GPLv3 约束。这仍然可以像 gold 在没有插件的情况下一样,用于链接非 GPLv3 程序。