【问题标题】:Library handling of linux / gcclinux/gcc的库处理
【发布时间】:2013-01-01 16:06:39
【问题描述】:

我目前正在做一个更大的项目,其中包含很多库,我有一些 关于为什么 gcc 在 linux 下的行为方式的问题。

首先,我想您可能知道,您可以使用 gcc/g++ 的“-lxyz”链接器标志在某些系统路径中搜索 libxyz.so 并链接到它。但是,这在静态库的情况下不起作用,即,如果我想链接 libxyz.a,我必须明确添加 /usr/lib/libxyz.a 作为目标文件。

我的问题如下:如果我想在我的项目中包含一个 pkg-config 样式的 .pc 文件,如果用户选择构建一个静态库,我应该在其中放入什么?

另外,我发现 gcc/g++ 没有像我期望的那样处理库依赖关系,这很烦人:

如果我将我的程序链接到 libabc.so,并且如果 ldd 告诉我 libabc.so 依赖于 libxyz.so,那么我认为 gcc/g++ 应该足够聪明,也可以链接到 libxyz.so。可悲的是,情况似乎并非如此。有什么好的理由说明这不起作用还是有可能强制 gcc/g++ 考虑这些依赖关系?

【问题讨论】:

  • 您也可以使用gcc -v 而不是仅使用gcc 进行编译和链接,这会告诉您发生了什么。

标签: linux gcc shared-libraries static-libraries


【解决方案1】:

如果您不想指定静态库的完整路径,则无需指定,但您需要通知链接器您要链接静态库而不是动态库。

这可以通过ld-Bstatic 参数来完成,您可以通过gcc 或g++ 将其传递给-Wl,-Bstatic(有变体,请参阅man ld)。

例如:

gcc -o main main.c -Wl,-Bstatic -lfoo -Wl,-Bdynamic -lbar

mainlibfoo.a 链接,但libbar.so。动态是支持 if(对于 GNU ld)的平台上的默认设置。如果你把类似的东西放在pkg-config 设置或类似设置中,在你的静态库之后重置为默认值是礼貌的。

至于您问题的第二部分,这有点令人费解,因为至少在 Linux 上这不是必需的(或实际上是好的做法)。您的可执行文件应该只包含它直接依赖的库的 NEEDED 条目。运行时链接器将在必要时负责加载这些依赖项。 (为什么这是一个好的做法?因为您不想导入间接依赖项 - 如果您依赖的库更改了它自己的依赖项(例如在更新之后),您的可执行文件仍然会加载有问题的旧依赖项并且可能引入错误。)

例如,假设我有main 调用libfoo.so 中的函数,而该函数恰好调用libbar.so 中的函数。要在可执行文件中注册的“正确”依赖项:

$ readelf -d libbar.so | grep Shared
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
$ readelf -d libfoo.so | grep Shared
 0x0000000000000001 (NEEDED)             Shared library: [libbar.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
$ readelf -d a.out | grep Shared
 0x0000000000000001 (NEEDED)             Shared library: [libfoo.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

ldd(它调用运行时链接器来完成它的工作)可以解决所有问题:

$ ldd a.out 
linux-vdso.so.1 (0x00007fff813ff000)
libfoo.so => ./libfoo.so (0x00007f48ee99d000)
libc.so.6 => /lib64/libc.so.6 (0x00007f48ee5c8000)
libbar.so => ./libbar.so (0x00007f48ee3c6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f48eeb9f000)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多