CMake: разница между ${} и "${}"

Какая разница в cmake между чем-то вроде:

set(any_new_var ${old_var})

а также

set(any_new_var "${old_var}")

Есть ли важное отличие? Когда я должен использовать ту или иную форму?

Например, я пытаюсь с помощью следующего мини-теста

# test.cmake

# Variable 'a' isn't defined.
set(hola "${a}")

# message(${hola})
message("${hola}")

Вывод этого мини-теста (cmake -P test.cmake) представляет собой пустую строку (потому что "a" не определено). Если я раскомментирую первое сообщение, cmake выдаст сообщение об ошибке:

CMake Error at prueba.cmake:6 (message):
  message called with incorrect number of arguments

Почему во втором случае это не бросок и ошибка, а пустая строка?

1 ответ

Решение

В CMake строки можно интерпретировать как списки. Правило простое: для формирования списка разбейте строку на точку с запятой. Например, строковое значение one;two;three можно рассматривать как список из трех элементов: one, two, а также three,

Чтобы вызвать команду, вы пишете имя команды и несколько слов в скобках. Однако эти слова не соответствуют аргументам, которые команда получает в формате один к одному. Каждое слово становится нулем или более аргументов, и все аргументы объединяются вместе. Если слово не заключено в кавычки, оно рассматривается как список и расширяется до нескольких аргументов. Процитированное слово всегда становится единственным аргументом.

Например, предположим, что X связан с one;two;three, Y привязан к пустой строке, и Z связан с foo, В следующем вызове команды есть три слова, но команда получает четыре аргумента:

some_command(${X} ${Y} ${Z})
# The command receives four arguments:
# 1. one
# 2. two
# 3. three
# 4. foo

Если бы мы цитировали слова, команда получила бы три аргумента:

some_command("${X}" "${Y}" "${Z}")
# The command receives three arguments:
# 1. one;two;three
# 2. (the empty list)
# 3. foo

Вернемся к исходному вопросу: message Команда может получить различное количество аргументов. Он принимает все свои аргументы, объединяет их в одну строку и затем печатает эту строку. Однако по неизвестной причине он не принимает нулевые аргументы.

Поведение message Имеет несколько аргументов, не очень полезно, поэтому вы склонны использовать один аргумент в кавычках:

set(SOURCES foo.c hoo.h)
message(${SOURCES})   # prints foo.cfoo.h
message("${SOURCES}") # prints foo.c;foo.h

Кроме того, когда set Получив несколько аргументов, он строит строку аргументов, разделенных точкой с запятой. Переменная затем устанавливается на эту строку.

Другие вопросы по тегам