2013-04-16 172 views
3

我的编译环境是的CentOS 5。我有一个名为libcunit的第三方库。我使用自动工具安装它,它会生成libcunit.alibcunit.so。我有我自己的应用程序,链接到一堆共享库。 libcunit.a在当前目录中,libcunit.so和其他共享库在/usr/local/lib/。当我编译这样的:GCC静态库链接VS动态链接

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

我得到一个链接错误:

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' 

但是,当我与.so编译,如:

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

它编译罚款和运行正常了。

为什么与libcunit.a静态连接时,它给错误?

回答

3

没注意到libcunit.a在你的情况下,居然发现与linakge问题而在库尼特库本身。就职俄语是绝对正确的,他不是在讨论预编译二进制文件。我们知道您已经自己构建了它。但是,CUinit本身似乎依赖于glibc中的符号,该符号不再可用于静态链接。因此,您只有两种选择:

  1. 向CUnit的开发人员报告此问题并要求他们修复此问题;
  2. 使用动态链接。

尽管如此,我对你的静态链接的风格建议仍然适用。 -L.一般不好的做法。 CUnit是第三方库,不应放入包含项目源文件的目录中。它的安装方式应与动态版本相同,即您可以使用libcunit.so/usr/local/lib。如果您在CUnit的配置阶段向自动工具提供prefix,则Autotools会正确安装所有内容。所以,如果你想与CUNIT静态链接,请考虑以下形式做:

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

这个答案是不正确的问题有*不*做与库顺序。 –

+0

@雇佣俄罗斯:你在哪里看到我的答案是解决_“图书馆订购”_的问题?建议的命令行只是OP命令行的一个复制粘贴,带有一些编辑/添加的标志,但没有改变链接顺序。 –

+0

如果直接列出libcunit.a,则不需要'-Wl,-Bstatic'(如同OP一样)。 –

6

Why is it giving error when linked statically with libcunit.a

的问题是,你的libcunit.a建一个古老的Linux系统上,并依赖于已符号从libc删除(这些符号用于glibc-2.2,并在10年前从glibc-2.3中删除)。更确切地说,这些符号已被hidden。它们可用于动态链接到旧的二进制文件(例如libcunit.so),但没有新的代码可以静态链接到它们(您不能创建引用它们的新可执行文件或共享库)。

你可以像这样观察的:

readelf -Ws /lib/x86_64-linux-gnu/libc.so.6 | egrep '\W__ctype_b\W' 
    769: 00000000003b9130  8 OBJECT GLOBAL DEFAULT 31 [email protected]_2.2.5 

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

嗨,我实际上是从源代码编译cunit项目(http://cunit.sourceforge.net/)。这不是给我的预编译二进制文件。我使用autotools来安装它。还有一个问题,libc.a没有ctype_b符号。但我并没有要求libc静态链接到我的测试应用程序。所以它应该动态链接到libc.so.6,对吧? – bala1486