简体   繁体   English

gcc静态库链接与动态链接

[英]gcc static library linking vs dynamic linking

My build environment is CentOS 5 . 我的构建环境是CentOS 5 I have a third party library called libcunit. 我有一个名为libcunit的第三方库。 I installed it with autotools and it generates both libcunit.a and libcunit.so . 我用autotools安装它,它生成libcunit.alibcunit.so I have my own application that links with a bunch of shared libraries. 我有自己的应用程序链接到一堆共享库。 libcunit.a is in the current directory and libcunit.so and other shared libraries are in /usr/local/lib/ . libcunit.a位于当前目录中, libcunit.so和其他共享库位于/usr/local/lib/ When I compile like: 当我编译时:

gcc -o test test.c -L. libcunit.a -L/usr/local/lib -labc -lyz

I get a linkage error: 我收到一个链接错误:

libcunit.a(Util.o): In function `CU_trim_left':
Util.c:(.text+0x346): undefined reference to `__ctype_b'
libcunit.a(Util.o): In function `CU_trim_right':
Util.c:(.text+0x3fd): undefined reference to `__ctype_b'

But when I compile with .so like: 但是当我使用.so编译时:

gcc -o test test.c -L/usr/local/lib -lcunit -labc -lyz

it compiles fine and runs fine too. 编译很好,运行也很好。

Why is it giving error when linked statically with libcunit.a ? 为什么在与libcunit.a静态链接时会libcunit.a

Why is it giving error when linked statically with libcunit.a 为什么在与libcunit.a静态链接时会libcunit.a

The problem is that your libcunit.a was built on an ancient Linux system, and depends on symbols which have been removed from libc (these symbols were used in glibc-2.2 , and were removed from glibc-2.3 over 10 years ago). 问题是你的libcunit.a是建立在一个古老的Linux系统上的,并且取决于从libc 删除的符号(这些符号在glibc-2.2 ,并且在10年前从glibc-2.3中删除)。 More exactly, these symbols have been hidden . 更准确地说,这些符号已被hidden They are made available for dynamic linking to old binaries (such as libcunit.so ) but no new code can statically link to them (you can't create a new executable or shared library that references them). 它们可用于动态链接到旧二进制文件(例如libcunit.so ),但没有新代码可以静态链接到它们(您无法创建引用它们的新可执行文件或共享库)。

You can observe this like so: 您可以这样观察:

readelf -Ws /lib/x86_64-linux-gnu/libc.so.6 | egrep '\W__ctype_b\W'
   769: 00000000003b9130     8 OBJECT  GLOBAL DEFAULT   31 __ctype_b@GLIBC_2.2.5

readelf -Ws /usr/lib/x86_64-linux-gnu/libc.a | egrep '\W__ctype_b\W'
# no output

Didn't notice that the libcunit.a is actually found in your case and the problem with linakge is rather in the CUnit library itself. 没有注意到libcunit.a实际上是在你的情况下找到的,而linakge的问题则在CUnit库中。 Employed Russian is absolutely right, and he's not talking about precompiled binary here. 雇用俄语是绝对正确的,他不是在谈论预编译的二进制文件。 We understand that you've built it yourself. 我们知道您自己构建了它。 However, CUinit itself seems to be relying on the symbol from glibc which is not available for static linking anymore. 然而,CUinit本身似乎依赖于来自glibc的符号,该符号不再用于静态链接。 As a result you have only 2 options: 因此,您只有2个选项:

  1. File a report to the developers of CUnit about this and ask them to fix it; 向CUnit的开发者提交一份报告,并要求他们修复它;
  2. Use dynamic linking. 使用动态链接。

Nevertheless, my recommendation about your style of static linkage still applies. 不过,我对你的静态连接方式的建议仍然适用。 -L. is in general bad practice . 总的来说是不好的做法 CUnit is a 3rd party library and should not be placed into the directory containing source files of your project. CUnit是第三方库,不应放在包含项目源文件的目录中。 It should be rather installed in the same way as the dynamic version, ie like you have libcunit.so in /usr/local/lib . 它应该以与动态版本相同的方式安装,就像你在/usr/local/liblibcunit.so一样。 If you'd supply prefix to Autotools on the configure stage of CUnit, then Autotools would install everything properly. 如果您在CUnit的配置阶段为Autotools提供prefix ,那么Autotools将正确安装所有内容。 So if you want to link statically with CUnit, consider doing it in the following form: 因此,如果要静态链接CUnit,请考虑以下面的形式进行:

gcc -o test test.c -L/usr/local/lib -Wl,-Bstatic -lcunit -Wl,-Bdynamic -labc -lyz

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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