0

why is cmake producing a binary with debug_info and not stripped?

here is my CMakeLists.txt

cmake_minimum_required(VERSION 3.22)

# project name
project(c-program)

set(CMAKE_C_COMPILER "/usr/bin/gcc")
set(CMAKE_C_STANDARD "90")
set(CMAKE_C_STANDARD_REQUIRED true)
set(CMAKE_C_FLAGS "-ansi -Wall")
set(CMAKE_C_FLAGS_DEBUG "-g3 -ggdb3")
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")

add_executable(c-program c-program.c)

i build like this from the project root folder

$ cmake -S . -B build/release -DCMAKE_BUILD_TYPE=Release

$ cmake --build build/release

when running

$ file build/release/c-program

i get

build/release/c-program: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, with debug_info, not stripped

i am confused about how debug/release builds are supposed to work, and nothing in the cmake tutorial guides or docs or otherwise online is helping me figure out why this is happening

tbny
  • 11
  • 3
  • 1
    Setting `CMAKE_C_COMPILER` after `project()` does nothing. Use a [toolchain file](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html) to set `*_COMPILER` variables and `*_FLAGS*` variables. – Alex Reinking Feb 22 '22 at 17:35
  • @AlexReinking so apparently in a toolchain file we want to set `CMAKE__FLAGS__INIT` vars i have setup a toolchain file ``` # cmake toolchain file # c flags and flags for debug and release builds set(CMAKE_C_COMPILER "/usr/bin/gcc") set(CMAKE_C_FLAGS_INIT "-ansi -Wall") set(CMAKE_C_FLAGS_DEBUG_INIT "-g3 -ggdb3") set(CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG") ``` but still, -DCMAKE_BUILD-TYPE=Release adds debug_info and does not strip i can't figure this out – tbny Feb 22 '22 at 18:19
  • then in the `CMakeOutput.log` file i can see that the `-ansi and -Wall` flags were added during compilation, but the `CMAKE_C_FLAGS_RELEASE_INIT` flags were not – tbny Feb 22 '22 at 18:50
  • figured it out, it's the linker that is also setting debug_info and not stripping, so adding ` set (CMAKE_C_LINKER_WRAPPER_FLAG "-Wl,--strip-debug") set (CMAKE_C_LINKER_WRAPPER_FLAG_SEP ",") ` to the toolchain file fixed that – tbny Feb 22 '22 at 19:20

1 Answers1

1

there are some issues with setting flags in CMakeLists.txt, so adding and using a toolchain file helped, and setting appropriate CMAKE_<LANG>_FLAGS_<CONFIG>_INIT vars in the toolchain file. also, the linker is adding debug info. adding -s flag to cmake release flags, and adding -Wl,--strip-debug to linker flags is what i was looking for

here is my final CMakeLists.txt and toolchain files

#CMakeLists.txt
cmake_minimum_required(VERSION 3.22)

# set toolchain file
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/toolchain.cmake"
    CACHE PATH "Path to the desired toolchain file.")

# project name
project(c-program C)

add_executable(c-program c-program.c)
# toolchain.cmake
# CMake toolchain file

# c compiler and standard
set(CMAKE_C_COMPILER "/usr/bin/gcc")
set(CMAKE_C_STANDARD "90")
set(CMAKE_C_STANDARD_REQUIRED YES)

# linker flags
set(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,--strip-debug")

# cflags
set(CMAKE_C_FLAGS_INIT "-ansi -Wall")

# cflags for debug build
set(CMAKE_C_FLAGS_DEBUG_INIT "-g3 -ggdb3")

# cflags for release build
set(CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG -s")
Alex Reinking
  • 16,724
  • 5
  • 52
  • 86
tbny
  • 11
  • 3
  • No! Do not use the `_LINKER_WRAPPER_FLAG` variables this way. The [documentation](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.html) is _super_ clear about their purpose. This will break the `target_link_options` command. If you want to add linker flags globally, set `CMAKE_EXE_LINKER_FLAGS_INIT` in the toolchain file. – Alex Reinking Feb 22 '22 at 22:02
  • I've fixed your answer to what you should actually use... – Alex Reinking Feb 22 '22 at 22:06