g++编译的静态库 gcc_如何使用gcc在Linux上静态链接C和C ++程序

本文介绍了如何在Linux上静态链接C和C++程序,讨论了静态链接的优缺点,并提供了使用gcc进行静态链接的步骤。重点在于解决glibc问题,以及如何确保内存映射在程序中静态确定和控制。
摘要由CSDN通过智能技术生成

g++编译的静态库 gcc

Before statically linking you C and C++ programs, you should be aware of the drawbacks of the static linking especially with glibc. There are some good discussions already: with glibc you’re linking static programs which are not really static and some others here and here.

在静态链接C和C ++程序之前,您应该了解静态链接的缺点,尤其是glibc。 已经有一些很好的讨论: 使用glibc,您可以链接并非真正静态的静态程序,还可以 在此处此处 链接其他程序

That said, you can choose to statically link C and C++ programs on Linux, only when you know what you are doing and why. And you have ways to avoid some problems like setting GCONV_PATH, enabling --enable-static-nss for glibc, using other DNS libraries rather than NSS and never use dlopen. You can even use other libc implementation like uClibc or musl libc which are more friendly for static linking. A comparison of C/POSIX standard library implementations for Linux can be found here.

也就是说,只有在知道自己在做什么和为什么的情况下 ,才能选择在Linux上静态链接C和C ++程序。 而且,您可以避免一些问题,例如设置GCONV_PATH为glibc启用--enable-static-nss使用其他DNS库而不是NSS从不使用dlopen 。 您甚至可以使用其他libc实现,例如uClibcmusl libc ,它们对于静态链接更友好。 可以在此处找到Linux的C / POSIX标准库实现的比较。

Linux binaries are not portable if they are built in normal way even with full static linking. However, there are many companies that supply portable Linux binaries that run on a wide range of Linux systems of various versions. Static linking is one of the techniques to build portable binaries. For a detailed explanation of common techniques for building portable binaries, I suggest Creating portable Linux binaries which discusses the “secret sauce”.

如果Linux二进制文件以完全静态链接的正常方式构建,则它们是不可移植的。 但是,有许多公司提供可移植的Linux二进制文件,这些二进制文件可在各种版本的Linux 系统上运行。 静态链接是构建可移植二进制文件的技术之一。 有关构建便携式二进制文件的常用技术的详细说明,我建议创建讨论“秘密秘诀”的便携式Linux二进制文件

One more note: this is not problems from the Linux kernel. Linux kernel keeps very good compatibility. Read Linus’ “WE DO NOT BREAK USERSPACE!” arguments here.

还有一点需要注意:这不是Linux内核的问题。 Linux内核保持了很好的兼容性。 阅读Linus的“我们不要破坏用户空间!” 这里的论点。

You may wonder why I am talking about static linking. My main motivation is to have memory mapping statically determined and controlled by the program. See the /proc/PID/maps of one statically linked program as follows:

您可能想知道为什么我要谈论静态链接。 我的主要动机是由程序静态确定和控制内存映射。 请参阅一个静态链接程序的/proc/PID/maps ,如下所示:

