CmakeLists.txt to build .so in AS - nonelittlesong/study-cpp GitHub Wiki

参考:

build.gradle

android {
    ...
    defaultConfig {
        ...
        externalNativeBuild {
            cmake {
                cppFlags "-frtti -fexceptions"
                arguments "-DANDROID_ARM_NEON=TRUE"
            }
        }
    }
    buildTypes {
        ...
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}
...

由于CMake的命令集成在了externalNativeBuild中,所以在gradle中有2个地方配置CMake
defaultConfig外面的externalNativeBuild - cmake,指明了CMakeList.txt的路径
defaultConfig里面的externalNativeBuild - cmake,主要填写CMake的命令参数。即由arguments中的参数最后转化成一个可执行的CMake的命令

步骤

  • 引用第三方库
  • 创建自己的库
  • 添加头文件
  • 链接
cmake_minimum_required(VERSION 3.4.1)

# configure import libs
set(distribution_DIR ${CMAKE_SOURCE_DIR}/../../../../distribution)

# 创建一个静态库 lib_gmath 直接引用libgmath.a 
add_library(lib_gmath STATIC IMPORTED) 
set_target_properties(lib_gmath PROPERTIES IMPORTED_LOCATION 
                      ${distribution_DIR}/gmath/lib/${ANDROID_ABI}/libgmath.a)

# 创建一个动态库 lib_gperf 直接引用libgperf.so 
add_library(lib_gperf SHARED IMPORTED) 
set_target_properties(lib_gperf PROPERTIES IMPORTED_LOCATION 
                      ${distribution_DIR}/gperf/lib/${ANDROID_ABI}/libgperf.so)

# build application's shared lib 
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")

# 创建库 hello-libs 
add_library(hello-libs SHARED hello-libs.cpp)

# 加入头文件 
target_include_directories(hello-libs PRIVATE 
                           ${distribution_DIR}/gmath/include ${distribution_DIR}/gperf/include)

# hello-libs库链接上 lib_gmath 和 lib_gperf 
target_link_libraries(hello-libs 
                      android 
                      lib_gmath 
                      lib_gperf 
                      log)

怎么指定C++标准?

在build.gradle中,配置cppFlags -std

externalNativeBuild {
  cmake {
    cppFlags "-frtti -fexceptions -std=c++14"
    arguments '-DANDROID_STL=c++_shared'
  }
}

add_library 如何编译一个目录中所有源文件?

使用 aux_source_directory 方法将路径列表全部放到一个变量中。

# 查找所有源码 并拼接到路径列表 
aux_source_directory(${CMAKE_HOME_DIRECTORY}/src/api SRC_LIST) 
aux_source_directory(${CMAKE_HOME_DIRECTORY}/src/core CORE_SRC_LIST) 
list(APPEND SRC_LIST ${CORE_SRC_LIST}) 
add_library(native-lib SHARED ${SRC_LIST})

怎么调试 CMakeLists.txt 中的代码

使用 message 方法

cmake_minimum_required(VERSION 3.4.1)
message(STATUS "execute CMakeLists")

然后运行后在 .externalNativeBuild/cmake/debug/{abi}/cmake_build_output.txt

设置输出路径

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/src/main/lib/${ANDROID_ABI})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})

双引号作用

当参数包含空格时通过双引号括起来