大佬教程收集整理的这篇文章主要介绍了GCC 使用库文件名进行链接,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
使用 GCC 进行 C/C++ 代码编译时,如果代码中使用到了库函数,需要使用 -l
选项指定该库函数所在的库。如:-lm
、-lrt
、-lpthread
等。这种方式使用的是库的缩写。一个库的文件名如果是:libxxx.so
或 libxxx.a
,则可以使用 -lxxx
进行链接。这种规则很常见,但是缺点也很明显。假设在一台 Linux 机器上,同时具有 libxxx.so
和 libxxx.a
,GCC 会优先链接 libxxx.so
。虽然,GCC 也提供了 -static
选项可以强制链接静态库。但是,这时候新的问题出现了,假设有两个库 x
和 y
,他们都具有静态库和动态库两个版本。如果我想要链接 libx.so
和 liby.a
,使用 -static
选项就无法满足这个要求。我需要更加精细的控制,最好是直接根据文件名直接指定链接哪个版本的库文件,就没有任何歧义。@H_696_33@
GCC 文档的关于 -l
选项的描述没有告诉我如何直接使用一个库文件名。于是翻看 ld
的文档。在关于 -l
选项的描述中,有这样一段话:@H_696_33@
If namespec is of the form ‘:filename’, ld will search the library path for a file called filename, otherwise it will search the library path for a file called ‘libnamespec.a’.@H_696_33@
也就是说可以使用 -l:filename
的形式直接指定库文件名。这个只是 ld
的选项,GCC 能不能直接使用还需要验证。设计三个 .cpp 文件,分为 x.cpp
y.cpp
和 @H_516_1@main.cpp。@H_696_33@
// x.cpp
#include <iostream>
void print_x()
{
std::cout << "x" << std::endl;
}
// y.cpp
#include <iostream>
void print_y()
{
std::cout << "y" << std::endl;
}
// main.cpp
void print_x();
void print_y();
int main()
{
print_x();
print_y();
}
使用如下 Makefile 进行编译。x.cpp
编译成 libx.so
和 libx.a
,y.cpp
编译成 liby.so
和 liby.a
。@H_516_1@main.cpp 与 libx.so
和 liby.a
编译链接成 @H_516_1@main.out。@H_696_33@
all : main
x :
gcc -o libx.so -shared -fPIC x.cpp
gcc -o x.o -c x.cpp
ar crs libx.a x.o
y :
gcc -o liby.so -shared -fPIC y.cpp
gcc -o y.o -c y.cpp
ar crs liby.a y.o
clean :
rm -f *.out *.o *.so *.a
main : x y
gcc -o main.out main.cpp -Wl,-rpath=./ -lstdc++ -l. -l:libx.so -l:liby.a
能直接通过编译,使用 ldd main.out
查看一下动态库依赖:@H_696_33@
linux-vdso.so.1 (0x00007ffe71ace000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f1bdea54000)
libx.so => ./libx.so (0x00007f1bdea4f000)
libc.so.6 => /lib64/libc.so.6 (0x00007f1bde845000)
libm.so.6 => /lib64/libm.so.6 (0x00007f1bde769000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1bdec7b000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f1bde74e000)
可以看到 libx.so
被动态链接,而 liby.a
被静态链接,没有显示。执行 @H_516_1@main.out,输出结果也符合预期。@H_696_33@
x
y
由此可见,-l:filename
能直接用于 GCC。这种方法除了控制链接的库是静态的还是动态的之外,还能用于控制库的版本号。例如 libx.so
同时存在两个版本 libx.so.1
和 libx.so.2
,可以使用 -l:libx.so.1
指定版本号为 1
的库。@H_696_33@
以上是大佬教程为你收集整理的GCC 使用库文件名进行链接全部内容,希望文章能够帮你解决GCC 使用库文件名进行链接所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。