交叉编译相关知识整理


因为嵌入式设备的特殊性,比如其内存,性能可能相比与通用设备较弱,或者设备上缺少编译工具链等等原因,很多时候想要在嵌入式设备上使用某些程序时,需要在 在通用机器上编译好,而在嵌入式设备上运行,而这两者的cpu架构是不同的,因而需要好好整理下交叉编译。

构建期间相关知识

查看搜索库的路径

aarch64-linux-gcc -print-search-dirs

查询某个库的路径

使用选项-print-file-name=<lib_name>
如列出libstdc++.so.6的库路径:

aarch64-linux-gcc -print-file-name=libstdc++.so.6

使用目标板的库

在configure时

--with-sysroot[=DIR]    Search for dependent libraries within DIR (or the
                          compiler's sysroot if not specified).

我理解是指定目标板根路径,头文件和库将在这里寻找。

--with-build-sysroot=SYSROOT use sysroot as the system root during the build

最终安装的根目录
待确认

gcc选项

aarch64-linux-gcc有此选项:

--sysroot=<directory>    Use <directory> as the root directory for headers and libraries.

编译构建运行期间相关命令

pkg-config

NAME
pkg-config - Return metainformation about installed libraries

除了在命令行上指定包名之外,还可以给出给定.pc文件的完整路径。这允许用户直接查询特定的.pc文件。
--cflags 这将打印在命令行上编译包所需的预处理器和编译标志,包括它们所有依赖项的标志。标志被“压缩”,因此每个相同的标志只出现一次。如果Pkg-config在命令行上找不到一个或多个包的元数据,则使用非零代码退出。
--libs 该选项与--cflags相同,只是它打印链接标志。与--cflags一样,重复的标志被合并(保持适当的顺序),并且依赖项的标志包含在输出中。
--static 为静态链接输出链接标志
--list-all 列出所有在pkg-config路径发现的模块

可以通过环境变量PKG_CONFIG_PATH来设置 pkg-config的额外搜索路径,pkg-config工具将按照设置路径的先后顺序进行搜索,直到找到指定的.pc文件为止。
需要注意的是,在交叉编译时,目标板的pkg-config输出结果只是针对目标板的,使用可能会有问题,可以设置PKG_CONFIG_SYSROOT_DIR为目标板的根目录,pkg-config则会在pc文件中得到的路径加上前缀$PKG_CONFIG_SYSROOT_DIR,处理后的路径可以正确定位到库文件和头文件的位置。
PKG_CONFIG_PATH环境变量用于指定额外的路径,以冒号分隔。

libtools

以.la为后缀的文件,后面再整理

ldconfig

NAME
ldconfig - configure dynamic linker run-time bindings

SYNOPSIS
/sbin/ldconfig [-nNvXV] [-f conf] [-C cache] [-r root] directory…
/sbin/ldconfig -l [-v] library…
/sbin/ldconfig -p

ldconfig 命令的用途,主要是在默认搜寻目录(/lib 和 /usr/lib)以及动态库配置文件(/etc/ld.so.conf)内所列的目录下,搜索出可共享的动态链接库(lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和缓存文件。缓存文件默认为 /etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表。
Linux下的共享库机制采用了类似于高速缓存的机制,将库信息保存在 /etc/ld.so.cache 里边。程序连接的时候首先从这个文件里边查找,然后再到 ld.so.conf 的路径里边去详细找。这就是为什么修改了 ld.so.conf 要重新运行一下 ldconfig 的原因。
如果是在自定义库的lib,需要修改/etc/ld.so.conf,或者添加路径到LD_LIBRARY_PATH
常见选项:
(1) -v或–verbose : 用此选项时,ldconfig将显示正在扫描的目录及搜索到的动态链接库,还有它所创建的连接的名字。
(2) -n : 用此选项时,ldconfig仅扫描命令行指定的目录,不扫描默认目录(/lib,/usr/lib),也不扫描配置文件/etc/ld.so.conf所列的目录.
(3) -N : 此选项指示ldconfig不重建缓存文件(/etc/ld.so.cache)。若未用-X选项,ldconfig照常更新文件的连接。
(4) -X : 此选项指示ldconfig不更新文件的连接。若未用-N选项,则缓存文件正常更新。
(5) -f CONF : 此选项指定动态链接库的配置文件为CONF,系统默认为/etc/ld.so.conf。
(6) -C CACHE : 此选项指定生成的缓存文件为CACHE,系统默认的是/etc/ld.so.cache,此文件存放已排好序的可共享的动态链接库的列表。
(7) -r ROOT : 此选项改变应用程序的根目录为ROOT(是调用chroot函数实现的)。选择此项时,系统默认的配置文件 /etc/ld.so.conf,实际对应的为 ROOT/etc/ld.so.conf。如用-r /usr/zzz时,打开配置文件 /etc/ld.so.conf时,实际打开的是/usr/zzz/etc/ld.so.conf文件,用此选项,可以大大增加动态链接库管理的灵活性。
(8) -l : 通常情况下,ldconfig搜索动态链接库时将自动建立动态链接库的连接。仅供专业人士使用。
(9) -p或–print-cache : 此选项指示ldconfig打印出当前缓存文件所保存的所有共享库的名字。
(10) -c FORMAT 或 --format=FORMAT : 此选项用于指定缓存文件所使用的格式,共有三种:ld(老格式),new(新格式)和compat(兼容格式,此为默认格式)。
(11) -V : 此选项打印出ldconfig的版本信息,而后退出。
(12) -? 或 --help 或 --usage : 这三个选项作用相同,都是让ldconfig打印出其帮助信息,而后退出。

运行时动态库路径

交叉编译之后需要把进程和动态库都拷贝到目标板,此时若没放在serach路径中,又没使用ldconfig,然后又不使用-rpath硬编码路径,可以使用LD_LIBRARY_PATH来将动态库路径添加到搜索路径。
进程依赖的动态库:

Dynamic section at offset 0x2da8 contains 28 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libparallelmenu.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

如果用readelf查看进程,可以看到有SONAME,这个是进程运行时真正查找的库。

0x0000000e (SONAME)                     Library soname: [libcurl.so.4]

参考资料:
–with-sysroot and --with-build-sysroot
内核交叉编译
编译时动态库名与运行时查找的不一样
pkg-config用法详解
交叉编译中pkg-config和libtool设置
ldconfig 命令用法
Linux library查找顺序(按优先级排列)
LIBRARY_PATH和LD_LIBRAY_PATH的区别和用法
libtool介绍

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值