Cmake

CMake是一个用于软件构建、测试和打包的开源跨平台系统。它通过配置文件管理项目,包括添加执行文件、库,查找库文件、设置包含目录和链接库等。CMake支持自定义搜索规则和通配符匹配文件,可用于管理复杂项目的源代码和依赖项。
摘要由CSDN通过智能技术生成

Cmake

cmake 是啥

cmake 是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。

配置说明

# 指定 cmake 的最低版本
cmake_minimun_required(VERSION 3.4.1)

# 指定项目名称
project(demo)


# 生成可执行文件
add_executable(test test.cpp)

# 生成静态库
add_library(common STATIC util.cpp)

# 生成动态库
add_library(common SHARED util.cpp)

# 明确指定包含那些源文件
add_library(demo demo.cpp test.cpp util.cpp)

# 发现一个目录下所有的源代码文件并将列表存放到一个变量中
aux_source_directory(. SRC_LIST) # 搜索当前目录下的所有.cpp文件
add_library(demo ${SRC_LIST})

# 自定义搜索规则
file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp")
add_library(demo ${SRC_LIST})
# 或者
file(GLOB SRC_LIST "*.cpp")
file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
# 或者
aux_source_directory(. SRC_LIST)
aux_source_directory(protocol SRC_PROTOCOL_LIST)
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})

# 查找指定的库文件
find_library(log-lib log)

# 查找文件
find_file()

# 查找路径
find_path()

# 查找程序
find_program()

# 查找包
find_package()

# 设置包含的目录
include_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_BINARY_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/include
)

# 链接库搜索目录
link_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}/libs
)

# target 需要链接的库
target_link_libraries(native-lib ${log-lib} )

# 链接静态库或者动态库
target_link_libraries(demo libface.a) # 链接libface.a
target_link_libraries(demo libface.so) # 链接libface.so

# 链接多个库
target_link_libraries(demo
    ${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.a
    boost_system.a
    boost_thread
    pthread)

target_link_libraries( 
        native-lib # 总库libnative-lib.so

        # 忽略顺序的方式,导入
        -Wl,--start-group
        avcodec avfilter avformat avutil swresample swscale
        -Wl,--end-group

        log # 日志库,打印日志用的
        z # libz.so库,是FFmpeg需要用ndk的z库,FFMpeg需要额外支持  libz.so
        rtmp # rtmp 后面会专门介绍
        android # android 后面会专门介绍,目前先要明白的是 ANativeWindow 用来渲染画面的 == Surface对象
        OpenSLES # OpenSLES 后面会专门介绍,目前先要明白的是 OpenSLES 用来播放声音的-特别是在native层播放(最快的)
)

# 设置变量
set(SRC_LIST main.cpp test.cpp)
add_executable(demo ${SRC_LIST})
set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -L${FFMPEG}/libs/${CMAKE_ANDROID_ARCH_ABI}") # ffmpeg库指定

set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -L${RTMP}/libs/${CMAKE_ANDROID_ARCH_ABI}") # rtmp库指定

set(SRC_LIST main.cpp)
set(SRC_LIST ${SRC_LIST} test.cpp)
add_executable(demo ${SRC_LIST})

set(SRC_LIST main.cpp)
list(APPEND SRC_LIST test.cpp)
list(REMOVE_ITEM SRC_LIST main.cpp)
add_executable(demo ${SRC_LIST})

Cmake 关键字

GLOB (globbing)

通配符 用于匹配文件

常用变量

CMAKE_BINARY_DIR,

PROJECT_BINARY_DIR

projectname_BINARY_DIR

这三个变量的内容是一致的, 如果是 in source 编译,指得就是工程顶层目录, 如果是 out-of-source 编译,指的是工程编译发生的目录。PROJECT_BINARY_DIR 跟其他指令稍有区别, 现在你可以理解为他们是一致的

CMAKE_SOURCE_DIR

PROJECT_SOURCE_DIR,

projectname_SOURCE_DIR

这三个变量指代的内容是一致的, 不论采用何种编译方式,都是工程顶层目录

CMAKE_CURRENT_SOURCE_DIR

指的是当前处理的 CMakeLists.txt 所在的路径, 比如上面我们提到的 src 子目录

CMAKE_CURRRENT_BINARY_DIR

如果是 in-source 编译, 它跟 CMAKE_CURRENT_SOURCE_DIR 一致,如果是 out-of-source 编译, 他指的是 target 编译目录。
使用我们上面提到的 ADD_SUBDIRECTORY ( src bin ) 可以更改这个变量的值。
使用 SET(EXECUTABLE_OUTPUT_PATH <新路径>)并不会对这个变量造成影响, 它仅仅修改了最终目标文件存放的路径

CMAKE_CURRENT_LIST_FILE

输出调用这个变量的 CMakeLists.txt 的完整路径

CMAKE_CURRENT_LIST_LINE

输出这个变量所在的行

CMAKE_MODULE_PATH

这个变量用来定义自己的 cmake 模块所在的路径。如果你的工程比较复杂,有可能会自己编写一些 cmake 模块, 这些 cmake 模块是随你的工程发布的, 为了让 cmake 在处理 CMakeLists.txt 时找到这些模块, 你需要通过 SET 指令,将自己的 cmake 模块路径设置一下。
比如SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)这时候你就可以通过 INCLUDE 指令来调用自己的模块了

EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH

分别用来重新定义最终结果的存放目录, 前面我们已经提到了这两个变量

PROJECT_NAME

返回通过 PROJECT 指令定义的项目名称

Cmake 调用环境变量

set(ENV{变量名})

系统信息

CMAKE_MAJOR_VERSION

CMAKE 主版本号, 比如 2.4.6 中的 2

CMAKE_MINOR_VERSION

CMAKE 次版本号, 比如 2.4.6 中的 4

CMAKE_PATCH_VERSION

CMAKE 补丁等级, 比如 2.4.6 中的 6

CMAKE_SYSTEM

系统名称, 比如 Linux-2.6.22

CMAKE_SYSTEM_NAME

不包含版本的系统名, 比如 Linux

CMAKE_SYSTEM_VERSION

系统版本, 比如 2.6.22

CMAKE_SYSTEM_PROCESSOR

处理器名称, 比如 i686

UNIX

在所有的类 UNIX 平台为 TRUE, 包括 OS X 和 cygwin

WIN32

在所有的 win32 平台为 TRUE, 包括 cygwin

主要的开关选项

CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS

用来控制 IF ELSE 语句的书写方式

BUILD_SHARED_LIBS

这个开关用来控制默认的库编译方式, 如果不进行设置,使用 ADD_LIBRARY 并没有指定库
类型的情况下, 默认编译生成的库都是静态库。

set(BUILD_SHARED_LIBS ON) 后, 默认生成动态库

CMAKE_C_FLAGS

设置 C 编译选项, 也可以通过指令 add_definitions() 添加

CMAKE_CXX_FLAGS

设置 C++ 编译选项, 也可以通过指令 add_definitions() 添加

Cmake 常用指令

add_definitions()

向 C/C++编译器添加-D 定义

add_dependencies()

定义 target 依赖的其他 target, 确保在编译本 target 之前, 其他的 target 已经被构建

add_executable()

使用指定的源文件来生成目标可执行文件。这里的目标可执行文件分为三类:普通可执行目标文件导入可执行目标文件别名可执行目标文件。分别对应上面的三种命令格式

add_executable (<name> [WIN32] [MACOSX_BUNDLE]
      [EXCLUDE_FROM_ALL]
      [source1] [source2 ...])
add_executable (<name> IMPORTED [GLOBAL])
add_executable (<name> ALIAS <target>)

add_library()

add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            source1 [source2 ...])

add_subdirectory()

add_subdirectory (source_dir [binary_dir] [EXCLUDE_FROM_ALL])

add_test()与enable_testing()

add_test(testname Exename arg1 arg2 ...)

enable_testing()

testname 是自定义的 test 名称, Exename 可以是构建的目标文件也可以是外部脚本等等。后面连接传递给可执行文件的参数。如果没有在同一个 CMakeLists.txt 中打开 ENABLE_TESTING() 指令, 任何 ADD_TEST 都是无效的。
比如我们前面的 Helloworld 例子, 可以在工程主 CMakeLists.txt 中添加

