gcc交叉编译时设置了“--sysroot“会产生哪些影响

GCC交叉编译实战:--sysroot选项如何影响头文件和库搜索路径(附CMake配置技巧) 本文深入解析GCC交叉编译中`--sysroot`选项的核心机制,详细说明其如何影响头文件和库搜索路径,特别是在ARM嵌入式开发中的应用。通过实战案例和CMake配置技巧,帮助开发者解决多架构库路径和符号链接断裂等常见问题,提升交叉编译效率。 阅读详情

gcc=“交叉编译”>交叉编译时设置了"–sysroot"会产生哪些影响

在做交叉编译的时候,常常涉及到一个gcc编译选项--sysroot,这个选项是用来设置目标平台根目录的。--sysroot选项的官方说明如下

--sysroot=dir
Use dir as the logical root directory for headers and libraries. For example, if the compiler normally searches for headers in /usr/include and libraries in /usr/lib, it instead searches dir/usr/include and dir/usr/lib.

If you use both this option and the -isysroot option, then the --sysroot option applies to libraries, but the -isysroot option applies to header files.

The GNU linker (beginning with version 2.16) has the necessary support for this option. If your linker does not support this option, the header file aspect of --sysroot still works, but the library aspect does not.

从--sysroot的说明可以看出,其会对编译和链接过程中,查找头文件和链接库造成影响。

例如:
原本默认会从/usr/include目录中搜索头文件、从/usr/lib中搜索依赖库,
当设置了--sysroot=dir后则会从dir/usr/include搜索头文件、从dir/usr/lib中搜索依赖库。

未设置--sysroot设置了--sysroot=dir后
头文件搜索路径/usr/includedir/usr/include
依赖库搜索路径/usr/libdir/usr/lib

通过gcc -print-search-dirs查看默认动态库搜索路径

$ ./aarch64-linux-gnu-gcc --sysroot=/home/admin/tx2-rootfs -print-search-dirs |
 grep libraries | sed 's/libraries: =//g' | tr ':' '\n' | xargs readlink -f
/usr/local/lib/linaro-7.3.1/lib/gcc/aarch64-linux-gnu/7.3.1
/usr/local/lib/linaro-7.3.1/lib/gcc/aarch64-linux-gnu
/usr/local/lib/linaro-7.3.1/lib/gcc
/usr/local/lib/linaro-7.3.1/aarch64-linux-gnu/lib/aarch64-linux-gnu
/usr/local/lib/linaro-7.3.1/aarch64-linux-gnu/lib64
/home/admin/tx2-rootfs/lib/aarch64-linux-gnu/7.3.1
/home/admin/tx2-rootfs/lib/aarch64-linux-gnu
/home/admin/tx2-rootfs/lib64
/home/admin/tx2-rootfs/usr/lib/aarch64-linux-gnu/7.3.1
/home/admin/tx2-rootfs/usr/lib/aarch64-linux-gnu
/home/admin/tx2-rootfs/usr/lib64
/usr/local/lib/linaro-7.3.1/aarch64-linux-gnu/lib
/home/admin/tx2-rootfs/lib
/home/admin/tx2-rootfs/usr/lib

gcc选项--sysroot对-I的影响

gcc官方文档关于-I依赖库搜索路径的介绍如下:

-I dir
-iquote dir
-isystem dir
-idirafter dir
Add the directory dir to the list of directories to be searched for header files during preprocessing. If dir begins with ‘=’ or $SYSROOT, then the ‘=’ or $SYSROOT is replaced by the sysroot prefix; see --sysroot and -isysroot.

Directories specified with -iquote apply only to the quote form of the directive, #include “file”. Directories specified with -I, -isystem, or -idirafter apply to lookup for both the #include “file” and #include <file> directives.

You can specify any number or combination of these options on the command line to search for header files in several directories. The lookup order is as follows:

1. For the quote form of the include directive, the directory of the current file is searched first.
2. For the quote form of the include directive, the directories specified by -iquote options are searched in left-to-right order, as they appear on the command line.
3. Directories specified with -I options are scanned in left-to-right order.
4. Directories specified with -isystem options are scanned in left-to-right order.
5. Standard system directories are scanned.
6. Directories specified with -idirafter options are scanned in left-to-right order.

You can use -I to override a system header file, substituting your own version, since these directories are searched before the standard system header file directories. However, you should not use this option to add directories that contain vendor-supplied system header files; use -isystem for that.

The -isystem and -idirafter options also mark the directory as a system directory, so that it gets the same special treatment that is applied to the standard system directories.

If a standard system include directory, or a directory specified with -isystem, is also specified with -I, the -I option is ignored. The directory is still searched but as a system directory at its normal position in the system include chain. This is to ensure that GCC’s procedure to fix buggy system headers and the ordering for the #include_next directive are not inadvertently changed. If you really need to change the search order for system directories, use the -nostdinc and/or -isystem options.

经过测试和验证发现,
-Idir编译器只会从dir路径下搜索头文件;
-I=dir或-I$SYSROOT/dir则会受--sysroot影响。

gcc选项--sysroot对-L的影响

gcc官方文档关于-L依赖库搜索路径的介绍比较简单

-Ldir
Add directory dir to the list of directories to be searched for -l.

经过测试和验证,发现结果和-I选项类似
-Ldir编译器只会从dir路径下搜索依赖库;
-L=dir或-I$SYSROOT/dir则会受--sysroot影响。

使用CMAKE进行交叉编译时的建议

1. CMAKE设置--sysroot通过CMAKE_SYSROOT()配置

CMAKE官方文档推荐在工具链文件中设置,如用来交叉编译tx2的工具链文件tx2.cmake内容如下

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR aarch64)

set(SYSROOT_PATH /home/admin/tx2-rootfs)
set(CMAKE_SYSROOT “${SYSROOT_PATH}”)
message(STATUS “Using sysroot path as ${SYSROOT_PATH}”)

set(CMAKE_STAGING_PREFIX /home/admin/workspace/staging/)
set(CMAKE_INSTALL_PREFIX /usr/local)

set(TOOLCHAIN_PATH /usr/local/lib/linaro-7.3.1)
set(TOOLCHAIN_HOST ${ TOOLCHAIN_PATH}/bin/aarch64-linux-gnu)

set(TOOLCHAIN_CC “ T O O L C H A I N H O S T − g c c " < / s p a n > < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ) < / s p a n > < s p a n c l a s s = " t o k e n f u n c t i o n " > s e t < / s p a n > < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ( < / s p a n > T O O L C H A I N C X X < s p a n c l a s s = " t o k e n s t r i n g " > " {TOOLCHAIN_HOST}-gcc"</span><span class="token punctuation">)</span> <span class="token function">set</span><span class="token punctuation">(</span>TOOLCHAIN_CXX <span class="token string">" TOOLCHAINH​OST−gcc"</span><spanclass="tokenpunctuation">)</span><spanclass="tokenfunction">set</span><spanclass="tokenpunctuation">(</span>TOOLCHAINC​XX<spanclass="tokenstring">"{TOOLCHAIN_HOST}-g++”)

set(CMAKE_C_COMPILER ${ TOOLCHAIN_CC})
set(CMAKE_CXX_COMPILER ${ TOOLCHAIN_CXX})

add_link_options(“LINKER:-rpath-link,/home/admin/tx2-rootfs/lib/aarch64-linux-gnu:/home/admin/tx2-rootfs/usr/lib/aarch64-linux-gnu”)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

  • 在执行cmake的时候指定该工具链文件,假如工具链文件的路径为/home/admin/workspace/tx2.cmake
$ cd /home/admin/workspace/myprj/build
$ cmake -DCMAKE_TOOLCHAIN_FILE=/home/admin/workspace/tx2.cmake ..
  • 或者在你CMakeLists.txt定义project(myprj)前添加include(tx2.cmake)亦可
