繁体   English   中英

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

[英]Linking partially static and partially dynamic in GCC

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

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

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

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

C ++静态链接共享库

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

我正在尝试编译的程序很简单(作为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM