【问题标题】:How can I influence the the source directory of an executable or library?如何影响可执行文件或库的源目录?
【发布时间】:2021-01-04 17:52:01
【问题描述】:

我最近在编译以下 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 构建执行 g++ 的方式是目录是绝对的,至少在构建外源代码时是这样。相反,我遇到了一个autotools 托管项目,其中源目录是本地目录。

其实有valid reasons是为了避免使用绝对构建目录,所以想了解一下:

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

其次,我想知道在 Linux 上是否有关于源目录的约定。理想情况下,可以安装源代码,而gdb 之类的工具将使用$PATH 之类的源代码来获取实际位置。

【问题讨论】:

  • 1.您似乎已经在影响源路径目录。你需要别的方法吗? 2. 所以在makefile 或你的构建工具中使用$PATH
  • 好吧,在cmake 我无法控制编译发生的目录。这就是我问的原因。如果有编译器标志,那么我可以将其添加到CMAKE_CXX_FLAGS
  • 您可以在运行 CMake 时使用-verbose 选项来查看确切发布的编译器命令行,并将这些与其他构建系统中的命令行进行比较。
  • cmake 不使用任何编译器标志,它只是在编译期间使用版本 2。看起来cmake 并没有有意影响源目录。据推测,autotools 使用版本 1。
  • @hfhc2 这可能有点帮助:stackoverflow.com/questions/45083285/…

标签: c++ linux debugging cmake compiler-options


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2011-01-08
    • 2022-08-09
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    相关资源
    最近更新 更多