在GCC中链接部分静态和部分动态 [英] Linking partially static and partially dynamic in GCC

查看:2394
本文介绍了在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:

GCC:静态链接只有一些库

gcc中共享库函数的静态链接

其中的一些答案表明,使用-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:

C ++静态链接的共享库

然而,答案似乎不适用于我的问题。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