前言介绍
交叉编译是一种操作系统或者硬件架构上生成在另一种操作系统或者硬件架构上运行的代码的过程。通常情况下,我们会使用cmake来配置和管理跨平台的项目。
交叉编译有三个核心元素:
- Host:你将在其上运行编译器的机器。
- Target:你打算运行你的代码的机器。
- Toolchain:一个为target系统定制的编译器工具集。
假设我们要在Linux上(host)为ARM设备(target)交叉编译一个Hello World程序。我们可以使用GCC交叉编译工具链(toolchain)。
实战演练
第一步:安装编译器
安装交叉编译工具链:在Ubuntu上可以使用如下命令安装:
sudo apt-get install gcc-arm-linux-gnueabi
其他Linux发行版也有类似方法。安装完成后,我们可以看到交叉编译用的工具链名字通常会比本地工具链更长。例如,在这种情况下,本地工具链可能叫做gcc,而交叉编译工具链叫做arm-linux-gnueabi-gcc。
第二步:待编译的源代码
用一个简单的例子:打印"Hello, World!",代码如下:
#include <stdio.h>int main() {printf("Hello, World!");return 0;
}
第三步:命令行编译方式(方法一)
arm-linux-gnueabi-gcc -o hello hello.c
第三步:CMakeList.txt方式(方法二)
在你的项目根目录下创建一个CMakeLists.txt文件。这个文件描述了项目的结构和构建规则。
cmake_minimum_required(VERSION 3.10)
project(MyProject)# 设置交叉编译工具链
set(CMAKE_C_COMPILER arm-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabi-g++)# 设置目标平台
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)# 添加源文件
add_executable(MyProject main.cpp)# 指定目标平台的编译选项
target_compile_options(MyProject PRIVATE -march=armv7-a -mthumb -mfpu=neon)
然后,在终端中导航到你的项目根目录,并创建一个build目录用于构建。
mkdir build
cd build
运行cmake命令来生成Makefile。
cmake ..
最后,使用make命令来构建项目。
make
交叉编译opencv
首先,你需要一个交叉编译工具链,如arm-linux-gnueabi-gcc和arm-linux-gnueabi-g++,并且还需要ARM设备的根文件系统。
然后,你需要创建一个用于存放OpenCV源代码、cmake编译配置文件、编译输出的工作目录,比如/home/ubuntu/opencv/。
假设你已经下载了OpenCV源代码,并解压到了/home/ubuntu/opencv/opencv-3.4.0/。
在工作目录/home/ubuntu/opencv/下创建一个CMake的交叉编译配置文件toolchain.cmake。
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)set(CMAKE_C_COMPILER arm-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabi-g++)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 /your/path/to/arm/rootfilesystem)
然后在工作目录下创建一个构建目录,并在此目录下运行CMake。
cd /home/ubuntu/opencv/
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake ../opencv-3.4.0
CMake将根据toolchain.cmake中指定的交叉编译工具链和目标平台设置,生成Makefile。
最后,在构建目录下运行make命令以构建项目。
make
执行完毕后,在/home/ubuntu/opencv/build/目录下就会得到一个ARM平台上的OpenCV库。
或者参考下面这篇博客OpenCV 之交叉编译及ARM移植(二)