CMake 保存剥离的调试信息

CMake save stripped debug information

通常的做法是使用调试符号进行编译,然后使用 objcopy 将二进制文件分成发布可执行文件和带有调试信息的文件(然后将其包装到单独的包中或存储在符号服务器上)。

如何在CMake中正确分隔调试符号?我只看到了一些讨论和不完整的代码示例。

平台是 Linux 和 GCC。

CMake 对此没有直接支持,但您可以使用一些 POST_BUILD 和 INSTALL 步骤来实现您想要的结果。但是,值得注意的是,使用 objcopy 并不是执行此类操作的唯一方法。您还可以使用 build-id,这可能更容易通过 CMake 稳健地实现。

GDB 文档中有一个 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,而不是在这里重复整个事情,它应该填补关于这两种方法(调试 link 与构建 ID)的任何剩余空白。这是 Michael 的一般构建 ID 方法(构建 ID 在他的示例中明确给出,请阅读参考文章以了解其预期代表的含义):

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.

以上利用了这样一个事实,即 .debug 文件应该是一个正常的可执行文件,没有删除调试信息。