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?

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.


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 ++.


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 ;.


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


4

// CMakeLists.txt: release

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

// CMakeLists.txt: debug

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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.