2012-03-07 98 views
11

我正在编译的项目使用CMake,其中loves absolute pathnames让gcc在调试信息中放置相关文件名

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

有没有一些选择可以告诉gcc在发出调试数据之前去除部分路径名?或者,也许有一些工具可以在编译的二进制文件上做到这一点?

我试过使用SET(CMAKE_USE_RELATIVE_PATHS ON)(这似乎是devs的frowned upon)选项,但由于我使用的是源代码外构建,所以路径名仍不是我希望它们的形式。即他们是./../src/mod_foo/foo.c而不是mod_foo/foo.c

+1

'./../ src/mod_foo/foo.c'是一个**相对**路径... – 2012-03-07 20:14:47

+0

是的,但不是相对于项目根目录*,尽管(它位于'./ ../ src') – drdaeman 2012-03-07 21:28:23

+0

您遇到CMake问题,而不是gcc。 GCC正好把它作为命令行参数放入'.debug_str'中。 – sirgeorge 2012-03-07 22:16:44

回答

5

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

在你最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="@[email protected]" 
PROJECT_SOURCE_DIR="@[email protected]" 

# 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标志的脚本参数。
+0

谢谢你的真棒答案! – drdaeman 2012-03-10 11:35:41

1

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

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

#!/bin/bash 

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

exec gcc "${out[@]}" 

如果您的源目录有子目录,那么你就需要仔细处理这些,但上述应平坦的源目录工作。我还没有测试过,如果我的引用错误,我不会感到惊讶,但是如果你的路径名带有空格,这只会是一个问题。它也不能处理像-I/whatever/include这样的参数,但你可以解决这个问题。

10

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