什么是编译器工具链?

What is a compiler toolchain?

从最新的CS:GO update, a valve dev commented this on the reddit post开始:

We are upgrading the compiler toolchain we use to build CS:GO. This pre-release branch has CS:GO built with the new toolchain. We are releasing it as a pre-release branch to allow for testing ahead of it being used in the next update.

There are no functional changes expected, though the new compiler toolchain may yield a small performance boost.

谁能解释一下什么是编译器工具链?

工具链是用于创建编程产品(runnable/executable 程序等)的一组工具(工具链)。

通常工具链在嵌入式世界中用于交叉编译,这意味着在主机上创建一个程序,最终 运行 在不同类型的目标上 - 因此需要创建它特定的编译器、链接器、调试器等

为了从头开始为目标创建编译器,您需要使用特定工具链交叉编译它 - 即编译器工具链。 因此,通过使用编译器工具链,您将能够为您的目标系统创建一个编译器。

编译器工具链是一组工具、支持库和头文件,可帮助构建从源代码到可执行文件的程序,该程序可以在机器上 运行。要查看在编译过程中调用了哪些不同的工具,请传递“-v”标志。例如,gcc -v hello.c 将打印以下内容(注意注释 # 是我的):

$ /usr/local/Cellar/gcc/11.2.0/bin/gcc-11 -v hello.c

# Configuration options which were used to build gcc itself.
Using built-in specs.
COLLECT_GCC=/usr/local/Cellar/gcc/11.2.0/bin/gcc-11
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/11.2.0/libexec/gcc/x86_64-apple-darwin20/11.2.0/lto-wrapper
Target: x86_64-apple-darwin20
Configured with: ../configure --prefix=/usr/local/Cellar/gcc/11.2.0 --libdir=/usr/local/Cellar/gcc/11.2.0/lib/gcc/11 --disable-nls --enable-checking=release --enable-languages=c,c++,objc,obj-c++,fortran,d --program-suffix=-11 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-zstd=/usr/local/opt/zstd --with-pkgversion='Homebrew GCC 11.2.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --enable-libphobos --build=x86_64-apple-darwin20 --with-system-zlib --disable-multilib --without-build-config --with-native-system-header-dir=/usr/include --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.2.0 (Homebrew GCC 11.2.0) 
COLLECT_GCC_OPTIONS='-v' '-mmacosx-version-min=11.5.0' '-asm_macosx_version_min=11.5' '-mtune=core2' '-dumpdir' 'a-'

# Compiler invocation of cc1
 /usr/local/Cellar/gcc/11.2.0/libexec/gcc/x86_64-apple-darwin20/11.2.0/cc1 -quiet -v -D__DYNAMIC__ hello.c -fPIC -quiet -dumpdir a- -dumpbase hello.c -dumpbase-ext .c -mmacosx-version-min=11.5.0 -mtune=core2 -version -o /var/folders/1n/lll3n8mj6wj975zjw804hg300000gq/T//ccfvEkdl.s
GNU C17 (Homebrew GCC 11.2.0) version 11.2.0 (x86_64-apple-darwin20)
    compiled by GNU C version 11.2.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include"
ignoring nonexistent directory "/usr/local/Cellar/gcc/11.2.0/lib/gcc/11/gcc/x86_64-apple-darwin20/11.2.0/../../../../../../x86_64-apple-darwin20/include"
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/Cellar/gcc/11.2.0/lib/gcc/11/gcc/x86_64-apple-darwin20/11.2.0/include
 /usr/local/Cellar/gcc/11.2.0/lib/gcc/11/gcc/x86_64-apple-darwin20/11.2.0/include-fixed
 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks
End of search list.
GNU C17 (Homebrew GCC 11.2.0) version 11.2.0 (x86_64-apple-darwin20)
    compiled by GNU C version 11.2.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: d0f2649375ab2f2193374e77e0a72e7c
COLLECT_GCC_OPTIONS='-v' '-mmacosx-version-min=11.5.0'  '-mtune=core2' '-dumpdir' 'a-'

# Assembler invocation
 as -arch x86_64 -v -force_cpusubtype_ALL -mmacosx-version-min=11.5 -o /var/folders/1n/lll3n8mj6wj975zjw804hg300000gq/T//cc2nzxXo.o /var/folders/1n/lll3n8mj6wj975zjw804hg300000gq/T//ccfvEkdl.s
Apple clang version 12.0.5 (clang-1205.0.22.9)
Target: x86_64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1as -triple x86_64-apple-macosx11.5.0 -filetype obj -main-file-name ccfvEkdl.s -target-cpu penryn -fdebug-compilation-dir /Users/Coolest -dwarf-debug-producer "Apple clang version 12.0.5 (clang-1205.0.22.9)" -dwarf-version=4 -mrelocation-model pic -mllvm -disable-aligned-alloc-awareness=1 -o /var/folders/1n/lll3n8mj6wj975zjw804hg300000gq/T//cc2nzxXo.o /var/folders/1n/lll3n8mj6wj975zjw804hg300000gq/T//ccfvEkdl.s
COMPILER_PATH=/usr/local/Cellar/gcc/11.2.0/libexec/gcc/x86_64-apple-darwin20/11.2.0/:/usr/local/Cellar/gcc/11.2.0/libexec/gcc/x86_64-apple-darwin20/11.2.0/:/usr/local/Cellar/gcc/11.2.0/libexec/gcc/x86_64-apple-darwin20/:/usr/local/Cellar/gcc/11.2.0/lib/gcc/11/gcc/x86_64-apple-darwin20/11.2.0/:/usr/local/Cellar/gcc/11.2.0/lib/gcc/11/gcc/x86_64-apple-darwin20/
LIBRARY_PATH=/usr/local/Cellar/gcc/11.2.0/lib/gcc/11/gcc/x86_64-apple-darwin20/11.2.0/:/usr/local/Cellar/gcc/11.2.0/lib/gcc/11/gcc/x86_64-apple-darwin20/11.2.0/../../../
COLLECT_GCC_OPTIONS='-v' '-mmacosx-version-min=11.5.0'  '-mtune=core2' '-dumpdir' 'a.'
 /usr/local/Cellar/gcc/11.2.0/libexec/gcc/x86_64-apple-darwin20/11.2.0/collect2 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/ -dynamic -arch x86_64 -macosx_version_min 11.5.0 -weak_reference_mismatches non-weak -o a.out -L/usr/local/Cellar/gcc/11.2.0/lib/gcc/11/gcc/x86_64-apple-darwin20/11.2.0 -L/usr/local/Cellar/gcc/11.2.0/lib/gcc/11/gcc/x86_64-apple-darwin20/11.2.0/../../.. /var/folders/1n/lll3n8mj6wj975zjw804hg300000gq/T//cc2nzxXo.o -lSystem -lgcc_ext.10.5 -lgcc -lSystem -no_compact_unwind -v
collect2 version 11.2.0

# linker invocation
/usr/bin/ld -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/ -dynamic -arch x86_64 -macosx_version_min 11.5.0 -weak_reference_mismatches non-weak -o a.out -L/usr/local/Cellar/gcc/11.2.0/lib/gcc/11/gcc/x86_64-apple-darwin20/11.2.0 -L/usr/local/Cellar/gcc/11.2.0/lib/gcc/11/gcc/x86_64-apple-darwin20/11.2.0/../../.. /var/folders/1n/lll3n8mj6wj975zjw804hg300000gq/T//cc2nzxXo.o -lSystem -lgcc_ext.10.5 -lgcc -lSystem -no_compact_unwind -v
@(#)PROGRAM:ld  PROJECT:ld64-650.9
BUILD 00:19:30 Mar 17 2021
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
Library search paths:
    /usr/local/Cellar/gcc/11.2.0/lib/gcc/11/gcc/x86_64-apple-darwin20/11.2.0
    /usr/local/Cellar/gcc/11.2.0/lib/gcc/11
    /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
Framework search paths:
    /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/

请注意,编译器工具链是构建可执行文件所必需的,但这还不够。工具链中缺少构建可执行程序所需的“一切”是“sysroot”。

通常,当我们为同一台机器编译程序时,编译器会使用“/usr/include”中可用的标准头文件和“/usr/lib”中的库。这些路径在编译器本身中是硬编码的,所以我们永远不必考虑它。但是,在构建自定义编译器或交叉编译程序时,我们必须通过传递标志来告诉编译器 sysroot 在哪里,例如

gcc --sysroot="/path/to/arm64/sysroot/usr" hello.c

大多数预打包的交叉编译器都带有一个 script/binary,其中嵌入了一个“sysroot”路径。例如,aarch64-linux-gnu-gcc (https://packages.ubuntu.com/xenial/devel/gcc-aarch64-linux-gnu).