背景

写这篇文章的起因是由于最近使用了一个静态库,编译过程中报错的信息为没有找到变量,但是在静态库当中确实是有这个变量的声明和定义的,只是这个变量是一个static修饰的全局的变量。

刚开始一直怀疑我链接错了静态库,由于工程比较大,一直在纠结路径问题。
后来直接加打印确认了我链接的静态库没有错,那就百思不得其解了,明明定义好的变量为何链接猴就消失了。

原因

查找了一天资料终于发现,在静态库中,如果使用了静态全局变量初始化数据,在链接过程中会优化掉这部分数据

就会导致,程序链接了lib,但是实际上lib内的静态全局变量都没有被声明,所以源程序找不到这个变量也就正常了。

当然十分不推荐静态库使用静态全局变量这种做法,实在太不安全了。

解决

这种情况需要在程序链接lib的时候添加 WHOLEARCHIVE选项,再进行链接

我通过在camke文件当中在链接之前添加以下两行解决:

1
2
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -WHOLEARCHIVE:libpreenhance_MT")
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -WHOLEARCHIVE:libpreenhance_MTd")

此时会将lib源程序中的所有符号都编译到lib里面,供程序调用