[TOC]
cmake
指定cmake的版本
cmake_minimum_required(VERSION major.minor[.patch[.tweak]]
[FATAL_ERROR])
cmake_minimum_required(VERSION 3.0)
变量
# 设置变量
set(<variable> <value>... [PARENT_SCOPE])
set(<variable> <value>... CACHE <type> <docstring> [FORCE])
## 环境变量
set(ENV{<variable>} <value>...)
# 使用变量
${var}
打印日志
message([STATUS|WARNING|SEND_ERROR|FATAL_ERROR] "info")
生成对象
# 静态库|动态库
add_library(<name> [SHARED|STATIC] <SOURCE_FILES>)
# 可执行文件
add_executable(<name> <files>)
源文件
#按照自己指定的伪正则进行匹配查找【不建议使用】
file(GLOB_RECURSE <variable> [<globbing-expressions>...])
# 只能查找本目录下所有的c/cxx/cpp结尾的文件
aux_source_directory(<dir> <variable>)
添加头文件
target_include_directories(<target> [SYSTEM] [BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
编译参数
# 预编译
target_compile_definitions(<target>
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
add_definitions(-DFOO -DBAR ...)
set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -MD")
# 编译
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-\\#pragma-messages")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11");
target_compile_options(<target> [BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
# 这个方法什么参数都可以加
add_compile_options(-Wno-#pragma-messages)
链接参数
target_link_libraries(<target>
<PRIVATE|PUBLIC|INTERFACE> <item>...
[<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
set(CMAKE_SHARED_LINKER_FLAGS "-z defs")
set(CMAKE_STATIC_LINKER_FLAGS "x")
编译依赖
# 执行target 需要先执行target-dependency
add_dependencies(<target 目标> [<target-dependency> 依赖项]...)
创建目标项
# 创建的目标为可执行文件
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
[EXCLUDE_FROM_ALL]
source1 [source2 ...])
# 创建的目标为库
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
source1 [source2 ...])
# 创建一个普通的目标
add_custom_target(Name [ALL] [command1 [args1...]]
[COMMAND command2 [args2...] ...]
[DEPENDS depend depend depend ... ]
[BYPRODUCTS [files...]]
[WORKING_DIRECTORY dir]
[COMMENT comment]
[VERBATIM] [USES_TERMINAL]
[SOURCES src1 [src2...]])
以上为简单的可以编译的具体的方式
如果需要编写逻辑条件的话,则需要CMAKE的具体语法规则了
查看我的另一篇文章:CMake 分享
还有几个点要说明一下:
进阶
通过文件来生成文件
通过 *.h.in 来生成具体的文件
configure_file(<input> <output>
[COPYONLY] [ESCAPE_QUOTES] [@ONLY]
[NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
*.h.in 的写法,主要是做字符串替换,如果需要使用生成的文件则需要添加到编译路径上面即可
#define TUTORIAL_VARSION_MAJOR @TUTORIAL_VARSION_MAJOR@
#define TUTORIAL_VERSION_MAJOR @TUTORIAL_VERSION_MAJOR@
// ${VAR} 这样的必须要用 #cmakedefine 才会替换
#define TUTORIAL_VERSION_MINOR ${TUTORIAL_VERSION_MINOR}
// 如果加了 @ONLY 则这里不会进行替换
#cmakedefine TEST_VAR ${TEST_VAR}
// 这里可以证明,宏名必须和需要替换的名称一致,否则有问题
#cmakedefine TTT @TEST_VAR@
// 如果是define 则宏名和替换的名称可以不一致
#define TTTDefine @TEST_VAR@
find_* 的用法
*.cmake 供 find_package 进行查找
命名规则:Find<package>.cmake
find_path (
<VAR>
name | NAMES name1 [name2 ...]
[HINTS path1 [path2 ... ENV var]]
[PATHS path1 [path2 ... ENV var]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
[NO_DEFAULT_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_CMAKE_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_SYSTEM_PATH]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH]
)
find_library (
<VAR>
name | NAMES name1 [name2 ...] [NAMES_PER_DIR]
[HINTS path1 [path2 ... ENV var]]
[PATHS path1 [path2 ... ENV var]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
[NO_DEFAULT_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_CMAKE_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_SYSTEM_PATH]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH]
)
查找包
通过 set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) 来指定查找路径
find_package(<package> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[NO_POLICY_SCOPE])
FAQ:
如何传递一个list 给到function
functionName("${listName}")即可,注意双引号
使用execute_process() 会产生换行符,怎么办?
可以使用
exec_program来进行替换,或者你需要使用string(REGEX REPLACE "\n$" "" GIT_CURRENT_TIME "${GIT_CURRENT_TIME}")来替换后面的换行符
如何多行注释 cmake
#[==[
多行注释
#]==]
file(READ)读取文件的时候,会出现换行,怎么破?
file(STRINGS)使用这个来进行读取,然后foreach循环读取每一行即可
以上所有测试,可以去我的github上面进行查看具体的例子使用 :地址
