diff --git a/part3intro/toolchaintechnotes.xml b/part3intro/toolchaintechnotes.xml index 1dad94103..616af0bd9 100644 --- a/part3intro/toolchaintechnotes.xml +++ b/part3intro/toolchaintechnotes.xml @@ -3,6 +3,9 @@ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ %general-entities; + + <the host triplet>"> ]> @@ -44,6 +47,14 @@ book for a cross-toolchain for some purpose other than building LFS, unless you really understand what you are doing. + + + It's known installing GCC pass 2 will break the cross-toolchain. + We don't consider it a bug because GCC pass 2 is the last package + to be cross-compiled in the book, and we won't fix + it until we really need to cross-compile some package after GCC + pass 2 in the future. + Cross-compilation involves some concepts that deserve a section of @@ -197,14 +208,104 @@ page. - In order to fake a cross-compilation in LFS, the name of the host triplet - is slightly adjusted by changing the "vendor" field in the - LFS_TGT variable so it says "lfs". We also use the - --with-sysroot option when building the cross-linker and - cross-compiler, to tell them where to find the needed host files. This - ensures that none of the other programs built in can link to libraries on the build - machine. Only two stages are mandatory, plus one more for tests. + + There are two key points for a cross-compilation: + + + + + + When producing and processing the machine code supposed to be + executed on the host, the cross-toolchain must be + used. Note that the native toolchain from the build + may be still invoked to generate machine code supposed to be + executed on the build. For example, the build system + may compile a generator with the native toolchain, then generate + a C source file with the generator, and finally compile the C + source file with the cross-toolchain so the generated code will + be able to run on the host. + + + With an autoconf-based build system, this requirement is ensured + by using the --host switch to specify + the host triplet. With this switch the build + system will use the toolchain components prefixed + with &host-triplet; + for generating and processing the machine code for + the host; e.g. the compiler will be + &host-triplet;-gcc and the + readelf tool will be + &host-triplet;-readelf. + + + + + The build system should not attempt to run any generated machine + code supposed to be executed on the host. For + example, when building an utility natively, its man page can be + generated by running the utility with the + --help switch and processing the output, + but generally it's not possible to do so as the utility may fail + to run on the build: it's obviously impossible to + run ARM64 machine code on a x86 CPU (without an emulator). + + + With an autoconf-based build system, this requirement is + satisfied in the cross-compilation mode where + the optional features requiring to run machine code for + the host are disabled. When the + host triplet is explicitly specified, the + cross-compilation mode is enabled if and only if either + the configure script fails to run a dummy + program compiled into the host machine code, or + the build triplet is explicitly specified via the + --build switch and it's different from + the host triplet. + + + + + In order to cross-compile a package for the LFS temporary system, + the name of the system triplet is slightly adjusted by changing the + "vendor" field in the LFS_TGT variable so it + says "lfs" and LFS_TGT is then specified as + the host triplet via --host, so + the cross-toolchain will be used for generating and processing the + machine code running as a part of the LFS temporary system. And, we + also need to enable the cross-compilation mode: despite + the host machine code, i.e. the machine code for the LFS + temporary system, is able to execute on the current CPU, it may refer + to a library not available on the the build (the host + distro), or some code or data non-exist or defined differently in the + library even if it happens to be available. When cross-compiling a + package for the LFS temporary system, we cannot rely on the + configure script to detect this issue with the + dummy program: the dummy only uses a few components in + libc that the host distro + libc likely provides (unless, + maybe the host distro uses a different + libc implementaion like Musl), + so it won't fail like how the really useful programs would likely. + Thus we must explicitly specify the build triplet to + enable the cross-compilation mode. The value we use is + just the default, i.e. the original system triplet from + config.guess output, but the cross-compilation + mode depends on an explicit specification as we've + discussed. + + We use the --with-sysroot option when + building the cross-linker and cross-compiler, to tell them where to find + the needed files for the host. This nearly ensures that + none of the other programs built in + can link to libraries on + the build. The word nearly is used because + libtool, a compatibility wrapper of + the compiler and the linker for autoconf-based build systems, + can try to be too clever and mistakenly pass options allowing the linker + to find libraries of the host. + To prevent this fallout, we need to delete the libtool archive + (.la) files and fix up an + outdated libtool copy shipped with the Binutils code. @@ -228,7 +329,7 @@ 3lfslfslfs - Rebuild and test cc-lfs using cc-lfs on lfs. + Rebuild (and maybe test) cc-lfs using cc-lfs on lfs. @@ -256,30 +357,12 @@ The upshot of the preceding paragraph is that cc1 is unable to build a fully functional libstdc++ with the degraded libgcc, but cc1 is the only compiler available for building the C/C++ libraries - during stage 2. There are two reasons we don't immediately use the - compiler built in stage 2, cc-lfs, to build those libraries. - - - - - Generally speaking, cc-lfs cannot run on pc (the host system). Even though the - triplets for pc and lfs are compatible with each other, an executable - for lfs must depend on glibc-&glibc-version;; the host distro - may utilize either a different implementation of libc (for example, musl), or - a previous release of glibc (for example, glibc-2.13). - - - - - Even if cc-lfs can run on pc, using it on pc would create - a risk of linking to the pc libraries, since cc-lfs is a native - compiler. - - - - - So when we build gcc stage 2, we instruct the building system to - rebuild libgcc and libstdc++ with cc1, but we link libstdc++ to the newly + during stage 2. As we've discussed, we cannot run cc-lfs on pc (the + host distro) because it may require some library, code, or data not + available on the build (the host distro). + So when we build gcc stage 2, we instruct the building system to + rebuild libgcc and libstdc++ with cc1, but we also override the library + search path to link libstdc++ against the newly rebuilt libgcc instead of the old, degraded build. This makes the rebuilt libstdc++ fully functional. @@ -290,12 +373,11 @@ package on a completed LFS system, the reinstalled content of the package should be the same as the content of the same package when first installed in &ch-final;. The temporary packages installed in &ch-tmp-cross; or - &ch-tmp-chroot; cannot satisfy this requirement, because some of them - are built without optional dependencies, and autoconf cannot - perform some feature checks in &ch-tmp-cross; because of cross-compilation, - causing the temporary packages to lack optional features, - or use suboptimal code routines. Additionally, a minor reason for - rebuilding the packages is to run the test suites. + &ch-tmp-chroot; cannot satisfy this requirement, because some optional + features of them are disabled because of either the missing + dependencies or the cross-compilation mode. + Additionally, a minor reason for rebuilding the packages is to run the + test suites. @@ -359,11 +441,10 @@ checking what linker to use... /mnt/lfs/tools/i686-lfs-linux-gnu/bin/ldNext comes glibc. The most important considerations for building glibc are the compiler, binary tools, and - kernel headers. The compiler and binary tools are generally not an issue - since glibc will always use those relating to the --host - parameter passed to its configure script; e.g., in our case, the compiler - will be $LFS_TGT-gcc and the readelf - tool will be $LFS_TGT-readelf. The kernel headers can + kernel headers. The compiler and binary tools are not an issue + as --host=$LFS_TGT makes the build system to use + those tools prefixed with $LFS_TGT- as we've + discussed. The kernel headers can be a bit more complicated. Therefore, we take no risks and use the available configure switch to enforce the correct selection. After the run of configure, check the contents of the @@ -384,12 +465,7 @@ checking what linker to use... /mnt/lfs/tools/i686-lfs-linux-gnu/bin/ldDESTDIR directory as the other programs, then the second pass of gcc is constructed, omitting some - non-critical libraries. Due to some weird logic in gcc's - configure script, CC_FOR_TARGET ends up as - cc when the host is the same as the target, but - different from the build system. This is why - CC_FOR_TARGET=$LFS_TGT-gcc is declared explicitly - as one of the configuration options. + non-critical libraries. Upon entering the chroot environment in ,