【问题标题】:Set CFLAGS and CXXFLAGS options using CMake使用 CMake 设置 CFLAGS 和 CXXFLAGS 选项
【发布时间】:2012-04-22 13:52:07
【问题描述】:

我只想调试一些在 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"

【问题讨论】:

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

标签: cmake cflags


【解决方案1】:

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

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

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

【讨论】:

  • 我确实将这些标志放在了项目命令之后。但是输出是一样的。
  • 我刚刚注意到你的标志中的QT_NO_EXCEPTIONS,所以我稍微扩展了我的答案。我猜${QT_DEFINITIONS} 附加了-g -O2
  • 是的,就是这样。将那些 set 命令放在 Qt 之后可以解决问题。非常感谢。
  • 非常感谢有关project() 命令的提示!这解决了一个问题,我们希望通过一个公共包含为所有项目设置CMAKE_CXX_FLAGS,但在项目命令之后这样做了。
  • 我收到“cl:命令行警告 D9002:忽略未知选项 '-ggdb'”
【解决方案2】:

对我来说最简单的解决方案是:

export CFLAGS=-ggdb
export CXXFLAGS=-ggdb

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

【讨论】:

  • 像这样在环境中设置标志是不修改 CMakeLists.txt 的唯一方法。请注意,环境值仅在第一次配置时读取,然后被放入缓存中,因此如果要更改此值,您需要清除 CMake 缓存并使用 env 中的新值重新运行配置步骤。文档:cmake.org/cmake/help/latest/envvar/CFLAGS.htmlcmake.org/cmake/help/latest/envvar/CXXFLAGS.html
  • 这不是“最简单的”,这是唯一正确的方法。
  • 次要问题,如果生成器正在为特定构建类型配置特定标志(例如在CMAKE_CXX_FLAGS_DEBUG 等中),则将其包含在CXXFLAGS 中(从而将其注入CMAKE_CXX_FLAGS ) 实际上不足以将选项传递给编译器。每个构建类型的配置优先于用户输入。
  • 但是您如何清除 CMake 缓存?如果您正在构建像 _build 这样的子目录,请擦除并重新创建它。
【解决方案3】:

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

根据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)
  • 使用“现代Cmake”语法有同样的想法吗?
【解决方案4】:

在 Unix 系统上,对于几个项目,我将这些行添加到 CMakeLists.txt 中,它编译成功,因为 base (/usr/include) 和 local 包含 (/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

【讨论】:

  • 使用include_directories而不是-I标志不是更好吗?
  • 非常感谢。我将链接器标志放在CMAKE_CXX_FLAGS 中,这导致它们被忽略。现在我根据您的回答将它们放在CMAKE_EXE_LINKER_FLAGS 中,它们工作得很好。
猜你喜欢
  • 2018-02-28
  • 2019-01-07
  • 1970-01-01
  • 2014-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多