Подтвердить что ты не робот

Cmake: когда цитировать переменные?

Я пишу макросы CMake в первый раз, и мне трудно понять, как работает переменная. В частности, ${a}, похоже, имеет другое значение, чем "$ {a}".

Например:

Передача списка макросу cmake

Я не понимаю, когда я должен добавить цитаты, и каков основной принцип.

4b9b3361

Ответ 1

Два принципа CMake, которые вы должны иметь в виду:

  • CMake - это script язык и аргументы оцениваются после расширения переменных
  • 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/Windows
    • вызов cmake -E echo A\ B\ C в GCC/Ubuntu
    • дать A B C
  • set(_my_text "A B C") с COMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}" VERBATIM будет
    • вызов cmake.exe -E echo "A B C" в VS/Windows
    • вызов cmake -E echo "A B C" в GCC/Ubuntu
    • дать A 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, и вы можете получить сюрпризы с вашими кавычками.

Ссылки