6.1 基本概念
宿主机host是执行编译、链接嵌入式软件的计算机;
目标机target是运行嵌入式软件的硬件平台。
通常我们用的PC机(window系统或者liunx系统)就是宿主机,
而客户使用的车机(QNX系统)、手机(Andorid系统)则是目标机。
在宿主机host上要生成目标机target的程序就是交叉编译。交叉编译时需要修改以下内容:
Ø 修改编译器;
Ø 修改依赖库;
Ø 修改头文件;
使用CMake进行交叉编译就是要告诉CMake目标机target是什么平台、
使用什么编译器、
到哪里寻找依赖库、
到哪里寻到头文件。
CMake使用一些内建变量定义上述内容。
Ø CMAKE_SYSTEM_NAME: 即你目标机target所在的操作系统名称,
比如ARM或者Linux你就需要写"Linux",
如果Windows平台你就写"Windows",
如果你的嵌入式平台没有相关OS你即需要写成"Generic",
只有当CMAKE_SYSTEM_NAME这个变量被设置了,
CMake才认为此时正在交叉编译,它会额外设置一个变量CMAKE_CROSSCOMPILING为TRUE.
Ø CMAKE_C_COMPILER: 顾名思义,即C语言编译器,
这里可以将变量设置成完整路径或者文件名,
设置成完整路径有一个好处就是CMake会去这个路径下去寻找编译相关的其他工具比如linker,binutils等,
如果你写的文件名带有arm-elf等等前缀,
CMake会识别到并且去寻找相关的交叉编译器。
Ø CMAKE_CXX_COMPILER: 同上,此时代表的是C++编译器
Ø CMAKE_FIND_ROOT_PATH: 代表了一系列的相关文件夹路径的根路径的变更
Ø CMAKE_FIND_ROOT_PATH_MODE_PROGRAM:
对FIND_PROGRAM()起作用,有三种取值,NEVER,ONLY,BOTH,
第一个表示不在你CMAKE_FIND_ROOT_PATH下进行查找,
第二个表示只在这个路径下查找,
第三个表示先查找这个路径,再查找全局路径,
对于这个变量来说,一般都是调用宿主机的程序,
所以一般都设置成NEVER
Ø CMAKE_FIND_ROOT_PATH_MODE_LIBRARY:
对FIND_LIBRARY()起作用,表示在链接的时候的库的相关选项,
因此这里需要设置成ONLY来保证我们的库是在交叉环境中找的.
Ø CMAKE_FIND_ROOT_PATH_MODE_INCLUDE:
对FIND_PATH()和FIND_FILE()起作用,一般来说也是ONLY
与交叉编译相关的这些变量如何传递给CMake了?最为方便的一个方法就是将相关的变量设置都放进一个文件(cmake脚本)中去,然后将该文件通过CMAKE_TOOLCHIAIN_FILE传递给CMake, 例如:
cmake-DCMAKE_TOOLCHIAIN_FILE="/path/to/toolchain-file" ..
6.2 附上一个CMake官方文档中的toolchian-file的小例子,这样我们就会对如何写toolchain-file文件有了感性认识:
# this one is important
SET(CMAKE_SYSTEM_NAMELinux)
#this one not so much
SET(CMAKE_SYSTEM_VERSION 1)
# specify the crosscompiler
SET(CMAKE_C_COMPILER /opt/eldk-2007-01-19/usr/bin/ppc_74xx-gcc)
SET(CMAKE_CXX_COMPILER/opt/eldk-2007-01-19/usr/bin/ppc_74xx-g++)
# where is the targetenvironment
SET(CMAKE_FIND_ROOT_PATH /opt/eldk-2007-01-19/ppc_74xx/home/alex/eldk-ppc74xx-inst)
# search for programs inthe build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAMNEVER)
# for libraries and headersin the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARYONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
6.3 编译生成Android平台上的程序,需要用到GOOGLE为我们提供了的Android NDK用来做Native(C/C++)的build。Android NDK中包含了整套的编译器、系统库、头文件、调试器等。
使用CMake交叉编译Android平台上的程序,就需要:
Ø 指明目标平台为Android
Ø 指明目标硬件是ARM还是X86
Ø 指明ndk level version
Ø 用ndk提供的编译器
Ø 从ndk安装目录搜寻依赖库和头文件
我们可以自己动手编写toolchain-file,设置相应的变量。这也比较麻烦。
幸运的是,我们有Android-cmake项目可以帮忙。该项目生成了一个名为的toolchain-file文件,该文件帮我们设置了大部分的变量。我们需要做的就是指定cmake的toolchain file为这个项目里面的文件,然后设置好Android NDK路径即可。
# Usage Linux:
export ANDROID_NDK=/absolute/path/to/the/android-ndk
mkdir build && cdbuild
cmake-DCMAKE_TOOLCHAIN_FILE=path/to/the/ ..
make -j8
make install
# Usage Windows:
SETANDROID_NDK=C:\absolute\path\to\the\android-ndk
mkdir build && cdbuild
-G"MinGWMakefiles" ^
-DCMAKE_TOOLCHAIN_FILE=path\to\the\ ^
-DCMAKE_MAKE_PROGRAM="%ANDROID_NDK%\prebuilt\windows\bin\"^
..
--build . --target install--clean-first