NDK

【NDK系列14】Cmake详解 CMakeLists.txt详

2019-06-21  本文已影响0人  ddssingsong

1. CMake简介

CMake是一个比make更高级的编译配置工具,它可以根据不同平台、不同的编译器,生成相应的Makefile或者vcproj项目。从而达到跨平台的目的。

Android Studio利用CMake生成的是ninja,ninja是一个小型的关注速度的构建系统。我们不需要关心ninja的脚本,知道怎么配置cmake就可以了。从而可以看出cmake其实是一个跨平台的支持产出各种不同的构建脚本的一个工具。

在android studio 2.2及以上,构建原生库的默认工具是 CMake。

2. 基本命令

#cmake最低版本
cmake_minimum_required(VERSION 3.6.0)

#指定项目
project(Main)

add_executable(demo demo.cpp) # 生成可执行文件
add_library(common STATIC util.cpp) # 生成静态库
add_library(common SHARED util.cpp) # 生成动态库或共享库

搜索c/cpp文件

# 搜索当前目录下的所有.cpp文件, 但不能查找子目录
aux_source_directory(. SRC_LIST) 
add_library(demo ${SRC_LIST})

#也可以 
file(GLOB DIR_SRCS *.c)
add_executable(main ${DIR_SRCS})

使用子目录中的CMakeList

# 添加 child 子目录下的cmakelist
add_subdirectory(child)
# 指定生成目标 
add_library(main ${DIR_SRCS})
# 添加链接库
target_link_libraries(main child)

# ===========================================
# child中设置
aux_source_directory(. DIR_LIB_SRCS)
# 生成链接库 默认生成静态库
add_library (child ${DIR_LIB_SRCS})
#指定编译为静态库
add_library (child STATIC ${DIR_LIB_SRCS})

设置预编译宏

#设置预编译宏 cflag和cxxflag
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTEST"  )
set(CMAKE_Cxx_FLAGS "${CMAKE_Cxx_FLAGS} -DTEST"  )  

引入头文件

#这样就可以使用 #include <xx> 引入 
#否则需要使用 #include "path/xx" 
include_directories( imported-lib/include/ )

逻辑判断语句

#逻辑判断 计较字符串
set(ANDROID_ABI "areambi-v7a")
if(${ANDROID_ABI} STREQUAL "areambi")
    message("armv5")
elseif(${ANDROID_ABI} STREQUAL "areambi-v7a")
    message("armv7a")
else()
    
endif()

3. build.gradle配置

//还可以在gradle中使用 arguments  设置一些配置
externalNativeBuild {
      cmake {
        arguments "-DANDROID_TOOLCHAIN=clang",  //使用的编译器clang/gcc
                  "-DANDROID_STL=gnustl_static" //cmake默认就是 gnustl_static
        cFlags "" //这里也可以指定cflag和cxxflag,效果和之前的cmakelist里使用一样
        cppFlags "" 
      }
    }   

4. 注意事项

  1. ​ 使用Android.mk在 >=6.0 设备上不能再使用预编译动态库(静态库没问题):

    cmake_minimum_required(VERSION 3.4.1)
    
    file(GLOB SOURCE *.c )
    add_library(
                 hello-jni
                 SHARED
                ${SOURCE} )
                
    #这段配置在6.0依然没问题 
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -L[SO所在目录]")
    
    #这段配置只能在6.0以下使用 
    #add_library(Test SHARED IMPORTED)
    #set_target_properties(Test PROPERTIES IMPORTED_LOCATION [SO绝对地址])
    
    target_link_libraries(  hello-jni Test )
    
  1. 存在两个动态库libhello-jni.solibTest.so

    libhello-jni.so依赖于libTest.so(使用NDK下的ndk-depends`可查看依赖关系),则:

    //<=5.0:
      System.loadLibrary("Test");
      System.loadLibrary("hello-jni");
    //>=6.0:
      System.loadLibrary("hello-jni");
    
上一篇下一篇

猜你喜欢

热点阅读