如果您不想指定静态库的完整路径,则无需指定完整路径,但您需要通知链接器您要链接静态库而不是动态库。
这可以通过 to 的-Bstatic
参数来完成ld
,您可以通过 gcc 或 g++ 传递该参数-Wl,-Bstatic
(有变体,请参阅 参考资料man ld
)。
例如:
gcc -o main main.c -Wl,-Bstatic -lfoo -Wl,-Bdynamic -lbar
将main
与 alibfoo.a
但 a链接libbar.so
。动态是支持 if(对于 GNU ld)的平台上的默认设置。如果你把类似的东西放在一个pkg-config
设置或类似的地方,在你的静态库之后重置为默认值是礼貌的。
至于您问题的第二部分,这有点令人费解,因为至少在 Linux 上这不是必需的(或实际上是好的做法)。您的可执行文件应该只包含NEEDED
它直接依赖的库的条目。运行时链接器将在必要时负责加载这些依赖项。(为什么这是一个好的做法?因为您不想导入间接依赖项 - 如果您依赖的库更改了自己的依赖项(例如在更新之后),您的可执行文件仍会加载有问题的旧依赖项并且可能引入错误。)
例如,假设我main
调用了 in 中的一个函数libfoo.so
,而该函数恰好调用了 in 中的一个函数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)