ChatGPT解决这个技术问题 Extra ChatGPT

CMakeLists.txt 中未使用 CMAKE_BUILD_TYPE

我在将默认构建配置设置为 Release 时遇到问题。在我的 CMakeLists.txt 文件中,我在文件顶部设置了 CMAKE_BUILD_TYPE:

#enable Release ALWAYS, configure vars
set(CMAKE_BUILD_TYPE Release)
set(EXECUTABLE_NAME "ParticleSimulator")
set(VERSION_MAJOR 0)
set(VERSION_MINOR 2)

但是在构建我的项目并打开解决方案时,我总是看到调试模式,这与我在 CMakeLists 文件中指定的相反。我究竟做错了什么?

我已经查看了那里的其他一些问题,但我没有看到任何特定于这个问题的内容。

CMakeLists.txt 的要点。

您是否清除了 CMake 缓存? cmake.org/pipermail/cmake/2008-September/023808.html
@usr1234567 是的,我也读过那个文件。我一定是在做一些愚蠢的事情,阻止 CMAKE_BUILD_TYPE 工作......
@usr1234567 仍然没有运气...还尝试了 set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Configuration type" FORCE) ,但没有成功
过去 2 天的第 3 次))set(CMAKE_BUILD_TYPE Release)不是它的工作方式。意外地,这将适用于 Makefile 生成器,对于像 Xcode 和 Visual Studio 这样的 IDE,此行将被忽略,因为 Release/Debug 在内部切换。 Documentation 对此非常清楚。如果您想限制您的构建变体,您需要设置 CMAKE_CONFIGURATION_TYPES
另外:在 this post 中设置 CMAKE_BUILD_TYPE 的默认值。一旦设置给出 make VERBOSE=1 显示发送到编译器的完整命令,可用于验证它是否有效。

P
Peter Mortensen

有两种类型的生成器:单配置和多配置。

单一配置

Make-like 生成器:Unix MakefilesNMake MakefilesMinGW Makefiles、...

您在生成步骤中设置配置类型:

cmake -H. -B_builds/Debug -DCMAKE_BUILD_TYPE=Debug "-GUnix Makefiles"

在这种情况下,构建步骤始终是 Debug:

> cmake --build _builds/Debug
/usr/bin/c++ -g ...
> cmake --build _builds/Debug --config Debug # `--config` ignored
/usr/bin/c++ -g ...
> cmake --build _builds/Debug --config Release # yep, ignored
/usr/bin/c++ -g ...

多配置

IDE 生成器:Visual StudioXcode

CMAKE_BUILD_TYPE 在生成步骤被忽略,两者:

> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Debug "-GVisual Studio 12 2013 Win64"

> cmake -H. -B_builds -DCMAKE_BUILD_TYPE=Release "-GVisual Studio 12 2013 Win64"

将产生相同的效果:

https://i.stack.imgur.com/C0vNC.png

这是因为所有配置都是内部的(即 _builds/msvc-opaque/Release_builds/msvc-opaque/Debug 之类的,无关紧要)。您可以使用 --config 选项进行切换:

> cmake --build _builds --config Release
cl /O2 ...
> cmake --build _builds --config Debug
cl /Od ...

控制 (?)

是的你可以。只需定义 CMAKE_CONFIGURATION_TYPES

# Somewhere in CMakeLists.txt
message("Generated with config types: ${CMAKE_CONFIGURATION_TYPES}")

默认输出:

-- Detecting CXX compiler ABI info - done
Generated with config types: Debug;Release;MinSizeRel;RelWithDebInfo
-- Configuring done

重写它:

> cmake -H. -B_builds -DCMAKE_CONFIGURATION_TYPES="Debug;Release" "-GVisual Studio 12 2013 Win64"
-- Detecting CXX compiler ABI info - done
Generated with config types: Debug;Release
-- Configuring done

https://i.stack.imgur.com/a3yIB.png

您甚至可以定义自己的配置类型:

> cmake -H. -B_builds -DCMAKE_CONFIGURATION_TYPES="Debug;MyRelease" -DCMAKE_CXX_FLAGS_MYRELEASE="/My-Rel-flag" -DCMAKE_EXE_LINKER_FLAGS_MYRELEASE="/My-Linker-flags" "-GVisual Studio 12 2013 Win64"

https://i.stack.imgur.com/y3V0k.png

并构建:

cmake --build _builds --config MyRelease

凌乱 (?)

如果您知道诀窍,则完全不会:) 这是如何在脚本/CI 服务器/文档的构建说明等中构建/测试配置:

> CONFIG=Debug
> cmake -H. -B_builds "-DCMAKE_BUILD_TYPE=${CONFIG}" # Set Debug to Makefile, ignored by IDE
> cmake --build _builds --config "${CONFIG}" # Build Debug in IDE, ignored by Makefile
> (cd _builds && ctest -VV -C "${CONFIG}") # Test Debug in IDE, ignored by Makefile

模式不好

if(CMAKE_BUILD_TYPE STREQUAL Debug) # Burn it with fire!!!
set(CMAKE_BUILD_TYPE MySuperRelease) # Be ready to catch a bug from IDE user...

好一个

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} --my-debug-flags")

效果很好。

target_compile_definitions(MyTarget PUBLIC "$<$<CONFIG:Debug>:MYDEBUG_MACRO>")

谢谢! :) 您为一名程序员节省了一天的时间。

使用 Makefile 为我工作,我很高兴......

引用您可能知道的一本好书的 nice guy(强调我的):

为什么要打扰?在各种系统上编程或使用各种编译器的人非常关心,因为如果他们不这样做,他们将被迫浪费时间寻找和修复晦涩难懂的错误。声称他们不关心可移植性的人通常这样做是因为他们只使用一个单一的系统,并且觉得他们可以承受“语言是我的编译器实现的”的态度。这是一种狭隘和短视的观点。如果您的程序是成功的,它很可能会被移植,因此必须有人找到并修复与实现相关的特性相关的问题。此外,程序通常需要与同一系统的其他编译器一起编译,甚至您喜欢的编译器的未来版本也可能与当前版本不同。在编写程序时,了解和限制实现依赖的影响要比事后试图解开混乱要容易得多。


哇,一旦它在 4 小时内可用,就应该得到一个赏金的答案。谢谢这么深入的回答。
请原谅我的无知...究竟,我们如何将 CMAKE_BUILD_TYPE 设置为 Release CmakeList.txt?我认为它在 Control (?) 部分的某个地方,但我在解析它时遇到了麻烦,因为我太缺乏经验了。另请注意,我们只想设置默认值;用户的罚款从命令行覆盖它。
我找到了答案; -H. 是一个 undocumented feature
我看到你tried to fix the documentation issue。感谢您的尝试。 :) 对于为什么不能记录或删除(如果确实存在风险),仍然没有令人满意的答案。
@Muscampester 仅供参考,最有趣的链接和解释可以在 this page 上找到
佚名

您还可以使用以下代码段:

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
            "Default build type: RelWithDebInfo" FORCE)
endif()

人们,如果您对提交的答案投了反对票,请找几句话来说明您这样做的原因。因为在所有建议的答案中,这个简单的答案是唯一对我有用的。在此之前,我在这里找到了类似的“接受”解决方案:blog.kitware.com/cmake-and-the-default-build-type
不适用于 Visual Studio 生成器
P
Peter Mortensen

出现的一种可能是其中一个子模块在缓存中设置了 CMAKE_BUILD_TYPE 值,即:

SET(CMAKE_BUILD_TYPE Debug CACHE) 

这意味着该值将从该点永久更新到配置运行结束。

跟踪此值已更改的违规位置的一种好方法是使用 CMake's variable_watch。在您的主 CMakelists.txt 文件中,添加以下行

variable_watch(CMAKE_BUILD_TYPE)

这将在每次访问此变量时打印到标准错误。并将其写入日志文件,请执行以下操作:

cmake <your options> 2>variable_watch.log

您可能会看到如下内容:

<...>/CMakeLists.txt:184 (add_library) 处的 CMake 调试日志:使用值为“Debug”的 READ_ACCESS 访问了变量“CMAKE_BUILD_TYPE”。

然后您可能会看到第一次更改 CMAKE_BUILD_TYPE 的点。从这里您将更接近跟踪有问题的 CMake 行。


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