即使传递了 -fno-lto,lld 也会运行 LTO
lld runs LTO even if -fno-lto is passed
我有一个包含多个子项目的 CMake 项目,这些子项目创建了使用 -flto=thin
构建的静态库。
该项目有很多链接到上述库的测试。使用 LTO 构建测试需要花费大量时间,因此我使用 -fno-lto
.
禁用了 LTO 测试
不过我注意到,lld
即使使用 -fno-lto
也会在测试中执行 LTO。如果我 运行 带有 --time-trace
的链接器,我可以看到大部分时间都花在了 LTO 上。
我的问题是:
- 这是预期的吗?如果是这样,我可以假设
lld
在它链接的对象中找到 LTO 信息时执行 LTO。
- 如果没有,是否有办法禁用此行为?将
-fno-lto
添加到编译器似乎不起作用,并且 lld
没有明确禁用 LTO 的参数。
- 如果不是,这是一个错误吗?
更新 1:
这是我在 CMake 中处理 lto
的方式:
# 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()
如果你用 -flto 编译库,那么至少对于 gcc 来说,目标文件将只包含中间语言而不包含二进制代码。
这意味着当您 link 将它们放入用 -fno-lto 编译的测试用例时,没有二进制代码到 link 。 linker 别无选择,只能先将中间语言编译成二进制文件,用于每个需要的功能,您可以将其视为 LTO 阶段。
在 gcc 中有一个选项 -ffat-lto-objects 告诉 gcc 在目标文件中包括中间语言和二进制代码。然后,无论是否使用 LTO,它们都可以用于 linking。缺点是这需要更长的时间来编译并生成更大的目标文件。
你必须检查 clang 是否有相同的选项,它们通常与选项兼容。
我有一个包含多个子项目的 CMake 项目,这些子项目创建了使用 -flto=thin
构建的静态库。
该项目有很多链接到上述库的测试。使用 LTO 构建测试需要花费大量时间,因此我使用 -fno-lto
.
不过我注意到,lld
即使使用 -fno-lto
也会在测试中执行 LTO。如果我 运行 带有 --time-trace
的链接器,我可以看到大部分时间都花在了 LTO 上。
我的问题是:
- 这是预期的吗?如果是这样,我可以假设
lld
在它链接的对象中找到 LTO 信息时执行 LTO。 - 如果没有,是否有办法禁用此行为?将
-fno-lto
添加到编译器似乎不起作用,并且lld
没有明确禁用 LTO 的参数。 - 如果不是,这是一个错误吗?
更新 1:
这是我在 CMake 中处理 lto
的方式:
# 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()
如果你用 -flto 编译库,那么至少对于 gcc 来说,目标文件将只包含中间语言而不包含二进制代码。
这意味着当您 link 将它们放入用 -fno-lto 编译的测试用例时,没有二进制代码到 link 。 linker 别无选择,只能先将中间语言编译成二进制文件,用于每个需要的功能,您可以将其视为 LTO 阶段。
在 gcc 中有一个选项 -ffat-lto-objects 告诉 gcc 在目标文件中包括中间语言和二进制代码。然后,无论是否使用 LTO,它们都可以用于 linking。缺点是这需要更长的时间来编译并生成更大的目标文件。
你必须检查 clang 是否有相同的选项,它们通常与选项兼容。