让我解释一下 -Wl,--whole-archive -lxixihaha -Wl,--no-whole-archive
和直接使用 target_link_libraries
的区别:
- 普通链接(
target_link_libraries
):
- 链接器只会链接那些被实际引用到的符号
- 如果某个目标文件中的符号没有被其他地方引用,这个符号就不会被链接进来
- 这是默认的链接行为,可以减小最终可执行文件的大小
--whole-archive
方式:
--whole-archive
告诉链接器必须包含库中的所有目标文件,而不管这些符号是否被引用- 所有符号都会被强制链接进来,即使没有被引用
-Wl,--no-whole-archive
用于关闭这个选项,使后续的库回到普通链接模式
在您的项目中:
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--whole-archive -lxixihaha -Wl,--no-whole-archive")
这行代码的意思是:
-Wl,--whole-archive
:开启完整归档模式-lxixihaha
:链接 lxixihaha 库,此时会链接其中所有符号-Wl,--no-whole-archive
:关闭完整归档模式
这种方式通常用于以下场景:
- 当库中包含一些初始化函数,这些函数虽然没有被显式调用,但需要在运行时执行
- 当使用了一些通过注册机制工作的模块,这些模块的符号可能没有直接引用
- 在嵌入式系统中,某些中断向量表或设备驱动需要完整保留
所以在您的项目中:
- lxixihaha 库可能包含了一些需要完整保留的系统功能
- 而其他库(bsp、application、platform、gcc)使用普通链接方式就足够了
这就是为什么我们移除了 target_link_libraries
中的 lxixihaha ,因为它已经通过 --whole-archive
方式被完整链接了。如果同时使用两种方式,可能会导致符号重复或链接错误。