Я пишу макросы CMake в первый раз, и мне трудно понять, как работает переменная. В частности, ${a}, похоже, имеет другое значение, чем "$ {a}".
Например:
Я не понимаю, когда я должен добавить цитаты, и каков основной принцип.
Я пишу макросы CMake в первый раз, и мне трудно понять, как работает переменная. В частности, ${a}, похоже, имеет другое значение, чем "$ {a}".
Например:
Я не понимаю, когда я должен добавить цитаты, и каков основной принцип.
Два принципа CMake, которые вы должны иметь в виду:
<сильные > Примеры
set(_my_text "A B C")
с message("${_my_text}")
даст A B C
set(_my_list A B C)
с message("${_my_list}")
даст A;B;C
set(_my_list "A" "B" "C")
с message("${_my_list}")
даст A;B;C
set(_my_list "A" "B" "C")
с message(${_my_list})
даст ABC
Некоторые правила большого пальца
Есть несколько правил, которые вы должны рассмотреть:
a) Когда ваша переменная содержит текст - особенно тот, который может содержать точки с запятой, вы должны добавить кавычки.
Рассуждение: точка с запятой является разделителем для элементов списка в CMake. Поэтому помещайте кавычки вокруг текста, который должен быть одним (он работает повсюду и для меня лично выглядит лучше с подсветкой синтаксиса CMake)
EDIT: Спасибо за подсказку @schieferstapel
b) Точнее: переменное содержимое с пробелами, у которых уже есть кавычки, сохраняет эти кавычки (представьте, что они становятся частью содержимого переменной). Это работает везде также без кавычек (обычные или пользовательские параметры функции) с заметным исключением вызовов if()
, где CMake повторно интерпретирует содержимое некотируемых переменных после расширения переменной (см. Также правило № 3 и политика CMP0054: интерпретировать аргументы if()
как переменные или ключевые слова при некотировании)
Примеры:
set(_my_text "A B C")
с message(${_my_text})
также даст A B C
set(_my_text "A;B;C")
с if (${_my_text} STREQUAL "A;B;C")
даст if given arguments: "A" "B" "C" "STREQUAL" "A;B;C" Unknown arguments specified
Если ваша переменная содержит список, вы обычно не добавляете кавычки.
Рассуждение: если вы передаете что-то вроде списка файлов команде CMake, то обычно ожидают список строк, а не одну строку, содержащую список. Разницу, которую вы можете видеть, например, в команде foreach()
, принимающей ITEMS
или LISTS
.
if()
- это особый случай, когда вы обычно не кладете фигурные скобки.
Рассуждение: строка может - после расширения - снова оценивать имя переменной. Чтобы предотвратить это, рекомендуется просто указать переменную, содержимое которой вы хотите сравнить (например, if (_my_text STREQUAL "A B C")
).
COMMAND
Примеры
set(_my_text "A B C")
с COMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}"
будет
cmake.exe -E echo "A B C"
в VS/Windowscmake -E echo A\ B\ C
в GCC/UbuntuA B C
set(_my_text "A B C")
с COMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}" VERBATIM
будет
cmake.exe -E echo "A B C"
в VS/Windowscmake -E echo "A B C"
в GCC/UbuntuA B C
set(_my_list A B C)
с COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}"
будет
cmake.exe -E echo A;B;C
A
, B: command not found
, C: command not found
set(_my_list A B C)
с COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" VERBATIM
будет
cmake.exe -E echo "A;B;C"
A;B;C
set(_my_list "A" "B" "C")
с COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" VERBATIM
будет
cmake.exe -E echo "A;B;C"
A;B;C
set(_my_list "A" "B" "C")
с COMMAND "${CMAKE_COMMAND}" -E echo ${_my_list}
VERBATIM
будет
cmake.exe -E echo A B C
A B C
set(_my_list "A + B" "=" "C")
с COMMAND "${CMAKE_COMMAND}" -E echo ${_my_list} VERBATIM
будет
cmake.exe -E echo "A + B" = C
A + B = C
Некоторые правила большого пальца с add_custom_target()
/add_custom_command()
/execute_process()
Есть несколько важных правил, которые следует учитывать при использовании переменных в вызовах COMMAND
:
a) Используйте кавычки для аргументов, содержащих пути к файлам (например, первый аргумент, содержащий сам исполняемый файл).
Рассуждение: оно может содержать пробелы и может быть переинтерпретировано как отдельные аргументы для вызова COMMAND
b) См. выше, работает также, если переменная set()
включила кавычки.
Использовать кавычки только в том случае, если вы хотите объединить что-то в один параметр, который будет передан исполняемому, который вызывается.
Рассуждение: переменная может содержать список параметров, которые - при использовании кавычек - не будут правильно извлечены (точки с запятой вместо пробелов)
Всегда добавляйте параметр VERBATIM
с помощью add_custom_target()
/add_custom_command()
Рассуждение: В противном случае кросс-платформенное поведение undefined, и вы можете получить сюрпризы с вашими кавычками.
Ссылки