g++,静态初始化和-nostdlib

15

使用-nostdlib进行编译/链接似乎会阻止静态初始化,即使我添加了自己的带有.init/.fini部分的crti.s和crtn.s。

有没有解决方法可以让g++生成插入.init中的静态初始化代码或可以手动调用的代码?

这是我尝试过的:

g++ -o test.o -c -fno-use-cxa-atexit test.cc  # has _start (entry point) 
                                              #   that calls _init and _main
as -o crti.o crti.s      # has _init in section .init
as -o crtn.o crtn.s
g++ -o test ./crti.o test.o -nodefaultlibs -nostartfiles ./crtn.o

-nodefaultlibs单独包括静态初始化代码和调用,但是强制使用libc-_start/_init。

-nodefaultlibs -nostartfiles允许我使用自己的 _start / _init,但不包括静态初始化代码或调用。


尝试这个命令:g++ -o test ./crti.o ./crtn.o test.o -Wl, -nodefaultlibs -nostartfiles。根据您的用法,我认为您只想要包含启动文件并且似乎对标准库中的其他库满意? - Pavan Manjunath
我对C++不是很熟悉,所以我不明白你所说的“但仍需要调用静态构造函数”的意思。你能给我举个例子吗?我一直在考虑静态库。 - Pavan Manjunath
@Pavan:我有几个模板类,其中包含静态类成员,在调用main函数之前会自动进行构造/初始化。由于编译器决定使用哪些模板实例化,因此很难显式地调用构造函数。这就是为什么我需要包含静态初始化代码的原因。 - Thomas
@Pavan:仅使用-nostartfiles无法让我用自己的代码替换libc-_start。 - Thomas
由于似乎没有办法使用命令行参数来完成我需要的操作,所以我采取了以下方法来解决问题:a) 使用-nodefaultlibs(否则必须存在libstdc++等)。b) 将自己的目录挂载到libc所在的位置。c) 构建自定义的crti.ocrtn.o,自定义_start,空的crt1.o并使用原始的crtbegin.ocrtend.o(这些包含初始化调用),并将所有内容复制到挂载的目录中。 - Thomas
显示剩余2条评论
1个回答

15

来自gcc链接器文档,

-nostdlib

在链接时不使用标准系统启动文件或库。 不会传递任何启动文件,只有您指定的库将传递给链接器,而指定系统库的链接选项(如-static-libgcc或-shared-libgcc)将被忽略。

因此使用,

-nodefaultlibs

在链接时不使用标准系统库。 只有您指定的库将传递给链接器,指定系统库链接的选项(如-static-libgcc或-shared-libgcc)将被忽略。通常情况下使用标准启动文件,除非使用-nostartfiles选项。编译器可能会生成对memcmp、memset、memcpy和memmove的调用,这些条目通常会通过libc中的条目解析。当指定此选项时,这些入口点应通过其他机制提供。

同时也可以尝试使用,

g++ -Wl, -static

-Wl      passes the next command on to the linker
-static  On systems that support dynamic linking, this prevents linking with 
         the shared libraries. On other systems, this option has no effect.

使用-nodefaultlibs选项,静态初始化代码被包含并调用,但我看不到如何使用自己的.init / _start代码。这仍然可能吗? - Thomas
是的,我尝试了-nostartfiles,但链接器没有将代码和静态初始化调用包含到我的.init节中。 - Thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接