• 交叉编译及运行的理解


    参考:程序编译与运行时头文件或动态链接库的查找(一) - 爱码网

    最近在做linux系统(ubuntu)下编译linuxptp到ARM开发板的移植,在做得过程中产生了一些疑问:

    • 程序编译过程中依赖的头文件,库是在哪里找的?

    1. 在ubuntu用交叉工具链arm-linux-gcc编译的头文件又是哪里找的呢?

    • 通过-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

    2. 在ubuntu用交叉工具链arm-linux-gcc编译依赖的库是在哪里找的呢?

    有这样一个例子,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编过

    3. 在ubuntu下用交叉工具链编译出来的可执行程序在arm开发板是如何找到运行阶段依赖的库的?

    编译出来的可执行程序在开发板跑起来,它依赖的库是在哪里找到的呢?编译过程的库是在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
    1. $ cat /etc/ld.so.conf
    2. include /etc/ld.so.conf.d/*.conf
    3. $ ls /etc/ld.so.conf.d/
    4. fakeroot-x86_64-linux-gnu.conf libc.conf x86_64-linux-gnu.conf
    5. $ cat libc.conf
    6. /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放到这两个目录下

    4. 查看可执行程序跑起来找库,符号表的过程

    • LD_DEBUG=libs

    1. $ LD_DEBUG=libs ./main
    2.       3557:    find library=libtest.so [0]; searching
    3.       3557:     search cache=/etc/ld.so.cache
    4.       3557:      trying file=/usr/local/lib/libtest.so 
    • LD_DEBUG=symbols ./main   //查看跑起来查找符号表的过程

    5. 使用交叉编译工具链在ubuntu查看(交叉编译生成的)可移植性程序的依赖情况

    • 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,然后程序就可以跑起来。

  • 相关阅读:
    关于电脑功耗与电费消耗的问题,你了解多少?
    【学习总结】激光雷达与相机外参标定:原理与代码
    模板初阶学习
    mybatis动态sql一对多查询
    Excel中text函数5中常用方法
    AI云服务平台大全:GPU租用 | App托管 | MLOps平台
    Dev C++开发环境的配置及使用
    Java Class反射
    XDOJ字符串压缩
    SpringMVC常用注解总结
  • 原文地址:https://blog.csdn.net/m0_37844072/article/details/126322482