1.include
https://blog.csdn.net/qq_38410730/article/details/102677143
CmakeLists.txt
才是cmake
的正统文件,而.cmake
文件是一个模块文件,可以被include
到CMakeLists.txt
中。
include指令一般用于语句的复用,也就是说,如果有一些语句需要在很多CMakeLists.txt文件中使用,为避免重复编写,可以将其写在.cmake文件中,然后在需要的CMakeLists.txt文件中进行include操作就行了。
include(file|module)
.cmake文件里包含了一些cmake命令和一些宏/函数,当CMakeLists.txt包含该.cmake文件时,当编译运行时,该.cmake里的一些命令就会在该包含处得到执行,并且在包含以后的地方能够调用该.cmake里的一些宏和函数。
之后有机会再了解什么事宏和函数。
2.protobuf_generate_cpp
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto)
将foo.proto文件生成源码,使用PROTO_SRC,PROTO_HARS变量分别指代生成的cpp和h文件并可用于连接到target和设置include。
要求protobuf_generate_cpp命令和生成add_executable() 或 add_library() 的命令必须在同一个CMakeList中.
3.file命令
file(GLOB variable [RELATIVE path] [globbingexpressions]...)
file GLOB命令主要用于匹配规则在指定的目录内匹配到所需要的文件。GLOB 会产生一个由所有匹配globbing表达式的文件组成的列表,并将其保存到变量中。(如果指定了RELATIVE 标记,返回的结果将是与指定的路径相对的路径构成的列表。)
如果没有写正则表达式,那么什么文件都匹配不到。例子:
file(GLOB files *)// 会把文件和文件夹都包含进来
foreach(file IN LISTS files)
message(STATUS ${file})
endforeach(file)
例子,注意要用双引号,cmake不支持单引号:
打印结果,目录和文件是同等地位,被包含进来:
这段代码的意思是挑选出当前文件下的所有文件,然后打印。
file(MAKE_DIRECTORY [directory1 directory2 ...])
MAKE_DIRECTORY在指定目录处创建子目录,如果它们的父目录不存在,也会创建它们的父目录。
5.add_subdirectory
https://www.jianshu.com/p/07acea4e86a3,添加一个子目录并构建该子目录。
add_subdirectory (source_dir [binary_dir] [EXCLUDE_FROM_ALL])# 绝对路径或当前目录的相对路径 []是可选参数
binary_dir,指定文件输出存放路径。
6.自带变量
https://blog.csdn.net/wzj_110/article/details/116674655, https://juejin.cn/post/6844903999448055815
内置变量
CMAKE_CURRENT_LIST_DIR: 当前处理的'cmake或CMakeListst.txt文件'所在的目录
CMAKE_CURRENT_SOURCE_DIR:指的是当前处理的 CMakeLists.txt 文件所在的路径。
PROJECT_SOURCE_DIR:项目源文件的目录,如果直接在代码目录下cmake,那么此变量与PROJECT_BINARY_DIR内容相同;
PROJECT_BINARY_DIR:可执行文件的目录。
7.function用法
https://blog.csdn.net/qq_38410730/article/details/102677143
function(<name> [arg1 [arg2 [arg3 ...]]])
COMMAND1(ARGS ...) # 命令语句
COMMAND2(ARGS ...)
...
function()
可以用${arg1}
来引用变量。当宏和函数调用的时候,如果传递的是经set设置的变量,必须通过${}取出内容。
function(Foo arg)
set(${arg} "abc" PARENT_SCOPE)
message("# After change the value of arg.")
message("arg = ${arg}")
endfunction()
message("=== Call function ===")
Foo(test)
message("test value = ${test}")
//CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
include(test.cmake)
打印结果
=== Call function ===
# After change the value of arg.
arg = test //不太明白这里为什么是test值?
test value = abc
总之在CMakeLists访问变量就带上${}。
8.add_library()
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[source1] [source2 ...])# Normal Libraries
- 添加名为
name
的库,name全局唯一; - 库的类型是
STATIC(静态库)
/SHARED(动态库)
/MODULE(模块库)
之一,生成的library名会根据STATIC
或SHARED
成为name.a
或name.lib;默认是STATIC选项。
add_library(<name> OBJECT [<source>...]) # Object Libraries
创建对象库(Object Library).对象库编译源文件,但不会将其存档或链接到库中。由add_library命令或add_executable命令创建的其它目标可以使用$<TARGET_OBJECTS:objlib>形式的表达式作为源来引用对象,其中objlib是对象库名称。
9.include_directories()
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 …]) //默认是AFTER
将指定目录添加到编译器的头文件搜索路径之下。相当于g++选项中的-I参数的作用,也相当于环境变量中增加路径到CPLUS_INCLUDE_PATH变量的作用.
使用SYSTEM
选项,会把指定目录当成系统的搜索目录。
10.get_filename_component
https://blog.csdn.net/wzj_110/article/details/116431616
cmake获取'文件名'的'特定'部分。
路径+文件名。
11.add_executable
https://blog.csdn.net/MacKendy/article/details/122549819
基于特定的源文件,创建可执行文件,名为<name>或者<name>.exe(根据平台不同,带exe后缀的是win平台)。
创建名为<name>的target,这个target在make的时候会编译为可执行文件。编译的源文件为[source1] [source2]…。
https://www.cnblogs.com/dbai/p/17209898.html,add_executable的3种写法,一种是最基础麻烦的,第二是用file命令,第三种是aux但头文件要单独加。
12.aux_source_directory
//语法:
aux_source_directory(<dir> <variable>)
//例子:
//# 查找目录下的所有源文件
//# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
13.target_include_directories
target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
该命令可以指定目标(exe或者so文件)需要包含的头文件路径。命名的<目标>必须是由add_executable()或add_library()之类的命令创建的,并且不能是ALIAS目标。
14.add_dependencies
add_dependencies(<target> [<target-dependency>]...)
明确依赖关系:始终在CMakeLists.txt中明确指定目标间的依赖关系,避免隐式依赖。
例子:【cmake 基础小知识】如何在CMake项目中使用add_dependencies命令管理目标依赖关系-阿里云开发者社区
15.cmake_parse_arguments
当编写自定义的 CMake 函数或宏时,通常需要解析传入的参数,而这些参数可能是选项(布尔类型)、单值参数或多值参数。cmake_parse_arguments 提供了一种简洁且标准化的方式来处理这些参数。函数参数:
cmake_parse_arguments(PREFIX "<options>"
"<one_value_keywords>" "<multi_value_keywords>" <args>)
- PREFIX:指定前缀,将用于存储解析结果。
- <options>:包含所有可能的选项(布尔类型)的列表,选项存在时其值为 ON,不存在时其值为 OFF。
- <one_value_keywords>:包含所有可能的单值参数的列表。
- <multi_value_keywords>:包含所有可能的多值参数的列表。
- <args>:传入的参数列表,一般使用 ${ARGN}。
例子:
function(my_function)
# 解析参数
cmake_parse_arguments(
MYFUNC # 前缀
"OPT1;OPT2" # 选项
"SINGLE_VAL" # 单值参数
"MULTI_VALS" # 多值参数
${ARGN} # 传入的参数列表
)
# 输出解析结果
message(STATUS "OPT1: ${MYFUNC_OPT1}")
message(STATUS "OPT2: ${MYFUNC_OPT2}")
message(STATUS "SINGLE_VAL: ${MYFUNC_SINGLE_VAL}")
message(STATUS "MULTI_VALS: ${MYFUNC_MULTI_VALS}")
endfunction()
# 调用函数
my_function(OPT1 SINGLE_VAL value1 MULTI_VALS value2 value3 value4)
// 输出结果
-- OPT1: TRUE
-- OPT2: FALSE
-- SINGLE_VAL: value1
-- MULTI_VALS: value2;value3;value4