CMake交叉编译Android
有时我们用C/C++编写的库,希望可以在Android / iOS上运行, 那么将其编译为Android/iOS的动态或静态库是个不错的选择, 这时就需要用到交叉编译, 意思就是在*nix或win平台编译出arm架构的库.
方法1: 手写编译命令 llvm/prebuilt/<host>/bin/clang++ -o xxx a.cpp b.cpp -I../inclue -Lliblog --sysroot=./ndk <...>
这种方法对于不熟悉编译命令的小白门槛稍高
方法2: 就是今天我们重点介绍的CMake交叉编译
Android Studio推荐我们使用cmake, 那么怎么才能正确编译出arm架构的so库呢, 其实相当简单, 我们都不需要去看cmake的官方手册-(当然CMakeLists.txt的写法还是要看一下). AS提供了现成的东西
1. AS随便建个c++工程
创建好大概长这样
build一下, 构建成功后看下这个文件 app/.cxx/cmake/debug/arm64-v8a/build_command.txt, 文件内容就是cmake编译命令.
Executable : /Users/apple/developer/AndroidSDK/cmake/3.10.2.4988404/bin/cmake # cmake程序目录 arguments : -H/Users/apple/development/CxxTest/app/src/main/cpp # 源码目录,AS特有(可选,as的cmake必要) -B/Users/apple/development/CxxTest/app/.cxx/cmake/debug/arm64-v8a # 编译产出的临时文件目录, AS特有 (可选, as的cmake必要) -DCMAKE_CXX_FLAGS=-std=c++14 # c++附加的编译参数, 这里意思采用c++14标准编译 (可选) -DCMAKE_BUILD_TYPE=Debug # 编译类型, Debug/Release, Release模式下so会小一点,删除了符号表. -DCMAKE_TOOLCHAIN_FILE=/Users/apple/developer/AndroidSDK/ndk/21.3.6528147/build/cmake/android.toolchain.cmake # 工具链文件路径(必要,重要) -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a # 架构类型(必要) -DANDROID_ABI=arm64-v8a # (可选) -DCMAKE_ANDROID_NDK=/Users/apple/developer/AndroidSDK/ndk/21.3.6528147 # (必要) -DANDROID_NDK=/Users/apple/developer/AndroidSDK/ndk/21.3.6528147 # (可选) -DANDROID_PLATFORM=android-19 # 最小支持版本(可选) -DCMAKE_EXPORT_COMPILE_COMMANDS=ON # 是否导出详细编译参数(可选) -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/Users/apple/development/CxxTest/app/build/intermediates/cmake/debug/obj/arm64-v8a # lib临时目录(可选) -DCMAKE_MAKE_PROGRAM=/Users/apple/developer/AndroidSDK/cmake/3.10.2.4988404/bin/ninja # 构建工具, 根据需要(可选) -DCMAKE_SYSTEM_NAME=Android # 系统名称(必要,重要) -DCMAKE_SYSTEM_VERSION=19 # 最小支持版本(必要) -GNinja # 生成类型, ninja据说比make要快, 默认生成Makefile (可选)
jvmArgs :
Android Studio自带的cmake程序可能是经过修改的, 它有一些特有参数, 如果不使用AS的cmake, 刚不需要这些参数
所以编译c/c++可以这样写
$ mkdir -p build
$ cd build # 这样编译产生的临时文件会build目录, 不会污染源码git
$ cmake ../src \ -DCMAKE_SYSTEM_NAME=Android \ -DCMAKE_SYSTEM_VERSION=19 \ -DANDROID_PLATFORM=android-19 \ -DCMAKE_ANDROID_STL_TYPE=c++_static \ #c++_static会将c++库一起打进目标, 如果不需要这样可以换成c++_shared, 默认就是c++_static -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOL_CHAIN \ -DCMAKE_ANDROID_NDK=$NDK_HOME \ -DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a
$ make -j8 # 即可编译出最终产物
我们甚至都不需要手动去处理include/library包含目录, cmake都帮我们做了, 是不是超简单
参考: