文章目录
1.ld命令1.1.简介1.2.使用示例
2.ld命令搜索路径顺序2.1.搜索路径顺序2.2.如何查看ld(链接器)的搜索顺序及编译时需要打开的库2.2.1.查看ld默认搜索路径2.2.2.查看编译时需要打开的库
1.ld命令
参考: Linux 命令(65)—— ld 命令 使用 ld 命令链接目标文件生成可执行文件
1.1.简介
ld(Link eDitor)命令是二进制工具集 GNU Binutils 的一员,是 GNU 链接器,用于将目标文件与库链接为可执行文件或库文件。
ld 命令支持众多链接选项,但是大部分选项很少被使用,常用参数:
-o 指定输出文件名
-e 指定程序的入口符号
1.2.使用示例
(1)链接目标文件生成可执行文件。如给定 C++ 目标文件 test.o 与 main.o,生成可执行文件 test.out。注意这个过程中还需要链接很多系统库文件,因此写法非常复杂。这也是ld命令很少使用的原因。
ld /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib64 -L/usr/lib -lstdc++ -lm -lgcc_s -lc -lgcc main.o test.o -o test.out
(2)因为生成一个C++可执行文件,需要依赖很多系统库和相关的目标文件,比如C语言库libc.a,所以使用ld进行链接时,需要注意添加较长的命令选项,不然会报链接错误。使用g++ -v命令可以查看生成可执行文所需的相关依赖。
g++ -v main.o test.o
...
usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib64 -L/usr/lib -lstdc++ -lm -lgcc_s -lc -lgcc main.o test.o
2.ld命令搜索路径顺序
2.1.搜索路径顺序
参考:Ubuntu之ld搜索路径顺序
注意:下面说的搜索顺序应该是对的,但是其他内容可能存在一些错误。比如LIBRARY_PATH和LD_LIBRARY_PATH就分别是静态库和动态库吗?另外库的默认搜索路径不止/lib /usr/lib /usr/local/lib这些。
静态库链接时搜索路径顺序
1. ld会去找GCC命令中的参数-L
2. 再找gcc的环境变量LIBRARY_PATH
3. 再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的
动态链接时、执行时搜索路径顺序:
1. 编译目标代码时指定的动态库搜索路径
2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径
3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径
4. 默认的动态库搜索路径/lib
5. 默认的动态库搜索路径/usr/lib
有关环境变量
LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径
LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径
2.2.如何查看ld(链接器)的搜索顺序及编译时需要打开的库
参考:如何查看ld(连接器)的搜索顺序及编译时需要打开的库
2.2.1.查看ld默认搜索路径
# 1. 把ld命令脚本的所有内容输入到ld_path文件中
ld --verbose | tee ~/ld_path.txt
# 2.仅仅过滤其中SEARCH有关的部分显示
ld --verbose | grep SEARCH
其中,ld --verbose | grep SEARCH显示结果如下,可以看到不仅包括lib /usr/lib uar/local/lib等目录,还有其他目录。
2.2.2.查看编译时需要打开的库
假设有一个文件dummy.cpp,内容如下:
#include
int main()
{
}
使用g++ dummy.cpp -Wl,--verbose | grep succeeded,或者系统语言是中文的话,输入g++ dummy.cpp -Wl,--verbose | grep 成功,查看编译过程中打开的库。结果如下: