【Linux应用】交叉编译环境配置,以及最简单粗暴的环境移植(直接从目标板上复制)
文章目录
- 交叉编译器
- 含有三方库的交叉编译
- 直接从目标板上复制编译环境
- glibc库不一致报错
- 方法1
- 方法2
- 附录:
- ZERO 3烧录
- ZERO 3串口shell
- 外设挂载
- 连接WiFi
- SSH连接
- SSH的文件交互
- 换源
交叉编译器
由于内核架构不同 指令集不同 在PC(x86架构)上编译的代码无法直接在ARM上运行
为了能够在PC上编译ARM架构的可执行程序 那么就需要用到交叉编译器
通常在PC的Linux平台下进行交叉编译
大多数Linux设备都为aarch内核 目前大部分为64位系统 所以就要安装aarch64的交叉编译器
# 查看可以安装的版本
apt-cache search aarch64
# 选择可以安装的版本进行安装
# 此处选择gcc-5-aarch64-linux-gnu以及g++-5-aarch64-linux-gnu进行安装
sudo apt-get install gcc-5-aarch64-linux-gnu
sudo apt-get install g++-5-aarch64-linux-gnu
# 安装依赖
sudo apt --fix-broken install
# 安装一个没有版本号的gcc和g++
sudo apt-get install gcc-aarch64-linux-gnu
sudo apt-get install g++-aarch64-linux-gnu
# 查看版本
aarch64-linux-gnu-g++ -v
aarch64-linux-gnu-gcc -v
一般来说 直接运行以下即可:
# 安装一个没有版本号的gcc和g++
sudo apt-get install gcc-aarch64-linux-gnu
sudo apt-get install g++-aarch64-linux-gnu
# 查看版本
aarch64-linux-gnu-g++ -v
aarch64-linux-gnu-gcc -v
安装后 可以查看所在位置
~$ whereis aarch64-linux-gnu-gcc
aarch64-linux-gnu-gcc: /usr/bin/aarch64-linux-gnu-gcc /usr/share/man/man1/aarch64-linux-gnu-gcc.1.gz
当使用cmake时 可以直接使用set CMAKE_C_COMPILER
和CMAKE_CXX_COMPILER
指定编译器
如:
cmake_minimum_required(VERSION 3.10)
set (CMAKE_C_COMPILER "/usr/bin/aarch64-linux-gnu-gcc")
set (CMAKE_CXX_COMPILER "/usr/bin/aarch64-linux-gnu-g++")
project(main)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
include_directories (${PROJECT_SOURCE_DIR}/include)
aux_source_directory(src SRC_LIST)
add_executable(main ${SRC_LIST})
含有三方库的交叉编译
配置了相关交叉编译后 即可通过编译器编译出适合ARM平台运行的程序
但若需要链接一些三方库 则需要另外配置编译环境
譬如链接了opencv库 则就需要将opencv源码下载下来 用交叉编译器编译一遍 然后再编译使用该库的工程
一般需要用到cmake来编译opencv这些三方库
sudo apt install cmake
sudo apt-get install cmake-gui
编译opencv:
cd your opencv dir
unzip opencv-4.6.0.zip
unzip opencv_contrib-4.6.0.zip
cd opencv-4.6.0
unzip .cache.zip #将.cache解压到opencv-4.6.0下
mkdir build
mkdir build/aarch64_1
mkdir install
mkdir install/aarch64_1
cd build/aarch64_1
安装依赖包:
#安装一些依赖
sudo apt install cmake git libavcodec-dev libavformat-dev libswscale-dev \
python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev \
libjasper-dev libdc1394-22-dev
sudo apt install libgtk2.0-dev
sudo apt install pkg-config
设置cmakelist
# 设置目标系统信息
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
# 设置交叉编译工具链路径
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)
# 设置根文件系统路径
set(CMAKE_SYSROOT /path/to/your/sysroot)
# 设置查找规则
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
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:
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../aarch64-linux-gnu.toolchain.cmake \
-D WITH_OPENCL=OFF \
-D WITH_CUDA=OFF \
-D BUILD_TESTS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=OFF \
../opencv
编译:
make -j$(nproc)
make install
生成相关opencv交叉编译文件后 就可以在工程中导入
但这种方式比较繁琐
直接从目标板上复制编译环境
另外还有一种方式 就是直接复制编译环境
可以先在目标板上装一个编译器 编译一下opencv
然后再把整个环境复制过来
需要从开发板获取的内容:
譬如用到了PCL和opencv库:
/usr/lib/aarch64-linux-gnu/ #下的所有OpenCV/PCL相关.so文件和符号链接
/usr/include/opencv4/ #头文件目录
/usr/lib/cmake/ #下的CMake配置文件
/usr/include/pcl-1.11/ #PCL头文件
在开发板上执行以下命令可以看到这两个库的依赖
dpkg -l | grep -E 'opencv|pcl|boost' > deps_list.txt
超级多
所以还不如干脆直接整个文件夹都拷过来
也就是usr目录下的include文件夹 和 lib目录下的编译器以及cmake文件夹
可以将其放到一个目录下 如radxaboot 然后将这个目录放到Linux环境的某个目录 比如 /home/ubuntu/radxaboot
通过cmake检查opencv配置:
在cmake中进行配置:
...
# 交叉编译配置必须放在project()之前
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)
set(CMAKE_SYSROOT /home/ubuntu/radxaboot) # 替换为实际的根文件系统路径
...
# 显式指定库配置路径(根据CMakeCache中的记录)
set(OpenCV_DIR ${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/cmake/opencv4)
set(PCL_DIR ${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/cmake/pcl)
set(Boost_COMPILER "-gcc10") # 根据实际gcc版本设置
...
# 查找依赖包(保持原有逻辑)
find_package(OpenCV REQUIRED)
find_package(PCL REQUIRED COMPONENTS common io filters features visualization)
find_package(Threads REQUIRED)
find_package(Boost REQUIRED COMPONENTS filesystem system iostreams date_time regex)
...
# 调整后的包含目录
include_directories(
${OpenCV_INCLUDE_DIRS}
${PCL_INCLUDE_DIRS}
${CMAKE_SYSROOT}/usr/include/eigen3
${CMAKE_SYSROOT}/usr/include/pcl-1.11
${CMAKE_CURRENT_SOURCE_DIR}
)
...
target_link_libraries(PCN
${OpenCV_LIBS}
${PCL_LIBRARIES}
Threads::Threads
${Boost_LIBRARIES}
# 补充交叉编译需要的特殊库
-Wl,--rpath-link=${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu
-Wl,--rpath-link=${CMAKE_SYSROOT}/lib/aarch64-linux-gnu
)
...
然后检测cmake
# 检查OpenCV配置
cmake -DCMAKE_TOOLCHAIN_FILE=../arm64_rootfs.cmake -DOpenCV_DIR=${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu/cmake/opencv4 ..
通过后即可编译 但是会报include错误
那么就需要加上:
# 调整后的包含目录
include_directories(
${OpenCV_INCLUDE_DIRS}
${PCL_INCLUDE_DIRS}
${CMAKE_SYSROOT}/usr/include/eigen3
${CMAKE_SYSROOT}/usr/include/pcl-1.11
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SYSROOT}/usr/include/vtk-7.1 # 新增VTK头文件路径
)
# 强化后的链接库配置
target_link_libraries(PCN
${OpenCV_LIBS}
${PCL_LIBRARIES}
Threads::Threads
${Boost_LIBRARIES}
# 补充交叉编译需要的特殊库
-Wl,--rpath-link=${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu
-Wl,--rpath-link=${CMAKE_SYSROOT}/lib/aarch64-linux-gnu
vtkCommonCore-7.1 # 示例VTK库链接
vtkFiltersGeneral-7.1 # 根据实际报错添加所需模块
)
另外需要确认以下两点:
移植的根文件系统中存在/usr/include/vtk-7.1
目录
确认VTK库文件路径在${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu
如果仍有其他VTK相关报错,建议在CMakeLists.txt开头显式指定VTK路径:
set(VTK_DIR ${CMAKE_SYSROOT}/usr/lib/cmake/vtk-7.1)
find_package(VTK REQUIRED)
再次执行编译就好了 但是要指定我们导入的库目录
cmake -B build -DCMAKE_SYSROOT=/home/ubuntu/radxaboot
编译成功后即可
glibc库不一致报错
如果编译的是静态文件 那么编译成功后就可以直接运行
但如果编译的是动态库
那么就需要考虑编译器版本是否一致 且glibc库是否一致
编译器版本可以在目标板上执行编译器版本命令进行获取
在编译器目录下执行命令:
sudo ./libc.so.6
可以查看libc版本
这里就可以获取到版本信息为GCC 10.2.1 + GLIBC 2.31
方法1
方法2
那么在PC的交叉环境中就要安装对应的编译器:
# 添加 Debian 11 (bullseye) 的仓库源(该版本包含所需工具链)
sudo tee /etc/apt/sources.list.d/debian-bullseye.list <<EOF
deb [arch=amd64] http://deb.debian.org/debian bullseye main
deb [arch=amd64] http://deb.debian.org/debian-security bullseye-security main
EOF
# 启用多架构支持并安装工具链
sudo dpkg --add-architecture arm64
sudo apt update
sudo apt install -y \
gcc-10-aarch64-linux-gnu \
g++-10-aarch64-linux-gnu \
libc6-arm64-cross=2.31-13+deb11u11 \
libc6-dev-arm64-cross=2.31-13+deb11u11
# 验证版本
aarch64-linux-gnu-gcc-10 -v # 应显示 gcc version 10.2.1
aarch64-linux-gnu-readelf -a /usr/aarch64-linux-gnu/lib/libc.so.6 | grep 'GNU C Library' # 应显示 2.31
但是 多半会安装失败 提示未找到对应版本的库文件
那么就可以手动下载:
# 进入临时目录
mkdir -p ~/temp_cross && cd ~/temp_cross
# 从清华镜像站下载指定版本(适用于Debian 11 bullseye)
wget https://mirrors.tuna.tsinghua.edu.cn/debian/pool/main/g/glibc/libc6-arm64-cross_2.31-13+deb11u11_all.deb
wget https://mirrors.tuna.tsinghua.edu.cn/debian/pool/main/g/glibc/libc6-dev-arm64-cross_2.31-13+deb11u11_all.deb
# 安装软件包
sudo dpkg -i libc6-arm64-cross_2.31-13+deb11u11_all.deb
sudo dpkg -i libc6-dev-arm64-cross_2.31-13+deb11u11_all.deb
# 安装主编译器(此时应该可以正常找到依赖)
sudo apt install -y gcc-10-aarch64-linux-gnu g++-10-aarch64-linux-gnu
# 清理安装包
rm libc6-*-cross_*.deb
强制安装配置:
# 修复依赖关系
sudo apt --fix-broken install
# 设置候选版本(确保后续更新不会覆盖)
sudo apt-mark hold libc6-arm64-cross libc6-dev-arm64-cross
安装后即可重新编译
附录:
开发板快速上手:镜像烧录、串口shell、外设挂载、WiFi配置、SSH连接、文件交互(RADXA ZERO 3为例)
ZERO 3烧录
ZERO 3有两种 最本质的就是一个带WiFi一个不带WiFi
ZERO 3作为一个Linux板 其存储支持从sd卡EFI启动
系统安装则直接通过Balena Etcher来进行
可以使用其Windows版本即可
官方文档:
官方文档快速上手描述
镜像下载则也可以使用官方镜像:
Radxa ZERO 3 Debian Build 6
该镜像是最初的镜像 很多依赖都没有
如果开发的话 可以直接下载第三方镜像 或者自己在原有官方镜像上去安装镜像包等等
烧录很简单 直接用工具选择U盘 选择镜像即可
下图为烧录好了的sd卡
除了系统分区外 就是一个config分区 其挂载根根目录名称即为config
ZERO 3串口shell
串口与ZERO 3链接如下图:
链接后 配置串口为
baudrate: 1500000
data bit: 8
stop bit: 1
parity : none
flow control: none
启动后 用户名和密码都为radxa
外设挂载
根据df
命令查询系统挂载点
其做好了的U盘外部存储空间为/config
连接WiFi
使用如下指令链接WiFi:
nmcli device wifi #扫描WiFi
sudo nmcli device wifi connect <ssid> password <passwd> #连接WiFi
连上后 使用ip a
命令即可查看连接状态和ip
SSH连接
使用命令sudo systemctl status ssh
查看ssh状态
前提是要安装ssh
如果没有安装 则通过shell安装ssh:
sudo apt-get update
sudo apt-get install openssh-server openssh-sftp-server
根据Active
判断是否需要重启ssh服务:
重启ssh服务:
sudo systemctl restart ssh
启动后如下:
Active
状态就被设置为了running
开机自启动ssh则使用命令:
sudo systemctl enable --now ssh
在PC上 支持ssh的设备中 使用以下指令链接到板子:
ssh [username]@[IP address] # or ssh [username]@[hostname]
如下图:
SSH的文件交互
若是在PC上作为主机去访问设备
那么就是在PC的cmd中运行shell
有的终端软件配备了ssh的文件管理传输功能
连上以后就可以直接搜素到当前目录下的各类文件 以便于实现文件管理
并且可以直接download
# 复制 Windows 文件到 Linux
scp D:\data\1.txt root@192.168.88.161:/root/data
# 复制 Windows 目录到 Linux(记得加 -r)
scp -r D:\data root@192.168.88.161:/root/data
# 复制 Linux 文件到 Windows
scp root@192.168.88.161:/root/data/1.txt D:\data
# 复制 Linux 目录到 Windows(记得加 -r)
scp -r root@192.168.88.161:/root/data D:\data
前提是设备开启了ssh可以被链接
发过去后便能在板子上看到:
回传文件夹:
如果是Linux设备去连接Windows设备 则需要在Windows里面设置对应的服务 相关教程很多 这里不过多赘述
如果是Linux设备访问Linux设备 则主设备也要指定IP
scp root@192.168.88.161:/root/1.txt root@192.168.88.162:/root
# 如果设置了Linux之间的免密登录,可这样写:
scp 192.168.88.161:///root/1.txt 192.168.88.162:///root
换源
Linux系统的源都在/etc/apt/
下 一般有两个文件
一个是sources.list
另外一个是sources.list.d
目录下的品牌list文件
如树莓派需要备份原本的源:
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo cp /etc/apt/sources.list.d/raspi.list /etc/apt/sources.list.d/raspi.list.bak
而radxa的则是:
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo cp /etc/apt/sources.list.d/radxa.list /etc/apt/sources.list.d/radxa.list.bak
将原本的文件进行编辑:
sudo nano /etc/apt/sources.list
注释掉最初的源 并添加新的源:
deb https://mirrors.tuna.tsinghua.edu.cn/debian bookworm main contrib non-free-firmware
deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free-firmware
deb https://mirrors.tuna.tsinghua.edu.cn/debian bookworm-updates main contrib non-free-firmware
如图:
然后再换子目录下的源
sudo nano /etc/apt/sources.list.d/raspi.list
替换成:
deb https://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ bullseye main
不过很可惜 清华源没有radxa 但是可以换debian的源(/etc/apt/sources.list
):
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free
deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib non-free
deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-backports main contrib non-free
deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-backports main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bullseye-security main contrib non-free
deb-src https://mirrors.tuna.tsinghua.edu.cn/debian-security bullseye-security main contrib non-free
换源后 执行
sudo apt-get upgrade
sudo apt-get update