Quando citar variables?

Eu estou escrevendo macros CMake pela primeira vez, e eu tenho dificuldade em entender como as variables ​​funcionam. Mais especificamente, ${a} parece ter um significado diferente de "${a}" .

Por exemplo aqui: Passando uma lista para uma macro cmake

Não consigo entender quando devo adicionar citações e quais são os maiores princípios subjacentes.

Dois princípios de CMake você deve ter em mente:

  1. O CMake é uma linguagem de script e os argumentos são avaliados depois que as variables ​​são expandidas
  2. CMake diferencia entre strings normais e variables ​​de lista (strings com delimitadores de ponto-e-vírgula)

Exemplos

  • set(_my_text "ABC") com message("${_my_text}") daria ABC
  • set(_my_list ABC) com message("${_my_list}") daria A;B;C
  • set(_my_list "A" "B" "C") com message("${_my_list}") daria A;B;C
  • set(_my_list "A" "B" "C") com message(${_my_list}) daria ABC

Algumas Regras de Polegar

Existem algumas regras que você deve considerar:

  1. a) Quando sua variável contém texto – especialmente um que pode conter ponto e vírgula – você deve adicionar aspas.

    Raciocínio : Um ponto e vírgula é um delimitador para elementos de lista no CMake. Então, coloque aspas em torno de um texto que deveria ser um (ele funciona em todos os lugares e, para mim, parece melhor com o realce da syntax do CMake)

    EDIT: Obrigado pela dica de @schieferstapel

    b) Para ser mais preciso: um conteúdo variável com espaços que já continha aspas mantém essas citações (imagine como parte do conteúdo da variável). Isso funciona em todos os lugares e sem aspas (parâmetros de function normais ou definidos pelo usuário) com a exceção proeminente de chamadas if() , onde CMake reinterpreta o conteúdo de variables ​​não nomeadas após a expansão da variável (consulte também a regra de ouro nº 3 e a política CMP0054: Somente interpretar if() argumentos como variables ​​ou palavras-chave quando não estiver marcado )

    Exemplos:

    • set(_my_text "ABC") com message(${_my_text}) também daria ABC
    • set(_my_text "A;B;C") com if (${_my_text} STREQUAL "A;B;C") daria if given arguments: "A" "B" "C" "STREQUAL" "A;B;C" Unknown arguments specified
  2. Se a sua variável contiver uma lista, você normalmente não adicionará aspas.

    Raciocínio : Se você der algo como uma lista de arquivos para um comando CMake, normalmente espera uma lista de strings e não uma string contendo uma lista. A diferença que você pode ver, por exemplo, no comando foreach() aceitando ITEMS ou LISTS .

  3. if() instruções são um caso especial em que você normalmente nem coloca as chaves.

    Raciocínio : Uma string pode – após a expansão – avaliar novamente para um nome de variável. Para evitar isso, é recomendado apenas nomear a variável cujo conteúdo você deseja comparar (por exemplo, if (_my_text STREQUAL "ABC") ).


Exemplos de COMMAND

  • set(_my_text "ABC") com o COMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}"
    • chamar cmake.exe -E echo "ABC" no VS / Windows
    • chamar cmake -E echo A\ B\ C no GCC / Ubuntu
    • dar ABC
  • set(_my_text "ABC") com o COMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}" VERBATIM faria
    • chamar cmake.exe -E echo "ABC" no VS / Windows
    • chamar cmake -E echo "ABC" no GCC / Ubuntu
    • dar ABC
  • set(_my_list ABC) com o COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}"
    • chamar cmake.exe -E echo A;B;C
    • A , B: command not found , C: command not found
  • set(_my_list ABC) com o COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" VERBATIM faria
    • chamar cmake.exe -E echo "A;B;C"
    • dar A;B;C
  • set(_my_list "A" "B" "C") com o COMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" VERBATIM faria
    • chamar cmake.exe -E echo "A;B;C"
    • dar A;B;C
  • set(_my_list "A" "B" "C") com o COMMAND "${CMAKE_COMMAND}" -E echo ${_my_list} VERBATIM faria
    • chamar cmake.exe -E echo ABC
    • dar ABC
  • set(_my_list "A + B" "=" "C") com o COMMAND "${CMAKE_COMMAND}" -E echo ${_my_list} VERBATIM iria
    • chamar cmake.exe -E echo "A + B" = C
    • A + B = C

Algumas Regras de Polegar com add_custom_target() / add_custom_command() / execute_process()

Existem algumas regras que você deve considerar ao usar variables ​​em chamadas de COMMAND :

  1. a) Use aspas para os argumentos que contêm caminhos de arquivo (como o primeiro argumento contendo o próprio executável).

    Raciocínio : Ele pode conter espaços e pode ser reinterpretado como argumentos separados para a chamada COMMAND

    b) Veja acima, funciona também se a variável set() incluiu aspas.

  2. Use aspas apenas se você quiser concatenar algo em um único parâmetro a ser passado para o executável que é chamado.

    Raciocínio : Uma variável pode conter uma lista de parâmetros que – ao usar aspas – não serão corretamente extraídos (ponto-e-vírgula ao invés de espaços)

  3. Sempre inclua a opção VERBATIM com add_custom_target() / add_custom_command()

    Raciocínio : caso contrário, o comportamento de plataforma cruzada é indefinido e você pode obter surpresas com suas strings entre aspas.

Referências

  • CMake: diferença entre $ {} e “$ {}”
  • Qual é a syntax do CMake para definir e usar variables?
  • Looping sobre uma lista de strings
  • CMake compara a string vazia com STREQUAL com falha