Gcc 我可以用动态符号表编译静态应用程序吗?

Gcc 我可以用动态符号表编译静态应用程序吗?,gcc,compiler-construction,compilation,linker,Gcc,Compiler Construction,Compilation,Linker,举一个简单的例子: void foo() {} int main() { return 0; } 我构建它并查看动态符号表: $ g++ test.cpp -o test $ nm --dynamic test 0804849c R _IO_stdin_used w __gmon_start__ U __libc_start_main 正如所料,我没有看到foo。因此,我构建了一个包含未使用的符号的模型 $ gcc test.c -rdyn

举一个简单的例子:

void foo() {}

int main()
{
       return 0;
}
我构建它并查看动态符号表:

$ g++ test.cpp -o test
$ nm --dynamic test
0804849c R _IO_stdin_used
         w __gmon_start__
         U __libc_start_main
正如所料,我没有看到
foo
。因此,我构建了一个包含未使用的符号的模型

$ gcc test.c -rdynamic -o test
$ nm --dynamic test
0804863c R _IO_stdin_used
         w _Jv_RegisterClasses
0804a010 A __bss_start
0804a008 D __data_start
         w __gmon_start__
080485e0 T __libc_csu_fini
08048570 T __libc_csu_init
         U __libc_start_main
0804a010 A _edata
0804a018 A _end
0804861c T _fini
08048638 R _fp_hw
08048438 T _init
080484a0 T _start
0804a008 W data_start
08048554 T foo
08048559 T main
您可以看到
foo
现在位于符号表中。现在我构建了一个静态版本

$ gcc test.c -rdynamic -static -o test
$ nm --dynamic test
nm: test: No symbols
我的符号已经消失了,尽管我明确指定了它们

根据GCC手册页:

-静止的 在支持动态链接的系统上,这会阻止和共享库的链接

我的函数
foo()
不是共享库

如果我扩展此应用程序,它调用
dlopen()
,并且我加载的库需要调用
foo()
,我的符号表不再包含对
foo()
的引用,我的应用程序将失败

这件事发生在我身上


为什么-static否定-rdynamic?我该如何解决它?

我认为一个与C库静态链接的可执行文件的想法,但是提供到共享库的导出可能是一个错误的概念。在这种情况下会发生什么?假设您的共享库分配了一些内存(使用它自己的C库副本),然后将其传递给可执行文件中的例程,该例程将释放它(在C库的另一个副本中)。这闻起来像个问题。如果需要静态链接某些库,可以在这些库之前使用
-Wl,-Bstatic
选项强制链接静态版本


另外,如果您需要更多地控制正在发生的事情,那么最好有单独的编译和链接步骤,并直接使用
ld
进行链接步骤。它不一定对您正在使用的命令行选项有帮助,但我怀疑您可能会遇到一些“有效”的问题,除非出现上述问题。

如果您先编译:
gcc-c test.c-rdynamic-o test.o
,然后调用
gcc
链接应用程序?
-static
-rdynamic
都是链接器的选项,因此它只是变成
gcc test.o-rdynamic-static-o test
。同样的结果,我的错误。将编译中的
-rdynamic
替换为
-shared
?我之前在深入查看gcc和ld的手册页时尝试了
-shared
。它编译、链接和创建一个动态符号表,但应用程序seg出现故障。这里回答了克服seg故障的诀窍:但这已经开始摆脱原来的问题。谢谢。我问这个问题的核心原因是想看看是否可以修复并发布Crosstool NG中静态原生gdb构建选项的补丁。就像你说的,从根本上讲,这没有多大意义。gdb的完全功能静态构建可以工作的唯一方法是将其链接到thread_db并删除dlopen()调用。