27

I am using Scientific Linux (SL). I am trying to compile a project that uses a bunch of C++ (.cpp) files.

In the directory user/project/Build, I enter make to compile and link all the .cpp files. I then have to go to user/run/ and then type ./run.sh values.txt

To debug with GDB, I have to go to user/run and then type gdb ../project/Build/bin/Project and to run, I enter run -Project INPUT/inputfile.txt. However, I am trying to print out the value of variable using p variablename.

However, I get the message s1 = <value optimized out>. I have done some research online, and it seems I need to compile without optimizations using -O0 to resolve this. But where do I enter that? In the CMakeLists? If so, which CMakeLists? The one in project/Build or project/src/project?

2
  • Have you tried simply running cmake again with the build type set to DEBUG? e.g. (from the Build directory) cmake -DCMAKE_BUILD_TYPE=DEBUG .. Feb 28, 2015 at 23:01
  • 1
    Why wasn't this posted on Stack Overflow? Aug 30, 2018 at 13:49

4 Answers 4

18

At invocation time, normally all that you need to make a debug build with CMake is:

cmake -DCMAKE_BUILD_TYPE=Debug ..

Doing that adds the -g flag as can be confirmed with:

make VERBOSE=1

which shows the GCC build commands as explained at: https://stackoverflow.com/questions/5820303/how-do-i-force-make-gcc-to-show-me-the-commands

-O0 is not added by default to the Debug build, but -O0 is the default -O value as mentioned at: https://stackoverflow.com/questions/1778538/how-many-gcc-optimization-levels-are-there and on man gcc, so it normally doesn't matter.

If you would really like to explicitly control the build flags for the debug you can also set them with

cmake -DCMAKE_BUILD_TYPE=Debug
      -DCMAKE_C_FLAGS_DEBUG="-g -O0" \
      -DCMAKE_CXX_FLAGS_DEBUG="-g -O0" \
      ..

The default values of CMAKE_C_FLAGS_DEBUG and CMAKE_CXX_FLAGS_DEBUG can be found as mentioned at: https://stackoverflow.com/questions/16851084/how-to-list-all-cmake-build-options-and-their-default-values with:

cmake -LAH .

which gives:

// Flags used by the CXX compiler during DEBUG builds.                                                   
CMAKE_CXX_FLAGS_DEBUG:STRING=-g                                                                          
                                                                                                                                                                                          
// Flags used by the C compiler during DEBUG builds.                                                     
CMAKE_C_FLAGS_DEBUG:STRING=-g

That command also shows other values of interest which clarify the default behavior across built types:

// Flags used by the CXX compiler during all build types.                               
CMAKE_CXX_FLAGS:STRING=                

// Flags used by the CXX compiler during DEBUG builds.                                       
CMAKE_CXX_FLAGS_DEBUG:STRING=-g             

// Flags used by the CXX compiler during MINSIZEREL builds.                               
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG

// Flags used by the CXX compiler during RELEASE builds.                                         
CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG     

// Flags used by the CXX compiler during RELWITHDEBINFO builds.
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG

If -DCMAKE_BUILD_TYPE=Debug is not passed, CMAKE_BUILD_TYPE is empty, and none of the extra CMAKE_CXX_FLAGS_XXX values are added, so we end with a build without -g.

Tested on Ubuntu 22.10, CMake 3.24.2.

14

Chip's answer was helpful, however since the SET line overwrote CMAKE_CXX_FLAGS_DEBUG this removed the -g default which caused my executable to be built without debug info. I needed to make a small additional modification to CMakeLists.txt in the project source directory to get an executable built with debugging info and -O0 optimizations (on cmake version 2.8.12.2).

I added the following to CMakeLists.txt to add -O0 and leave -g enabled:

# Add -O0 to remove optimizations when using gcc
IF(CMAKE_COMPILER_IS_GNUCC)
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
    set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
ENDIF(CMAKE_COMPILER_IS_GNUCC)

This adds the -O0 optimization to flags already used for debug by CMake and only is included for GCC builds if you happen to be using a cross platform project.

7

Add this to CMakeLists.txt (the one in the project source directory; don't touch anything in the build directory):

SET(CMAKE_CXX_FLAGS_DEBUG "-O0")
SET(CMAKE_C_FLAGS_DEBUG "-O0")

and then

$ cmake -DCMAKE_BUILD_TYPE=Debug

will work. Alternatively just add this to CMakeLists.txt:

SET(CMAKE_CXX_FLAGS "-O0")
SET(CMAKE_C_FLAGS "-O0")
4

I found that in some tests my CMAKE_C_FLAGS contained some optimization option by default (i.e. -O2). In this case, the above suggestions to do something like set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0") resulted in "-O2 -g -O0" which doesn't disable optimization.

Instead, I've had success using a simple regex to replace "-O#" with an empty string before appending "-O0".

My regex could probably use some fine tuning, but so far it seems to work well enough:

option(OPTIMIZE "Allow compiler optimizations.  Set to OFF to disable" ON)

if(NOT OPTIMIZE)
    string(REGEX REPLACE "(\-O[011123456789])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
    string(REGEX REPLACE "(\-O[011123456789])" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
endif()
1
  • 1
    Actually, gcc overrides previously provided flags whenever a new one is found. So, adding -O0 after -O2 disables optimization. Your solution produces a cleaner execution output nonetheless.
    – Cengiz Can
    Jun 17, 2021 at 14:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .