news 2026/4/15 18:07:26

Shell语言的基础知识介绍 - Cmake

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Shell语言的基础知识介绍 - Cmake

CMake 是一种跨平台的构建系统生成工具,它使用一种特定的领域语言(DSL)来描述构建过程。CMake 语言主要用于编写 CMakeLists.txt 文件和 .cmake 脚本文件。下面我将按照您提出的方面详细介绍 CMake 语言的基础知识。

1. 基础数据类型

CMake 语言中的基础数据类型包括字符串(String)、数字(Number)和布尔值(Boolean)。

  • 字符串:在 CMake 中,字符串可以用双引号括起来,但也可以不用引号。如果字符串中包含空格或特殊字符,则需要使用双引号。字符串可以通过${}进行变量替换。
    例如:
set(MY_STRING "Hello World") message(${MY_STRING})
  • 数字:数字在 CMake 中通常以字符串的形式表示,但在某些上下文中(如数学运算)会被解释为数字。
    例如:
set(MY_NUMBER 42)
  • 布尔值:CMake 中的布尔值有ONOFFYESNOTRUEFALSE等。在条件判断中,这些值会被相应地解释为真或假。
    例如:
set(MY_BOOL ON) if(MY_BOOL) message("It's true!") endif()

2. 复杂数据结构类型

CMake 本身不支持像数组或字典这样的复杂数据结构,但可以通过列表(List)来模拟数组,以及通过将变量名组合成字符串来模拟字典。

  • 列表:列表是由分号分隔的字符串组成的,可以用于存储多个值。CMake 提供了一些命令来操作列表,如list
    例如:
set(MY_LIST "a;b;c") # 创建一个列表 list(APPEND MY_LIST "d") # 向列表追加元素 注意,列表在内部存储为字符串,其中元素用分号分隔。因此,如果一个元素本身包含分号,则需要转义。
  • 字典:CMake 没有内置的字典类型,但可以通过约定来模拟。例如,使用前缀相同的变量名来模拟键值对,或者使用两个列表来分别存储键和值。

3. 关键字和保留字

CMake 语言中有一些关键字和保留字,用于定义命令和控制流。例如:

  • if,else,elseif,endif

  • foreach,endforeach,while,endwhile

  • function,endfunction,macro,endmacro

  • set,unset,option,find_package,add_executable,target_link_libraries等命令也是保留的。

这些关键字和保留字不能用作变量名或函数名。

4. 程序控制结构类型

CMake 提供了常见的控制结构,包括条件判断和循环。

  • 条件判断:使用ifelseifelseendif
    例如:

    复制 下载 if(CMAKE_SYSTEM_NAME STREQUAL "Linux") message("Building on Linux") elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") message("Building on Windows") else() message("Building on unknown system") endif() 条件判断中可以使用各种逻辑操作符和比较操作符。
