参考:程序编译与运行时头文件或动态链接库的查找(一) - 爱码网
最近在做linux系统(ubuntu)下编译linuxptp到ARM开发板的移植,在做得过程中产生了一些疑问:
- 通过-I参数可指定编译依赖的头文件路径
比如在main.c中包含了test.h(在/usr/local/tesh文件夹),那么可这样编译:arm-linux-gcc main.c -I /usr/local/tesh
- 设置gcc的环境变量C_INCLUDE_PATH(编译.c文件)、CPLUS_INCLUDE_PATH (编译.cpp文件)、CPATH(编译 C 、 C++ 和 Objective-C )来找头文件
可通过export命令去设置环境变量:比如
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/local/tesh
即可设置头文件搜索路径
- 编译还会到默认的路径去搜索头文件,比如main.c包含stdio.h可以通过arm-linux-gcc main.c编译过.
可以通过:命令
echo 'main(){}' | /home/pc123/Public/workspace/toolchain/AG550/ql-ag550qcn-le20-gcc820-v1-toolchain/gcc/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-gcc -E -v - 来查找 【加粗的是交叉工具链gcc的位置】
可以看到交叉工具链的默认搜索路径是如图的样子
- 通过sysroot参数
比如arm-oe-linux-gnueabi-gcc --sysroot=dir main.c 就可让搜索的默认路径改为如下的方式
gcc交叉编译时设置了“--sysroot“会产生哪些影响_AgileTortoise的博客-CSDN博客_gcc sysroot
有这样一个例子,main.c依赖libtest.so,那么编译可参考如下方法
- 用户可以通过-L指定连接时库的路径
比如libtest.so这个库在/usr/pc123/test这个位置,那么
arm-oe-linux-gnueabi-gcc main.c -L = /usr/pc123/test -ltest
即可在编译main.c链接libtest.so,并且在/usr/pc123/test路径查找
- 默认的路径
比如把libtest.so放到/lib /usr/lib /usr/local/lib,即可通过gcc main.c ltest编过
- 实用 | 程序运行时,是怎么找到动态库的?_嵌入式资讯精选的博客-CSDN博客
- 有这样一个例子,main.c依赖libtest.so,那么编译可参考如下方法
编译出来的可执行程序在开发板跑起来,它依赖的库是在哪里找到的呢?编译过程的库是在ubuntu上找到的,那arm板上这个库又是去哪里找的呢?
会按照一定的顺序在下面这些方式定义的路径去寻找
- LD_PRELOAD
export LD_PRELOAD=./libtest.so
./main 即可
取消环境变量:unset LD_PREALOD
RPATH即“runtime library path”,那么可这样编译:
gcc main.c -Wl,-rpath=/usr/local/lib/ -ltest 这样在运行的时候会在/usr/local/lib/找libtest.so
LD_LIBRARY_PATH或者在运行前,配置环境变量,这样就会在/usr/local/lib查找库
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib
./main 即可
/etc/ld.so.conf
$ cat /etc/ld.so.conf include /etc/ld.so.conf.d/*.conf $ ls /etc/ld.so.conf.d/ fakeroot-x86_64-linux-gnu.conf libc.conf x86_64-linux-gnu.conf $ cat libc.conf /usr/local/lib
打开/etc/ld.so.conf发现,其实是去调用/etc/ld.so.conf.d/下的所有的.conf文件,打开libc.conf文件发现,包含的路径是/usr/local/lib目录所以要用这种办法:
(1) 就在/etc/ld.so.conf.d/文件下加个 test.conf文件
(2)在里面写上需要查找库的位置(比如/usr/local/lib)
(3)sudo ldconfig让config生效
/lib/ 和/usr/lib/
这两个是默认路径,可把so放到这两个目录下
LD_DEBUG=libs
$ LD_DEBUG=libs ./main 3557: find library=libtest.so [0]; searching 3557: search cache=/etc/ld.so.cache 3557: trying file=/usr/local/lib/libtest.so
- LD_DEBUG=symbols ./main //查看跑起来查找符号表的过程
- aarch64-linux-gnu-objdump -x "filename" | grep "NEEDED"
- aarch64-linux-readelf -a "filename" | grep "Shared"
【filename是可执行程序】【以上两种方式均可】
比如 B asicService依赖的文件如下
查看库文件 :发现libstdc++.so.6是链接文件,真正的文件是libstdc++.so.6.0.28【因为最大是 21M】
把libstdc++.s o.6.0.28放到板子上,然后把libstdc++.so.6.0.28改名为libstdc++.so.6,然后程序就可以跑起来。