没有链接具有构造函数属性的gcc函数



我有一堆静态库,它们是相互依赖的。由于依赖关系,我在为目标链接这些库时遇到了问题。作为一种变通方法,我从所有库中创建了一个单独的存档文件。

其中一个静态库具有构造函数和析构函数,组合归档也具有构造函数和析构函数(使用nmobjdump检查归档(但是,当我为目标使用组合存档时,最终的二进制文件不包含构造函数和析构函数。

我也尝试过使用--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构造函数未链接"等术语的热门搜索结果,我想分享一下。

最新更新