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都帮我们做了, 是不是超简单

参考: 

  Cross Compiling for Android with the NDK

posted @ 2020-11-11 11:09  Coding&Life  阅读(2912)  评论(0编辑  收藏  举报