Как загрузить переменные в синтаксис bar = foo в CMake?

Приятно иметь возможность использовать один и тот же файл между Makefile и сценариями оболочки, потому что они оба могут справиться со следующим синтаксисом для пар ключ-значение:

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

Итак, достаточно будет source config из сценария оболочки, а также include config из Makefile. Однако с CMake синтаксис становится SET(var1 value). Есть ли простой способ накормить CMake файлом с переменными, используя синтаксис выше? Я имею в виду легкость в том смысле, что я не люблю бегать, например. sed над ним.


person Anne van Rossum    schedule 18.06.2013    source источник


Ответы (3)


Ответ @ 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()
person Fraser    schedule 18.06.2013
comment
Мне нравится такой подход. Это не совсем просто, но для этого не нужны зависимости, такие как sed, которые я использовал до сих пор. Я просто не думал об использовании regexp в самом cmake! - person Anne van Rossum; 19.06.2013
comment
Что ж ... хорошо иметь оба ответа в одном месте. Имеет симметрию :) - person Fraser; 24.06.2013

Создайте файл config.in со всеми переменными, которые вы хотите «извлечь» из ваших CMakeLists:

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

и добавьте вызов configure_file в свой CMakeLists.txt:

configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/config.in
    ${CMAKE_CURRENT_BINARY_DIR}/config
    @ONLY
)

Это создаст файл конфигурации.

person Guillaume    schedule 18.06.2013

С 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 может быть ненадежным для некоторого содержимого.

person Sergey    schedule 16.01.2021