cmake_minimum_required (VERSION 3.19)
include(tx2.cmake)
project (myprj CXX)

2. CMAKE中用来添加头文件搜索路径的宏INCLUDE_DIRECTORIES()并不会受到--sysroot选项影响

这是因为如果想要--sysroot产生作用,则需要-I=include_dir或-I$SYSROOT/include_dir,而如果通过INCLUDE_DIRECTORIES(“$SYSROOT/include_dir”)则CMAKE将这个$SYSROOT/include_dir识别为一个相对于当前工程的相对路径,并且会在编译阶段将路径补全成相对于当前工程目录的绝对路径,例如当前工程路径为/home/admin/workspace/myprj在编译阶段传递到gcc的参数就变成了-I/home/admin/workspace/myprj/\$SYSROOT/include_dir而不是真正想要的-I$SYSROOT/include_dir

推荐做法
直接通过CMAKE本身的包管理工具find_package(pkg)然后将搜索到的包导出的头文件目录列表添加到include_directories(${pkg_INCLUDE_DIR})。

find_package(pkg)
include_directories(${pkg_INCLUDE_DIR})

注意:示例中查找的包名为pkg,则头文件路径会保存在名为pkg_INCLUDE_DIR的变量中,大小写敏感

3. 解决链接时无法找到动态库依赖嵌套问题

如果所编译的可执行程序所依赖的动态库也需要依赖其他动态库,但连接器没有发现,就会报下面错误。

warning: lib*.so.1, needed by lib*.so, not found (try using -rpath or -rpath-link)

解决此类问题的关键点

  • 修复sysroot目录中/usr/lib/aarch64-linux-gnu中错误的动态库符号链接
  • 添加链接选项-Wl,-rpath-link

原理分析

以找不到libm.so.6为例,到/home/admin/tx2-rootfs/usr/lib/aarch64-linux-gnu下查看libm.so

$ ls -la 
lrwxrwxrwx  1 admin admin       32 Jun  5 01:25 libm.so -> /lib/aarch64-linux-gnu/libm.so.6

发现libm.so指向了一个无效的链接,类似的无效符号链接有很多,为了保证以后链接不会出问题,需要:

  1. 修复这些符号链接到正确的路径
  2. 创建/lib/aarch64-linux-gnu符号链接

可是即使修复了指向无效动态库链接的问题,这个链接警告和报错还是没有实际解决。这时就要借助
-rpath和-rpath-link选项了
在CMAKE官方文档中,说可以通过设置CMAKE_INSTALL_RPATH和CMAKE_BUILD_WITH_INSTALL_RPATH这两个变量来向gcc增加-Wl,rpath,选项

set(CMAKE_INSTALL_RPATH "dir")
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)

可是实际操作发现,只能设置-rpath而不能设置-rpath-link。
为了支持-rpath-link,推荐使用add_link_options增加-rpath-link选项

 add_link_options("LINKER:-rpath-link,/home/admin/tx2-rootfs/lib/aarch64-linux-gnu:/home/admin/tx2-rootfs/usr/lib/aarch64-linux-gnu")

add_link_option 宏在cmake 3.13版本以后才支持的
注意:由于--sysroot选项不会作用于-rpath-link,所以要填写完整路径名

谢谢关注

避坑指南:当CMake遇上GCC的--sysroot时,90%开发者会踩的3个路径陷阱 本文深入剖析了在交叉编译场景下,CMake与GCC的--sysroot选项交互时最易出错的三个路径陷阱。针对头文件搜索路径、动态库嵌套依赖解析以及工具链路径配置,提供了清晰的根源分析、实用的解决方案和诊断技巧,帮助开发者避免常见编译与链接错误,提升构建效率。 阅读详情

相关推荐

GCC交叉编译中--sysroot的隐藏坑点:如何正确设置-I和-L路径避免编译失败

