【问题标题】:how to generate pdb files for Release build with cmake flags?如何使用 cmake 标志为 Release 构建生成 pdb 文件?
【发布时间】:2015-03-26 13:39:56
【问题描述】:

我正在使用 cmake 生成视觉工作室解决方案。现在我想为发布版本生成 pdb 文件。 (为什么?因为我想有符号以防用户发现一些错误)

我尝试设置以下标志但没有成功:

set(CMAKE_CONFIGURATION_TYPES ${CMAKE_BUILD_TYPE} CACHE STRING "Build Types" FORCE)

IF(WIN32)

set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/Release")
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "/debug /INCREMENTAL")
set( CMAKE_SHARED_LINKER_FLAGS_RELEASE "/debug /INCREMENTAL")
set( CMAKE_MODULE_LINKER_FLAGS_RELEASE "/debug /INCREMENTAL")
set( CMAKE_CXX_FLAGS_RELEASE "/MD /Zi /O2 /Ob1 /D NDEBUG")
set( CMAKE_C_FLAGS_RELEASE "/MD /Zi /O2 /Ob1 /D NDEBUG")
ENDIF(WIN32)

看起来 Cmake 忽略了这些集合: 提前感谢您的帮助!

【问题讨论】:

  • 您能否详细说明 - 没有成功?您是否收到错误、缺少结果或只是不起作用?
  • 只是不起作用。我想知道 "set(CMAKE_CONFIGURATION_TYPES ${CMAKE_BUILD_TYPE} CACHE STRING "Build Types" FORCE)" 行是否覆盖了标志
  • 除了add_executable(out a.cpp b.cpp) 之外,我还尝试了这个,当我构建发布配置时,还有一个 .pdb 文件。它是可调试的。你能发布更多细节吗?顺便说一句,为 MSVC 生成时不要使用CMAKE_BUILD_TYPE

标签: visual-studio visual-studio-2012 cmake pdb-files


【解决方案1】:

我使用了标志

set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")

This site解释详情

【讨论】:

【解决方案2】:

另一种方法是使用cmake生成器表达式(https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html),例如:

对于所有目标和所有配置:

add_compile_options("$<$<NOT:$<CONFIG:Debug>>:/Zi>")
add_link_options("$<$<NOT:$<CONFIG:Debug>>:/DEBUG>")
add_link_options("$<$<NOT:$<CONFIG:Debug>>:/OPT:REF>")
add_link_options("$<$<NOT:$<CONFIG:Debug>>:/OPT:ICF>")

仅针对特定目标和Release 配置:

target_compile_options(my_exe PRIVATE "$<$<CONFIG:Release>:/Zi>")
target_link_options(my_exe PRIVATE "$<$<CONFIG:Release>:/DEBUG>")
target_link_options(my_exe PRIVATE "$<$<CONFIG:Release>:/OPT:REF>")
target_link_options(my_exe PRIVATE "$<$<CONFIG:Release>:/OPT:ICF>")

【讨论】:

  • 另外,add_link_options 和 add_compile_options 对我有用,而扩展 CMAKE_* 变量(如 2015 年的回复)对我不起作用。
【解决方案3】:

在“Modern Cmake”中,您可以为每个目标设置这个,这是要走的路:

if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" AND CMAKE_BUILD_TYPE MATCHES "Release")
   target_compile_options(${TARGET_NAME} PRIVATE /Zi)

   # Tell linker to include symbol data
    set_target_properties(${TARGET_NAME} PROPERTIES 
        LINK_FLAGS "/INCREMENTAL:NO /DEBUG /OPT:REF /OPT:ICF"
    )

    # Set file name & location
    set_target_properties(${TARGET_NAME} PROPERTIES 
        COMPILE_PDB_NAME ${TARGET_NAME} 
        COMPILE_PDB_OUTPUT_DIR ${CMAKE_BINARY_DIR}
    )
endif()

这些标志是 MSVC 特定的,而不是 WIN32

【讨论】:

  • 好吧,在现代 CMake 中,您应该使用生成器表达式,因为在配置步骤期间,MSVC 未定义 CMAKE_BUILD_TYPE 的值。请参阅stackoverflow.com/questions/24460486/… 中接受的答案
  • 但正如答案所说,使用'-DCMAKE_BUILD_TYPE=Debug',它是在配置时定义的,对吧?然后你可以使用‘if (CMAKE_BUILD_TYPE STREQUAL Release)’。我们一直这样做
  • 好吧,问题是您可以在配置时传递-DCMAKE_BUILD_TYPE=Debug,然后在 Visual Studio 中将项目构建为 Release(生成时)。因此在配置时间依赖CMAKE_BUILD_TYPE 配置多配置IDE(包括VS)是不可靠的。例如。在您的代码案例中,您可以做相反的事情,将CMAKE_BUILD_TYPE 传递为Release,然后通过IDE 将项目构建为Debug,您很可能会得到重复的"/INCREMENTAL:NO /DEBUG /OPT:REF /OPT:ICF" 标志。我同意,在这种情况下这可能无害,但可能会破坏其他人的构建。
  • 重读我的评论后,我想我可能没有表达这一点,那就是:你根本不应该为 Visual Studio 传递CMAKE_BUILD_TYPE,因为它没有被它使用。引用文档:“此变量仅对单一配置生成器有意义”。 cmake.org/cmake/help/v3.15/variable/CMAKE_BUILD_TYPE.html 每当您在代码中使用它时,您都应该将其视为与任何其他用户定义的变量没有区别,例如MY_BUILD_TYPE 变量。如果没有生成器表达式,您的方法只是“现代 CMake”的一半。
  • -1 表示CMAKE_BUILD_TYPE 问题。在没有明确检查活动生成器是否为单一配置的情况下读取该变量是永远无效的。
猜你喜欢
  • 2021-12-03
  • 2013-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-13
  • 2021-10-24
  • 1970-01-01
相关资源
最近更新 更多