00400000-0060c000 r-xp 00000000 fd:00 920962                             /home/kvplus/think/tmp/runtime/vpc
0080b000-00814000 rwxp 0020b000 fd:00 920962                             /home/kvplus/think/tmp/runtime/vpc
00814000-408a5000 rwxp 00000000 00:00 0 
41652000-41675000 rwxp 00000000 00:00 0                                  [heap]
100000000-800000000 rwxp 00000000 00:00 0 
240000000000-250000000000 rwxs 00000000 ca:11 36                         /mnt/kvplus1-data/pmem-kvplus-0-0
250000000000-260000000000 rwxs 00000000 ca:11 37                         /mnt/kvplus1-data/pmem-kvplus-0-1
260000000000-270000000000 rwxs 00000000 ca:11 38                         /mnt/kvplus1-data/pmem-kvplus-0-2
270000000000-280000000000 rwxs 00000000 ca:11 39                         /mnt/kvplus1-data/pmem-kvplus-0-3
280000000000-290000000000 rwxs 00000000 ca:11 40                         /mnt/kvplus1-data/pmem-kvplus-0-4
290000000000-2a0000000000 rwxs 00000000 ca:11 41                         /mnt/kvplus1-data/pmem-kvplus-0-5
2a0000000000-2b0000000000 rwxs 00000000 ca:11 42                         /mnt/kvplus1-data/pmem-kvplus-0-6
2b0000000000-2c0000000000 rwxs 00000000 ca:11 43                         /mnt/kvplus1-data/pmem-kvplus-0-7
2c0000000000-2d0000000000 rwxs 00000000 ca:11 44                         /mnt/kvplus1-data/pmem-kvplus-0-8
2d0000000000-2e0000000000 rwxs 00000000 ca:11 45                         /mnt/kvplus1-data/pmem-kvplus-0-9
2e0000000000-2f0000000000 rwxs 00000000 ca:11 46                         /mnt/kvplus1-data/pmem-kvplus-0-10
2f0000000000-300000000000 rwxs 00000000 ca:11 47                         /mnt/kvplus1-data/pmem-kvplus-0-11
340000000000-350000000000 rwxs 00000000 ca:11 48                         /mnt/kvplus1-data/pmem-kvplus-0-12
350000000000-360000000000 rwxs 00000000 ca:11 49                         /mnt/kvplus1-data/pmem-kvplus-0-13
360000000000-370000000000 rwxs 00000000 ca:11 50                         /mnt/kvplus1-data/pmem-kvplus-0-14
370000000000-380000000000 rwxs 00000000 ca:11 51                         /mnt/kvplus1-data/pmem-kvplus-0-15
380000000000-390000000000 rwxs 00000000 ca:11 52                         /mnt/kvplus1-data/pmem-kvplus-0-16
390000000000-3a0000000000 rwxs 00000000 ca:11 53                         /mnt/kvplus1-data/pmem-kvplus-0-17
3a0000000000-3b0000000000 rwxs 00000000 ca:11 54                         /mnt/kvplus1-data/pmem-kvplus-0-18
3b0000000000-3c0000000000 rwxs 00000000 ca:11 55                         /mnt/kvplus1-data/pmem-kvplus-0-19
3c0000000000-3d0000000000 rwxs 00000000 ca:11 56                         /mnt/kvplus1-data/pmem-kvplus-0-20
3d0000000000-3e0000000000 rwxs 00000000 ca:11 57                         /mnt/kvplus1-data/pmem-kvplus-0-21
3e0000000000-3f0000000000 rwxs 00000000 ca:11 58                         /mnt/kvplus1-data/pmem-kvplus-0-22
3f0000000000-400000000000 rwxs 00000000 ca:11 59                         /mnt/kvplus1-data/pmem-kvplus-0-23
7fd664000000-7fd664021000 rwxp 00000000 00:00 0 
7fd664021000-7fd668000000 ---p 00000000 00:00 0 
7fd66abb1000-7fd66abb2000 ---p 00000000 00:00 0 
7fd66abb2000-7fd66b5b2000 rwxp 00000000 00:00 0 
7fd66b5b2000-7fd66b5b3000 ---p 00000000 00:00 0 
7fd66b5b3000-7fd66efb8000 rwxp 00000000 00:00 0 
7fd66efb8000-7fd66efb9000 ---p 00000000 00:00 0 
7fd66efb9000-7fd66f9b9000 rwxp 00000000 00:00 0 
7fff054ba000-7fff054cf000 rwxp 00000000 00:00 0                          [stack]
7fff055ff000-7fff05600000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

And a non-statically-linked programs /proc/PID/maps is as follows:

和非静态链接的程序/proc/PID/maps如下:

