CMP0156

在版本 3.29 中添加。

基于链接器功能在链接行上去除重复的库。

传统的链接器在链接期间维护一组未定义的符号。链接器按照它们在命令行中出现的顺序处理每个文件,直到未定义符号集为空。当遇到目标文件时,它会被链接到输出对象中,其未定义的符号会被添加到集合中。当遇到归档文件时,传统的链接器会搜索其中包含的对象,并处理那些满足未解析集合中符号的对象。

当使用传统的链接器时,处理相互依赖的归档文件可能会很麻烦。归档文件可能必须多次指定。

一些链接器(例如 Apple 或 Windows 链接器,以及 LLVM LLD)在迭代命令行参数时记录在对象和归档文件中找到的所有符号。当这些链接器之一遇到一个未定义的符号,该符号可以通过先前处理的归档文件中包含的目标文件来解析时,它会立即提取该目标文件并将其链接到输出对象中。

CMake 3.28 及更低版本可能会生成重复静态库的链接行,就像传统的链接器需要的那样,即使在使用不需要它的链接器时也是如此。它们也可能通过保留共享库的最后一次出现来去除重复项,这在 Windows 平台上可能会更改 DLL 加载顺序。

CMake 3.29 及更高版本倾向于根据链接器功能应用不同的策略。因此,当以 Apple 和 Windows 平台为目标时,所有库都会被去重。此外,在 Windows 平台上,库通过保留它们的第一次出现来去重,从而尊重项目指定的顺序。此策略提供与尚未更新以期望后一种行为的项目的兼容性。

注意

当此策略设置为 NEW 时,策略 CMP0179 控制在去重时保留静态库的哪个实例。

此策略的 OLD 行为始终重复静态库,就像使用传统链接器一样,并且始终通过保留每个共享库的最后一次出现来去重。NEW 行为是根据链接器功能应用不同的策略。

此策略在 CMake 版本 3.29 中引入。它可以通过 cmake_policy()cmake_minimum_required() 设置。如果未设置,CMake 不会发出警告,并使用 OLD 行为。

注意

策略的 OLD 行为 按定义已弃用,并可能在未来的 CMake 版本中移除。