[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Arch triplet for uefi applications



On Tue, 10 Aug 2021 at 15:19:10 -0700, Josh Triplett wrote:
> Bastien Roucariès wrote:
> > I suppose that [EFI] will be  x86_64-efi-none (or maybe x86_64-windows-efi  )  and 
> > i686-uefi-none ?

It's certainly not x86_64-windows-efi. The EFI environment isn't Windows
(even though it borrows some conventions like FAT, backslashes in paths
and the PE executable format from Windows).

> UEFI is effectively an "operating system", insofar as it provides a
> runtime environment with some baseline properties and a set of system
> calls. uefi definitely isn't a "vendor", and the OS shouldn't be "none"
> since there is an OS of sorts.
> 
> For that reason, Rust uses the target names "aarch64-unknown-uefi",
> "i686-unknown-uefi", and "x86_64-unknown-uefi". Those seem like the
> right names for these targets in other toolchains, as well.

These names used in Rust seem correct to me. The UEFI environment behaves
like a miniature operating system, which runs instead of GNU/Linux during
the first stage of boot, so replacing the linux-gnu part of the tuple with
uefi makes sense.

Note that there are two forms for writing a GNU tuple: with or without
the vendor. The full tuple consists of CPU-VENDOR-OS, where OS sometimes
consists of KERNEL-USERSPACE, or KERNEL-ABI, or KERNEL-USERSPACEABI where
both disambiguators are needed.

Developers who are used to (GNU/)Linux are likely to think the
KERNEL-USERSPACE form is most common, but actually that one is the
exception, and the more usual form has traditionally just had a single
token for OSs where the kernel and user-space are tightly coupled,
such as solaris2, netbsd or freebsd:

                                 |CPU    |vendor |kernel |userspace|ABI
                                 |       |       |       | (libc)  |
    -----------------------------|-------|-------|-------|---------|----
    i386-pc-solaris2             |i386   |PC     |    Solaris 2    |
    x86_64-pc-freebsd            |x86_64 |PC     |    FreeBSD      |
    arm-unknown-netbsd-eabi      |arm    |unknown|    NetBSD       |EABI
    x86_64-unknown-uefi          |x86_64 |unknown|     UEFI        |
    x86_64-pc-linux-gnu          |x86_64 |PC     |Linux  |GNU      |
    x86_64-pc-linux-musl         |x86_64 |PC     |Linux  |musl libc|
    x86_64-pc-linux-gnux32       |x86_64 |PC     |Linux  |GNU      |x32
    aarch64-unknown-linux-gnu    |aarch64|unknown|Linux  |GNU      |
    arm-unknown-linux-gnu        |arm    |unknown|Linux  |GNU      |OABI
    arm-unknown-linux-gnueabi    |arm    |unknown|Linux  |GNU      |EABI
    x86_64-pc-kfreebsd-gnu       |x86_64 |PC     |FreeBSD|GNU      |

In Debian multiarch tuples and GNU-style cross-compilation tool
prefixes, the tuple is written in a shorter form without the vendor as
CPU-OS (where, again, the OS might be KERNEL-USERSPACE or KERNEL-ABI or
KERNEL-USERSPACEABI), because the vendor is not usually significant when
determining whether two binaries share an ABI and can interoperate:

    i386-solaris2
    x86_64-freebsd
    arm-netbsd-eabi
    x86_64-uefi
    x86_64-linux-gnu
    x86_64-linux-musl
    x86_64-linux-gnux32
    aarch64-linux-gnu
    arm-linux-gnu
    arm-linux-gnueabi
    x86_64-kfreebsd-gnu

(For instance we have x86_64-linux-gnu-gcc and /usr/lib/x86_64-linux-gnu.)

I prefer to call these strings tuples rather than triplets, because
calling them triplets can be misleading. The "target triplet" in Autoconf
specifically refers to the CPU-VENDOR-OS arrangment - remember that GNU
started by building Free Software tools to run on top of other (often
proprietary) operating systems, where the ABI was externally imposed by
the OS vendor, so initially it wouldn't have made sense to talk about the
kernel and user-space separately. The Linux, kFreeBSD and Hurd kernels
and the possibility of running a complete GNU operating system only came
later. So "triplet" refers to the three parts of a full tuple with the
vendor, broken up like this:

    <--1-->    <--2-->  <--3-->
    i386-      pc-      solaris2
    x86_64-    pc-      linux-gnu

"Triplet" does not refer to the three parts of an abbreviated
GNU/Linux-style tuple written without the vendor, even though this decade
that's the one we see most often:

    # NOT THIS
    x86_64-    linux-   gnu

because not all operating systems' short-form tuples break down into
three parts like that (as you can see from the Solaris, FreeBSD, NetBSD
examples above).

Traditional cross-compilation (cross-libraries in subdirectories of /usr,
such as /usr/i386-solaris2 or /usr/arm-unknown-netbsd-eabi) might write the
tuple with or without the vendor. In Debian, we use the tuple without the
vendor included for multilib (e.g. /usr/i686-linux-gnu in libc6-i386-cross),
but we use the tuple *with* the vendor included for mingw-w64
(/usr/i686-w64-mingw32, /usr/x86_64-w64-mingw32).

    smcv


Reply to: