美文网首页
CMakeLists语法详解

CMakeLists语法详解

作者: Epimenides | 来源:发表于2020-08-06 22:30 被阅读0次

使用AndroidStudio创建一个C/C++Support的项目,默认在app/src/main目录下会生成CPP目录,里面包含CMakeLists.txtnative-lib.cpp。右边的代码为CMakeLists.txt去掉英文注释格式化后的内容。

cmake_minimum_required(VERSION 3.4.1)

add_library(
        native-lib
        SHARED
        native-lib.cpp)
        
find_library(
        log-lib
        log
        )
        
target_link_libraries(
        native-lib
        ${log-lib})

常用命令:

aux_source_directory(. DIR_SRCS)
  • 查找当前目录下所有源文件 并将源文件名称列表保存到 DIR_SRCS变量中。
  • 不能查找子目录。
add_library(<name> [STATIC | SHARED | MODULE [EXCLUDE_FROM_ALL] source1 source2 ... sourceN])
  1. 添加一个库

    • 添加一个库文件,名为<name>。

    • 指定STATIC, SHARED, MODULE 参数来指定库的类型。

      STATIC:静态库,

      SHARED: 动态库,

      MODULE: 在使用dyld的系统有效, 若不支持dyld,等同于SHARED

    • EXCLUDE_FROM_ALL: 表示该库不会被默认构建。

    • source1 source2 ··· sourceN:用来指定库的源文件。

add_library<name>
<SHARED | STATIC | MODULE | UNKNOWN> IMPORTED)
# 比如
add_library(test SHARED IMPORTED)
set_target_properties(
    test #指定目标库名
    PROPERTIES IMPORTED_LOCATION #指定要设置的参数/库目录/
    ${ANDROID_ABI}/libtest.so #导入库的路径
)

常用命令中的-set命令:

# 设置可执行文件的输出路径(EXCUTABLE_OUTPUT_PATH是全局变量)
set(EXECUTABLE_OUTPUT_PATH [out_path])

# 设置库文件的输出路径(LIBRARY_OUTPUT_PATH是全局变量)
set (LIBRARY_OUTPUT_PATH [output_path])

# 设置C++编译参数(CMAKE_CXX_FLAGS是全局变量)
set (CMAKE_CXX_FLAGS "-Wall std=C++11")

# 设置源文件集合(SOURCE_FILES是本地变量即自定义变量)
set(SOURCE_FILE main.cpp test.cpp ...)

常用命令-include_directories

# 可以使用相对或者绝对路径,也可以用自定义的变量
include_directories(./include $(MY_INCLUDE))
  • 设置头文件目录
  • 想当于g++选项中的-l参数

常用命令-add_executable

#添加可执行文件
add_executable(<name> ${SRC_LIST})

常用命令-target_link_libraries

target_link_libraries(<name> lib1 lib2 lib3)

#如果出现相互依赖的静态库,CMake会允许依赖图中包含循环依赖,如:
add_library(A STATIC a.c)
add_library(B STATIC b.c)
target_link_libraries(A B)
target_link_libraries(B A)
add_executable(main main.c)
target_link_libraries(main A)
  • 将若干库链接到目标库文件
  • 链接的顺序应当符合gcc链接顺序规则,被链接的库放在依赖它的库的后面,即如果上面的命令中,lib1依赖于lib2,lib2又依赖于lib3,则在上面命令中必须严格按照lib1 lib2 lib3的顺序排列,否则会报错。

常用命令-add_definitions

add_definitions(-DFOO -DDEBUG ...)
  • 为当前路径以及子目录的源文件加入由-D引入的define flag

常用命令-add_subdirectory

# sub_dir指定包含CMakeList.txt和源码文件的子目录位置
# binary_dir 是输出路径,一般可以不指定
add_subdirecroty(sub_dir [binary_dir])
  • 如果当前目录下还有子目录时可以使用add_subdirectory,子目录中也需要包含有CMakeLists.txt

常用命令-file

# 将message写入filename文件中,会覆盖文件中原有内容
file(WRITE filename "message")
# 将message写入filename文件中,会追加在文件末尾
file(APPEND filename "message")
# 从filename文件中读取内容并存储到var变量中,如果指定了numBytes和offset,
# 则从offset处开始最多读numBytes个字节,另外如果指定了HEX参数,则内容会以十六进制形式存储在var变量中
file(READ filename var [LIMIT numBytes] [OFFSET offset] [HEX])
# 重命名文件
file(RENAEM <oldname> <newname>)
# 删除文件,相当于 rm 命令
file(REMOVE [file1 ...])
# 递归的执行删除文件命令,等于rm -r 
file(REMOVE_RECURSE [file1 ...])
# 根据指定的url下载文件
# timeout 超时时间; 下载的状态会保存到status中; 下载日志会保存到logl; sum指定所下载文件预期的MD5值,如果指定会自动进行比对,
# 如果不一致,则返回一个错误; SHOW_PROGRESS,进度信息会以状态信息的形式被打印出来
file(DOWNLOAD url file [TIMEOUT timeout] [STATUS status] [LOG log] [EXPECTED_MD5 sum] [SHOW_PROGRESS])
# 创建目录
file(MAKE_DIRECTORY [dir1 dir2 ..,])
# 会把path转换为以unix的/开头的cmake分格路径,保存在result中
file(TO_CMAKE_PATH path result)
# 它会把cmake风格的路径准换为本地路径风格: window下用"\",而unix下用"/"
file(TO_NATIVE_PATH path result)
# 将会为所有匹配查询表达式的文件生成一个文件list, 并将该list存储进变量variable里, 如果一个表达式指定了RELATIVE, 返回的结果将会是相对于给定路径的相对路径,查询表达式例子: *.cxx, *.vt?
# NOTE: 按照官方文档的说法,不建议使用file的GLOB指令来收集工程的源文件
file(GLOB variable [RELATIVE path] [globbing expressions]...)

