2 CMake 语法与命令

本文详细介绍CMake的基础语法、数据类型、变量定义、控制结构及常用命令,如project、add_executable、find_path等,帮助读者快速掌握CMake构建系统的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址:https://blog.youkuaiyun.com/fan_hai_ping/article/details/42524205

 

基本语法

注释的语法

# 字符开始到此行结束。

 

CMake命令

命令可以是一个内置命令(例如:project,add_executable等),也可以是一个用户定义的宏(macro)或者函数(function)

 

数据类型

CMake的基本数据类型是字符串,一组字符串在一起称为列表(list),例如:

# 通过 set 命令构建一个 listVAR

set(VAR a b c)

 

变量

使用 set() 定义变量

使用语法 ${VariableName} 来访问变量

set(VAR a b c)

# 输出 VAR = a;b;c

message("VAR = ${VAR}")

使用语法 $ENV{VariableName} 来访问环境变量的值

 

If语句

if(expression)

    #...

elseif(expression2)

    #...

else()

    #...

endif()

对于 if(string) 来说:

如果 string 为(不区分大小写)1、ON、YES、TRUE、Y、非 0 的数则表示真

如果 string 为(不区分大小写)0、OFF、NO、FALSE、N、IGNORE、空字符串、以 -NOTFOUND 结尾的字符串则表示假

示例:

cmake_minimum_required(VERSION 2.8)

set(YES 0)

# 输出 True

if(YES)

   message(True)

else()

   message(False)

endif()

 

# 输出 False

if(${YES})

   message(True)

else()

   message(False)

endif()

 

表达式中可以包含操作符,操作符包括:

一元操作符,例如:EXISTS、COMMAND、DEFINED 等

二元操作符,例如:EQUAL、LESS、GREATER、STRLESS、STRGREATER 等

NOT(非操作符)

AND(与操作符)、OR(或操作符)

操作符优先级:一元操作符 > 二元操作符 > NOT > AND、OR

常用操作符示例:

if(NOT expression)

if(expr1 AND expr2)

if(expr1 OR expr2)

if(COMMAND command-name)

为真的前提是存在 command-name 命令、宏或函数且能够被调用

if(EXISTS name)

为真的前提是存在 name 的文件或者目录(应该使用绝对路径)

if(file1 IS_NEWER_THAN file2)

为真的前提是 file1 比 file2 新或者 file1、file2 中有一个文件不存在

if(IS_DIRECTORY directory-name)

为真的前提是 directory-name 表示的是一个目录(应该使用绝对路径)

if(variable|string MATCHES regex)

为真的前提是变量值或者字符串匹配 regex 正则表达式

if(variable|string LESS variable|string)

if(variable|string GREATER variable|string)

if(variable|string EQUAL variable|string)

为真的前提是变量值或者字符串为有效的数字且满足小于(大于、等于)的条件

if(variable|string STRLESS variable|string)

if(variable|string STRGREATERvariable|string)

if(variable|string STREQUALvariable|string)

为真的前提是变量值或者字符串以字典序满足小于(大于、等于)的条件

if(DEFINED variable)

为真的前提是 variable 表示的变量被定义了。

 

foreach 循环

set(VAR a b c)

foreach(f ${VAR})

   message(${f})

endforeach()

 

while 循环

set(VAR 5)

while(${VAR} GREATER 0)

   message(${VAR})

   math(EXPR VAR "${VAR} - 1")

endwhile()

 

函数和宏定义

函数使用set变量为局部作用域,函数外无法使用

宏则使用set变量为全局作用域,宏外可以使用

范例:

# 定义一个宏 hello

set(MESSAGE )

macro(hello MESSAGE)

   set(MESSAGE aaa)

endmacro()

message(${MESSAGE })

 

# 定义一个函数 hello

function(hello MESSAGE)

   set(MESSAGE aaa) # 错误,函数不能使用全局作用域

endfunction()

 

函数和宏可以通过命令 return() 返回,但是函数和宏的返回值必须通过参数传递出去。例如:

cmake_minimum_required(VERSION 2.8)

function(get_func RESULT)

    #RESULT 的值为实参的值,因此需要使用 ${RESULT}

    #这里使用 PARENT_SCOPE 是因为函数会构建一个局部作用域

   set(${RESULT} "Hello Function" PARENT_SCOPE)

endfunction()

 

字符串的一些问题

字符串可跨行且支持转移字符,例如:

