You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()命令:

  1. 先创建一个解析脚本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"
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 13:25:16