Android CMakeLists.txt配置解析与Cmake语法必备

1.CMakeLists.txt配置解析

# 最低支持的版本,注意:这里并不能代表最终的版本,最终版本在app.build.gradle中设置的
cmake_minimum_required(VERSION 3.10.2)

# 当前工程名,以前的旧版本是没有设置的,这个可以设置也可以不设置
project("mscmake")

#批量导入源文件  源文件跟CMakeLists 在同一个目录的情况
file(GLOB SOURCE *.cpp *.c)

# 批量导入 cpp c源文件
file(GLOB SOURCE ${CMAKE_SOURCE_DIR}/cpp/*.cpp ${CMAKE_SOURCE_DIR}/cpp/*.c)

# 添加一个库(动态库SHARED,静态库STATIC)
add_library(native-lib # 库的名字 ---> libnative-lib.so
        SHARED
        # cpp的源文件:把cpp源文件编译成 libnative-lib.so 库
        ${SOURCE})

# 第一步:导入fmod头文件
include_directories("${CMAKE_SOURCE_DIR}/cpp/inc")

# 第二步:导入库文件 (方式一)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/jniLibs/${CMAKE_ANDROID_ARCH_ABI}")

message(status "cmake日志-----------------------${CMAKE_SOURCE_DIR}"  )




# 第三步链接到总库中去 # native-lib是我们的总库
target_link_libraries(
        native-lib # 被链接的总库
        log # 自动寻找  # 具体的库 链接到 libnative-lib.so里面去
        fmod # 具体的库 链接到 libnative-lib.so里面去
        fmodL # 具体的库 链接到 libnative-lib.so里面去
        )
      
#另一种方式导入库的方式 通过条件判断 决定加载动态库还是静态库
# 另外一种导入的方式
include_directories("${CMAKE_SOURCE_DIR}/cpp/inc")

set(isSTATIC ON)

if(${isSTATIC})
    # 导入静态库
    add_library(postndk STATIC IMPORTED)
   # 开始真正导入 
    set_target_properties(postndk PROPERTIES IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/cpp/libpostndk.a)
    message("isSTATIC == static")
else(${isSTATIC})
    # 导入动态库
    add_library(postndk SHARED IMPORTED)
#    动态库 System.loadLibrary("postndk"); // 如果是动态库,这里需要加载,否则注释
    set_target_properties(postndk PROPERTIES
            IMPORTED_LOCATION
            ${CMAKE_SOURCE_DIR}/jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libpostndk.so)
    message("isSTATIC == shared")
endif(${isSTATIC})


2.动态库和静态库的区别

动态库.so后缀名,不会拷贝源代码,在运行的时候才会进行地址回填,所以so库必须能找到才行。

静态库.a后缀名,会直接将源码代码拷贝到总的so库里边,apk安装包里边看不到静态库。

3.Cmake工具介绍

CMake是一个跨平台的构建工具,可以用简单的语句来描述所有平台的安装(编译过程)。 能够输出各种各样的makefile或者project文件。CMake并不直接构建出最终的软件, 而是产生其他工具的脚本(如makefile),然后再依据这个工具的构建方式使用。

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

Android Studio利用CMake生成的是ninja。ninja是一个小型的关注速度的构建系统。

CMake其实是一个跨平台的支持产出各种不同的构建脚本的一个工具。

4.Cmake语法解析

通过CMakeLists.txt学习cmake语法非常方便
# log 信息输出的查看
#Build --> Refresh Linked_C++_Projects 查看cmake_server_log.txt 就能看到cmake输出的日志了
#.cxx/cmake/debug/armeabi-v7a/cmake_server_log.txt  (cmake_server_log.txt路径)

#[[
(无) = 重要消息;
STATUS = 非重要消息;
WARNING = CMake 警告, 会继续执行;
AUTHOR_WARNING = CMake 警告 (dev), 会继续执行;
SEND_ERROR = CMake 错误, 继续执行,但是会跳过生成的步骤;
FATAL_ERROR = CMake 错误, 终止所有处理过程;
]]

#日志输出
message(STATUS "这是cmake日志 STATUS 非重要消息 ")
message(WARNING "这是cmake日志 WARNING CMake 警告, 会继续执行 ")
message(AUTHOR_WARNING "这是cmake日志 AUTHOR_WARNING CMake 警告 (dev), 会继续执行 ")
#message(SEND_ERROR "这是cmake日志 SEND_ERROR CMake 错误, 继续执行,但是会跳过生成的步骤 ")
#message(FATAL_ERROR "这是cmake日志 FATAL_ERROR CMake 错误, 终止所有处理过程 ")

#CMake变量

# 声明变量:set(变量名 变量值)
set(number 999)
# CMake中所有变量都是string类型。可以使用set()和unset()命令来声明或移除一个变量
# 引用变量:message 命令用来打印
message("number = ${number}")

# 移除变量
unset(number)
message("my_number= ${number}") # 会取不到值,因为被移除了


# CMake列表(lists)
# 声明列表:set(列表名 值1 值2 ... 值N) 或 set(列表名 "值1;值2;...;值N")
set(list_var 1 2 3 4 5) # 字符串列表呢? CMake中所有变量都是string类型
message("list_var = ${list_var}")

# CMake流程控制-条件命令
# true(1,ON,YES,TRUE,Y,非0的值) === true
# false(0,OFF,NO,FALSE,N,IGNORE,NOTFOUND)  === false
set(if_tap OFF) # 定义一个变量if_tap,值为false
set(elseif_tap ON) # 定义一个变量elseif_tap,值为ture

if (${if_tap})
    message("------if-------")
elseif (${elseif_tap})
    message("-----elseif---------------")
else (${if_tap})   # 可以不加入 ${if_tap}
    message("-----else---------")
    # endif(${if_tap}) # 结束if
endif () # 结束if 可以不加


# CMake流程控制-循环命令
# NOT! a STREQUAL "xxx"  (a等不等于xxx,不等于)
set(a "")
while (NOT a STREQUAL "xxx")
    set(a "${a}x")
    message(">>>>>>a = ${a}")
endwhile ()

#[[ 注意:
break()命令可以跳出整个循环  Java有的,他也有
continue()可以继续当前循环  Java有的,他也有
]]

foreach (item 1 2 3)
    message("foreach----1item = ${item}")
endforeach (item) # 结束for

# cmake RANGE
foreach (item RANGE 2) # RANGE 默认从0开始, 所以是:0 1 2
    message("RANGE--------2item = ${item}")
endforeach (item)

foreach (item RANGE 1 6 2) #  1 3 5 每次跳级2
    message("3item = ${item}")
endforeach (item)


set(list_va3 1 2 3) # 列表
# foreach(item IN LISTS ${list_va3}) # 没有报错,没有循环
foreach (item IN LISTS list_va3) # 正规的写法
    message("item IN LISTS-------》4item = ${item}")
endforeach (item)


#  CMake自定义函数  Shell的函数很类似
#[[
ARGC:表示传入参数的个数
ARGV0:表示第一个参数,ARGV1、ARGV2以此类推即可
ARGV:表示所有参数
]]

function(cmake_method n1 n2 n3)
    message("call cmake_method method")
    message("n1 = ${n1}")
    message("n2 = ${n2}")
    message("n3 = ${n3}")
    message("ARGC = ${ARGC}")
    message("arg1 = ${ARGV0} arg2 = ${ARGV1} arg3 = ${ARGV2}")
    message("all args = ${ARGV}")
endfunction(cmake_method)
num_method(11 110 1110)  # 调用cmake_method函数




猜你喜欢

转载自blog.csdn.net/u014078003/article/details/124996270