Depurar vs Liberar no CMake

434

Em um projeto compilado pelo GCC,

  • Como executo o CMake para cada tipo de destino (depuração / liberação)?
  • Como especificar debug e liberar sinalizadores C / C ++ usando o CMake?
  • Como eu expresso que o executável principal será compilado g++e uma biblioteca aninhada gcc?
Cartesius00
fonte

Respostas:

656

Com o CMake, geralmente é recomendável fazer uma compilação "fora da fonte" . Crie o seu CMakeLists.txtna raiz do seu projeto. A partir da raiz do seu projeto:

mkdir Release
cd Release
cmake -DCMAKE_BUILD_TYPE=Release ..
make

E para Debug(novamente a partir da raiz do seu projeto):

mkdir Debug
cd Debug
cmake -DCMAKE_BUILD_TYPE=Debug ..
make

Release/ Debugadicionará os sinalizadores apropriados para o seu compilador. Há também RelWithDebInfoe MinSizeRelconfigurações de compilação.


Você pode modificar / adicionar aos sinalizadores especificando um arquivo de cadeia de ferramentas no qual você pode adicionar CMAKE_C_FLAGS_DEBUGe CMAKE_C_FLAGS_RELEASEvariáveis, por exemplo:

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall")

Veja CMAKE_BUILD_TYPE para mais detalhes.


Quanto à sua terceira pergunta, não sei exatamente o que você está perguntando. O CMake deve detectar e usar automaticamente o compilador apropriado para seus diferentes arquivos de origem.

kb1ooo
fonte
3
Você também pode fazer um teste cmake -i .., para que o cmake seja executado interativamente, perguntando qual tipo de compilação você deseja (Nenhum, Liberar, Depurar, MinSizeRel, RelWithDebInfo).
Thiagowfx
5
@thiagowfx -iopção resulta nessa mensagem de erro: The "cmake -i" wizard mode is no longer supported.. Estou usando o cmake 3.7.1
Philipp Claßen
3
Boa observação. Parece que foi preterido desde a versão 3.0.0. Referência .
Thiagowfx
7
Esta NÃO é uma compilação fora da fonte se você estiver criando um subdiretório! É recomendável criar o diretório de construção fora / acima do diretório de origem.
Victor Lamoine
Observe que, se CMAKE_BUILD_TYPEnão estiver definido, o cmake não escolherá nenhum tipo de compilação padrão; portanto, a linha de comando do compilador gerado não corresponderá a nenhuma configuração de compilação.
david
22

Para sinalizadores de depuração / liberação, consulte a CMAKE_BUILD_TYPEvariável (você a transmite como cmake -DCMAKE_BUILD_TYPE=value). Leva valores como Release, Debug, etc.

https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/Useful-Variables#compilers-and-tools

O cmake usa a extensão para escolher o compilador, então apenas nomeie seus arquivos .c.

Você pode substituir isso por várias configurações:

Por exemplo:

set_source_files_properties(yourfile.c LANGUAGE CXX) 

Compilaria arquivos .c com g ++. O link acima também mostra como selecionar um compilador específico para C / C ++.

duncan
fonte
15

Em vez de manipular as CMAKE_CXX_FLAGSstrings diretamente (o que poderia ser feito de maneira mais agradável usando o string(APPEND CMAKE_CXX_FLAGS_DEBUG " -g3")btw), você pode usar add_compiler_options:

add_compile_options(
  "-Wall" "-Wpedantic" "-Wextra" "-fexceptions"
  "$<$<CONFIG:DEBUG>:-O0;-g3;-ggdb>"
)

Isso adicionaria os avisos especificados a todos os tipos de compilação, mas apenas os sinalizadores de depuração fornecidos para a DEBUGcompilação. Observe que as opções de compilação são armazenadas como uma lista do CMake, que é apenas uma string que separa seus elementos por ponto e vírgula ;.

sebastiano
fonte
2
Não list(APPEND CMAKE_CXX_FLAGS_DEBUG "-g3")adicionará um ponto e vírgula antes de -g3 encerrar o comando e iniciar um novo comando -g3 que certamente falhará?
precisa saber é o seguinte
Você está certo nãoCMAKE_CXX_FLAGS é uma lista cmake, mas uma sequência de sinalizadores de linha de comando separados por espaço. Acho que inconsistente comportamento ...
sebastian
add_compile_options () é legal. É complementado por add_link_options () para quando você também precisa adicionar opções ao vinculador, como -fsanitize = address.
Bowie Owens
1
Essa ainda é a maneira apropriada em 2020 / cmake 3.17? Essa última linha parece desagradável
Jay
8

Se você deseja construir uma configuração diferente sem gerar novamente, se estiver usando, você também pode executar cmake --build {$PWD} --config <cfg>Para ferramentas de configuração múltipla, escolha <cfg>ex. Depurar, Liberar, MinSizeRel, RelWithDebInfo

https://cmake.org/cmake/help/v2.8.11/cmake.html#opt%3a--builddir

Russel Waters
fonte
Eu tentei jogar com a --configopção sem nenhum resultado. Não afeta a $<CONFIG>variável como -DCMAKE_BUILD_TYPE=faz.
loshad vtapkah
4

// CMakeLists.txt: release

set(CMAKE_CONFIGURATION_TYPES "Release" CACHE STRING "" FORCE)

// CMakeLists.txt: debug

set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE)
sailfish009
fonte
9
Eu não entendo por que isso é votado, é um código real usado na produção, mas eu não me importo.
precisa
5
Talvez porque, de acordo com o CMake, os documentos CMAKE_CONFIGURATION_TYPEScontenham os valores possíveis para CMAKE_BUILD_TYPE. Portanto, você deve definir o último como sugerem as outras respostas. Talvez sua solução funcione porque limita as opções possíveis àquela que você gostaria de ter.
bjhend
2
Voto a favor porque isso irá funcionar. Eu amo o CMake, mas existem peculiaridades e, às vezes, você precisa usar um martelo grande para fazer as coisas funcionarem. Eu tenho alguns projetos que, por um motivo ou outro, rejeitarão o sinalizador da linha de comando.
Cory.todd 16/05/19
Aqui estão algumas informações adicionais sobre por que a configuração pode não funcionar: stackoverflow.com/a/24470998/3196753
tresf