即使传递了 -fno-lto ,lld 也会运行 LTO

Sim*_*lli 7 c++ clang clang++ lto lld

我有一个 CMake 项目,其中有几个子项目,这些子项目创建使用-flto=thin.

该项目有很多与上述库相关的测试。使用 LTO 需要花费大量时间来构建测试,因此我已禁用 LTO 进行使用-fno-lto.

但我注意到,lld即使使用-fno-lto. 如果我运行链接器,--time-trace我可以看到大部分时间都花在了 LTO 上。

我的问题是:

  1. 这是预期的吗?如果是这样,我可以假设lld只要在它链接的对象中找到 LTO 信息,就会执行 LTO。
  2. 如果没有,有没有办法禁用这种行为?添加-fno-lto到编译器似乎不起作用,并且lld没有显式禁用 LTO 的参数。
  3. 如果不是,这是一个错误吗?

更新1:

这就是我lto在 CMake 中的处理方式:

# Enable Thin LTO only on non-test targets.
if(ENABLE_LTO)
  if (IS_TEST)
    target_compile_options(${TARGET} PRIVATE -fno-lto)
    # Probably pointless.
    target_link_options(${TARGET} PRIVATE -fno-lto)
  else()
    message(STATUS "ENABLE_LTO on target ${TARGET})")
    target_compile_options(${TARGET} PRIVATE -flto=thin)
    target_link_options(${TARGET} PRIVATE -flto=thin -Wl,--thinlto-cache-dir=${CMAKE_BINARY_DIR}/lto.cache)
  endif()
endif()
Run Code Online (Sandbox Code Playgroud)

Gos*_*low 3

如果您使用-flto编译库,那么至少对于 gcc 而言,目标文件将仅包含中间语言,而不包含二进制代码。

这意味着当您将它们链接到使用-fno-lto编译的测试用例时,没有可链接的二进制代码。链接器别无选择,只能首先将每个所需函数的中间语言编译为二进制文件,您将其视为 LTO 阶段。

在 gcc 中,有一个选项-ffat-lto-objects告诉 gcc 在目标文件中包含中间语言和二进制代码。然后它们可用于与 LTO 进行链接或不与 LTO 进行链接。缺点是这需要更长的时间来编译并生成更大的目标文件。

你必须检查 clang 是否有相同的选项,它们通常与选项非常兼容。