add_test(mytest ${PROJECT_BINARY_DIR}/bin/main)

enable_testing()

aux_source_directory()

作用是发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建源文件列表

AUX_SOURCE_DIRECTORY(. SRC_LIST)

cmake_minimum_required()

CMAKE_MINIMUM_REQUIRED(VERSION 2.5 FATAL_ERROR)

file()

file(WRITE filename "message to write"... )
file(APPEND filename "message to write"... )
file(READ filename variable)
file(GLOB variable [RELATIVE path] [globbing expression_r_rs]...)
file(GLOB_RECURSE variable [RELATIVE path] [globbing expression_r_rs]...)
file(REMOVE [directory]...)
file(REMOVE_RECURSE [directory]...)
file(MAKE_DIRECTORY [directory]...)
file(RELATIVE_PATH variable directory file)
file(TO_CMAKE_PATH path result)
file(TO_NATIVE_PATH path result)

include()

用来载入 CMakeLists.txt 文件,也用于载入预定义的 cmake 模块

include(file [optional])

include(module [optionnal])

optional 参数的作用是文件不存在也不会产生错误。

你可以指定载入一个文件, 如果定义的是一个模块, 那么将在 CMAKE_MODULE_PATH 中搜索这个模块并载入。
载入的内容将在处理到 INCLUDE 语句是直接执行

install()

install用于指定在安装时运行的规则。它可以用来安装很多内容,可以包括目标二进制、动态库、静态库以及文件、目录、脚本等

install(TARGETS <target>... [...])
install({FILES | PROGRAMS} <file>... [...])
install(DIRECTORY <dir>... [...])
install(SCRIPT <file> [...])
install(CODE <code> [...])
install(EXPORT <export-name> [...])

find_file()

查找一个文件的完整路径

find_file(<VAR> name1 [path1 path2 ...])

find_library()

用于查找库

find_library(<VAR> name1 [path1 path2 …])

find_path()

find_path( name1 [path1 path2 …])

find_program()

find_program(<VAR> name1 [path1 path2 ...])

find_package()

find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]

控制流程

if , else if, else

if(expression)
	message(STATUS if_branch)
elseif(expression)
	message(STATUS else_if_branch)
else()
	message(STATUS else_branch)
endif()
表示真假的变量

空,0,N,NO,OFF,FALSE,NOTFOUND或者var_NOTFOUND为假

非0, Y,YES,ON,TRUE为真

NOT

取反

if(NOT VAR)

AND

2 个变量同时满足要求

if(var1 AND var2)

OR

有一个变量满足就为真

if(var1 OR var2)

COMMAND

if(COMMAND cmd)

当给的的 cmd 确实是命令时并且可以调用时为真

EXIST

if(EXIST dir) 或者 if(EXIST file)

目录或者文件存在时为真

IS_NEWER_THAN

if(file1 IS_NEWER_THAN file2)

file1 比 file2 新, 或者 file1 / file2 其中有一个不存在时为真, 文件名请使用全路径

IS_DIRECTORY

if(IS_DIRECTORY dirname)

dirname 为目录时为真

MATCHES

if(variable MATCHES regex)

if(string MATCHES regex)

当给定的变量或者字符串能够匹配正则表达式 regex 时为真

LESS

数字小于

if(a LESS b)

GREATER

数字大于

if(a GREATER b)

EQUAL

数字等于

if(a EQUAL b)

STRLESS

字符串小于

if(a STRLESS b)

STRGREATER

字符串大于

if(a STRGREATER b)

STREQUAL

字符串等于

if(a STREQUAL b)

DEFINED

if(DEFINED var)

如果 var 被定义为真

while()

while(condition)
	...
endwhile()

foreach()

  1. 列表
foreach(loopval arg1 arg2 ...)
	...
endforeach()
  1. 范围

    以 0 开始到 total 结束, 每次加 1

foreach(loopval RANGE total)
	...
endforeach()
  1. 范围带步长

    以 start 开始到 stop 结束, 每次加 step

foreach(loopval RANGE start stop [step])
	...
endforeach()

set

set(Val main.c) 设置一个变量 Val 它的值为 main.c

访问自定义变量使用 ${Val}

参考内容

cmake参考地址

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值