在GCC中链接部分静态和部分动态 [英] Linking partially static and partially dynamic in GCC
问题描述
我试图编译一个非常简单(简单的hello世界)C程序使用动态和静态链接与GCC。我想知道如何做到这一点,所以我最小的测试示例是简单地试图链接libc作为静态和libm动态。
I'm trying to compile a very simple (as simple as hello world) C program using both dynamic and static linking with GCC. I want to know how to do this in general, so my minimal test example is simply trying to link libc as static and libm dynamically.
我遇到至少以下有关同一主题的其他问题:
I've come across at least the following other questions regarding the same topic:
其中的一些答案表明,使用-Wl,-Bstatic和-Wl,-Bdynamic来指定哪些库分别是静态和动态的。还建议其中简单地指定要链接的静态库的完整路径。
Some of the answers therein suggest things such as using -Wl,-Bstatic and -Wl,-Bdynamic to specify which libraries are respectively static and dynamic. Also suggested is among others simply specifying the full path of the static library to link against.
我已经尝试了几个这些建议及其变体。我不明白它给我的错误信息。
I've tried several of these suggestions, and variants thereof. I don't understand the error message it gives me. I know what PIE is, but I don't see how it relates to what I'm trying to do.
这里有一些失败的尝试:
Here are some failed attempts:
$ 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工作正常,但我需要部分静态编译:
Compiling just with no arguments, and with -static work fine, but I need partial static compilation:
$ gcc test.c -lm
$ gcc -static test.c -lm
但是,以下操作也失败:
However, the following fails too:
$ gcc test.c /usr/lib64/libc.a /usr/lib64/libm.a
我在这篇文章中遇到了类似的错误:
I've come across a similar error in this post:
然而,答案似乎不适用于我的问题。
However the answers do not seem to apply to my problem.
我想编译的程序只是test.c):
The program I'm trying to compile is simply (as 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()调用完全。
Please note that the program must be complex enough to actually require libm, otherwise linking attempts might give false positives if libm is not really needed. In my original test.c example, I used only sinf() to a constant value, which made the compiler optimize out the sinf() call completely.
使用:
$ 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
。
The OP wants to link one library dynamically and another statically. He have the example of linking libc
statically and libm
dynamically. That particular case I have not been able to achieve. However, the opposite is possible i.e. linking libc
dynamically and libm
statically.
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)
注意链接顺序matters.eg gcc -L。 -lm test.c
不起作用。
Note that the link order matters.e.g gcc -L. -lm test.c
does not work.
这也适用于其他库。例如 gomp
This works with other libraries as well. For example gomp
gcc -fopenmp test.c
ldd显示 libgomp.so.1
。我们可以像这样静态链接它
ldd shows libgomp.so.1
. We can link it statically like this
ln -s `gcc -print-file-name=libgomp.a`
gcc -L. -fopenmp test.c
现在 ldd a.out
不显示 libgomp.so.1
。但在这种情况下, pthreads
仍然动态链接。要静态链接pthread,请要求链接 libc
静态的。。
Now ldd a.out
does not show libgomp.so.1
. But in this case pthreads
is still linked dynamically. To link pthreads statically requires that libc
be linked statically as well.
这篇关于在GCC中链接部分静态和部分动态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!