Defina as opções CFLAGS e CXXFLAGS usando CMake

88

Eu só quero depurar algum código em execução no Linux e preciso de um build de depuração ( -O0 -ggdb). Então, adicionei essas coisas ao meu 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")

Quando tentei compilar, liguei o verbose no uso make VERBOSE=1 e observei a saída, assim

... /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, o código é compilado "-g -O2"e não é isso que eu quero. Como posso forçá-lo a usar "-O0 -ggdb"apenas?

majie
fonte
1
Se você quiser uma compilação depurável, basta fazer uma configuração de depuração na linha de comando. "cmake -DCMAKE_BUILD_TYPE = Depurar". A compilação resultante terá os sinalizadores de depuração ativados para o sistema de compilação fornecido. Não há razão para modificar o próprio arquivo cmake. Você também pode enviar o valor CMAKE_C_FLAGS com outro argumento -D.
Atifm de

Respostas:

83

Você precisa definir os sinalizadores após o projectcomando em seu CMakeLists.txt.

Além disso, se você estiver chamando include(${QT_USE_FILE})ou add_definitions(${QT_DEFINITIONS}), deverá incluir esses setcomandos após os do Qt, pois eles acrescentariam outros sinalizadores. Se esse é o caso, você talvez só deseja anexar suas bandeiras para as Qt, por isso a mudança para eg

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -ggdb")
Fraser
fonte
Eu coloquei esses sinalizadores após o comando do projeto. Mas a saída é a mesma.
maio,
Acabei de notar o QT_NO_EXCEPTIONSem suas sinalizações, então estendi minha resposta um pouco. Eu estou supondo que ${QT_DEFINITIONS}está anexando o -g -O2.
Fraser de
1
Sim, é isso. Colocar esses setcomandos após os do Qt resolve o problema. Muito obrigado.
majie,
18

A solução mais fácil funcionando bem para mim é esta:

export CFLAGS=-ggdb
export CXXFLAGS=-ggdb

CMake irá anexá-los a todos os sinalizadores de configuração. Apenas certifique-se de limpar o cache CMake.

Virus_7
fonte
3
Definir os sinalizadores no ambiente dessa forma é a única maneira de fazer isso sem modificar seu CMakeLists.txt. Observe que o valor do ambiente só é lido na primeira configuração e, em seguida, colocado no cache, portanto, se quiser alterar isso, você precisa limpar o cache do CMake e executar novamente a etapa de configuração com os novos valores no env. Documentos: cmake.org/cmake/help/latest/envvar/CFLAGS.html cmake.org/cmake/help/latest/envvar/CXXFLAGS.html
bleater
3
Isso não é "mais fácil", é a única maneira certa de fazer isso.
Slava
Pequeno detalhe, se o gerador está configurando um sinalizador específico para um tipo específico de compilação (por exemplo, em CMAKE_CXX_FLAGS_DEBUG etc.), então incluí-lo em CXXFLAGS(e, portanto, injetá-lo em CMAKE_CXX_FLAGS) não é suficiente para passar a opção para o compilador. A configuração por tipo de construção tem precedência sobre a entrada do usuário.
Ext3h
15

Você deve alterar os FLAGS padrão cmake C / CXX.

De acordo com o CMAKE_BUILD_TYPE={DEBUG/MINSIZEREL/RELWITHDEBINFO/RELEASE} colocado no 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")

Isso substituirá os valores definidos em CMakeCache.txt

Carl-Erwin
fonte
que substitui seus sinalizadores cmake que são atuais. então interrompe a depuração, a menos que você mesmo adicione o sinalizador -g (gcc)
activedecay
Existe a mesma ideia usando a sintaxe "Modern Cmake"?
Sandburg
6

Em sistemas Unix, para vários projetos, adicionei essas linhas ao CMakeLists.txt e ele estava compilando com sucesso porque base ( / usr / include ) e inclui locais ( / usr / local / include ) vão para diretórios 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")

Ele anexa o diretório correto, incluindo caminhos para os sinalizadores do compilador C e C ++ e o caminho do diretório correto para os sinalizadores do vinculador.

Nota: o compilador C ++ (c ++) não suporta -L, então temos que usar CMAKE_EXE_LINKER_FLAGS

sbz
fonte
3
Não é melhor usar em include_directoriesvez da -Ibandeira?
Tejas Kale de
Muito obrigado. Eu estava colocando meus sinalizadores de linker CMAKE_CXX_FLAGS, o que fez com que fossem ignorados. Agora que os coloquei com CMAKE_EXE_LINKER_FLAGSbase na sua resposta, eles estão funcionando muito bem.
Nahiyan