【问题标题】:Make gcc put relative filenames in debug information使 gcc 将相关文件名放入调试信息中
【发布时间】:2012-03-25 07:34:58
【问题描述】:

我正在编译的项目使用 CMake,loves absolute pathnames

当我在启用调试信息的情况下进行编译时,gcc 会将这些长名称放入 .debug_str 部分,这不利于调试。我想在那里有简短的相对于项目根路径名。

是否有一些选项可以告诉 gcc 在发出调试数据之前去除路径名的某些部分?或者,也许有一些工具可以对已编译的二进制文件执行此操作?

我试过使用SET(CMAKE_USE_RELATIVE_PATHS ON)(这似乎是开发人员的frowned upon)选项,但由于我使用的是源外构建,路径名仍然不是我想要的形式是。 IE。他们是./../src/mod_foo/foo.c 而不是mod_foo/foo.c

【问题讨论】:

  • ./../src/mod_foo/foo.c 是一个相对路径...
  • 是的,但与 项目根目录 无关(位于 ./../src
  • 您的 CMake 有问题,而不是 gcc。 GCC 将其作为命令行参数放入 .debug_str
  • 我并不真正关心方法。我看到了三种理论上可行的方法,其中任何一种对我来说都很好: 1)使 CMake 将目录更改为项目根目录并传递 gcc 相对于项目根目录的源文件名; 2) 改变这个 GCC 行为,所以它会在写入之前破坏文件名; 3)用一些工具修补编译的二进制文件,以修复文件名。问题是,我不知道该怎么做。

标签: debugging gcc cmake debug-symbols


【解决方案1】:

您可以使用 -fdebug-prefix-map 标志重新映射调试信息路径。例如,要使路径相对于构建位置,请使用:-fdebug-prefix-map=/full/build/path=.

【讨论】:

  • 这应该是公认的答案。它比 sakra 的答案要简单得多。另外值得注意的是-ffile-prefix-map 标志,因为-fdebug-prefix-map 不会影响诸如__FILE__ 宏之类的东西。
【解决方案2】:

您可以设置 CMake 目标的 RULE_LAUNCH_COMPILE 属性,让 CMake 调用一个 shell 脚本,该脚本在调用 gcc 之前将源文件路径转换为项目相对路径。使用 CMake 函数 configure_file 生成一个 shell 脚本,该脚本知道您项目的 PROJECT_SOURCE_DIRPROJECT_BINARY_DIR

在你最外层的CMakeLists.txt添加以下代码:

configure_file(
    "${PROJECT_SOURCE_DIR}/gcc_debug_fix.sh.in"
    "${PROJECT_BINARY_DIR}/gcc_debug_fix.sh"
    @ONLY)

add_executable (MyExecutable ...)

set_target_properties(MyExecutable PROPERTIES 
    RULE_LAUNCH_COMPILE "${PROJECT_BINARY_DIR}/gcc_debug_fix.sh")

以下模板shell脚本gcc_debug_fix.sh.in需要到CMake项目的根目录下:

#!/bin/sh

PROJECT_BINARY_DIR="@PROJECT_BINARY_DIR@"
PROJECT_SOURCE_DIR="@PROJECT_SOURCE_DIR@"

# shell script invoked with the following arguments
# $(CXX) $(CXX_DEFINES) $(CXX_FLAGS) -o OBJECT_FILE -c SOURCE_FILE

# extract parameters
SOURCE_FILE="${@: -1:1}"
OBJECT_FILE="${@: -3:1}"
COMPILER_AND_FLAGS=${@:1:$#-4}

# make source file path relative to project source dir
SOURCE_FILE_RELATIVE="${SOURCE_FILE:${#PROJECT_SOURCE_DIR} + 1}"

# make object file path absolute
OBJECT_FILE_ABSOLUTE="$PROJECT_BINARY_DIR/$OBJECT_FILE"

cd "$PROJECT_SOURCE_DIR"

# invoke compiler
exec $COMPILER_AND_FLAGS -c "${SOURCE_FILE_RELATIVE}" -o "${OBJECT_FILE_ABSOLUTE}"

shell 脚本使用来自变量PROJECT_BINARY_DIRPROJECT_SOURCE_DIR 的信息将源文件的路径转换为相对于项目根目录的路径,并将目标文件的路径转换为绝对路径。因为 gcc 现在通过了项目相对路径,.debug_str 也应该使用该路径。

以下注意事项适用:

  • 一定要设置gcc_debug_fix.sh.in的可执行位。
  • 要使脚本正常工作,CMAKE_USE_RELATIVE_PATHS 必须再次设置为 OFF
  • 脚本对命令行上文件路径的位置做出假设。如果 CMake 使用不同的规则来调用编译器,这可能不起作用。更强大的解决方案是扫描脚本参数以查找 -o-c 标志。

【讨论】:

  • 感谢您的精彩回答!
【解决方案3】:

如果我真的无法修复 make 文件/工具以正确执行此操作,我将为 gcc 编写一个包装脚本,该脚本可识别绝对路径名并将其转换为相对路径名。

在 bash 中可能看起来像这样:

#!/bin/bash

out=()
for arg; do
  out=("${out[@]}" $(echo "$arg" | sed 's:/my/absolute/directory/:../:'))
done

exec gcc "${out[@]}"

如果您的源目录有子目录,那么您需要小心处理这些子目录,但以上内容应该适用于平面源目录。不过我还没有测试过,如果引用错误,我不会感到惊讶,但是如果你的路径名中有空格,那只会是个问题。它也不处理像 @987654322 这样的参数@,但你可以解决这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-30
    • 2023-03-06
    • 1970-01-01
    • 2010-11-19
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多