我有一堆静态库,它们是相互依赖的。由于依赖关系,我在为目标链接这些库时遇到了问题。作为一种变通方法,我从所有库中创建了一个单独的存档文件。
其中一个静态库具有构造函数和析构函数,组合归档也具有构造函数和析构函数(使用nm和objdump检查归档(但是,当我为目标使用组合存档时,最终的二进制文件不包含构造函数和析构函数。
我也尝试过使用--wholearchive,但这个选项似乎对我不起作用(二进制大小没有增加(。
任何可能出了问题的想法。感谢
链接器只加载它必须加载的模块(即您实际隐式引用的或显式引用的(,除非您强制执行。
这既是一件好事,也是一件不幸的事。它使链接过程更快,并防止代码膨胀。它通常也不会引起问题,因为通常你会以某种方式引用所有需要的模块,而你没有引用的模块是不需要的。正常情况下
但这也是这种无声失败的原因:链接器从不加载包含构造函数/析构函数的模块,甚至从不查看它。这是因为您从未实际调用过这些函数。
通过显式链接与包含构造函数/析构函数的源对应的对象文件,可以强制链接器包含模块。
换句话说,如果构造函数/析构函数在foo.c
中,请将-l/path/to/foo.o
添加到链接器的选项中,或者只需在命令行上将foo.o
传递给链接器(作为额外的参数(。
在任何一种情况下,通过这样做,您都明确地告诉链接器考虑这个模块,这样做将使它找到构造函数并正确地调用它们。
另一种选择(不需要您使用命令行(可能是将变量或函数(不一定做任何事情(放入与构造函数/析构函数相同的源文件中,并从主程序中的任何源文件中调用该函数
这也将强制链接器加载包含模块(它将在其中找到构造函数函数(。
更新:
我测试了这个替代方案,它运行良好:
/* libcode.c */
void enable_constructors() { /* do nothing */ }
void __attribute__ ((constructor)) con() { __builtin_puts("construct"); }
void __attribute__ ((destructor)) des() { __builtin_puts("destruct"); }
/* main.c */
extern void enable_constructors();
int main()
{
enable_constructors();
__builtin_puts("main");
return 0;
}
输出为:
construct
main
destruct
它还与全局变量一起工作,您可以从主程序中的源文件中触摸该全局变量:
/* libcode.c */
int enable_constructors; /* not used for anything */
void __attribute__ ((constructor)) cons() { __builtin_puts("construct"); }
void __attribute__ ((destructor)) des() { __builtin_puts("destruct"); }
/* main.c */
extern int enable_constructors;
int main()
{
++enable_constructors; /* touch the other module */
__builtin_puts("main");
return 0;
}
来自另一个答案:
通过显式链接与包含构造函数/析构函数的源对应的对象文件,可以强制链接器包含模块。
使用现代CMake,这就像库上的INTERFACE
源代码一样简单。只需为构造函数使用一个专用的源文件。
cmake_minimum_required(VERSION 3.13)
add_library(mylib STATIC libsource.c)
target_sources(mylib INTERFACE lib_ctor.c)
# CMake prior 3.13 requires an absolute path
# target_sources(mylib INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/lib_ctor.c)
add_executable(prog app.c)
target_link_libraries(prog mylib)
这里,lib_ctor.c
将包含构造函数。CCD_ 6源被添加到针对CCD_ 7链接的每个目标的源文件的列表中。因此,它们被显式链接,构造函数由链接器读取。
在意识到我的构建系统可以以一种更干净的方式处理这件事之前,我在--whole-archive
和其他黑客攻击上浪费了一两个小时。由于CMake现在非常流行,而且这是"gcc强制构造函数"one_answers"gcc构造函数未链接"等术语的热门搜索结果,我想分享一下。