我正在尝试使用GCC编译一个非常简单(像hello world一样简单)的C程序,同时使用动态和静态链接。 我想了解如何在一般情况下执行此操作,因此我的最小测试示例只是尝试将libc作为静态库链接并将libm作为动态库链接。
我至少遇到了以下关于同一主题的问题: GCC:仅静态链接某些库 gcc中共享库函数的静态链接 其中的一些答案建议使用-Wl,-Bstatic和-Wl,-Bdynamic来指定分别是静态和动态库。 还建议仅指定要链接的静态库的完整路径等其他内容。
我尝试了几个建议以及其变体。 我不明白它给我的错误消息。 我知道PIE是什么,但我不知道它与我正在尝试做的有什么关系。
这是一些失败的尝试:
然而,以下也失败了:
我至少遇到了以下关于同一主题的问题: GCC:仅静态链接某些库 gcc中共享库函数的静态链接 其中的一些答案建议使用-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