它们的位置是硬编码到 gcc 代码中还是 gcc 只是调用as
并且我们必须as
在 PATH 变量中有位置?
在后一种情况下,我们如何创建两个完全独立的 gcc 工具链?我的意思是,如果和都被调用,我们如何gcc-A
调用as-A
和gcc-B
调用?as-B
as-A
as-B
as
一些路径(例如 to cc1
)被编译进来。其他的(例如as
)在 $PATH 中使用正常的查找。这可能因 GCC 配置的选项而异。
您可以通过运行 withstrace
和 grepping for 来轻松判断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", …
这是通过编译路径对 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
as
这是在 $PATH中寻找的。您可以判断,因为它按顺序尝试 $PATH 中的每个位置。
我省略了很多 strace 输出——即使只有 stat 和 exec,它也有好几页。
运行gcc -v
将显示一些已编译的路径(作为配置行的一部分)。
我们如何创建两个完全独立的 gcc 工具链?
从源代码编译 GCC 两次,详细说明位于:单个主机上的多个 glibc 库
据我所知,一切都是硬编码和高度耦合的,我认为没有其他像样的解决方案。
查询 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/
和一个特定的程序:
gcc -print-prog-name=cc1
样本输出:
/usr/lib/gcc/x86_64-linux-gnu/6/cc1
GCC 规范文件
值得一提的是,实际上决定最终cpp
的 ,是 GCC 源代码ld
中as
的“规范”文件,另请参阅:什么是 GCC 的传递和调用程序?
有一个临时选项:-B*prefix*,引用 gcc 文档:
对于每个要运行的子程序,编译器驱动程序首先尝试 -B 前缀(如果有)。如果未找到该名称,或者未指定 -B,则驱动程序会尝试两个标准前缀,即 /usr/lib/gcc/ 和 /usr/local/lib/gcc/。[...]