常用命令-set_directory_properties

set_directory_properties(PROPERTIES pro1 value1 prop2 value2)
  • 设置某个路径的一种属性
  • prop1, prop2代表属性,取值为:
INCLUDE_DIRECTORIES
LINK_DIRECTORIES
INCLUDE_REGULAR_EXPRESSION
ADDITIONAL_MAKE_CLEAN_FILES

常用命令-set_property

set_property(<GLOBAL |
            DIRECTORY [dir] |
            TARGET [target ...] |
            SOURCE [src1 ...] |
            TEST [test1 ...] |
            CACHE [entry1 ...]>
            [APPEND]
            PROPERTY <name> [value ...])
  • 在给定的作用域内设置一个命令的属性
  • PROPERTY参数是必须的
  • 第一个参数决定了属性可以影响的作用域:
GLOBAL: 全局作用域
DIRECTORY: 默认当前路径,也可以用[dir]指定路径
TARGET: 目标作用域, 可以是0个或多个以有目标
SOURCE: 源文件作用域,可以是0个或多个源文件
TEST: 测试作用域,可以是0个或多个已有的测试
CACHE: 必须指定0个或者多个cache中已有的条目

多个源文件处理

cmake_minimum_required(VERSION 3.4.1)
# 查找当前目录所有源文件 并将名称保存到 DIR_SRCS 变量
# 不能查找子目录
aux_source_directory(. DIR_SRCS)
# 也可以使用
# file(GLOB DIR_SRCS *.c *.cpp)

add_library(
        native-lib
        SHARED
        ${DIR_SRCS})
  • 如果源文件很多,把所有文件一个个加入很麻烦,可以使用aux_source_directory命令或file命令,会查找指定目录下的所有源文件,然后将结果存进指定变量名。

多目录源文件处理

cmake_minimum_required(VERSION 3.4.1)
aux_source_directory(. DIR_SRCS)
# 添加 child 子目录下的cmakelist
add_subdirectory(child)

add_library(
        native-lib
        SHARED
        ${DIR-SRCS})
target_link_libraries(native-lib child)
---------------------------------------
#child目录下的CMakeLists.txt:
cmake_minimum_required(VERSION 3.4.1)
aux_source_directory(. DIR_LIB_SRCS)
add_library(
        child
        SHARED
        ${DIR_LIB_SRCS})

添加预编译库(Android6.0版本以前)

cmake_minimum_required(VERSION 3.4.1)
# 使用 IMPORTED 标志告知 CMake 只希望将库导入到项目中
# 如果是静态库则将shared改为static
add_library( imported-lib
            SHARED
            IMPORTED )
# 参数分别为:库、属性、导入地址、库所在地址
set_target_properties(
                    imported-lib
                    PROPERTIES
                    IMPORTED_LOCATION
<路径>/libimported-lib.so)
aux_source_directory(. DIR_SRCS)
add_library(
        native-lib
        SHARED
        ${DIR_SRCS})
target_link_libraries(native-lib imported-lib)
  • 假设我们本地项目引用了libimported-lib.so
  • 添加add_library命令,第一个参数是模块名,第二个参数SHARED表示静态库名,第三个参数IMPORTED表示以导入的形式添加的.
  • 添加set_target_properties命令设置导入路径属性。
  • import-lib添加到target_link_libraries命令参数中,表示native-lib需要链接imported-lib模块

添加预编译库(Andorid6.0版本以后)

# set命令定义一个变量
# CMAKE_C_FLAGS: c的参数,会传递给编译器
# 如果是c++文件, 需要用CMAKE_CXX_FLAGS
# -L: 库的查找路径
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -L[SO所在目录]")

添加头文件的目录:

cmake_minimum-required(VERSION 3.4.1)
# 设置头文件目录
include_directories(<文件目录>)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -L[SO所在目录]")
aux_source_directory(. DIR_SRCS)
add_library(
        native-lib
        SHARED
        ${DIR_SRCS})
target_link_libraries(native-lib imported-lib)

Build.gradle配置

android{
    defaultConfig {
        externalNativeBuild{
            cmake{
                //使用的编译器clang/gcc
                //cmake默认就是 gnustl_static 
                arguments "-DANDROID_TOOLCHAIN=clang",
                "-DANDROID_STL=gnustl_static"
                //指定cflags和cppflags,效果和cmakelist使用一样
                cFlags ""
                cppFlags ""
                //指定需要编译的cpu架构
                abiFilters "ameabi-v7a"
            }
        }
    }
    externalNativeBuild {
        cmake {
            //指定CMakeLists.txt文件相对当前Build.gradle的路径
            path"xxx/CMakeLists.txt"
        }
    }
}

相关文章

网友评论

      本文标题:CMakeLists语法详解

      本文链接:https://www.haomeiwen.com/subject/tynrrktx.html