set(VAR "hello

world")

 

# 输出结果为:

# ${VAR} = hello

# world

message("\${VAR} = ${VAR}")

 

CMake命令

project 命令

命令语法:project(<projectname> [languageName1 languageName2 … ] )

命令简述:用于指定项目的名称

使用范例:project(Main)

 

cmake_minimum_required命令

命令语法:cmake_minimum_required(VERSION major[.minor[.patch[.tweak]]][FATAL_ERROR])

命令简述:用于指定需要的 CMake 的最低版本

使用范例:cmake_minimum_required(VERSION 2.8)

 

aux_source_directory命令

命令语法:aux_source_directory(<dir> <variable>)

命令简述:用于将 dir 目录下的所有源文件的名字保存在变量 variable 中

使用范例:aux_source_directory(. DIR_SRCS)

 

add_executable 命令

命令语法:add_executable(<name> [WIN32] [MACOSX_BUNDLE][EXCLUDE_FROM_ALL] source1 source2 … sourceN)

命令简述:用于指定从一组源文件 source1 source2 … sourceN 编译出一个可执行文件且命名为 name

使用范例:add_executable(Main ${DIR_SRCS})

 

add_library 命令

命令语法:add_library([STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1source2 … sourceN)

命令简述:用于指定从一组源文件 source1 source2 … sourceN 编译出一个库文件且命名为 name

使用范例:add_library(Lib ${DIR_SRCS})

 

add_dependencies 命令

命令语法:add_dependencies(target-name depend-target1 depend-target2 …)

命令简述:用于指定某个目标(可执行文件或者库文件)依赖于其他的目标。这里的目标必须是 add_executable、add_library、add_custom_target 命令创建的目标

 

add_subdirectory 命令

命令语法:add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

命令简述:用于添加一个需要进行构建的子目录(其目录下有CMakeLists.txt)

使用范例:add_subdirectory(Lib)

 

target_link_libraries命令

命令语法:target_link_libraries(<target> [item1 [item2 […]]][[debug|optimized|general] ] …)

命令简述:用于指定 target 需要链接 item1 item2 …。这里 target 必须已经被创建,链接的 item 可以是已经存在的 target(依赖关系会自动添加)

使用范例:target_link_libraries(Main Lib)

 

set 命令

命令语法:set(<variable> <value> [[CACHE <type><docstring> [FORCE]] | PARENT_SCOPE])

命令简述:用于设定变量 variable 的值为 value。如果指定了 CACHE 变量将被放入 Cache(缓存)中。

使用范例:set(ProjectName Main)

 

unset 命令

命令语法:unset(<variable> [CACHE])

命令简述:用于移除变量 variable。如果指定了 CACHE 变量将被从 Cache 中移除。

使用范例:unset(VAR CACHE)

 

message 命令

命令语法:message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] “message todisplay”…)

命令简述:用于输出信息

使用范例:message(“Hello World”)

 

include_directories 命令

命令语法:include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 …)

命令简述:用于设定目录,这些设定的目录将被编译器用来查找 include 文件

使用范例:include_directories(${PROJECT_SOURCE_DIR}/lib)

 

find_path 命令

命令语法:find_path(<VAR> name1 [path1 path2 …])

命令简述:用于查找包含文件 name1 的路径,如果找到则将路径保存在 VAR 中(此路径为一个绝对路径),如果没有找到则结果为 <VAR>-NOTFOUND。默认的情况下,VAR 会被保存在 Cache 中,这时候我们需要清除 VAR 才可以进行下一次查询(使用 unset 命令)。

使用范例:

find_path(LUA_INCLUDE_PATH lua.h${LUA_INCLUDE_FIND_PATH})

if(NOT LUA_INCLUDE_PATH)

   message(SEND_ERROR "Header file lua.h not found")

endif()

 

find_library 命令

命令语法:find_library(<VAR> name1 [path1 path2 …])

命令简述:用于查找库文件 name1 的路径,如果找到则将路径保存在 VAR 中(此路径为一个绝对路径),如果没有找到则结果为 <VAR>-NOTFOUND。一个类似的命令 link_directories 已经不太建议使用了

 

add_definitions 命令

命令语法:add_definitions(-DFOO -DBAR …)

命令简述:用于添加编译器命令行标志(选项),通常的情况下我们使用其来添加预处理器定义

使用范例:add_definitions(-D_UNICODE -DUNICODE)

 

execute_process 命令

命令语法:

execute_process(COMMAND <cmd1>[args1...]]

                  [COMMAND <cmd2>[args2...] [...]]

                  [WORKING_DIRECTORY<directory>]

                  [TIMEOUT <seconds>]

                  [RESULT_VARIABLE<variable>]

                  [OUTPUT_VARIABLE<variable>]

                  [ERROR_VARIABLE<variable>]

                  [INPUT_FILE <file>]

                  [OUTPUT_FILE <file>]

                  [ERROR_FILE <file>]

                  [OUTPUT_QUIET]

                  [ERROR_QUIET]

                 [OUTPUT_STRIP_TRAILING_WHITESPACE]

                 [ERROR_STRIP_TRAILING_WHITESPACE])

命令简述:用于执行一个或者多个外部命令。

使用范例:execute_process(COMMAND ls)

 

file 命令

命令简述:此命令提供了丰富的文件和目录的相关操作(这里仅说一下比较常用的)

使用范例:

# 目录的遍历

# GLOB 用于产生一个文件(目录)路径列表并保存在variable 中

# 文件路径列表中的每个文件的文件名都能匹配globbing expressions(非正则表达式,但是类似)

# 如果指定了 RELATIVE 路径,那么返回的文件路径列表中的路径为相对于 RELATIVE 的路径

# file(GLOB variable [RELATIVE path][globbing expressions]...)

# 获取当前目录下的所有的文件(目录)的路径并保存到 ALL_FILE_PATH 变量中

file(GLOB ALL_FILE_PATH ./*)

 

# 获取当前目录下的 .h 文件的文件名并保存到ALL_H_FILE 变量中

# 这里的变量CMAKE_CURRENT_LIST_DIR 表示正在处理的 CMakeLists.txt 文件的所在的目录的绝对路径(2.8.3 以及以后版本才支持)

file(GLOB ALL_H_FILE RELATIVE${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/*.h)

 

string命令

替换:

string(REPLACE <match_string> <replace_string> <output variable> <input> [<input>...])

正则匹配,结果放入<output variable>中:

string(REGEX MATCH <regular_expression> <output variable> <input> [<input>...])

取子串:

string(SUBSTRING <string> <begin> <length> <output variable>)

 

示例:

string(REPLACE ${PROJECT_SOURCE_DIR}/ "" newf ${f})

 

add_definitions

定义一个宏,示例:

add_definitions(-D _SysEncodeUTF8)

这里定义了宏_SysEncodeUTF8,我们可以在源码文件中使用这个宏(如:#ifdef _SysEncodeUTF8)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值