Я пишу макросы CMake в первый раз, и мне трудно понять, как работает переменная. В частности, ${a}, похоже, имеет другое значение, чем "$ {a}".
Например:
Я не понимаю, когда я должен добавить цитаты, и каков основной принцип.
Я пишу макросы CMake в первый раз, и мне трудно понять, как работает переменная. В частности, ${a}, похоже, имеет другое значение, чем "$ {a}".
Например:
Я не понимаю, когда я должен добавить цитаты, и каков основной принцип.
Два принципа CMake, которые вы должны иметь в виду:
<сильные > Примеры
set(_my_text "A B C") с message("${_my_text}") даст A B Cset(_my_list A B C) с message("${_my_list}") даст A;B;Cset(_my_list "A" "B" "C") с message("${_my_list}") даст A;B;Cset(_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 Cset(_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 Cset(_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 Cset(_my_list A B C) с COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" будет
cmake.exe -E echo A;B;CA, B: command not found, C: command not foundset(_my_list A B C) с COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" VERBATIM будет
cmake.exe -E echo "A;B;C"A;B;Cset(_my_list "A" "B" "C") с COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" VERBATIM будет
cmake.exe -E echo "A;B;C"A;B;Cset(_my_list "A" "B" "C") с COMMAND "${CMAKE_COMMAND}" -E echo ${_my_list}
VERBATIM будет
cmake.exe -E echo A B CA B Cset(_my_list "A + B" "=" "C") с COMMAND "${CMAKE_COMMAND}" -E echo ${_my_list} VERBATIM будет
cmake.exe -E echo "A + B" = CA + B = C Некоторые правила большого пальца с add_custom_target()/add_custom_command()/execute_process()
Есть несколько важных правил, которые следует учитывать при использовании переменных в вызовах COMMAND:
a) Используйте кавычки для аргументов, содержащих пути к файлам (например, первый аргумент, содержащий сам исполняемый файл).
Рассуждение: оно может содержать пробелы и может быть переинтерпретировано как отдельные аргументы для вызова COMMAND
b) См. выше, работает также, если переменная set() включила кавычки.
Использовать кавычки только в том случае, если вы хотите объединить что-то в один параметр, который будет передан исполняемому, который вызывается.
Рассуждение: переменная может содержать список параметров, которые - при использовании кавычек - не будут правильно извлечены (точки с запятой вместо пробелов)
Всегда добавляйте параметр VERBATIM с помощью add_custom_target()/add_custom_command()
Рассуждение: В противном случае кросс-платформенное поведение undefined, и вы можете получить сюрпризы с вашими кавычками.
Ссылки