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.