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?

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.


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


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 .


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


5

// CMakeLists.txt: release

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

// CMakeLists.txt: debug

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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.