Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake save stripped debug information

It's a usual practice to compile with debug symbols and then separate the binary using objcopy into the release executable and the file with debug information (then wrap that into separate packages or store on the symbol server).

How to separate debug symbols properly in CMake? I've seen just some discussions and incomplete code samples.

Platform is Linux and GCC.

like image 349
Velkan Avatar asked Sep 30 '15 08:09

Velkan


1 Answers

CMake doesn't have direct support for this, but you can use some POST_BUILD and INSTALL steps to achieve the result you want. It is, however, worth noting that using objcopy isn't the only way to do this sort of thing. You can also make use of the build-id and this may well be easier to implement robustly with CMake.

Rather than repeat the whole thing here, there's a pretty good description of your choices and the methods that was posted to the CMake mailing list few years ago by Michael Hertling. I'll just pick out the working alternative here for reference, but I recommend reading that link. There's also an even more complete discussion of the two alternatives in the GDB documentation which should fill in any remaining blanks about the two approaches (debug link versus build-id). Here's Michael's general build-id approach (the build-id is explicitly given in his example, read the referenced articles for an explanation of what it is expected to represent):

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(BUILDID C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
SET(BUILDID "abcdef1234")
STRING(SUBSTRING "${BUILDID}" 0 2 BUILDIDPREFIX)
STRING(SUBSTRING "${BUILDID}" 2 8 BUILDIDSUFFIX)
FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "int main(void){return 0;}\n")
ADD_EXECUTABLE(main main.c)
SET_TARGET_PROPERTIES(main PROPERTIES
    LINK_FLAGS "-Wl,--build-id=0x${BUILDID}")
ADD_CUSTOM_COMMAND(TARGET main POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:main>
                                     ${CMAKE_BINARY_DIR}/main.debug
    COMMAND ${CMAKE_STRIP} -g $<TARGET_FILE:main>)
INSTALL(FILES ${CMAKE_BINARY_DIR}/main.debug
    DESTINATION ${CMAKE_BINARY_DIR}/.build-id/${BUILDIDPREFIX}
    RENAME ${BUILDIDSUFFIX}.debug)

Configure with CMAKE_BUILD_TYPE==debug and build; subsequently, invoke

gdb -ex "set debug-file-directory ." -ex "file main"

from within CMAKE_BINARY_DIR, and you will read "no debugging symbols found" as expected. Now, issue "make install", re-invoke gdb and read:

"Reading symbols from .../.build-id/ab/cdef1234.debug"

As you can see, the debug info file is connected with the stripped executable solely by the build ID; no objcopy in sight.

The above makes use of the fact that the .debug file is expected to be a normal executable with debug info not stripped.

like image 168
Craig Scott Avatar answered Sep 19 '22 12:09

Craig Scott