Debug vs Release en CMake

437

En un proyecto compilado de GCC,

  • ¿Cómo ejecuto CMake para cada tipo de destino (depuración / liberación)?
  • ¿Cómo especifico depurar y liberar banderas C / C ++ usando CMake?
  • ¿Cómo expreso que se compilará el ejecutable principal g++y una biblioteca anidada gcc?
Cartesius00
fuente

Respuestas:

660

Con CMake, generalmente se recomienda hacer una compilación "fuera de la fuente" . Crea tu CMakeLists.txten la raíz de tu proyecto. Luego, desde la raíz de su proyecto:

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

Y para Debug(nuevamente desde la raíz de su proyecto):

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

Release/ Debugagregará las banderas apropiadas para su compilador. También hay RelWithDebInfoy MinSizeRelconfiguraciones de construcción.


Puede modificar / agregar a las banderas especificando un archivo de cadena de herramientas en el que puede agregar CMAKE_C_FLAGS_DEBUGy CMAKE_C_FLAGS_RELEASEvariables, por ejemplo:

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

Ver CMAKE_BUILD_TYPE para más detalles.


En cuanto a su tercera pregunta, no estoy seguro de lo que está preguntando exactamente. CMake debería detectar y usar automáticamente el compilador apropiado para sus diferentes archivos fuente.

kb1ooo
fuente
3
También puede hacer un cmake -i ..en su lugar, por lo que cmake se ejecutará de forma interactiva, preguntándole qué tipo de compilación desea (Ninguno, Release, Debug, MinSizeRel, RelWithDebInfo).
thiagowfx
55
@thiagowfx -iopción produce este mensaje de error: The "cmake -i" wizard mode is no longer supported.. Estoy usando cmake 3.7.1
Philipp Claßen
3
Buena observación Parece que fue obsoleto desde la versión 3.0.0. Referencia .
thiagowfx
77
¡Esta NO es una compilación fuera del código fuente si está creando un subdirectorio! Se recomienda crear el directorio de compilación fuera / encima del directorio de origen.
Victor Lamoine
Tenga en cuenta que si CMAKE_BUILD_TYPEno se establece, cmake no elegirá ningún tipo de compilación predeterminado, por lo tanto, la línea de comando del compilador generado no coincidirá con ninguna configuración de compilación.
David
23

Para las marcas de depuración / liberación, vea la CMAKE_BUILD_TYPEvariable (la pasa como cmake -DCMAKE_BUILD_TYPE=value). Toma valores como Release, Debug, etc.

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

cmake usa la extensión para elegir el compilador, así que solo nombra tus archivos .c.

Puede anular esto con varias configuraciones:

Por ejemplo:

set_source_files_properties(yourfile.c LANGUAGE CXX) 

Compilaría archivos .c con g ++. El enlace de arriba también muestra cómo seleccionar un compilador específico para C / C ++.

Duncan
fuente
16

En lugar de manipular las CMAKE_CXX_FLAGScadenas directamente (lo que se podría hacer mejor usando string(APPEND CMAKE_CXX_FLAGS_DEBUG " -g3")btw), puede usar add_compiler_options:

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

Esto agregaría las advertencias especificadas a todos los tipos de compilación, pero solo los indicadores de depuración dados a la DEBUGcompilación. Tenga en cuenta que las opciones de compilación se almacenan como una lista CMake, que es solo una cadena que separa sus elementos por punto ;y coma .

sebastian
fuente
2
¿No list(APPEND CMAKE_CXX_FLAGS_DEBUG "-g3")agregará un punto y coma antes de que -g3 termine el comando y comience un nuevo comando -g3 que seguramente fallará?
cburn11
Tienes razón, noCMAKE_CXX_FLAGS es una lista cmake sino una cadena de banderas de línea de comando separadas por espacios. Encuentro ese comportamiento inconsistente ...
sebastian
add_compile_options () está ordenado. Se complementa con add_link_options () para cuando necesita agregar opciones al enlazador también, como -fsanitize = address.
Bowie Owens
1
¿Sigue siendo la forma adecuada en 2020 / cmake 3.17? Esa última línea parece desagradable
Jay
8

Si desea crear una configuración diferente sin regenerar si está utilizando, también puede ejecutar cmake --build {$PWD} --config <cfg>Para herramientas de configuración múltiple, elija <cfg>ej. Depurar, liberar, MinSizeRel, RelWithDebInfo

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

Russel Waters
fuente
He intentado jugar con la --configopción sin ningún resultado. No afecta a la $<CONFIG>variable como lo -DCMAKE_BUILD_TYPE=hace.
loshad vtapkah
5

// CMakeLists.txt: release

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

// CMakeLists.txt: debug

set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE)
sailfish009
fuente
10
No entiendo por qué se vota, es un código real que se usa en producción, por cierto no me importa.
sailfish009
55
Tal vez porque de acuerdo con los documentos CMake CMAKE_CONFIGURATION_TYPEScontiene los valores posibles para CMAKE_BUILD_TYPE. Por lo tanto, debe configurar este último como sugieren las otras respuestas. Tal vez su solución funcione porque limita las posibles opciones a la que le gustaría tener.
bjhend
2
Vota porque esto funcionará. Me encantan algunos CMake, pero hay peculiaridades y, a veces, necesitas usar un gran martillo para que las cosas funcionen. Tengo algunos proyectos que por una razón u otra rechazarán el indicador de línea de comando.
cory.todd
Aquí hay información adicional sobre por qué la configuración puede no funcionar: stackoverflow.com/a/24470998/3196753
tresf