我如何影响可执行文件或库的源目录?

How can I influence the the source directory of an executable or library?

我最近在编译以下 C++ 程序时注意到一些奇怪的事情:

int main() { return 0; }

在 linux 上使用 g++。具体来说,我使用以下两个命令编译了程序(位于 /a/directory )两次:

  1. g++ -g -o main main.cc
  2. g++ -g -o /a/directory/main /a/directory/main.cc.

对于我输入的每个程序 gdb main,键入 break main 和 运行 程序。当 gdb 遇到断点时,我得到了以下结果:

  1. 断点 1,main ()main.cc:1
  2. 断点 1,main ()/a/directory/main.cc:1

简单地说,g++在使用调试符号编译时在二进制文件中嵌入了对源目录的引用。更重要的是,这个目录是传递给编译器的(字面的,非规范化的)目录(这通过使用 strings 检查二进制文件来确认)。

显然,cmake 构建 execute g++ 的方式使得目录是绝对的,至少在构建源外时是这样。相反,我遇到了一个 autotools 托管项目,其中源目录是本地目录。

实际上有valid reasons避免使用绝对构建目录,所以我想知道以下内容:

我可以使用某些编译器选项影响放入库/可执行文件的源目录吗?使用 cmake 时如何为整个项目完成此操作(例如设置相对于项目根目录的目录)?

其次,我想知道Linux上是否有关于源目录的约定。理想情况下,可以安装像 gdb 这样的源和工具,通过使用像 $PATH.

这样的东西来获取实际位置

CMake编译时总是使用绝对路径,原因在here.

但是,您可以使用 GCC 选项 -fdebug-prefix-map 来更改嵌入在二进制文件中的调试路径。它的文档位于 here.

我试过这个:

g++ -g -o `pwd`/main `pwd`/main.cc -fdebug-prefix-map=`pwd`=.

gdb 输出为:Breakpoint 1 at 0x1129: file ./main.cc, line 1.

对于整个项目,传递 -fdebug-prefix-map=<absolute path of source root>=<source root relative to build path> 可能会奏效。例如,如果源位于 /a/directory/ 下并且构建目录是 /a/directory/build/ 那么您将传递 -fdebug-prefix-map=/a/directory/=...

编辑: 之前回答过:Make gcc put relative filenames in debug information