一文说清串口字符型LCD通信机制:通俗解释波特率设置
2025/12/29 4:10:29
set()是 CMake 中最基本、最常用的命令之一,用于设置、修改或取消设置变量。理解set()的用法是掌握 CMake 的关键。
set(<variable> <value>... [PARENT_SCOPE])set(<variable> <value>... CACHE <type> <docstring> [FORCE])set(ENV{<variable>} [<value>])# 设置单个值 set(MY_VARIABLE "Hello World") # 设置多个值(列表) set(MY_LIST "item1" "item2" "item3") # 设置空值 set(EMPTY_VARIABLE "") set(UNDEFINED_VARIABLE) # 无值参数PARENT_SCOPE参数function(my_function) set(RESULT "function result" PARENT_SCOPE) set(LOCAL_VAR "local") # 只在函数内有效 endfunction() my_function() message("${RESULT}") # 输出: function result message("${LOCAL_VAR}") # 输出: 空(未定义)set(<variable> <value> CACHE <type> <docstring> [FORCE] )<type>)| 类型 | 说明 | GUI 中显示为 |
|---|---|---|
BOOL | 布尔值(ON/OFF) | 复选框 |
STRING | 字符串 | 单行文本框 |
FILEPATH | 文件路径 | 文件选择框 |
PATH | 目录路径 | 目录选择框 |
INTERNAL | 内部变量 | 通常不显示 |
# 布尔型缓存变量 set(BUILD_TESTS ON CACHE BOOL "是否构建测试") # 字符串型缓存变量 set(INSTALL_PREFIX "/usr/local" CACHE PATH "安装前缀") # 文件路径型缓存变量 set(CONFIG_FILE "${CMAKE_SOURCE_DIR}/config.ini" CACHE FILEPATH "配置文件路径") # 带默认值的选项 set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "构建类型") set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo" "MinSizeRel")FORCE参数# 如果没有设置过,则设置;如果已设置,保持原值 set(MY_OPTION "default" CACHE STRING "我的选项") # 强制覆盖,无论之前是否设置 set(MY_OPTION "new_value" CACHE STRING "我的选项" FORCE)# 设置环境变量 set(ENV{PATH} "/usr/local/bin:$ENV{PATH}") # 获取环境变量 message("PATH: $ENV{PATH}") # 清空环境变量 set(ENV{DEBUG_FLAGS}) # 设置为空# 父目录 CMakeLists.txt set(MY_VAR "parent_value") add_subdirectory(subdir) # subdir/CMakeLists.txt message("子目录中: ${MY_VAR}") # 输出: parent_value set(MY_VAR "child_value") # 覆盖父目录的值 message("修改后: ${MY_VAR}") # 输出: child_valuePARENT_SCOPE向外传递function(test_function) set(LOCAL_VAR "inside_function") set(OUTPUT_VAR "result" PARENT_SCOPE) endfunction() test_function() message("${LOCAL_VAR}") # 空(未定义) message("${OUTPUT_VAR}") # resultCMakeCache.txt中# 创建列表 set(MY_LIST a b c d e) # 访问元素 list(GET MY_LIST 0 FIRST_ITEM) # a list(GET MY_LIST -1 LAST_ITEM) # e(负索引从末尾开始) # 列表长度 list(LENGTH MY_LIST LIST_LENGTH) # 5set(MY_LIST "apple" "banana") # 追加元素 list(APPEND MY_LIST "cherry") # apple;banana;cherry # 插入元素 list(INSERT MY_LIST 1 "orange") # apple;orange;banana;cherry # 移除元素 list(REMOVE_ITEM MY_LIST "banana") # apple;orange;cherry list(REMOVE_AT MY_LIST 0) # orange;cherry # 排序 list(SORT MY_LIST) # cherry;orangeset(NUMBERS "1;5;3;8;2") # 查找元素 list(FIND NUMBERS "3" INDEX) # INDEX = 2 # 过滤 list(FILTER NUMBERS INCLUDE REGEX "^[0-9]$") # 1;5;3;8;2 list(FILTER NUMBERS EXCLUDE REGEX "[0-9]") # 空# 简单字符串 set(MESSAGE "Hello World") # 多行字符串 set(MULTILINE "第一行 第二行 第三行") # 包含特殊字符 set(PATH_STR "C:\\Program Files\\MyApp") set(QUOTED_STR "\"包含引号的字符串\"")set(STR "Hello CMake World") # 子字符串 string(SUBSTRING "${STR}" 6 5 RESULT) # CMake # 查找和替换 string(FIND "${STR}" "CMake" POS) # POS = 6 string(REPLACE "CMake" "Make" NEW_STR "${STR}") # Hello Make World # 大小写转换 string(TOUPPER "${STR}" UPPER_STR) # HELLO CMAKE WORLD string(TOLOWER "${STR}" LOWER_STR) # hello cmake world # 去空格 set(STR_WITH_SPACES " hello ") string(STRIP "${STR_WITH_SPACES}" STRIPPED) # hello # 正则表达式匹配 string(REGEX MATCH "C[a-z]+" MATCHED "${STR}") # CMake# 根据条件设置不同的值 if(WIN32) set(LIBRARY_EXTENSION ".dll") set(EXECUTABLE_EXTENSION ".exe") elseif(APPLE) set(LIBRARY_EXTENSION ".dylib") else() set(LIBRARY_EXTENSION ".so") endif()# 如果变量未定义,则设置默认值 if(NOT DEFINED INSTALL_PREFIX) set(INSTALL_PREFIX "/usr/local") endif() # 简写形式(CMake 3.13+) set(INSTALL_PREFIX "$ENV{HOME}/.local" CACHE PATH "安装前缀")# 允许用户添加选项而不覆盖 set(MY_OPTIONS "" CACHE STRING "附加选项") # 在脚本中添加 set(MY_OPTIONS "${MY_OPTIONS} -Wall -Wextra") # 用户可以在配置时添加更多选项 # cmake .. -DMY_OPTIONS="-O2 -march=native"# 根据构建类型设置不同的标志 set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -DDEBUG") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG") set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")# 使用生成器表达式进行条件设置 target_compile_definitions(myapp PRIVATE $<$<CONFIG:Debug>:DEBUG_MODE=1> $<$<CXX_COMPILER_ID:MSVC>:_CRT_SECURE_NO_WARNINGS> ) # 设置不同的安装路径 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/Debug/bin") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/Release/bin")# option() 实际上是 set() 的包装 option(ENABLE_FEATURE_X "启用 X 特性" ON) # 等价于: set(ENABLE_FEATURE_X ON CACHE BOOL "启用 X 特性")# 选项之间的依赖关系 set(USE_OPENGL OFF CACHE BOOL "使用 OpenGL") set(OPENGL_VERSION "4.6" CACHE STRING "OpenGL 版本") # 只有当 USE_OPENGL 为 ON 时,OPENGL_VERSION 才有效 if(NOT USE_OPENGL) unset(OPENGL_VERSION CACHE) # 从缓存中移除 endif()set(NUM_THREADS "4" CACHE STRING "线程数量") # 验证输入 if(NOT NUM_THREADS MATCHES "^[0-9]+$") message(FATAL_ERROR "NUM_THREADS 必须是正整数") endif() if(NUM_THREADS LESS 1 OR NUM_THREADS GREATER 64) message(FATAL_ERROR "NUM_THREADS 必须在 1-64 范围内") endif()set(VAR1 "Hello") set(VAR2 "World") set(MESSAGE "${VAR1} ${VAR2}!") # Hello World! # 嵌套引用 set(PREFIX "MY") set(${PREFIX}_VALUE 42) # 创建变量 MY_VALUE message("${${PREFIX}_VALUE}") # 输出 42# 美元符号转义 set(DOLLAR "Cost: \${100}") # Cost: ${100} # 分号转义(列表分隔符) set(PATH_LIST "C:\\Program Files\\;D:\\Tools\\") # 两个元素的列表 # 引号处理 set(QUOTED "\"quoted string\"") # "quoted string"# 不好:多次设置 set(FLAGS "-Wall") set(FLAGS "${FLAGS} -Wextra") set(FLAGS "${FLAGS} -Werror") # 更好:一次性设置 set(FLAGS "-Wall -Wextra -Werror")# 在函数中使用局部变量,避免污染全局空间 function(process_files) set(LOCAL_FILES ${ARGV}) # 使用局部变量 # ... 处理文件 endfunction()# 简单打印 message("MY_VAR = ${MY_VAR}") # 打印类型和值 if(DEFINED MY_VAR) message(STATUS "MY_VAR 已定义: ${MY_VAR}") else() message(STATUS "MY_VAR 未定义") endif() # 打印所有以 "CMAKE_" 开头的变量 get_cmake_property(vars VARIABLES) foreach(var ${vars}) if(var MATCHES "^CMAKE_") message("${var} = ${${var}}") endif() endforeach()# 跟踪变量的变化 variable_watch(MY_VARIABLE [command]) # 示例:当 MY_VARIABLE 变化时打印信息 variable_watch(MY_VARIABLE "message(\"MY_VARIABLE 被修改: \${MY_VARIABLE}\")")# 项目配置 set(PROJECT_NAME "MyApplication") set(PROJECT_VERSION_MAJOR 1) set(PROJECT_VERSION_MINOR 2) set(PROJECT_VERSION_PATCH 3) set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") # 用户配置选项 set(BUILD_SHARED_LIBS ON CACHE BOOL "构建共享库") set(ENABLE_TESTS OFF CACHE BOOL "启用测试") set(INSTALL_PREFIX "/usr/local" CACHE PATH "安装路径") # 根据选项设置变量 if(BUILD_SHARED_LIBS) set(LIBRARY_TYPE SHARED) set(LIB_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX}) set(LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}) else() set(LIBRARY_TYPE STATIC) set(LIB_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX}) set(LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX}) endif()# 平台检测和设置 if(WIN32) set(IS_WINDOWS TRUE) set(PLATFORM_NAME "Windows") set(EXECUTABLE_SUFFIX ".exe") set(LIBRARY_SUFFIX ".dll") # Windows 特定编译器标志 set(PLATFORM_FLAGS "/W4 /EHsc") elseif(APPLE) set(IS_MACOS TRUE) set(PLATFORM_NAME "macOS") set(EXECUTABLE_SUFFIX "") set(LIBRARY_SUFFIX ".dylib") # macOS 特定设置 set(PLATFORM_FLAGS "-Wall -Wextra") elseif(UNIX) set(IS_LINUX TRUE) set(PLATFORM_NAME "Linux") set(EXECUTABLE_SUFFIX "") set(LIBRARY_SUFFIX ".so") # Linux 特定设置 set(PLATFORM_FLAGS "-Wall -Wextra -pthread") endif() message(STATUS "平台: ${PLATFORM_NAME}") message(STATUS "可执行文件后缀: ${EXECUTABLE_SUFFIX}")# 定义选项组 set(CMAKE_CXX_FLAGS "" CACHE STRING "C++ 编译器标志") set(CMAKE_C_FLAGS "" CACHE STRING "C 编译器标志") set(CMAKE_EXE_LINKER_FLAGS "" CACHE STRING "可执行文件链接器标志") # 设置属性以改善 GUI 显示 set_property(CACHE CMAKE_CXX_FLAGS PROPERTY ADVANCED TRUE) set_property(CACHE CMAKE_C_FLAGS PROPERTY ADVANCED TRUE) # 依赖关系管理 set(USE_OPENMP OFF CACHE BOOL "使用 OpenMP 并行") set(OPENMP_FLAGS "" CACHE STRING "OpenMP 标志") if(USE_OPENMP) find_package(OpenMP REQUIRED) if(OpenMP_CXX_FOUND) set(OPENMP_FLAGS ${OpenMP_CXX_FLAGS}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPENMP_FLAGS}") endif() endif() # 验证和规范化 if(CMAKE_CXX_FLAGS) # 移除多余的空格 string(STRIP "${CMAKE_CXX_FLAGS}" CMAKE_CXX_FLAGS) # 更新缓存 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "C++ 编译器标志" FORCE) endif()# 错误:期望在父作用域中看到变量 function(setup) set(OUTPUT_DIR "build") # 只在函数内有效 endfunction() setup() message("${OUTPUT_DIR}") # 空! # 正确:使用 PARENT_SCOPE function(setup_correct) set(OUTPUT_DIR "build" PARENT_SCOPE) endfunction() setup_correct() message("${OUTPUT_DIR}") # build# 错误:普通变量被缓存变量覆盖 set(MY_VAR "initial") # 普通变量 # 用户运行:cmake .. -DMY_VAR="user_value" message("${MY_VAR}") # 输出 user_value(可能不是期望的) # 正确:明确区分 set(MY_VAR_DEFAULT "initial") set(MY_VAR "${MY_VAR_DEFAULT}" CACHE STRING "用户可配置的变量")# 错误:误解分号分隔 set(LIST_VAR "a;b;c") message("${LIST_VAR}") # 输出: a;b;c # 正确:理解 CMake 列表 foreach(item IN LISTS LIST_VAR) message("项目: ${item}") # 输出: a, b, c 各一行 endforeach()set()是 CMake 变量系统的核心,掌握其各种用法对于编写高效、可维护的 CMake 脚本至关重要。