贡献者: addis
参考官方教程。
ccmake
可以有 TUI。否则就用 cmake
CMakeLists.txt
的路径下,cmake .
生成 Makefile,然后 make -j12
多线程编译。make VERBOSE=1 -j12
输出编译命令。cmake 会在当前路径生成 Makefile
和一些临时文件和文件夹,清理麻烦,所以还是建议输出到子文件夹。
CMakeLists.txt
中,注释如 #[[一些注释]]
或者 #一些注释
cmake 源码路径
即可。
cmake -L 源码路径
列出编译选项,-LH
列出选项以及帮助说明。-LAH
列出所有选项(会多出很多 CMAKE_
开头的,不是作者提供的选项),用 cmake -D 选项1=值1 -D 选项2=值2 源码路径
来设置选项(-D
后面可以没有空格)。
cmake -S CMakeList的路径 -B 生成Makefile的路径
,然后再到 Makefile 的路径 make -j12
即可。如果要清理 cmake 生成的文件以及所有编译出来的文件,直接把第二个路径清空即可。
make
,所以也可以用 cmake --build 生成Makefile的路径 [--target 可执行文件] -- -j 12
其中 --
后面的选项会传给 make
或者别的具体用于编译的程序。
command(arg1 arg2 ...)
其中 command
不区分大小写,arg
用空格隔开,如果 arg
本身有空格,用双引号即可
arg
前后都可以换行
message(STATUS "...")
可以输出到 stdout。如果 message(STATUS ${var})
中的变量是 list,那么中间不会有空格,应该用 message(STATUS "${var}")
,输出中每个元素会用分号隔开。message(STATUS ${var1} ${var2} ...)
相当于把若干变量合成 list。
${VAR}
。注意不能用 $VAR
。
set
可以对变量赋值,例如 set(var, 123)
set
也可以把许多变量变成一个 list,如 set(Foo aaa bbb ccc)
(等效于 set(Foo "aaa" "bbb" "ccc")
)将 Foo
变成 list
command()
的参数相当于多个 arg
。例如 command(${Foo})
相当于 command(aaa bbb ccc)
。
set(MY_LIST "one" "two")
相当于 set(MY_LIST "one;two")
。后者是 list 的内部的表示方法。
command("${Foo}")
相当于 command("aaa;bbb;ccc")
(双引号中的是一个字符串不是 list)
$EVN{VAR}
。例子:message(STATUS $ENV{PWD})
。注意 cmake 看到的环境变量未必和 bash 中的相同,可以用 cmake -E environment
检查。
separate_arguments(VAR)
可以把一个含有若干空格的字符串拆分成 list(即把空格替换为分号)。
cmake_minimum_required(VERSION x.x)
(必须有)
project(project_name)
指定项目名称(必须有)
set(CMAKE_CXX_COMPILER "/usr/bin/g++")
设置 compiler
set(CMAKE_CXX_FLAGS "-std=c++11")
设置 flag,包括 c++ 标准。
set(CMAKE_CXX_STANDARD 11)
会对 g++ 自动使用 -std=gnu11
而不是 -std=c++11
,一些情况会出错。
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address")
set(var str1 [str2] ...)
对变量赋值(若有多个值就生成 list)
list(APPEND var str1 [str2] ...)
在变量(list)后面添加元素
list(REMOVE_ITEM var str1 ...)
从 var
的 list 中移除(如果不存在也不报错)
set(var "${var} str1 str2")
等效于上一条
file(GLOB var "folder/*.cpp" "fname2.cpp")
可以列出所有 "folder/*.txt"
文件,以及 fname2.cpp
(如果存在)赋值给 var
。注意文件名包括绝对路径。match 的结果也会存到 CMAKE_MATCH_编号
,编号从 1 开始。
file(READ 文件名 变量
读取文件内容到变量。
string(REGEX MATCH "...(...)..." 变量 字符串变量
。在 字符串变量
中匹配正则表达式,并把 ()
中的匹配结果赋值给 变量
。
add_definitions(-D FOO -D BAR)
给编译器添加宏定义
add_compile_options(-Wall -fopenmp)
给编译器添加选项(注意不能用 -D
)
add_executable(exe_name source_name)
前者是可执行文件名,后者是所有需要 link 的 c/c++
文件名,不需要头文件。cmake 会自动分析代码得到哪个 cpp 调用哪个头文件,如果头文件改变了,只有调用它的 cpp 会重新编译。
configure_file(file_in file_out)
将文件中 @var@
替换为变量 var
的字符串。
include_directories(dir1 [dir2] ...)
添加头文件的搜索路径
add_library(exe_name source_name)
单独编译一个 library(在 library 路径的 CMakeLists.txt
中使用这个命令而不是 add_executable
命令)
link_directories(路径)
相当于编译器的 -L
选项,添加静态或动态 library 的搜索路径。
set(CMAKE_INSTALL_RPATH 路径)
相当于设置 rpath
(到底是 RUNPATH
还是 RPATH
?)
add_subdirectory(dir1 [dir2] ...)
执行子路径中的 CMakeLists.txt
target_link_libraries(exe_name lib1 [lib2] ...)
link 阶段链接 library,相当于 -l lib1 -l lib2
option(opt_name description default)
定义一个 option 开关(会在 gui 中显示开关)以及默认值。opt_name
可以在 CMakeLists.txt
中的 if
语句中使用例如 if(opt_name) ... endif(opt_name)
。default
可以是 ON
或 OFF
。
option
的默认值后,需要清空 cmake 的临时文件才可以生效。
set(VAR "默认值" CACHE STRING "描述")
。如果之前 VAR
已经被赋值(例如命令行 -D VAR=...
),则值不会被覆盖。这种变量叫做 cached variable。
cmake -LH .
的帮助中看到说明。
opt_name
为 ON
时 #cmakedefine opt_name
会被替换为 #define opt_name
target_precompile_headers(可执行文件 PRIVATE foo.h bar.h)
可以编译头文件,注意貌似不会自动包括 .h 包括的文件。如果头文件(或者依赖的文件)改了,那么将会自动重新编译头文件。
execute_process(COMMAND 命令 参数1 参数2 ...)
可以执行命令,其中命令和参数中都可以用 ${VAR}
。其他功能(包括命令返回的内容,文件输入输出),详见文档。
include(文件或者模块)
,详见文档。模块可以是 *.cmake
的文件,也可以是 cmake 的内建模块如 CheckCXXCompilerFlag
macro(宏名 [参数1 参数2]) 一些命令 endmacro()
定义宏,调用如 ei_add_cxx_compiler_flag(参数1 参数2)
check_cxx_source_compiles(代码变量 输出变量)
(文档) 可以判断某个源码是否可以编译成功。在调用前,可以用 CMAKE_REQUIRED_LIBRARIES
变量设置所需的库,CMAKE_REQUIRED_FLAGS
指定额外的编译器选项,等。
check_cxx_compiler_flag(编译器选项 输出变量)
可以检查某个编译器选项是否可用。输出变量
是 True 或 False。
foreach(var IN 列表) ... endforeach()
可以循环。foreach(var var1 var2 ...) ... endforeach()
可以循环。文档。
find_package(包名)
包名
会在 CMAKE_MODULE_PATH
的路径里面搜索名为 Find包名.cmake
的文件。该文件通常会设置一些变量,可以在 find_package
结束后访问。
PROJECT_NAME
是 project()
设置的项目名称
PROJECT_SOURCE_DIR
是源文件的根路径,就是传给 ccmake
的路径
PROJECT_BINARY_DIR
是 Cmake 的输出路径,临时文件,Makefile 等都在这个路径。这就是运行 ccmake
的路径
CMAKE_CURRENT_LIST_DIR
当前在处理的 CMakeLists.txt
的路径。
CMAKE_SOURCE_DIR
和 CMAKE_BINARY_DIR
和上面两个有什么区别?
CMAKE_BUILD_TYPE
可以被用户设置为 Release
,Debug
等。例如 cmake -DCMAKE_BUILD_TYPE=Debug
用 debug 模式编译
WIN32
可以判断是否在 windows 上(包括 32 和 64 位)
MSVC
判断是否用 Visual C++ 编译器
参考这里。
if(1 或 ON 或 YES 或 TRUE 或 Y)
……
elseif(0 或 OFF 或 NO 或 FALSE 或 N 或 IGNORE 或 NOTFOUND)
这里永远不会执行
elseif(条件 AND (条件 OR 条件) OR NOT 条件)
……
elseif(("bar" IN_LIST var) OR (file1 IS_NEWER_THAN file2))
……
elseif(var)
当变量 var 有定义且不是 false constant
if(ENV{var})
这里永远不会执行
elseif (DEFINED <name>|CACHE{<name>}|ENV{<name>})
若定义了变量
elseif (var1 STREQUAL var2)
比较字符串
elseif (IS_DIRECTORY 某路径)
判断某路径是否存在
else()
……
endif()
*.lib
,只需要在 add_executable()
命令前面插入(必须在之前)abc.lib
的路径 link_directories(path/to/lib)
然后再 add_executable()
之后插入 target_link_libraries(exe_name abs)
即可
if(MSVC)...end(MSVC)
可以专门给 Visual Studio 执行一些命令
ZERO_CHECK
会重新运行/更新 CMakeLists.txt
,ALL_BUILD
会编译所有工程。如果看着不爽的话也可以把这两个 project 删掉。如果直接 run without debug 的话,会提示 ALL_BUILD
不能 run,所以要 run 只能右键某个 project 然后 run(所以还是把两个多余的 project 删掉好些)。
sudo apt install cmake-curses-gui
安装
ccmake
,这个路径可以是源文件路径
ccmake ../
h
帮助,q
退出,c
configure,G
生成 Makefile
 
 
 
 
 
 
 
 
 
 
 
友情链接: 超理论坛 | ©小时科技 保留一切权利