Target Triplet
目标三元组(Target Triplet)描述了何种平台,何种代码代码运行在该平台上的信息,并且是GNU构建系统中的核心概念。 它们包含三个字段: CPU系列/型号的名称,供应商和操作系统名称。 你可以通过运行以下操作查看当前系统的明确目标三元组:
gcc -dumpmachine
结构
目标三元组具有这种简单的结构:
machine机器-vendor供应商-operatingsystem操作系统
例如,FreeBSD系统可以写为:
x86_64-unknown-freebsd
请注意,对于32位x86系统,供应商字段通常是 “pc”,或者对于其他系统,“unknown” 或 “none”。 到目前为止,我们看到的简单的三字段的目标三元组是明确的,并且易于解析。 但是,由于供应商字段大部分未使用,因此GNU构建系统允许你忽略供应商字段; 生成系统在消除你的目标三重歧义时会自动插入默认的供应商部分。 例如,这允许你键入:
x86_64-freebsd
然后,如果构建系统希望知道明确的目标三元组,则会自动推断出供应商是默认的 ( 未知 )。 请注意,解析目标三元组有点棘手,因为有时操作系统字段可以是两个字段:
x86_64-unknown-linux-gnu
这变得更糟,因为供应商字段可以被排除在外:
x86_64-linux-gnu
这绝对是模棱两可的。 大多数基于autoconf的软件包都附带一个巨大的shell脚本,称为 config.sub,其功能是使用一长串已知的cpu和已知的操作系统来消除目标三元组的歧义。
基本原理
目标三元组旨在是系统明确的平台名称 (嗯,在消除歧义之后)。 它们使构建系统可以准确地了解代码将在哪个系统上运行,并允许自动启用特定于平台的功能。 在任何编译设置中,通常涉及三个平台 (可能是相同的三个):
- 构建平台 : 这是在其上执行编译工具的平台。
- 主机平台 : 这是代码最终将在其上运行的平台。
- 目标平台 : 如果这是编译器,则这是编译器将为其生成代码的平台。
这意味着最多可以使用三个不同目标的编译器 (如果你在平台A上构建GCC,它将在平台B上运行,从而为平台C生成可执行文件)。通过简单地在编译工具上加上目标三元组来解决此问题。 当你构建交叉编译器时,安装的可执行文件将以指定的目标三元组为前缀:
i686-elf-gcc
如果构建系统小心地将所有编译工具与目标前缀前缀,则可以防止使用错误的编译器 (并防止构建计算机中的内容泄漏到目标计算机上)。
操作系统开发的目标三元组
例如,如果你开发自己的操作系统和 修改GCC以添加新的目标三元组,则你的操作系统可能是:
x86_64-myos
但是,在开始时,你只是希望使用非常明了的早期OS开发通用目标:
i686-elf x86_64-elf arm-none-eabi aarch64-none-elf riscv64-none-elf
这些可以用于没有用户空间的独立程序 (引导程序和内核) 的明确目标。