CMake读取bash格式变量文件失败,如何正确调用其中变量?
解决CMake与Bash脚本共享变量的问题
你之前用configure_file的思路搞反了——这个命令是把CMake变量注入到模板文件,生成最终的配置文件,而不是从Bash格式的文件里读取变量到CMake中。要实现从var=value格式的文件里提取变量给CMake用,可以用以下两种方法:
方法一:CMake原生解析Bash变量文件
直接用CMake的字符串处理能力读取并解析变量文件,不需要额外脚本:
cmake_minimum_required(VERSION 3.16) # 读取变量文件的每一行 file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/config.in" CONFIG_LINES) foreach(LINE IN LISTS CONFIG_LINES) # 跳过空行和以#开头的注释行 if(LINE MATCHES "^\\s*#" OR LINE MATCHES "^\\s*$") continue() endif() # 匹配var=value格式,支持值带空格(用单/双引号包裹的情况) if(LINE MATCHES "^([A-Za-z0-9_]+)=(.*)$") set(VAR_NAME "${CMAKE_MATCH_1}") set(VAR_VALUE "${CMAKE_MATCH_2}") # 移除值两端的引号(如果存在) string(REGEX REPLACE "^\"(.*)\"$" "\\1" VAR_VALUE "${VAR_VALUE}") string(REGEX REPLACE "^'(.*)'$" "\\1" VAR_VALUE "${VAR_VALUE}") # 将提取到的变量设置为CMake变量 set(${VAR_NAME} "${VAR_VALUE}") endif() endforeach() # 验证变量是否被正确读取 message(STATUS "foo is equal to: ${FOO}")
方法二:通过Bash脚本转换为CMake可识别的格式
如果变量文件里有复杂的Bash语法(比如变量引用、条件判断),可以用Bash先解析变量,再输出CMake能识别的set()命令:
- 先创建一个解析脚本
parse_config.sh:
#!/bin/bash # 读取传入的变量文件路径 CONFIG_FILE="$1" while read -r line; do # 跳过注释和空行 [[ "$line" =~ ^\s*# || "$line" =~ ^\s*$ ]] && continue # 提取变量名和值 if [[ "$line" =~ ^([A-Za-z0-9_]+)=(.*)$ ]]; then var_name="${BASH_REMATCH[1]}" var_value="${BASH_REMATCH[2]}" # 转义CMake中的特殊字符(比如双引号) var_value=$(printf '%s' "$var_value" | sed 's/"/\\"/g') # 输出CMake的set命令格式 echo "set(${var_name} \"${var_value}\")" fi done < "$CONFIG_FILE"
- 在CMakeLists.txt中调用脚本并加载变量:
cmake_minimum_required(VERSION 3.16) # 调用Bash脚本生成CMake变量定义文件 execute_process( COMMAND bash "${CMAKE_CURRENT_SOURCE_DIR}/parse_config.sh" "${CMAKE_CURRENT_SOURCE_DIR}/config.in" OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/config_vars.cmake" RESULT_VAR PARSE_RESULT ) # 检查脚本执行是否成功 if(NOT PARSE_RESULT EQUAL 0) message(FATAL_ERROR "Failed to parse config file") endif() # 加载生成的变量文件 include("${CMAKE_CURRENT_BINARY_DIR}/config_vars.cmake") # 验证变量 message(STATUS "foo is equal to: ${FOO}")
两种方法都能让CMake读取到config.in里的FOO=foobar变量,之后你就可以在CMake中使用${FOO},同时config.in也能直接给Bash脚本使用。
内容的提问来源于stack exchange,提问作者Patryk Kowalski
相关产品推荐
相关产品推荐