- **循环**:CMake 支持 `foreach` 循环和 `while` 循环。 `foreach` 循环示例: ```cmake set(MY_LIST "a;b;c") foreach(item IN LISTS MY_LIST) message(${item}) endforeach()
`while` 循环示例:
set(i 0) while(i LESS 5) message("i = ${i}") math(EXPR i "${i} + 1") endwhile()

5. 函数

在 CMake 中,可以定义函数(function)和宏(macro)。函数和宏的主要区别在于作用域:函数有自己独立的作用域,而宏则类似于文本替换,没有独立作用域。

  • 函数定义
function(my_function arg1 arg2) message("arg1 = ${arg1}, arg2 = ${arg2}") set(${ARGV2} "new_value" PARENT_SCOPE) # 修改父作用域的变量 endfunction()
调用函数: ```cmake my_function("Hello" "World") 函数参数可以通过 `ARGV`、`ARGV0`、`ARGV1` 等访问,也可以通过命名的参数访问。 ```
  • 宏定义
复制 下载 macro(my_macro arg1 arg2) message("arg1 = ${arg1}, arg2 = ${arg2}") endmacro() 宏的调用方式与函数相同,但宏内部没有独立的作用域,因此会直接影响调用者的变量。

6. 输入输出

CMake 中的输入输出主要通过命令实现。

  • 输出:使用message命令输出信息,可以指定输出级别(如STATUSWARNINGFATAL_ERROR等)。
    例如:
message(STATUS "This is a status message")
  • 输入:CMake 没有直接的输入命令,但可以通过变量设置来传递输入。例如,在命令行中使用-D选项定义变量,或在 CMake GUI 中设置变量。
    例如,在命令行中:
复制 下载 cmake -DMY_VARIABLE=value .. 然后在 CMakeLists.txt 中可以使用 `${MY_VARIABLE}`。

7. 基础库,第三方库

CMake 提供了丰富的内置命令和模块,可以视为基础库。此外,CMake 还可以通过find_package命令来查找和使用第三方库。

  • 内置命令和模块:CMake 自带了很多模块,如FindOpenGLFindThreads等,可以通过find_packageinclude来使用。
    例如:
复制 下载 find_package(OpenGL REQUIRED) include(CheckCXXCompilerFlag)
  • 第三方库:对于第三方库,如果提供了 CMake 配置文件(如FooConfig.cmakefoo-config.cmake),则可以使用find_package来查找。如果没有,可能需要自己编写查找脚本,或者使用add_subdirectory直接包含库的源代码。

8. 指针,引用等

CMake 语言中没有指针和引用的概念。变量都是字符串或字符串列表,通过变量名直接引用。在函数中,如果需要修改父作用域的变量,可以使用PARENT_SCOPE选项。
例如:

function(set_parent_var) set(my_var "new_value" PARENT_SCOPE) endfunction() set(my_var "old_value") set_parent_var() message(${my_var}) # 输出 new_value

其他方面补充说明

  • 变量作用域:CMake 有全局作用域、目录作用域和函数作用域。变量可以在父作用域中定义,然后在子作用域中修改(使用PARENT_SCOPE)。

  • 缓存变量:CMake 允许将变量存储在缓存中(使用-D选项或set命令的CACHE选项),这样可以在多次运行中持久化。

  • 属性:CMake 有属性的概念,可以设置目标(target)、目录(directory)、源文件(source file)等对象的属性。例如,设置目标的属性:

set_target_properties(my_target PROPERTIES CXX_STANDARD 11)
  • 生成器表达式:CMake 支持生成器表达式(Generator Expressions),这是一种在生成构建系统时进行求值的表达式,常用于设置依赖于配置(如Debug/Release)的属性。例如:
target_compile_definitions(my_target PRIVATE $<$<CONFIG:Debug>:DEBUG_MODE>) 表示在Debug配置下定义DEBUG_MODE宏。
  • 跨平台支持:CMake 的一个主要优势是跨平台,它可以根据不同平台生成相应的构建系统(如 Makefile、Visual Studio 项目等)。

以上是 CMake 语言的基础知识介绍。CMake 语言虽然简单,但通过其丰富的命令和模块,可以管理复杂的构建过程。建议在实践中逐步深入学习。

CMake 语言全面介绍

1. 基础数据类型

CMake 语言本质上是一种字符串处理语言,所有数据都以字符串形式表示,但具有特定的语义分类:

1.1 字符串(String)

# 基础字符串定义 set(MY_STRING "Hello World") set(ANOTHER_STRING WithoutQuotes) # 如果没有特殊字符,引号可选 # 包含特殊字符的字符串 set(PATH_STRING "C:/Program Files/MyApp") set(ESCAPED_STRING "Line1\nLine2\tTabbed") # 支持转义字符 # 多行字符串(CMake 3.0+) set(MULTILINE_STRING [[ First line Second line Third line with "quotes" ]])

1.2 数字(Numeric)

虽然所有值都是字符串,但某些上下文会解释为数字:

set(MY_NUMBER 42) set(FLOATING_NUMBER 3.14159) set(HEX_NUMBER 0xFF) # 十六进制

1.3 布尔值(Boolean)

CMake 支持多种布尔表示形式:

set(TRUE_VALUES ON YES TRUE Y 1) set(FALSE_VALUES OFF NO FALSE N 0 IGNORE NOTFOUND)

1.4 空值/未定义值

set(EMPTY_STRING "") # 空字符串 unset(UNDEFINED_VAR) # 未定义变量

2. 复杂数据结构类型

2.1 列表(Lists)

CMake 使用分号分隔的字符串表示列表:

# 创建列表 set(MY_LIST item1 item2 item3) # 自动用分号分隔 set(EXPLICIT_LIST "item1;item2;item3") set(LIST_WITH_SPACES "item 1;item 2;item 3") # 列表操作 list(APPEND MY_LIST item4) # 添加元素 list(LENGTH MY_LIST LIST_LEN) # 获取长度 list(GET MY_LIST 0 FIRST_ITEM) # 获取元素 list(REMOVE_ITEM MY_LIST item2) # 删除元素 list(FIND MY_LIST item3 INDEX) # 查找元素

2.2 缓存变量(Cache Variables)

具有持久性的特殊变量:

# 定义缓存变量 set(MY_CACHE_VAR "default_value" CACHE STRING "Description") # 类型可以是:STRING, FILEPATH, PATH, BOOL, INTERNAL option(ENABLE_FEATURE "Enable feature" ON) # BOOL类型缓存变量

3. 关键字和保留字

3.1 命令关键字

CMake 有大量内置命令,常用的包括:

  • 项目定义:project,cmake_minimum_required
  • 目标定义:add_executable,add_library,add_custom_target
  • 目录操作:add_subdirectory,include,include_directories
  • 属性设置:set_target_properties,set_property,set_directory_properties
  • 条件控制:if,else,elseif,endif,while,endforeach
  • 函数/宏:function,endfunction,macro,endmacro

3.2 保留的变量名

CMAKE__CMAKE__开头的变量名:

# 内置变量示例 CMAKE_VERSION # CMake版本 CMAKE_SOURCE_DIR # 源代码目录 CMAKE_BINARY_DIR # 构建目录 CMAKE_CURRENT_LIST_DIR # 当前CMakeLists.txt所在目录 # 项目相关变量 PROJECT_NAME # 项目名称 PROJECT_VERSION # 项目版本

3.3 生成器表达式(Generator Expressions)

特殊的表达式语法,在生成构建系统时求值:

# 条件表达式 $<CONFIG:Debug> # Debug配置时为1 $<PLATFORM_ID:Windows> # Windows平台时为1 # 目标相关表达式 $<TARGET_FILE:my_target> # 目标文件路径 $<TARGET_PROPERTY:target,prop> # 目标属性 # 布尔表达式 $<AND:cond1,cond2> # 逻辑与 $<OR:cond1,cond2> # 逻辑或

4. 程序控制结构

4.1 条件语句

# 基础if语句 if(condition) # ... elseif(another_condition) # ... else() # ... endif() # 条件操作符 if(variable) # 变量存在且不为false值 if(NOT condition) # 逻辑非 if(cond1 AND cond2) # 逻辑与 if(cond1 OR cond2) # 逻辑或 # 比较操作符 if(variable STREQUAL "value") # 字符串相等 if(variable VERSION_EQUAL 2) # 版本相等 if(NOT EXISTS path) # 文件/目录是否存在

4.2 循环语句

# foreach循环 foreach(item IN LISTS my_list) message("Processing: ${item}") endforeach() foreach(i RANGE 1 10 2) # 从1到10,步长为2 message("Number: ${i}") endforeach() # while循环 set(counter 0) while(counter LESS 5) message("Counter: ${counter}") math(EXPR counter "${counter} + 1") endwhile()

5. 函数和宏

5.1 函数(Function)

函数有独立的作用域:

function(my_function arg1 arg2) # 参数处理 message("arg1=${arg1}, arg2=${arg2}") set(${ARGV2} "modified" PARENT_SCOPE) # 修改父作用域变量 endfunction() # 调用函数 my_function("value1" "value2")

5.2 宏(Macro)

宏是文本替换,没有独立作用域:

macro(my_macro arg1) set(${arg1}_modified "new_value") endmacro() # 调用宏 my_macro(MY_VAR)

5.3 参数处理

function(process_args) # ARGC - 参数个数 # ARGV - 所有参数的列表 # ARGN - 命名参数之后的所有参数 foreach(arg IN LISTS ARGV) message("Argument: ${arg}") endforeach() endfunction()

6. 输入输出

6.1 消息输出

# 消息级别 message(STATUS "Informational message") # 状态信息 message(WARNING "Warning message") # 警告信息 message(AUTHOR_WARNING "Author warning") # 开发者警告 message(SEND_ERROR "Error but continue") # 错误但继续 message(FATAL_ERROR "Fatal error") # 致命错误,停止处理

6.2 文件操作

# 读写文件 file(WRITE filename.txt "content") file(APPEND filename.txt "more content") file(READ filename.txt CONTENT_VAR) # 文件系统操作 file(GLOB SOURCE_FILES "src/*.cpp") file(MAKE_DIRECTORY ${output_dir}) file(REMOVE ${file_to_delete}) # 配置时文件操作 configure_file(input.txt output.txt @ONLY)

7. 基础库和第三方库

7.1 CMake 内置模块

# 查找包 find_package(Threads REQUIRED) # 查找线程库 find_package(OpenGL REQUIRED) # 查找OpenGL # 使用模块 include(CMakePrintHelpers) # 打印辅助 include(CheckCXXCompilerFlag) # 检查编译器标志 include(FeatureSummary) # 功能摘要 # 测试框架 enable_testing() # 启用测试 add_test(NAME test1 COMMAND mytest) # 添加测试

7.2 查找和使用库

# 查找系统库 find_library(MATH_LIB m) find_path(INCLUDE_DIR someheader.h) # 现代CMake目标方式 add_library(mylib STATIC src.cpp) target_include_directories(mylib PUBLIC include) target_compile_definitions(mylib PRIVATE MY_DEFINE) target_link_libraries(mylib PUBLIC Threads::Threads) # 使用第三方库(包配置文件) find_package(Boost 1.70 REQUIRED COMPONENTS filesystem system) target_link_libraries(myapp PUBLIC Boost::filesystem Boost::system)

7.3 包管理器集成

# 使用FetchContent(CMake 3.11+) include(FetchContent) FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.11.0 ) FetchContent_MakeAvailable(googletest) # 使用ExternalProject include(ExternalProject) ExternalProject_Add( external_lib URL "http://example.com/library.zip" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" )

8. CMake中的"指针"和"引用"

8.1 变量引用

CMake 使用${}进行变量展开:

set(VAR_NAME "value") set(REFERENCE "${VAR_NAME}") # 引用变量值

8.2 目标别名(类似引用)

add_library(mylib_real STATIC src.cpp) add_library(mylib::mylib ALIAS mylib_real) # 创建别名 # 使用别名(类似智能指针) target_link_libraries(myapp PRIVATE mylib::mylib)

8.3 属性作为间接访问

# 设置属性 set_property(TARGET mytarget PROPERTY INCLUDE_DIRECTORIES "/path/include") # 获取属性 get_property(inc_dirs TARGET mytarget PROPERTY INCLUDE_DIRECTORIES)

9. 其他重要特性

9.1 作用域

# 目录作用域 set(LOCAL_VAR "value") # 当前目录作用域 # 函数作用域 function(my_func) set(LOCAL_VAR "new" PARENT_SCOPE) # 修改父作用域 endfunction() # 缓存作用域 set(CACHE_VAR "default" CACHE STRING "Description")

9.2 策略(Policies)

# 设置策略 cmake_policy(SET CMP0077 NEW) # 启用新行为 # 检查版本 if(POLICY CMP0077) cmake_policy(SET CMP0077 NEW) endif()

9.3 交叉编译

# 工具链文件 set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)

9.4 安装规则

# 安装目标 install(TARGETS myapp mylib RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib/static ) # 安装文件 install(FILES headers/myheader.h DESTINATION include) install(DIRECTORY doc/ DESTINATION share/doc)

10. 最佳实践和技巧

10.1 现代CMake实践

# 使用目标为中心的现代方法 add_library(mylib) target_sources(mylib PRIVATE src.cpp) target_include_directories(mylib PUBLIC include) target_compile_features(mylib PUBLIC cxx_std_17) # 正确使用PUBLIC/PRIVATE/INTERFACE # PUBLIC - 接口和实现都需要 # PRIVATE - 仅实现需要 # INTERFACE - 仅接口需要

10.2 调试技巧

# 打印变量 message("Variable value: ${MY_VAR}") # 打印所有变量 get_cmake_property(vars VARIABLES) foreach(var ${vars}) message("${var}=${${var}}") endforeach() # 调试模式 set(CMAKE_VERBOSE_MAKEFILE ON)

10.3 模块化设计

# 创建可重用模块 # mymodule.cmake function(add_mylibrary target) add_library(${target} STATIC ${ARGN}) target_compile_definitions(${target} PRIVATE MYLIB_EXPORT) endfunction() # 使用模块 include(mymodule) add_mylibrary(mylib src1.cpp src2.cpp)

总结

CMake 是一门专门用于构建系统的领域特定语言(DSL),其核心特点包括:

  1. 字符串基础:所有数据都以字符串形式处理
  2. 声明式语法:主要描述构建依赖和规则
  3. 跨平台设计:支持多种编译器和操作系统
  4. 模块化:支持包含和重用CMake代码
  5. 生成器表达式:提供条件化和目标相关的配置

现代CMake强调:

  • 使用目标(target)为中心的配置
  • 最小化全局变量使用
  • 正确传播依赖关系(PUBLIC/PRIVATE/INTERFACE)
  • 支持包管理和查找

CMake的学习曲线相对陡峭,但掌握后能极大简化跨平台项目的构建管理。建议从简单项目开始,逐步学习现代CMake的最佳实践。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/13 13:15:49

JAVA赋能同城上门做饭:一键预约美味到家

以下是一篇围绕标题《JAVA赋能同城上门做饭&#xff1a;一键预约美味到家》展开的文章内容&#xff0c;突出技术实现与用户体验的结合&#xff1a;JAVA赋能同城上门做饭&#xff1a;一键预约美味到家在快节奏的都市生活中&#xff0c;外卖虽便捷&#xff0c;但高油高盐、卫生隐…

作者头像 李华
网站建设 2026/4/14 13:18:36

灾害损失评估:航拍图像房屋损毁程度分级

灾害损失评估&#xff1a;航拍图像房屋损毁程度分级 引言&#xff1a;灾害响应中的智能视觉需求 在自然灾害&#xff08;如地震、洪水、台风&#xff09;发生后&#xff0c;快速准确地评估受灾区域的建筑损毁情况是应急响应和灾后重建的关键环节。传统的人工现场勘查方式效率低…

作者头像 李华
网站建设 2026/4/13 19:53:25

计算机毕业设计springboot茅台酒销售管理系统设计与实现 基于Spring Boot的茅台酒业进销存一体化平台开发 Spring Boot驱动的茅台白酒电商运营后台设计

计算机毕业设计springboot茅台酒销售管理系统设计与实现7j0mjv6t &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。 互联网把传统酒水销售从柜台搬到了指尖&#xff0c;茅台作为高…

作者头像 李华
网站建设 2026/4/14 8:19:53

2026年就业逆袭指南:这3大黄金行业正在疯狂招人,你的机会

收藏&#xff01;2026网络安全风口&#xff1a;小白到程序员的入行指南&#xff0c;高薪就业全攻略 文章分析了2026年就业市场形势&#xff0c;指出传统岗位竞争激烈&#xff0c;而人工智能、新媒体运营和数字经济等新兴行业人才缺口巨大。文章强调选对赛道的重要性&#xff0…

作者头像 李华
网站建设 2026/4/15 10:30:58

基于python和flask的婚庆服务平台的功能设计_5qtr5245

目录功能模块设计技术实现要点特色功能关于博主开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;功能模块设计 用户管理模块 提供用户注册、登录、个人信息管理功能。用户分为新人&#xff0…

作者头像 李华
网站建设 2026/4/12 1:21:17

基于python和flask的野生动物园管理系统设计与实现_xb41711s

目录野生动物园管理系统设计与实现摘要关于博主开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;野生动物园管理系统设计与实现摘要 该系统基于Python和Flask框架开发&#xff0c;旨在实现野…

作者头像 李华