配置交叉编译器后出现如下报错:
/usr/arm/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.4.1/../../../../aarch64-linux-gnu/bin/ld: 找不到 -lz
/usr/arm/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.4.1/../../../../aarch64-linux-gnu/bin/ld: 找不到 -lcrypto
/usr/arm/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.4.1/../../../../aarch64-linux-gnu/bin/ld: 找不到 -lssl
经检查user/lib下存在该库的链接,但编译就是报错,没办法把上述三个库的链接重新放到了makefile指定的库文件路径下:
到指定库文件下,建立库的软链接:
ln -s /home/voy/桌面/ubuntu18/ubuntu18/usr/lib/libz.so ./
ln -s /home/voy/桌面/ubuntu18/ubuntu18/usr/lib/libssl.so ./
ln -s /home/voy/qihua-x507-linux4.9/release/ubuntu18/ubuntu18/usr/lib/libcrypto.so ./
编译通过。
知识点总结:
1.头文件路径添加:
-Idir1 -Idir2 ...
2. 两种文件包含: #include <stdio.h> #include "stdio.h"
使用尖括号表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的),而不在源文件目录去查找;
使用双引号则表示首先在当前的源文件目录中查找,若未找到才到包含目录中去查找。
3. 文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。
4..如果想在指定路径下检索头文件,可加选项-I。如我的/home/Desktop目录下有个头文件local1.h,在编译包含local1.h的test.c文件时,
可用:gcc test.c -o test -I /root/Desktop。
C语言库文件的查找路径:
1.链接阶段(link time)
此阶段,需要告诉编译器,在哪里找到库文件?以静态还是动态的方式链接库文件?默认情况下使用动态方式链接,这要求存在对应的.so动态库文件,
如果不存在,则寻找相应的.a静态库文件。若在编译时向gcc传入-static选项,则使用静态方式链接,这要求所有库文件都必须有对应的*.a静态库。
在链接阶段,gcc编译器如何寻找库文件呢(linker本身并没有默认的查找路径,这些查找路径是由gcc传递给linker的)?
可以在编译时,向gcc加入-v选项来观察它向linker传递的库文件查找路径(观察LIBRARY_PATH变量的值),通常查找路径如下:
1) 任何由-rpath-link或-rpath选项指定的目录
2) LD_RUN_PATH(如果没有找到-rpath或-rpath-link选项)
3) -Ldir1 -Ldir2 ...
4) /usr/lib/gcc///
5) /usr/lib/
-rpath-link与-rpath区别:-rpath选项指定的目录被硬编码到可执行文件中,-rpath-link选项指定的目录只在链接阶段生效,这两个选项都是链接器ld的选项
例: gcc -Wl, -rpath, /usr/local/lib 相当于向ld向传递了如下参数: ld -rpath /usr/local/lib
如果没有设置-rpath或-rpath-link选项,则查找LD_RUN_PATH环境变量指定的目录,并把它当作-rpath选项来处理。
第三项 :-Ldir1 -Ldir2 ...,是我们通过gcc的-L选项向其指定的库文件查找路径,查找顺序按照我们传递的-L参数从左到右进行搜索;
第四项属于gcc自己的库目录;第五项/usr/lib/是Linux系统默认的系统库文件的目录。第四、第五项,都是gcc自动向linker传递的查找目录。
ps:gcc有时会把/usr/local/lib/目录也作为链接阶段的查找路径,但在运行时阶段,却说找不到该库文件
如果设置了 LIBRARY_PATH变量 ,使用gcc -v可以看到LIBRARY_PATH变量值为:LIBRARY_PATH= /XXX/:/XXX/
2、运行时阶段(runtime)
仅当可执行程序采用动态的方式链接库文件时,才会存在运行时库文件的查找问题。对于这种可执行程序,它本身只是记录动态库的名称。
所以在运行该程序时,操作系统的加载程序(ld.so)需要根据库的名称,在必要时加载库文件到内存中。
在linux中,在运行时阶段,动态库(又叫共享库)的查找路径如下:
1) -rpath选项指定的目录(已被硬编码到可执行文件中)
2) LD_LIBRARY_PATH
3) /lib或/usr/lib
4) 系统默认的查找路径
可以通过readelf查看被硬编码到可执行文件中的rpath: readelf -d <可执行文件名>
LD_LIBRARY_PATH 通常不建议使用这个环境变量,因为修改这个变量意味着影响所有依赖于这个环境变量的程序
系统默认的查找路径: ld.so通过读取/etc/ld.so.cache文件来查找库文件的位置,如果没有找到则继续从/etc/ld.so.conf文件中指定的目录查找
其他:
1) 查看某个程序使用了那些动态库,使用ldd命令查看 # ldd XXX
2) 指定链接库:g++ -o demo main.cpp ---> g++ -o demo -lz -lm -lrt main.cpp
3) 指定库目录路径: -Ldir1 指定该目录中具体的库 -Ldir1 -lsdk_compose -lsdk_g2d -lsdk_dvr : 命名规则 -lsdk_g2d 对应的库应该位 libsdk_g2d.so
4) 指定头文件路径:-I XXX
5) 链接器ld: GNU的链接器称为ld,它负责把若干目标文件与若干库文件链接起来,并重定位它们的数据位置。在编译一个程序时,最后一步就是运行ld命令
6) 安装库: sudo apt-get install apt-file ------- apt-file updat ------- apt-file search NAME.so
7) find查找文件:find -name NAME.so