cmake 交叉编译

之前编译代码都是纯手写makefile脚本 , 和手写makefile相比cmake语法简单易懂容易编写。遇到cmake之后我就再也没有手写makefile了, 都是直接写CMakeLists.txt然后自动生成makefile。 cmake生成交叉编译的makefile,可以有两种方式:

手写CMakeLists.txt

通过手写交叉编译CMakeLists.txt然后生成交叉编译makefile。以最简单的helloworld为例:

// main.cpp
#include <iostream>

int main()
{
std::cout << "Hello, World!" << std::endl;
return 0;
}
#对应的标准 CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(helloworld)
set(CMAKE_CXX_STANDARD 11)

add_executable(helloworld main.cpp)

现在改写为适用于xilinx zcu102开发板的CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(helloworld)
set(CMAKE_CXX_STANDARD 11)

add_executable(helloworld main.cpp)

#添加以下语句
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_FIND_ROOT_PATH "/data/Xilinx/zcu102_rv_ss/sw/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_C_COMPILER "/data/Xilinx/SDK/2017.4/gnu/aarch64/lin/aarch64-linux/bin/aarch64-linux-gnu-gcc")
SET(CMAKE_CXX_COMPILER "/data/Xilinx/SDK/2017.4/gnu/aarch64/lin/aarch64-linux/bin/aarch64-linux-gnu-g++")

我只添加了后面的7行内容,下面分别讲解每一行的具体含义:

  • SET(CMAKE_SYSTEM_NAME Linux)
    告诉cmake编译的时候目标平台target是什么 , 默认的时候cmake会以本机平台类型为目标平台

  • SET(CMAKE_FIND_ROOT_PATH “/data/Xilinx/zcu102_rv_ss/sw/sysroot”)
    告诉CMake在编译的时候查找所需文件(头文件, 库文件, 编译用到的程序)的根目录在哪里

  • 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_C_COMPILER “/data/Xilinx/SDK/2017.4/gnu/aarch64/lin/aarch64-linux/bin/aarch64-linux-gnu-gcc”)
    SET(CMAKE_CXX_COMPILER “/data/Xilinx/SDK/2017.4/gnu/aarch64/lin/aarch64-linux/bin/aarch64-linux-gnu-g++”)
    分别指定交叉编译的C和C++编译器

下面执行命令开始编译:

编译成功后 , 用file命令可以看到编译出来的helloworld是ARM aarch64架构的。

cmake-gui 自动生成

除了手写CMakeLists.txt, 还可以通过cmake-gui这个图形工具来生成交叉编译的CMakeLists.txt和makefile。

点击configure , 选择如图所示 :

这里的配置就和手写CMakeLists.txt里面的一样

点击generate自动生成makefile后,进入到相应的目录执行make

同样地 , 也成功生成了交叉编译的helloworld。