Configure las opciones de CFLAGS y CXXFLAGS usando CMake

88

Solo quiero depurar un código que se ejecuta en Linux y necesito una compilación de depuración ( -O0 -ggdb). Así que agregué estas cosas a mi CMakeLists.txt:

set(CMAKE_BUILD_TYPE DEBUG)
set(CMAKE_C_FLAGS "-O0 -ggdb")
set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb")
set(CMAKE_C_FLAGS_RELEASE "-O0 -ggdb")
set(CMAKE_CXX_FLAGS "-O0 -ggdb")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "-O0 -ggdb")

Cuando traté de compilar, me volví detallado sobre el uso make VERBOSE=1 y observé la salida, así

... /usr/bin/c++ -D_BSD_SOURCE **-O0 -ggdb** -Wnon-virtual-dtor 
-Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W 
-Wpointer-arith -Wformat-security -fno-exceptions -DQT_NO_EXCEPTIONS 
-fno-check-new -fno-common -Woverloaded-virtual -fno-threadsafe-statics 
-fvisibility=hidden -fvisibility-inlines-hidden **-g -O2** 
-fno-reorder-blocks -fno-schedule-insns -fno-inline ...

Aparentemente, el código está compilado "-g -O2"y esto no es lo que quiero. ¿Cómo puedo obligarlo a usar "-O0 -ggdb"solo?

majie
fuente
1
Si desea una compilación depurable, simplemente realice una configuración de depuración en la línea de comandos. "cmake -DCMAKE_BUILD_TYPE = Depurar". La compilación resultante tendrá las banderas de depuración activadas para el sistema de compilación dado. No hay razón para modificar el archivo cmake en sí. También puede enviar el valor CMAKE_C_FLAGS con otro argumento -D.
Atifm

Respuestas:

83

Debe establecer las banderas después del projectcomando en su CMakeLists.txt.

Además, si está llamando a include(${QT_USE_FILE})o add_definitions(${QT_DEFINITIONS}), debe incluir estos setcomandos después de los de Qt, ya que estos agregarían más banderas. Si ese es el caso, tal vez solo desee agregar sus banderas a las de Qt, así que cambie a, por ejemplo,

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -ggdb")
Fraser
fuente
Puse esas banderas después del comando del proyecto. Pero la salida es la misma.
majie
Acabo de notar el QT_NO_EXCEPTIONSen sus banderas, así que extendí un poco mi respuesta. Supongo que ${QT_DEFINITIONS}se agrega el -g -O2.
Fraser
1
Si esto es. Poner esos setcomandos después de los de Qt resuelve el problema. Muchas gracias.
majie
18

La solución más fácil que funciona bien para mí es esta:

export CFLAGS=-ggdb
export CXXFLAGS=-ggdb

CMake los agregará a los indicadores de todas las configuraciones. Solo asegúrese de borrar la caché de CMake.

Virus_7
fuente
3
Establecer las banderas en el entorno de esta manera es la única forma de hacerlo sin modificar su CMakeLists.txt. Tenga en cuenta que el valor del entorno solo se lee en la primera configuración y luego se coloca en la caché, por lo que si desea cambiar esto, debe borrar la caché de CMake y volver a ejecutar el paso de configuración con los nuevos valores en el entorno env. Documentos: cmake.org/cmake/help/latest/envvar/CFLAGS.html cmake.org/cmake/help/latest/envvar/CXXFLAGS.html
bleater
3
Eso no es "más fácil", es la única forma correcta de hacerlo.
Slava
Un problema menor, si el generador está configurando una bandera específica para un tipo de compilación específico (por ejemplo, en, CMAKE_CXX_FLAGS_DEBUG etc.), incluirlo CXXFLAGS(y por lo tanto inyectarlo CMAKE_CXX_FLAGS) no es suficiente para pasar la opción al compilador. La configuración por tipo de compilación tiene prioridad sobre la entrada del usuario.
Ext3h
15

Debe cambiar las BANDERAS predeterminadas de cmake C / CXX.

Según CMAKE_BUILD_TYPE={DEBUG/MINSIZEREL/RELWITHDEBINFO/RELEASE} poner en el principal CMakeLists.txtde:

Para C

set(CMAKE_C_FLAGS_DEBUG "put your flags")
set(CMAKE_C_FLAGS_MINSIZEREL "put your flags")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "put your flags")
set(CMAKE_C_FLAGS_RELEASE "put your flags")

Para C ++

set(CMAKE_CXX_FLAGS_DEBUG "put your flags")
set(CMAKE_CXX_FLAGS_MINSIZEREL "put your flags")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "put your flags")
set(CMAKE_CXX_FLAGS_RELEASE "put your flags")

Esto anulará los valores definidos en CMakeCache.txt

carl-erwin
fuente
que anula sus banderas de cmake que son actuales. por lo que interrumpe la depuración a menos que agregue el indicador -g usted mismo (gcc)
activedecay
¿Existe la misma idea al usar la sintaxis "Modern Cmake"?
Sandburg
6

En sistemas Unix, para varios proyectos, agregué estas líneas en CMakeLists.txt y se estaba compilando exitosamente porque la base ( / usr / include ) y las inclusiones locales ( / usr / local / include ) van en directorios separados:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/local/include -L/usr/local/lib")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/local/include")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib")

Añade el directorio correcto, incluidas las rutas para los indicadores del compilador C y C ++ y la ruta del directorio correcto para los indicadores del vinculador.

Nota: el compilador C ++ (c ++) no es compatible con -L, por lo que tenemos que usar CMAKE_EXE_LINKER_FLAGS

sbz
fuente
3
¿No es mejor usar en include_directorieslugar de la -Ibandera?
Tejas Kale
Muchas gracias. Estaba colocando mis banderas del vinculador CMAKE_CXX_FLAGS, lo que hizo que se ignoraran. Ahora que los coloqué CMAKE_EXE_LINKER_FLAGSsegún su respuesta, están funcionando bien.
Nahiyan