cmake 系列使用教程
cmake 使用教程 (一)- 起步
cmake 使用教程 (二)- 添加库
cmake 使用教程 (三)- 安装测试系统自检
cmake 使用教程 (四)- 文件生成器
cmake 使用教程 (五)-cpack 生成安装包
cmake 使用教程 (六)- 蛋疼的语法
cmake 使用教程 (七)- 流程和循环
cmake 使用教程 (八)-macro 和 function
这个系列的文章翻译自官方 cmake 教程: cmake tutorial
示例程序地址: github.com/rangaofei/t
不会仅仅停留在官方教程本人作为一个安卓开发者, 实在是没有 linux c 程序开发经验, 望大佬们海涵教程是在 macos 下完成, 大部分 linux 我也测试过, 有特殊说明的我会标注出来本教程基于 cmake-3.10.2, 同时认为你已经安装好 cmake
简介
该文章未介绍如何编译, 可以参考我的另一篇文章
shell 脚本生成安卓全 abi 动态库与静态库
用 cmake 交叉编译相当简单, 基本可以达到一次编写, 每次都能运行的目的
CMake 使用 toolchain 来编译, 链接 library 和创建 archives, 以及其他 task 来驱动构建 可用的 toolchain 实用程序由启用的语言确定 在正常版本中, CMake 根据系统默认值自动确定主使用的 toolchain 在交叉编译场景中, 可以使用关于编译器和实用程序路径的信息来指定 toolchain 文件
假如我们已经编写好了自己的 toolchain 文件, 那么在执行构建时添加参数
-DCMAKE_TOOLCHAIN_FILE=path/to/file
即可, cmake 系统会自动使用执行的 toolchain.cmake 文件
安卓平台交叉编译有两种方式, 一是使用 ndk 编译, 另一种是使用自己的工具链编译, 我感觉我只会 ndk 编译, 另一中我就不介绍了, 因为我不会
这里介绍如何构建 makefile 和 ninja 两种方式的交叉编译
变量说明
有几个特殊的变量需要设置:
CMAKE_SYSTEM_NAME
编译安卓平台时请设置这个变量为 Android 而且
CMAKE_SYSTEM_VERSION
必须指定
CMAKE_SYSTEM_VERSION
设置安卓的 api level, 假如未设置这个值, 则会由以下两个方式决定:
CMAKE_ANDROID_API 设置了, 则使用该 api level
CMAKE_SYSROOT 设置了, 则使用该 api level
都没设置, 则使用 ndk 中最新的 api levele
- CMAKE_ANDROID_ARCH_ABI
- arm64-v8a armeabi-v7a armeabi-v6 armeabi mips mips64 x86 x86_64
这个牛逼了, 设置 abi 架构, 假如未设置, 则使用默认的 armeabi 设置了这个变量系统会自动设置 CMAKE_ANDROID_ARCH, 不必手动设置
CMAKE_ANDROID_NDK
这个更牛逼了, 使用它来设置 ndk 的路径, 必须是绝对路径, 到 ndk 的根目录即可
CMAKE_ANDROID_NDK_DEPRECATED_HEADERS
设置为 true, 则会使用每个 api level 中已经废弃的头文件, 而不会使用统一的头文件默认为 false, 使用统一的头文件
CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION
设置 NDK 编译链的版本, 假如不设置, 则使用最新的
CMAKE_ANDROID_STL_TYPE
这个牛逼了有好几个值:
- none No C++ Support
- system
- Minimal C++ without STL
- gabi++_static GAbi++ Static
- gabi++_shared GAbi++ Shared
- gnustl_static
- GNU libstdc++ Static
- gnustl_shared
- GNU libstdc++ Shared
- c++_static LLVM libc++ Static
- c++_shared LLVM libc++ Shared
- stlport_static STLport Static
- stlport_shared STLport Shared
默认值是 gnustl_static
CMAKE_<LANG>_ANDROID_TOOLCHAIN_PREFIX
自动生成的, 绝对路径的前缀
CMAKE_<LANG>_ANDROID_TOOLCHAIN_SUFFIX
自动生成的, 绝对路径的后缀
构建顺序
假如设置了 CMAKE_ANDROID_NDK, 就会使用该变量指定的 NDK 路径
假如设置了
CMAKE_ANDROID_STANDALONE_TOOLCHAIN
, 而 1 中的变量未设置, 就会使用该独立的工具链编译
假如设置了 CMAKE_SYSROOT,12 未设置, 并且路径形式是
<ndk>/platforms/android-<api>/arch-<arch>
, 则相当于设置了 CMAKE_ANDROID_NDK, 并且会使用该路径的 ndk
假如设置了 CMAKE_SYSROOT,123 未设置, 并且路径形式是
<standalone-toolchain>/sysroot
, 则相当于设置了
CMAKE_ANDROID_STANDALONE_TOOLCHAIN
并且使用该工具链编译
假如设置了 ANDROID_NDK,1234 未设置, 则相当于设置了 1, 并且使用该 ndk
假如设置了
ANDROID_STANDALONE_TOOLCHAIN
,12345 未设置, 则相当于设置了 2, 并且使用该工具链
假如设置了环境变量 ANDROID_NDK_ROOT 或者 ANDROID_NDK,123456 则相当于设置了 1, 并且使用 NDK
假如设置了
ANDROID_STANDALONE_TOOLCHAIN
,1234567 未设置, 则相当于设置了 2, 并且使用该工具链
全都没设置会报错
编译方式
一般需要设置的如下:
- set(CMAKE_SYSTEM_NAME Android)
- set(CMAKE_SYSTEM_VERSION 21) # API level
- set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
- set(CMAKE_ANDROID_NDK /path/to/android-ndk)
- set(CMAKE_ANDROID_STL_TYPE gnustl_static)
假如不想编写 toolchain.cmake 文件, 也课可以在命令行直接输入参数来完成构建:
- cmake ../src \
- -DCMAKE_SYSTEM_NAME=Android \
- -DCMAKE_SYSTEM_VERSION=21 \
- -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \
- -DCMAKE_ANDROID_NDK=/path/to/android-ndk \
- -DCMAKE_ANDROID_STL_TYPE=gnustl_static
效果与上边是一样的
来源: https://juejin.im/post/5a8ebe006fb9a0635a6574de