how to generate pdb files for Release build with cmake flags?
Asked Answered
O

3

21

I am generating a visual studio solution using cmake. And now I want to generate pdb files for a Release build. (Why? because I want to have the symbols in case that the user found some bug)

I tried by setting the following flags without succeed:

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)

It looks like Cmake is ignoring these sets: thanks in advance for the help!

Occupier answered 27/1, 2015 at 20:3 Comment(3)
Can you elaborate on - without succeed? Do you receive an error, missing results or just doesn't work?Bluh
Just doesn't work. I wonder if the line "set(CMAKE_CONFIGURATION_TYPES ${CMAKE_BUILD_TYPE} CACHE STRING "Build Types" FORCE)" is overwriting the flagsOccupier
I tried this in addition to add_executable(out a.cpp b.cpp) and when I built the Release configuration there was also a .pdb file. And it was debuggable. Could you post more details? And btw don't use CMAKE_BUILD_TYPE when generating for MSVCHalloo
E
20

I used the flags

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 explains the details

Estrone answered 7/7, 2015 at 9:36 Comment(7)
CMAKE_SHARED_LINKER_FLAGS_RELEASE is a globally cached variable so I had to add CACHE STRING "" FORCE. Also make sure to use CMAKE_STATIC_LINKER_FLAGS_RELEASE and CMAKE_EXE_LINKER_FLAGS_RELEASE vars as appropriate.Now
There is no CMake documentation available for the variables CMAKE_CXX_FLAGS_RELEASE & CMAKE_SHARED_LINKER_FLAGS_RELEASE. Where did you find them?Transfix
Wow, I didn't know that. Thanks!Transfix
@DrumM, not much of a documentation, but there are cmake.org/cmake/help/latest/variable/… and cmake.org/cmake/help/latest/variable/…Leguminous
The linked article explaining the details moved here: wintellect.com/correctly-creating-native-c-release-build-pdbsMaddie
Above mentioned article's link is now: training.atmosera.com/…Glassful
At the second line, I used CMAKE_EXE_LINKER_FLAGS_RELEASE (instead of CMAKE_SHARED_LINKER_FLAGS_RELEASE) to have pdb file for the exe (instead of shared libs).Glassful
L
10

Another way to do it is to use cmake generator expressions (https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html), e.g.:

for all targets and all configurations:

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

for particular target and Release configuration only:

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>")
Leguminous answered 13/10, 2020 at 10:54 Comment(2)
Also, add_link_options and add_compile_options worked for me while extending the CMAKE_* variables (like in the reply from 2015) didn't work for me.Fourscore
You don't need to copy-paste the lines though, multiple options can be passed to the compiler with generator expressions too. IIRC with ; separating them and quotes around the whole thing.Polarity
T
0

In 'Modern Cmake' you can set this per target, this is the way to go:

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

These flags are MSVC specific not WIN32.

Transfix answered 13/8, 2019 at 13:53 Comment(8)
Well, in modern CMake you should use generator expressions, since value of CMAKE_BUILD_TYPE is undefined for MSVC during configuration step. See accepted answer in #24460986Hexahedron
But as the answer says by using ‘-DCMAKE_BUILD_TYPE=Debug’, it is defined at config time, right? Then you can use ‘if (CMAKE_BUILD_TYPE STREQUAL Release)’. We do it all the timeTransfix
Well, the issue is that you can pass -DCMAKE_BUILD_TYPE=Debug in configuration time and then build the project as Release in Visual Studio (generation time). Thus relying on CMAKE_BUILD_TYPE in configuration time for multiple-configuration IDEs (including VS) is not reliable. E.g. in your code case you can do the opposite, pass CMAKE_BUILD_TYPE as Release and then build project via IDE as Debug and you will most likely get duplicated "/INCREMENTAL:NO /DEBUG /OPT:REF /OPT:ICF" flags. I agree, this may be not harmfull in this case, but can break build in others.Hexahedron
After rereading my comment I think I might have not expressed the point, which is: you should not pass CMAKE_BUILD_TYPE for Visual Studio at all, as it is not used by it. To quote the docs: "This variable is only meaningful to single-configuration generators". cmake.org/cmake/help/v3.15/variable/CMAKE_BUILD_TYPE.html Whenever you use it in your code, you should treat it no different than any other user-defined variable e.g. MY_BUILD_TYPE variable. Without generator expressions your approach is only half-way of being "Modern CMake".Hexahedron
That's true! But who says I want to use Visual Studio :-) The only thing I find strange is that you have to do the same generator expressions for the other calls: set_target_properties and set_target_properties. Like 1 if doesn't sufficeTransfix
This question is tagged visual-studio, so you should assume so in your answer.Hexahedron
-1 for the CMAKE_BUILD_TYPE issue. It is never valid to read that variable without an explicit check that the active generator is single-config.Leund
You're right @AlexReinking, I need an update!Transfix

© 2022 - 2024 — McMap. All rights reserved.