使用CMake设置CFLAGS和CXXFLAGS选项


88

我只想调试一些在Linux上运行的代码,并且需要一个调试版本(-O0 -ggdb)。所以我将这些东西添加到我的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")

当我尝试编译时,我使用启用了详细功能,make VERBOSE=1 并且观察了输出,就像这样

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

显然代码是用编译的"-g -O2",这不是我想要的。我该如何强迫它"-O0 -ggdb"仅使用?


1
如果要构建可调试版本,只需在命令行上进行调试配置即可。“ cmake -DCMAKE_BUILD_TYPE =调试”。生成的构建将为给定的构建系统启用调试标志。没有理由修改cmake文件本身。您也可以使用另一个-D参数发送CMAKE_C_FLAGS值。
Atifm

Answers:


83

您需要在CMakeLists.txt中的命令设置标志project

另外,如果您要调用include(${QT_USE_FILE})add_definitions(${QT_DEFINITIONS}),则应set在Qt命令之后包括这些命令,因为这些命令会附加更多标志。如果这样,您可能只想将您的标志附加到Qt上,因此将其更改为例如

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -ggdb")

我确实在项目命令后放置了这些标志。但是输出是一样的。
majie

我刚刚注意到QT_NO_EXCEPTIONS您的旗帜,所以我将回答扩展了一些。我猜${QT_DEFINITIONS}是在追加-g -O2
Fraser

1
是的,就是这样。将这些set命令放在Qt命令之后即可解决问题。非常感谢你。
majie 2012年

18

最适合我的最简单解决方案是:

export CFLAGS=-ggdb
export CXXFLAGS=-ggdb

CMake会将它们附加到所有配置的标志。只要确保清除CMake缓存即可。


3
在这样的环境中设置标志是唯一无需修改CMakeLists.txt的方法。请注意,仅在第一次配置时读取环境值,然后将其放入高速缓存中,因此,如果要更改此值,则需要清除CMake高速缓存,然后使用环境中的新值重新运行configure步骤。文件:cmake.org/cmake/help/latest/envvar/CFLAGS.html cmake.org/cmake/help/latest/envvar/CXXFLAGS.html
凌晨

3
那不是“最简单的”,那是唯一正确的方法。
斯拉瓦(Slava)

次要捕获,如果生成器正在为特定的构建类型(例如inCMAKE_CXX_FLAGS_DEBUG 等)配置特定的标志,则将其包括CXXFLAGS(从而将其注入CMAKE_CXX_FLAGS)实际上不足以将选项传递给编译器。每个构建类型配置优先于用户输入。
Ext3h

15

您必须更改cmake C / CXX默认标记。

根据CMAKE_BUILD_TYPE={DEBUG/MINSIZEREL/RELWITHDEBINFO/RELEASE} 放入的主要内容CMakeLists.txt之一:

对于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")

对于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")

这将覆盖CMakeCache.txt中定义的值


会覆盖您当前的cmake标志。因此,除非您自己添加-g标志(gcc),否则它会中断调试
activedecay

使用“现代Cmake”语法是否有相同的想法?
桑德堡

6

在Unix系统上,对于几个项目,我将这些行添加到CMakeLists.txt中,由于基本/ usr / include)和本地包含(/ usr / local / include)进入了单独的目录,因此编译成功:

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")

它附加了正确的目录,包括C和C ++编译器标志的路径以及链接器标志的正确目录路径。

注意:C ++编译器(c ++)不支持-L,因此我们必须使用CMAKE_EXE_LINKER_FLAGS


3
使用标记include_directories代替-I标记不是更好吗?
Tejas Kale

非常感谢。我将链接器标记放在中CMAKE_CXX_FLAGS,这导致它们被忽略。现在,CMAKE_EXE_LINKER_FLAGS根据您的回答,我将它们放进去,它们工作正常。
Nahiyan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.