gpt4 book ai didi

c - 在 GCC 中链接部分静态和部分动态

转载 作者:行者123 更新时间:2023-12-03 00:34:14 25 4
gpt4 key购买 nike

我正在尝试使用 GCC 的动态和静态链接来编译一个非常简单(就像 hello world 一样简单)的 C 程序。我想知道一般如何做到这一点,所以我的最小测试示例只是尝试将 libc 链接为静态,将 libm 动态链接。

我至少遇到过以下有关同一主题的其他问题:

GCC: static linking only some libraries

Static link of shared library function in 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

我在这篇文章中遇到了类似的错误:

C++ Statically linked shared library

但是答案似乎不适用于我的问题。

我尝试编译的程序很简单(如 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不起作用。

这也适用于其他库。例如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 requires that libc be linked statically as well .

关于c - 在 GCC 中链接部分静态和部分动态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26161332/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com