00400000-00406000 r-xp 00000000 fd:00 4115                               /bin/sleep
00605000-00606000 rw-p 00005000 fd:00 4115                               /bin/sleep
0173c000-0175d000 rw-p 00000000 00:00 0                                  [heap]
7f53a7dba000-7f53adbeb000 r--p 00000000 fd:00 133506                     /usr/lib/locale/locale-archive
7f53adbeb000-7f53adc02000 r-xp 00000000 fd:00 1873                       /lib64/libpthread-2.11.2.so
7f53adc02000-7f53ade01000 ---p 00017000 fd:00 1873                       /lib64/libpthread-2.11.2.so
7f53ade01000-7f53ade02000 r--p 00016000 fd:00 1873                       /lib64/libpthread-2.11.2.so
7f53ade02000-7f53ade03000 rw-p 00017000 fd:00 1873                       /lib64/libpthread-2.11.2.so
7f53ade03000-7f53ade07000 rw-p 00000000 00:00 0 
7f53ade07000-7f53adf7a000 r-xp 00000000 fd:00 1849                       /lib64/libc-2.11.2.so
7f53adf7a000-7f53ae179000 ---p 00173000 fd:00 1849                       /lib64/libc-2.11.2.so
7f53ae179000-7f53ae17d000 r--p 00172000 fd:00 1849                       /lib64/libc-2.11.2.so
7f53ae17d000-7f53ae17e000 rw-p 00176000 fd:00 1849                       /lib64/libc-2.11.2.so
7f53ae17e000-7f53ae183000 rw-p 00000000 00:00 0 
7f53ae183000-7f53ae18a000 r-xp 00000000 fd:00 1877                       /lib64/librt-2.11.2.so
7f53ae18a000-7f53ae389000 ---p 00007000 fd:00 1877                       /lib64/librt-2.11.2.so
7f53ae389000-7f53ae38a000 r--p 00006000 fd:00 1877                       /lib64/librt-2.11.2.so
7f53ae38a000-7f53ae38b000 rw-p 00007000 fd:00 1877                       /lib64/librt-2.11.2.so
7f53ae38b000-7f53ae3a9000 r-xp 00000000 fd:00 1842                       /lib64/ld-2.11.2.so
7f53ae5a0000-7f53ae5a3000 rw-p 00000000 00:00 0 
7f53ae5a7000-7f53ae5a8000 rw-p 00000000 00:00 0 
7f53ae5a8000-7f53ae5a9000 r--p 0001d000 fd:00 1842                       /lib64/ld-2.11.2.so
7f53ae5a9000-7f53ae5aa000 rw-p 0001e000 fd:00 1842                       /lib64/ld-2.11.2.so
7f53ae5aa000-7f53ae5ab000 rw-p 00000000 00:00 0 
7fff7fede000-7fff7fef3000 rw-p 00000000 00:00 0                          [stack]
7fff7fffd000-7fff7fffe000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

The mmap from the .so are problems for certain programs.

.so的mmap是某些程序的问题。



The following part of this post will introduce how to “statically” link C and C++ programs with gcc on Linux.

本文的以下部分将介绍如何在Linux上通过gcc“静态”链接C和C ++程序。

You should first install the glibc-static package. On Fedora/RHEL/CentOS, you can

您应该首先安装glibc-static软件包。 在Fedora / RHEL / CentOS上,您可以

# yum install glibc-static

Add the -static as a compilation option to gcc:

-static作为编译选项添加到gcc:

$ gcc -static src.c obj.o -o prog

Check whether the compiled binary is statically linked:

检查编译后的二进制文件是否静态链接:

$ ldd prog

It should print out:

它应该打印出:

not a dynamic executable

If you are using some libraries, such as pthread, you should specify these libraries according to their reference order (referrer appears first):

如果您正在使用某些库,例如pthread ,则应根据它们的引用顺序指定这些库(引荐来源网址首先出现):

$ gcc -static prog.c -o prog -lpthread

More on the library order in the gcc manual

gcc手册中有关库顺序的更多信息

-l library
Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX compliance and is not recommended.)
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.

-l库
链接时搜索名为library的库。 (使用库作为单独参数的第二种替代方法仅是为了符合POSIX,不建议这样做。)
在命令中写入此选项的位置会有所不同。 链接器按照指定的顺序搜索和处理库和目标文件。 因此,foo.o -lz bar.o在文件foo.o之后但在bar.o之前搜索库z。 如果bar.o引用z中的函数,则可能不会加载这些函数。

First, install the package needed:

首先,安装所需的软件包:

# yum install glibc-static libstdc++-static

Under GCC 4.4, you can use the -static option as for C programs:

在GCC 4.4下,您可以像使用C程序一样使用-static选项:

$ g++ -static

After GCC 4.5, gcc supports the -static-libstdc++ option:

在GCC 4.5之后, gcc支持-static-libstdc++选项:

$ gcc -static -static-libstdc++ -static-libgcc

Also note the library order.

另请注意库顺序。

After building the program, check whether the program is statically linked as what we do for C programs:

生成程序后,请检查程序是否像我们对C程序所做的那样静态链接:

$ ldd cpp-program
not a dynamic executable

Note for CMake: to specify a static library (libssl as an example) in CMake (find more here):

CMake的注意事项:在CMake中指定一个静态库(以libssl为例)(在此处查找更多信息 ):

find_library(OPENSSL_LIBRARY libssl.a)

翻译自: https://www.systutorials.com/how-to-statically-link-c-and-c-programs-on-linux-with-gcc/

g++编译的静态库 gcc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值