[英]Linking partially static and partially dynamic in GCC
我正在尝试使用GCC的动态和静态链接编译一个非常简单(简单的hello world)C程序。 我想知道如何一般地这样做,所以我的最小测试示例只是尝试动态地将libc链接为静态和libm。
我至少遇到过关于同一主题的以下其他问题:
其中的一些答案提出了诸如使用-Wl,-Bstatic和-Wl,-Bdynamic之类的事情来指定哪些库分别是静态和动态的。 还建议其中只是指定要链接的静态库的完整路径。
我已经尝试了其中一些建议及其变体。 我不明白它给我的错误信息。 我知道PIE是什么,但我不知道它与我想做什么有什么关系。
以下是一些失败的尝试:
$ gcc test.c /usr/lib64/libc.a
linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
urned 1 exit status
$ gcc test.c -Wl,-Bdynamic -lm -Wl,-Bstatic -lc
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
$ gcc -Wl,-Bdynamic -lm -Wl,-Bstatic -lc test.c
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
$ gcc -Wl,-Bstatic -lc -Wl,-Bdynamic -lm test.c
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: error: ld returned 1 exit status
只编译没有参数,并且-static工作正常,但我需要部分静态编译:
$ gcc test.c -lm
$ gcc -static test.c -lm
但是,以下也失败了:
$ gcc test.c /usr/lib64/libc.a /usr/lib64/libm.a
我在这篇文章中遇到过类似的错误:
但是答案似乎并不适用于我的问题。
我正在尝试编译的程序很简单(作为test.c):
#include <stdio.h>
#include <math.h>
int main(int argc, char **argv)
{
int i = 0;
for(i = 0; i < 65535; i++) {
printf("%f\n", sinf(i));
printf("%f\n", cosf(i));
printf("%f\n", tanf(i));
printf("%f\n", sqrtf(i));
}
return 0;
}
编辑:请注意,该程序必须足够复杂,实际上需要libm,否则如果不真正需要libm,链接尝试可能会产生误报。 在我原来的test.c示例中,我只将sinf()用于常量值,这使得编译器完全优化了sinf()调用。
我正在使用:
$ gcc --version
gcc (Gentoo 4.7.3-r1 p1.4, pie-0.5.5) 4.7.3
以下对我有用
ln -s `gcc -print-file-name=libc.a`
gcc -static-libgcc -L. -lc test.c
然后ldd a.out
给出:
not a dynamic executable
编辑:
OP希望动态链接一个库,静态链接另一个库。 他有一个动态链接libc
静态和libm
的例子。 那个我无法实现的特殊情况。 但是,相反的情况是可能的,即动态链接libc
和静态链接libm
。
ln -s `gcc -print-file-name=libm.a`
gcc test.c -L. -lm
然后ldd a.out
给出
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x41960000)
/lib/ld-linux.so.2 (0x4193d000)
请注意,链接顺序很重要gcc -L. -lm test.c
gcc -L. -lm test.c
不起作用。
这也适用于其他库。 例如gomp
gcc -fopenmp test.c
ldd显示了libgomp.so.1
。 我们可以像这样静态链接它
ln -s `gcc -print-file-name=libgomp.a`
gcc -L. -fopenmp test.c
现在ldd a.out
没有显示libgomp.so.1
。 但在这种情况下, pthreads
仍然是动态链接的。 要静态链接pthreads,还需要静态链接libc
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.