贡献者: addis
参考官方教程。
ccmake 可以有 TUI。否则就用 cmake
cmake CMakeLists.txt的路径,可以是相对路径。
CMakeLists.txt 的路径下,新建 build(名字任意)文件夹,然后 cd 进去,使用 cmake .. 在当前目录生成一些缓存文件和 Makefile(或 ninja 文件),然后 make -j 多线程编译。
make VERBOSE=1 -j 输出编译命令。
make 命令默认 VERBOSE=1,可以在之前用 cmake -DCMAKE_VERBOSE_MAKEFILE=ON
CMakeLists.txt 中,注释如 #[[一些注释]] 或者 #一些注释 直到行末
cmake -G 生成器 CMakeLists.txt的路径 可以指定生成器,生成器 可以是 Unix Makefiles,MinGW Makefiles,Ninja
ninja 编译(默认使用当前路径的 build.ninja 文件),ninja install 安装
cmake -L CMakeLists.txt的路径 列出编译选项,-LH 列出选项以及帮助说明。-LAH 列出所有选项(会多出很多 CMAKE_ 开头的,不是作者提供的选项),用 cmake -D 选项1=值1 -D 选项2=值2 CMakeLists.txt的路径 来设置选项(-D 后面可以没有空格)。如果需要一个 list 作为值,就用 -D 选项="值1;值2;..." 例如 -DCMAKE_PREFIX_PATH="/path1;/path2;/path3" ..
cmake -S CMakeLists.txt的路径 -B 生成Makefile的路径,然后再到 Makefile 的路径 make -j12 即可。cmake 会自动生成 生成Makefile的路径。如果要清理 cmake 生成的文件以及所有编译出来的文件,直接把第二个路径清空即可。
make,所以也可以用 cmake --build 生成Makefile的路径 [--target 可执行文件] -- -j 12 其中 -- 后面的选项会传给 make 或者别的具体用于编译的程序。更跨平台的多线程编译方法也可以 --parallel [线程数]。
CMAKE_INSTALL_PREFIX 可以指定默认安装路径。
cmake --install /build/path --prefix /install/path 可以指定 build 路径和安装路径。
命令(arg1 arg2 ...) 其中 命令 不区分大小写,arg 用空格隔开也可以换行,如果 arg 本身有空格,用双引号即可
cmake 中的变量本质上都是字符串。即使是 list,也不过是特殊的字符串 str1;str2;str3。所谓的 bool 类型不过是 ON 和 OFF 字符串。数字也一样,并不是真正的数字。
${变量}。注意不能用 $变量。
set(my_var abc123)。
message(STATUS "...") 可以输出到 stdout。如果 message(STATUS ${变量}) 中的变量是 list,那么输出中 ; 会消失。应该用 message(STATUS "${变量}"),输出的格式为 str1;str2;str3。message(STATUS ${变量1} ${变量2} ...) 相当于把若干变量合成 list。
message(FATAL_ERROR "字符串") 会输出错误信息并立即退出。
[=[字符串]=] 等号可以有一个也可以有多个。
set 可以对变量赋值,例如 set(变量 123)。
set 也可以把许多变量变成一个 list,如 set(Foo aaa bbb ccc) 等效于 set(Foo "aaa" "bbb" "ccc") 等效于 set(Foo "aaa;bbb;ccc") 等效于 set(Foo aaa;bbb;ccc)。
命令() 的参数相当于多个 arg。例如 命令(${Foo}) 相当于 命令(aaa bbb ccc)。
命令("${Foo}") 相当于 命令("aaa;bbb;ccc") 也就是说命令的第一个参数是一个 list。
$EVN{变量}。例子:message(STATUS $ENV{PWD})。注意 cmake 看到的环境变量未必和 bash 中的相同,可以用 cmake -E environment 检查。
separate_arguments(变量) 可以把一个含有若干空格的字符串拆分成 list(即把空格替换为分号)。
include_directories(), link_directories(), add_definitions(), add_link_options() 这些改变 global 状态的命令,只对在它们之后定义的目标生效
cmake_minimum_required(VERSION x.x) 要求 cmake 最小版本(必须有)
project(项目名) 指定项目名称(必须有),project(项目名 VERSION 1.2.3) 额外指定版本号。该编号可以通过变量 PROJECT_VERSION 获取
set(CMAKE_CXX_COMPILER "/usr/bin/g++") 设置 compiler
set(CMAKE_CXX_FLAGS "-选项 -选项") 设置 flag,包括 C++ 标准。注意这不是一个 list。如果要在后面添加选项,就用 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -选项1 -选项2")。
set(CMAKE_CXX_STANDARD 11) 设置 C++ 标准
set(CMAKE_CXX_STANDARD_REQUIRED ON)(默认关)如果编译器不支持该标准就报错
CMAKE_C_STANDARD 和 CMAKE_C_STANDARD_REQUIRED 同理,对 C 语言使用。
set(CMAKE_CXX_EXTENSIONS OFF)(默认开)不使用 C++ 标准拓展,例如 -std=gnu11。后者并不完全兼容标准,一些情况会出错。
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address") 或者下面的 list(APPEND ...)
CMAKE_CXX_FLAGS_RELEASE 可以设置 release 模式下的 flag。
set(变量 str1 [str2] ...) 对变量赋值(若有多个值就生成 list)
list(APPEND 变量 str1 [str2] ...) 在变量(list)后面添加元素
list(REMOVE_ITEM 变量 str1 ...) 从 变量 的 list 中移除(如果不存在也不报错)
set(变量 "${变量} str1 str2") 等效于 list(APPEND ...)。
file(GLOB 变量 "文件夹/*.cpp" "fname2.cpp")(GLOB 表示 global,指的是 *,这个名字从 sh 脚本而来)可以列出所有 "folder/*.cpp" 文件,以及 fname2.cpp(如果存在)赋值给 变量。注意文件名包括绝对路径。match 的结果也会存到 CMAKE_MATCH_编号,编号从 1 开始。
file(GLOB_RECURSE 变量 "文件夹/*.cpp") 还会递归搜索所有子文件夹。
get_filename_component(变量 "文件名含路径" NAME或DIRECTORY) 会从 "文件名含路径" 中提取文件名或路径,赋值给 变量。最后加上 REALPATH 选项可以对路径正则化,例如 get_filename_component(MY_PATH "${PROJECT_SOURCE_DIR}/../foo/bar" REALPATH) 会给出整洁的绝对路径。
file(READ 文件名 变量) 读取文件内容到变量。
string(REGEX MATCH "...(...)..." 变量 字符串变量。在 字符串变量 中匹配正则表达式,并把 () 中的匹配结果赋值给 变量。
string(REPLACE "老词" "新词" 变量 "字符串") 做字符串替换。
add_definitions(-D FOO -D BAR) 给编译器添加宏定义(整个 cmakelist),-D 后面有没有空格都可以。
target_compile_definitions(MyLibrary PRIVATE MY_MACRO1 MY_MACRO2=VALUE) 可以给指定的 target 添加宏定义。PRIVATE 是该定义只给该 target 添加,不会继承。
add_compile_options(-Wall -fopenmp) 给编译器添加选项(注意不能用 -D 定义宏),该命令不受 CMAKE_BUILD_TYPE 的影响。
CMAKE_CXX_COMPILER_ID 加不同 option
# Define flags for different compilers
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# GCC and Clang specific flags
add_compile_options(
-Wall # Enable all warnings
# Disable warning for constructor initialization order
-Wno-reorder
# Disable warning for misleading indentation
-Wno-misleading-indentation
-O3 # High-level optimization
-fopenmp # Enable OpenMP
-fmax-errors=1 # Limit the number of errors
-D NDEBUG # Disable debugging macros
)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# MSVC specific flags
add_compile_options(
/W4 # Enable high warning level
/O2 # High-level optimization (equivalent to -O3 in g++)
/openmp # Enable OpenMP
/DNDEBUG # Disable debugging macros
)
endif()
CMAKE_SYSTEM_NAME 判断当前的系统
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
....
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
....
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
....
endif()
MINGW,CYGWIN, MSYS, IOS, 等(文档)
add_executable(目标名 源码1 源码2) 前者是可执行文件名,后者是所有需要 link 的 C/C++ 文件名(可以混合),不需要头文件。cmake 会自动分析代码得到哪个 cpp 调用哪个头文件,如果头文件改变了,只有调用它的 cpp 会重新编译。注意 目标名 可以是任意名字不一定是可执行文件名。
set_target_properties(exe_targ_name PROPERTIES OUTPUT_NAME 可执行文件的名字)
add_executable 指定的源码不需要包含头文件,但如果头文件需要由其他 rule 来生成,那就需要包含。所以最保险还是把所有头文件都包含。
configure_file(file_in file_out) 将文件中 @变量@ 替换为变量 变量 的字符串。
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。往往用于编译某个 library。当前的变量会在子 list 中可见,但是子 list 中新增或者改变的变量默认不会影响父 list,除非使用 set(VAR VALUE PARENT_SCOPE)。
target_link_libraries(exe_name lib1 [lib2] ...) link 阶段链接 library,相当于 -l lib1 -l lib2
option(opt_name description default) 定义一个 option 开关(会在 cmake 的 GUI 中显示开关)以及默认值。opt_name 可以在 CMakeLists.txt 中的 if 语句中使用例如 if(opt_name) ... endif(opt_name)。default 可以是 ON 或 OFF。
option 的默认值后,需要清空 cmake 的临时文件才可以生效。
set(变量 "默认值" CACHE BOOL或STRING或FILEPATH或PATH或INTEGER "描述")。如果之前 变量 已经被赋值(例如命令行 cmake -D 变量=...),则值不会被覆盖。这种变量叫做 cached variable。
cmake -LH . 的帮助中看到说明。
*.in 中,当 opt_name 为 ON 时,使用 configure_file 命令后 #cmakedefine opt_name 会被替换为 #define opt_name。如果想要给宏定义一个值,用 #cmakedefine USE_FEATURE_B @USE_FEATURE_B@
target_precompile_headers(可执行文件 PRIVATE foo.h bar.h) 可以编译头文件,注意貌似不会自动包括 .h 包括的文件。如果头文件(或者依赖的文件)改了,那么将会自动重新编译头文件。
execute_process(COMMAND 命令 参数1 参数2 ...) 可以执行 shell 命令,其中命令和参数中都可以用 ${变量}。其他功能(包括命令返回的内容,文件输入输出),详见文档。注意这个命令是在运行 cmake 时执行而不是运行 make 时。后者可以用 add_custom_target,再用 add_dependencies(目标, target) 把 target 作为目标的依赖。
include(文件或者模块),详见文档。模块可以是 *.cmake 的文件,也可以是 cmake 的内建模块如 CheckCXXCompilerFlag。
include(文件) 相当于把文件内容直接粘贴到该位置。但注意 文件 中的 CMAKE_CURRENT_LIST_DIR 可以显示 文件 的路径。
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(变量 IN 列表) ... endforeach() 或者 foreach(变量 IN 变量1 变量2 ...) ... endforeach() 其中 IN 在 cmake 2.4 以后可以省略。文档。
find_program(变量 程序名 [路径1 路径2 ...]) 可以在指定路径或者 $PATH 中寻找某个可执行文件,并把绝对路径写入 变量。如果没有找到,会赋空值。
add_custom_command(OUTPUT output_files COMMAND 命令... [ARGS 参数...] [WORKING_DIRECTORY dir] [DEPENDS 依赖文件] [COMMENT 注释]) 相当于 Makefile 中的一个 rule,指定依赖关系,以及使用的命令。其中 命令 可以包含完整的命令而不需要额外用 参数。当 OUTPUT 的文件缺失时或者 依赖文件 更新时,就会运行命令。可以把 命令 和所有的参数写成一整个字符串,但是 cmake 可能会自动把空格 escape 比较恶心。可以试试用 string(REPLACE " " ";" 命令变量 ${命令变量}) 然后 COMMAND ${命令变量} 把命令拆成一个 list。注释 会在该命令被运行时输出到 stdout。
add_custom_command 的另一种用法是
add_custom_command(
TARGET <target> # Target to attach to (e.g., executable)
PRE_BUILD | PRE_LINK | POST_BUILD # When to run the command
COMMAND <command> [args...] # Command to execute
WORKING_DIRECTORY <dir> # (Optional) Run command in this dir
COMMENT "<message>" # (Optional) Print a message
)
可以在编译 target 的某个阶段执行一些命令,最常见的是 POST_BUILD 用于在编译结束后复制一些文件。
命令 可以使用 ${CMAKE_COMMAND} -E 一些命令。其中 ${CMAKE_COMMAND} 就是当前使用的 cmake 命令,-E 代表 cmake 的命令执行模式,一些命令 如 echo 字符串(注意这不是 Linux 的而是 cmake 的 echo),copy 文件 目标文件,copy_if_different 文件 要被更新的文件,make_directory 目录,remove_directory 目录,remove 文件 等。
cmake -E copy_if_different <source> <destination> 就可以更新文件(而不用在乎是在 Linux 还是在 PowerShell)。
add_custom_target(目标名 [COMMAND 命令...] [ARGS arguments...] [DEPENDS depends...] [BYPRODUCTS byproducts...] [WORKING_DIRECTORY dir] [SOURCES sources...] [COMMENT 注释]) 会在生成的 Makefile 中添加一个 target。
add_dependencies(目标名 依赖1 [依赖2 ...]) 可以给 target(例如可执行文件)添加依赖。
check_symbol_exists("符号名字" "路径/头文件1;头文件2" 变量) 可以检查 符号名字 是否有定义,包括函数名,变量名,以及宏。
check_symbol_exists 的实现使用了 try_compile() 和 try_run() 函数,试图编译和运行一个测试程序,从运行结果来判断是否存在符号。
target_include_directories(my_target
# Only my_target can see these directories.
PRIVATE
src1/include
src2/include
# my_target and its dependents can see these directories.
PUBLIC
src3/include
src4/include
# Only dependents of my_target can see these directories.
INTERFACE
src5/include
src6/include
)
find_library() 的默认搜索路径如 /usr/lib,/usr/local/lib,/usr/[local/]share/cmake/Modules/,/usr/lib/x86_64-linux-gnu/cmake/ 以及环境变量 LD_LIBRARY_PATH 中的路径。
find_library(变量 NAMES 库名1 库名2 PATHS /usr/lib /usr/local/lib HINTS $ENV{LIBRARY_PATH} $ENV{LD_LIBRARY_PATH}) 可以寻找 lib库名.so或a[.版本号],然后把路径写入 变量(不做其他事情)。注意不会搜索 HINTS 的子文件夹。若要指定版本可以用例如 gfortran.3,也可以指定 gfortran.so或a。注意指定目录的子目录不会被搜索。
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a或.so或.lib") 可以让 find_library() 只寻找某种类型的 lib。也可以用 ".a;.so" 来指定优先级。
CMAKE_LIBRARY_PATH 变量可以指定 find_library 的更多默认搜索路径,且会优先搜索。
BUILD_SHARED_LIBS 变量用于让 add_library() 默认编译成动态库。即 add_library(example SHARED ${sources}) 而不是 add_library(example STATIC ${sources})。手动指定 STATIC/SHARED 时,还是会按照手动的设置。
自定义函数如
# 计算一个数的平方
function(compute_square number result_var)
math(EXPR result "${number} * ${number}")
set(${result_var} ${result} PARENT_SCOPE)
endfunction()
# 函数调用
set(my_number 5)
compute_square(${my_number} my_result)
message(STATUS "The square of ${my_number} is ${my_result}")
find_package 是一个更高级的命令,找到某个 cmake 包的设置文件,这个文件负责把一切设置好,包括 include,如何 link 等,以及 import 一些变量。而不是像 find_library 那样简单地找到一个包所在的路径。
find_package(包名 [版本] [REQUIRED] [COMPONENTS 组件1 组件2...])
REQUIRED:如果找不到就报错终止。
find_package 会依次寻找 /usr/lib/cmake/,/usr/local/lib/cmake/,CMAKE_PREFIX_PATH.
包名 会先在 CMAKE_MODULE_PATH 后在默认路径里面搜索名为 Find包名.cmake(Module Mode,该文件通常由 cmake 提供或用户自己写)或者 包名Config.cmake(Config Mode,该文件通常由 package 作者提供,更高级和智能)的文件。该文件通常会设置一些变量,可以在 find_package 结束后访问。
*Config.cmake 是可以由包作者在 CMakeLists.txt 中使用 CMakePackageConfigHelpers 自动生成的,无需手写!例如
# 导出到 cmake 模块
include(CMakePackageConfigHelpers)
configure_package_config_file(MyPkgConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/MyPkgConfig.cmake
INSTALL_DESTINATION lib/cmake/MyPkg
NO_CHECK_REQUIRED_COMPONENTS_MACRO)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/MyPkgConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/MyPkgConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/MyPkgConfigVersion.cmake
DESTINATION lib/cmake/MyPkg
COMPONENT dev)
install(EXPORT MyPkg
FILE MyPkgTargets.cmake
NAMESPACE MyPkg::
DESTINATION lib/cmake/MyPkg
COMPONENT dev)
find_package(Boost 1.71 REQUIRED COMPONENTS filesystem system)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(myapp main.cpp)
target_link_libraries(myapp ${Boost_LIBRARIES})
endif()
find_package(Boost 1.71 REQUIRED COMPONENTS filesystem)
if(Boost_FOUND)
add_executable(my_app main.cpp)
target_link_libraries(my_app Boost::filesystem)
endif()
Boost::filesystem 就是 find_package 导入的一个 imported target,:: 只是名字的一部分并没有特别的 namespace 机制。Boost_FOUND 是导入的变量,显示 Boost 是否被找到.
包名Config.cmake(Config Mode)
如果要写 Find包名.cmake,其实只需要使用 set() 设置若干路径变量即可。一般只有库的作者没有提供 config mode 的 cmake 时才需要用户写这个文件。用 apt 安装的包如果提供了该 cmake 一般也会被搜到。
要写 包名Config.cmake,需要给 add_library 定义要导出的 target,以及用 set_target_properties 指定库文件和头文件的路径,这样用户导入的时候就不需要再设置一次了。
# MyLibraryConfig.cmake
# Define the paths to the library and include directories
set(MyLibrary_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/lib/file.a")
set(MyLibrary_INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}/include")
# Create an imported target for MyLibrary
add_library(MyLibrary STATIC IMPORTED)
# Set the properties for the imported target
set_target_properties(MyLibrary PROPERTIES
# set lib files location so that user can import the target
IMPORTED_LOCATION "${MyLibrary_LIBRARIES}"
# set header files location so that user can import the target
INTERFACE_INCLUDE_DIRECTORIES "${MyLibrary_INCLUDE_DIRS}"
)
# Optionally, set the MyLibrary_FOUND variable
# to indicate the library was found
set(MyLibrary_FOUND TRUE)
# Minimum CMake version
cmake_minimum_required(VERSION 3.10)
# Project name
project(MyLibrary)
# Set the version (optional)
set(MYLIBRARY_VERSION_MAJOR 1)
set(MYLIBRARY_VERSION_MINOR 0)
# Define the library target
add_library(MyLibrary SHARED IMPORTED)
# Specify the directories for header files
target_include_directories(MyLibrary
INTERFACE
# Replace with actual path
${CMAKE_CURRENT_SOURCE_DIR}/include
)
# Link the library files (use separate statements
# for different OSes if needed)
set_target_properties(MyLibrary PROPERTIES
# Linux
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/lib/mylibrary.so"
# Windows
IMPORTED_IMPLIB "${CMAKE_CURRENT_SOURCE_DIR}/lib/mylibrary.dll"
)
# Define macros required by the library
target_compile_definitions(MyLibrary
INTERFACE
MYLIBRARY_DEFINE_1
MYLIBRARY_DEFINE_2=VALUE # Example with a value
)
# Export the library target for use in other projects
export(TARGETS MyLibrary FILE MyLibraryConfig.cmake)
install()
PROJECT_NAME 是 project(项目名) 设置的 项目名
CMAKE_SOURCE_DIR:顶层的 CMakeLists.txt 目录,即 cmake 目录 指定的那个。该目录的结构也叫 cmake source tree。
PROJECT_SOURCE_DIR 是最近一次使用 project(...) 命令定义项目的 CMakeLists.txt 文件的绝对路径。
CMAKE_BINARY_DIR 是 Cmake 的输出路径,临时文件,Makefile 等都在这个路径。这就是运行 cmake 目录 命令时的当前路径。也可以用 -B 路径 指定。该目录的结构也叫 cmake build tree。PROJECT_BINARY_DIR 同理可得。
cmake . 的时候,CMAKE_SOURCE_DIR 和 CMAKE_BINARY_DIR 相同,此时叫做 in-source build,不推荐这么做。
CMAKE_CURRENT_LIST_DIR 当前在处理的 CMakeLists.txt 的路径。当 include(子文件) 时则变为 子文件 所在的目录。
CMAKE_CURRENT_SOURCE_DIR 当 include(子文件) 时不改变。
add_subdirectory(子目录) 时,CMAKE_CURRENT_LIST_DIR 和 CMAKE_CURRENT_SOURCE_DIR 都会更新到 子目录。
CMAKE_BUILD_TYPE 可以被用户设置为 Release,Debug 等。例如 cmake -DCMAKE_BUILD_TYPE=Debug 用 debug 模式编译。Debug 模式下,编译器优化会被自动关闭,-g 选项会自动加上,NDEBUG 不会。在两种模式下,CMAKE_CXX_FLAGS_DEBUG 和 CMAKE_CXX_FLAGS_RELEASE 中的选项会分别传给编译器。任何模式下 CMAKE_CXX_FLAGS 的选项都会传给编译器。
CMAKE_MODULE_PATH 提供 include() 和 find_package() 命令的优先搜索路径(多个路劲用 ; 隔开)。例如 include(MyFuncs) 就会在这些路径中搜索 MyFuncs.cmake
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 变量) OR (file1 IS_NEWER_THAN file2))
……
elseif(变量)
当变量有定义且不是 false constant
if(ENV{变量})
这里永远不会执行
elseif (DEFINED <name>|CACHE{<name>}|ENV{<name>})
若定义了变量
elseif (变量1 STREQUAL 变量2)
比较字符串
elseif (IS_DIRECTORY 某路径)
判断某路径是否存在
else()
……
endif()
一些细节:
if (NOT MY_VAR),if ("${MY_VAR}" STREQUAL "") 也可以但是啰嗦。
if (MY_VAR STREQUAL "字符串") 和 if ("${MY_VAR}" STREQUAL "字符串") 有一些区别:
MY_VAR 未定义,if(MY_VAR STREQUAL "") 和 if("${MY_VAR}" STREQUAL "") 有什么区别?
MY_VAR 为 a;b;c,二者又有什么区别?是否还有其他情况有区别?
*.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
 
 
 
 
 
 
 
 
 
 
 
友情链接: 超理论坛 | ©小时科技 保留一切权利