如何在 CMake 中以"bar=foo"语法加载变量?



能够在Makefile和shell脚本之间共享相同的文件是很好的,因为它们都可以处理键值对的以下语法:

$> cat config 
  var1=value
  var2=value
  var3=value
  var4=value
  var5=value

所以,只要从shell脚本中的source config,以及从Makefileinclude config就可以了。然而,使用CMake,语法变成了SET(var1 value)。是否有一些简单的方法,我可以饲料CMake与使用上述语法变量的文件?我的意思是简单,因为我不喜欢在它上面运行,例如sed

@Guillaume的答案非常适合从CMakeLists.txt中生成配置文件。

然而,如果你想将配置文件的内容导入到你的CMake环境中,你需要添加如下内容:
file(STRINGS <path to config file> ConfigContents)
foreach(NameAndValue ${ConfigContents})
  # Strip leading spaces
  string(REGEX REPLACE "^[ ]+" "" NameAndValue ${NameAndValue})
  # Find variable name
  string(REGEX MATCH "^[^=]+" Name ${NameAndValue})
  # Find the value
  string(REPLACE "${Name}=" "" Value ${NameAndValue})
  # Set the variable
  set(${Name} "${Value}")
endforeach()

创建配置。在文件中包含你想"提取"的CMakeLists的所有变量:

var1=@VAR1@
var2=@VAR2@
var3=@VAR3@
var4=@VAR4@
var5=@VAR4@

并在CMakeLists.txt中添加configure_file调用:

configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/config.in
    ${CMAKE_CURRENT_BINARY_DIR}/config
    @ONLY
)
这将创建一个配置文件

使用cmake 3.12可以尝试这样做:

file(STRINGS config CONFIG REGEX "^[ ]*[A-Za-z0-9_]+[ ]*=")
list(TRANSFORM CONFIG STRIP)
list(TRANSFORM CONFIG REPLACE "([^=]+)=[ ]*(.*)" "set(\1 "\2")n")
cmake_language(EVAL CODE ${CONFIG})
# just for test
message(STATUS "a="${a}"")
message(STATUS "b="${b}"")

测试:

rion@dizzynb ~/temp $ cmake --trace -P test.cmake 
Running with trace output on.
/home/rion/temp/test.cmake(1):  file(STRINGS config CONFIG REGEX ^[ ]*[A-Za-z0-9_]+[ ]*= )
/home/rion/temp/test.cmake(2):  list(TRANSFORM CONFIG STRIP )
/home/rion/temp/test.cmake(3):  list(TRANSFORM CONFIG REPLACE ([^=]+)=[ ]*(.*) set(\1 "\2")n )
/home/rion/temp/test.cmake(4):  cmake_language(EVAL CODE ${CONFIG} )
/home/rion/temp/test.cmake:4:EVAL(1):  set(a hello world )
/home/rion/temp/test.cmake:4:EVAL(2):  set(b 10 )
/home/rion/temp/test.cmake(6):  message(STATUS a="${a}" )
-- a="hello world"
/home/rion/temp/test.cmake(7):  message(STATUS b="${b}" )
-- b="10"
rion@dizzynb ~/temp $ cat config 
# this is my config
a=hello world
 b = 10 
#c= O_o

但是请记住上面的eval对于某些内容可能是不可靠的

最新更新