gcc如何查找as、ld和其他binutils可执行文件?

gcc如何查找as、ld和其他binutils可执行文件?,gcc,binutils,Gcc,Binutils,它们的位置是硬编码到gcc代码中的,还是gcc只是将作为调用,并且我们必须在PATH变量中包含作为位置 在后一种情况下,我们如何创建两个完全独立的gcc工具链?我的意思是,如果as-A和as-B都被称为as,那么我们如何使gcc-A调用as-A和as-B呢?一些路径(例如,到cc1的路径)都是编译的。其他(例如,as)使用$PATH中的正常查找。这取决于GCC配置的选项 通过使用strace运行并搜索exec | stat,您可以很容易地判断 $ strace -f gcc foo.c -o f

它们的位置是硬编码到gcc代码中的,还是gcc只是将
作为
调用,并且我们必须在PATH变量中包含
作为
位置

在后一种情况下,我们如何创建两个完全独立的gcc工具链?我的意思是,如果
as-A
as-B
都被称为
as
,那么我们如何使
gcc-A
调用
as-A
as-B
呢?

一些路径(例如,到
cc1
的路径)都是编译的。其他(例如,
as
)使用$PATH中的正常查找。这取决于GCC配置的选项

通过使用
strace
运行并搜索
exec | stat
,您可以很容易地判断

$ strace -f gcc foo.c -o foo |& grep exec
⋮
[pid 24943] execve("/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.6.1/cc1", …
正如您从 缺乏对它的寻找。它也不在$PATH中

[pid 24944] execve("/home/anthony/bin/as", ["as", "--64", "-o", "/tmp/ccCIrcGi.o", "/tmp/ccbw3PkL.s"], [/* 51 vars */]) = -1 ENOENT (No such file or directory)
[pid 24944] execve("/usr/local/bin/as", ["as", "--64", "-o", "/tmp/ccCIrcGi.o", "/tmp/ccbw3PkL.s"], [/* 51 vars */]) = -1 ENOENT (No such file or directory)
[pid 24944] execve("/usr/bin/as", ["as", "--64", "-o", "/tmp/ccCIrcGi.o", "/tmp/ccbw3PkL.s"], [/* 51 vars */]) = 0
在$PATH中查找
作为
。你可以分辨出来,因为它尝试了每一种方法 按顺序排列$PATH中的位置

即使只使用stat和exec,我也省略了很多strace输出 几页长


运行
gcc-v
将向您显示一些编译路径(作为配置行的一部分)。

有一个特别选项:-B*前缀*,引用gcc文档:

对于要运行的每个子程序,编译器驱动程序首先尝试-B前缀(如果有)。如果 找不到该名称,或者如果未指定-B,则驱动程序将尝试使用两个标准前缀, 它们是/usr/lib/gcc/和/usr/local/lib/gcc/。[……]


我们如何创建两个完全独立的gcc工具链?

从源代码处编译GCC两次,详细说明如下:

就我所见,一切都是硬编码和高度耦合的,我认为没有任何其他像样的解决方案

查询GCC搜索路径

您还可以使用以下命令查询GCC搜索路径:

gcc -print-search-dirs | grep -E '^programs' | tr ':' '\n'
样本输出:

programs
 =/usr/lib/gcc/x86_64-linux-gnu/6/
/usr/lib/gcc/x86_64-linux-gnu/6/
/usr/lib/gcc/x86_64-linux-gnu/
/usr/lib/gcc/x86_64-linux-gnu/6/
/usr/lib/gcc/x86_64-linux-gnu/
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/6/
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../x86_64-linux-gnu/bin/
/usr/lib/gcc/x86_64-linux-gnu/6/cc1
以及一个具体的计划,包括:

gcc -print-prog-name=cc1
样本输出:

programs
 =/usr/lib/gcc/x86_64-linux-gnu/6/
/usr/lib/gcc/x86_64-linux-gnu/6/
/usr/lib/gcc/x86_64-linux-gnu/
/usr/lib/gcc/x86_64-linux-gnu/6/
/usr/lib/gcc/x86_64-linux-gnu/
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/6/
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../x86_64-linux-gnu/bin/
/usr/lib/gcc/x86_64-linux-gnu/6/cc1
GCC规范文件


值得一提的是,真正决定最终的
cpp
ld
as
是GCC源代码中的“spec”文件,另请参见:

非常感谢。您知道哪些配置选项定义最终行为吗?有没有办法限制gcc只使用/my/path/as和my/path/ld?@MichalisVichos:可能配置标志
——使用as=/my/path/as
就可以做到这一点。显示配置文档可从(当然也可以通过
/configure--help
)获取