好久没更新了,来水一篇,毕竟今年有50
篇的目标呢。
前两天遇到一个问题,因为链接依赖的某个库的时候少加了一个参数,导致最后程序逻辑出现了问题。缺席的参数是--whole-archive
,由于依赖的库中使用了contructor
这个函数属性
来做一些特别的处理,两个因素叠加导致了问题。
先贴下这两个特性的描述:
|
|
--whole-archive
的作用后面再说,constructor
这个函数属性
的作用就是可以让加了这个属性的函数在main
函数执行之前自动被调用。
|
|
下面用一个小例子来描述下问题,小例子要做的事情就是打印出一个全局变量toy_table
的值,并且我有一个静态库libnew_toy.a
,我希望链接这个库的时候就能添加一些新的内容到全局变量toy_table
中。先来看main
是怎么写的。
代码列表
print_toy_table.c
嗯,简单粗暴,就打印了下变量值,下面看下top.h
的实现。
|
|
toy.h
这个头文件定义了两个结构,一个全局变量,一个函数声明,一个宏。宏REGISTER_NEW_TOY
中会声明并定义函数new_toy_init_##toy
,这个函数添加了函数属性
:contructor
。
|
|
toy.c
toy.c
中会初始化全局变量toy_table
,并实现函数new_toy_register
。
|
|
下面看下我们想生成的静态库libnew_toy.a
对应有源码。
new_toy.c
这里定义了一个my_new_toy
的变量,并且调用了宏REGISTER_NEW_TOY
。
|
|
实验
生成静态库libnew_toy.a
|
|
不加--whole-archive
直接链接
|
|
可以看到虽然链接了静态库libnew_toy.a
,但是相应的函数被没有被执行。回头再看看--whole-archive
的描述:
include every object file in the archive in the link, rather than
searching the archive for the required object files.
因为new_toy.c
中的内容没有被print_toy_table.c
引用,所以自然REGISTER_NEW_TOY(my_new_toy)
这一句没有被执行。
链接时添加参数--whole-archive
|
|
可以看到在main
函数执行之前my_new_toy
就被添加到toy_table
中了。
总结
事情落地之前,总有你意想不到的问题会发生,这时候就需要利用以往的经验快速解决。