本文深入探讨GCC交叉编译中`--sysroot`参数与`-I`/`-L`路径设置的常见陷阱,提供实用解决方案以避免编译失败。通过真实案例和详细配置示例,帮助开发者正确设置路径,优化交叉编译环境,特别适合嵌入式开发和跨平台编译场景。

weixin_30314813的博客 405

CMAKE交叉编译配置SYSROOT的问题

项目场景: 以编译Simd库为例 编译Simd库找不到库或者目标文件: 4-oe-linux/8.2.0/ld: cannot find crti.o: No such file or directory 4-oe-linux/8.2.0/ld: cannot find crtbeginS.o: No such file or directory 4-oe-linux/8.2.0/ld: cannot find /lib/libc.so.6 4-oe-linux/8.2.0/ld: cannot find

5827

ARM-Linux-GCC交叉编译器:嵌入式开发从环境搭建到实战部署

交叉编译是嵌入式开发的核心技术,它允许开发者在x86主机上为ARM等不同架构的目标设备生成可执行代码。其原理在于使用专门的交叉编译器工具链,将源代码翻译为目标平台特有的机器指令。这项技术的价值在于极大提升了开发效率,开发者无需在资源受限的嵌入式设备上进行本地编译。在物联网、边缘计算和智能硬件等应用场景中,交叉编译是连接开发环境与目标运行环境的桥梁。本文以arm-linux-gcc这一经典工具链为例,深入讲解其选型、安装、环境配置及在树莓派等嵌入式Linux平台上的实战应用,帮助开发者解决从编译到部署的全流程

weixin_34296641的博客 341

【cmake开发(15)】交叉编译时如何设置CMAKE_SYSROOT和CMAKE_FIND_ROOT_PATH

在交叉编译场景中,正确设置和以确保 CMake 能够正确地找到 ARM 架构的库、头文件和其他系统文件。应该设置为你的 ARM 文件系统根目录,即。这个变量会告诉编译器和链接器在查找标准库和系统文件时使用这个目录作为根目录。用于为 CMake 的find_系列命令(如find_path等)添加额外的搜索路径前缀。如果你有一些特定的库或头文件不在 ARM 文件系统的标准位置,或者你想要在除了之外的额外目录中搜索,你可以将那些目录添加到中。

AbiUni(YY熊) 4500

arm64和x64交叉编译时头文件路径设置技巧

在进行arm64和x64架构的交叉编译时,正确设置头文件路径至关重要。通过合理配置编译器搜索路径,可有效避免因架构差异导致的编译错误,提升跨平台构建效率。

weixin_33240461的博客 464

编译选项--sysroot和-isysroot对嵌入式编译的影响

sysroot和-isysroot选项在使用方式上有所不同,–sysroot用于编译器,-isysroot用于链接器。其中,–sysroot和-isysroot是两个常用的选项,用来指定系统根目录的位置,对编译过程和结果产生重要影响。这个选项告诉链接器在指定的系统根目录中查找库文件。在上述示例中,–sysroot选项指定了系统根目录的位置,并且编译器将在该目录中查找所需的头文件和库文件。在上述示例中,-isysroot选项指定了系统根目录的位置,并且链接器将在该目录中查找所需的库文件。

WangWEel的博客 1316

Linux:gcc交叉编译时设置了“--sysroot“会产生哪些影响

一、介绍 在做交叉编译的时候,常常涉及到一个gcc编译选项--sysroot,这个选项是用来设置目标平台根目录的。--sysroot选项的官方说明如下: --sysroot=dir Use dir as the logical root directory for headers and libraries. For example, if the compiler normally searches for headers in /usr/include and libraries in /usr/

hhd1988的专栏 4079

编译链接实战(4)--sysroot和-isysroot选项对编译的影响

在做交叉编译的时候,常常涉及到一个gcc编译选项–sysroot,这个选项是用来设置目标平台根目录的。–sysroot选项的官方说明如下从--sysroot的说明可以看出,其会对编译和链接过程中,查找头文件和链接库造成影响。例如:原本默认会从目录中搜索头文件、从/usr/lib中搜索依赖库,当设置了后则会从搜索头文件、从中搜索依赖库。通过。

二进制君 3404

Linux gcc 增加sysroot,从设备使用sysroot交叉编译

我用sshfs将目标设备的根(Beaglebone Black,ARM arch)安装到主机上的一个文件夹中,并尝试使用--sysroot但有一个问题-有些include头文件不仅位于/usr/include文件夹中,还位于其子文件夹中arm-linux-gnueabihf. 同样还有/usr/lib/arm linux gnueabihf文件夹。“Hello world”示例编译失败[gmixa...

weixin_42491886的博客 1835

激光雷达与相机融合(四)----基于激光雷达与相机的碰撞检测

在这一部分,基于前面的各个部分内容,将利用激光雷达和相机实现目标的检测分类及单目标跟踪,并对车辆前方的车辆目标计算相应的碰撞时间TTC。计算方法分别利用相机和雷达实现。 1.系统的总体架构: 2.TTC计算 简单介绍一下通过激光雷达和相机计算碰撞时间的原理: 利用激光雷达点计算碰撞时间:首先根据检测框聚类出前车目标的点,并过滤掉这些点中的离群点,然后找出这些点中相对于本车最近的点,基于前后两帧以及数据采集频率就可以求解出相对速度,然后用当前帧的距离除以速度得出当前的TTC。但该方法对最近点的选取稳定性不是

张飞飞的博客 3984

AnyLogic 8.8.3 最新版安装指南:从下载到配置的完整流程(附Java环境设置技巧)

本文提供了AnyLogic 8.8.3最新版从下载到配置的完整安装指南,重点解决了跨平台(Windows、macOS、Linux)部署中的常见问题。核心内容详细讲解了Java开发环境(JDK)的精准配置技巧,包括版本选择、系统环境变量设置与验证,确保为仿真建模工作奠定稳固基础。

efc1234567的博客 756

从踩坑到解决:CMake交叉编译时features.h报错的全过程记录

本文详细记录了在CMake交叉编译过程中遇到features.h报错的完整排查与解决过程。文章深入分析了CMAKE_SYSROOT与CMAKE_FIND_ROOT_PATH这两个关键变量的区别与正确用法,并提供了针对ARM64平台的具体配置方案和最佳实践,帮助开发者彻底解决此类编译环境配置问题。

vim8coder的博客 1025

从零打造音乐会级特雷门琴:原理、设计与调试全解析

电子乐器的工作原理通常基于信号生成与调制。特雷门琴作为世界上最早的电子乐器之一,其核心原理是利用射频振荡器和电容传感,将演奏者的手势变化转化为音高与音量信号。这种技术通过外差式混频实现音高控制,并利用压控放大器实现细腻的音量动态,其工程价值在于将抽象的空间位置信息精确映射为连续的音频参数。在音乐制作、声音艺术和交互装置等领域,这类技术为创造独特的演奏体验提供了基础。本文聚焦于如何从电路层面实现一台高稳定性的特雷门琴,详细阐述了从LC振荡器设计、天线场形优化到音色混合检波等关键环节,并分享了基于LTspice

weixin_34046298的博客 170

--sysroot 在编译时的作用

--sysroot 在编译时的作用

开阳-英飞凌-小华 1279

SAP 批量处理分包事后调整:BAPI_GOODSMVT_CREATE 关键参数与避坑指南

本文详细解析了SAP系统中使用BAPI_GOODSMVT_CREATE进行分包事后批量调整的关键参数配置与常见错误排查。重点介绍了GOODSMVT_CODE设置为'07'的必要性、GOODSMVT_ITEM结构体的正确配置方法,以及如何避免M7384、M7386等常见错误,帮助用户高效处理分包业务中的数量调整问题。

weixin_29276847的博客 565

(蓝桥杯)STM32G431RBT6(SysTick timer)

选用最基础的定时器。

2301_81764359的博客 1897

CMake交叉编译避坑指南:当--sysroot遇上find_package时的路径处理玄学

本文深入解析CMake交叉编译中`--sysroot`与`find_package`的路径处理机制,揭示GCC工具链与CMake抽象层的交互逻辑。通过实战案例展示如何正确处理头文件和库文件路径,提供五项黄金法则确保交叉编译环境的一致性,帮助开发者高效构建ARM64等嵌入式系统。

ii567的博客 71

Zuken E3.series schematic/cable/Formboard 连载(1)

​ 1987-2001年,CIM-Team公司(德国)推出基于MS-DOS环境下运行的CAD软件DDS-schematic 2002年,在此基础上,推出基于windows环境下运行,应用于电气工程领域的E3.Series 2002-2006年,CIM-Team公司成为Zuken公司(日本)的一家分公司,实现电子电气系统的完整设计平台 覆盖电子、电气原理设计,三维机柜设备布局与配线设计,线缆线束设计及其各类生产报表文档生成的完整设计流程

u010930036的博客 2498

Qt 5.14.2 ARM交叉编译实战:从sysroot到板端部署的完整指南

在嵌入式Linux开发中,交叉编译是连接x86宿主机与ARM目标板的核心技术,其本质是在一套环境中编译生成另一套架构可运行的代码。要成功完成这一过程,不仅需要正确选择工具链,更需深刻理解sysroot的作用——它将编译器的视线限制在目标板根文件系统内,避免宿主机库的污染。同时,参数配置、模块裁剪、依赖库如tslib的对接,以及板端部署时的动态链接与显示后端选择,都直接影响最终应用的稳定性与性能。本文以Qt 5.14.2为例,系统梳理了从环境准备、configure配置、编译排错到目标板运行的完整链条,聚焦实

weixin_34183910的博客 311

【人脸识别/轻量级模型】MobileFaceNet:适用于人脸识别的轻量级网络模型(文末附pytorch代码)

MobileFaceNet:用于人脸识别的轻量级网络模型

Roaddd的博客 6984

【SpringBoot】1、创建第一个SpringBoot项目

创建SpringBoot项目可以通过两种方式,1、通过访问:https://start.spring.io/,SpringBoot的官方网站进行创建SpringBoot项目;2、通过工具(例如:Idea)创建SpringBoot项目。本次使用开发工具:Idea创建我的第一个SpringBoot项目。 首先,打开我们的Idea开发工具 选择Create New Poject(创建一个新的项目) ...

JACKAL 21万+

ARM Cortex-A平台下GCC交叉编译器详解

深入讲解在ARM Cortex-A架构上使用GCC进行交叉编译的关键步骤与配置方法,帮助开发者高效构建目标平台程序,掌握交叉编译工具链的核心应用。

weixin_29867767的博客 364

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

用Clang在Windows上交叉编译ARM Linux程序(告别GCC实战)

交叉编译是嵌入式开发中不可或缺的环节,指在一种平台上编译生成另一种平台可执行代码的过程。传统的GCC交叉编译方案在Windows上配置繁琐,工具链获取困难,且架构切换极不灵活。而Clang作为现代编译器,将前端与后端解耦,通过--target参数即可轻松指定目标架构,天生适合交叉编译。配合LLD链接器与ARM sysroot,开发者无需更换编译器本体,便能生成ARM Linux可执行文件。这一方案在嵌入式开发、ARM Linux应用开发及CI流水线中具有极高的实用价值,尤其适合使用Windows笔记本、面向

weixin_34288121的博客 380

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

上一篇: 静电导致CPU死机
下一篇: QT笔记--嵌入式QT交叉编译与移植(含OpenGL ES2)
szembed
博客等级 码龄18年 1475粉丝 256原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值