[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Web Updates & Qoth Q3 2024 4/5] update the cross-gnu compilation page.
From: |
address@hidden |
Subject: |
[Web Updates & Qoth Q3 2024 4/5] update the cross-gnu compilation page. |
Date: |
Mon, 30 Sep 2024 21:09:29 -0400 |
* toolchain/cross-gnu.mdwn: I added an introductory paragraph to
explain the difference between native and cross compilation, and I
linked to Flavio's cross-hurd project. I removed the cross-gnu project
reference. Does anyone still use that shell script? And I added
Sergey's guide for how to cross-compile the X86 Hurd on a GNU/Linux
machine as an example guide.
---
toolchain/cross-gnu.mdwn | 351 ++++++++++++++++++---------------------
1 file changed, 160 insertions(+), 191 deletions(-)
diff --git a/toolchain/cross-gnu.mdwn b/toolchain/cross-gnu.mdwn
index 53a85214..da07b1eb 100644
--- a/toolchain/cross-gnu.mdwn
+++ b/toolchain/cross-gnu.mdwn
@@ -11,16 +11,23 @@ License|/fdl]]."]]"""]]
[[!tag stable_URL]]
-[[Thomas_Schwinge|tschwinge]] has written a shell script for building a
-complete cross-build environment for GNU/Hurd systems.
-
-Find it in the [[source_repositories/incubator]], *cross-gnu/master* branch.
-
-
-# Using
-
-Read through it. Understand it. Only then use it by following the next steps.
-
+How do you go about building the Hurd on a different CPU architecture?
+Typically you compile the Hurd natively. That is to say, that you
+build an `X86_64` Hurd on an `X86_64` computer, but how do you compile
+the Hurd to a new CPU architecture? Say AArch64, Power9, or Risc-V ?
+In that case you build the Hurd with a `X86_64` computer for a
+different architecture, which is called a cross build. Some Hurd
+developers (like Sergey) prefer to develop the Hurd on via cross
+building it, which lets them use GNU/Linux's gdb to debug the
+resulting binaries. Others like Samuel, prefer just to use the
+standard debian workflow that Debian GNU/Hurd provides.
+
+Flávio Cruz has written a shell script to cross build GNU/Hurd systems
+called [[cross-hurd|https://github.com/flavioc/cross-hurd]]. It is
+probably the most complete tool for the job. With it you can build a
+`hurd-i386` and `hurd-x86_64` system with GNU/Linux. If you are
+trying to cross-build an AArch64 Hurd system, then you will probably
+want to look at the [[arm port page|open_issues/arm_port]].
# Status
@@ -30,189 +37,151 @@ support for C and C++ so far, but not for other
languages. A bunch of fixes /
enhancements of [[glibc]] are missing. We're working towards minimizing these
differences, as well as towards pushing all patches upstream.
+# cross compiling the Hurd manually
+
+Just use Flávio's [[cross-hurd|https://github.com/flavioc/cross-hurd]]
+project. If however, you just want to cross-compile the Hurd manually
+for the learning experienence or want to port the Hurd to a CPU
+architecture that cross-hurd doesn't support, then please do read
+through Flávio's cross-hurd project. Try to understand how it works.
+Only then try to manually cross-compile the Hurd.
+
+Here's how you can cross-compile a X86 (32 bit) Hurd from a GNU/Linux
+machine. On your GNU/Linux machine install the dependencies: bison,
+flex, the three libraries GCC needs. In the below guide, make sure
+that you download the latest software. The below guide will have to
+download outdated software, but the build process is still the same.
+The guide below has `-j8` written a lot, which corresponds to the
+number of cores that your processor has. If your processor has four
+cores then use `-j4` instead.
+
+Set up the basic directory structure:
+
+ $ export PREFIX=~/dev/crosshurd
+ $ export PATH=$PREFIX/bin:$PATH
+ $ mkdir $PREFIX && cd $PREFIX
+ $ mkdir src include i686-gnu
+ $ ln -s ../include i686-gnu/sys-include
+ $ ln -s ../lib i686-gnu/lib
+ $ cd src
+
+Build binutils:
+
+ $ wget https://ftp.gnu.org/gnu/binutils/binutils-2.39.tar.gz
+ $ tar xf binutils-2.39.tar.gz
+ $ cd binutils-2.39
+ $ mkdir build && cd build
+ $ ../configure --target=i686-gnu --prefix=$PREFIX
--with-lib-path=$PREFIX/lib
+ $ make -j8
+ $ make install
+
+Verify that e.g. `$PREFIX/bin/i686-gnu-nm -v` works.
+
+Now build GCC:
+
+ $ wget https://ftp.gnu.org/gnu/gcc/gcc-12.2.0/gcc-12.2.0.tar.gz
+ $ tar xf gcc-12.2.0.tar.gz
+ $ cd gcc-12.2.0
+ $ mkdir build && cd build
+ $ ../configure --prefix=$PREFIX --target=i686-gnu
+ --with-lib-path=$PREFIX/lib --disable-multilib --enable-languages=c
+ $ make -j8 all-gcc
+ $ make install-gcc
+
+Note that at this step we're only building GCC itself, not libgcc --
+that will have to wait until we install glibc headers.
+
+Next, we want to build MIG. MIG needs Mach headers, but we can't build
+GNU Mach without MIG. So what we do is we 'make' GNU Mach twice, once
+to install the headers, and later on once more to actually build it.
+
+ $ git clone git://git.savannah.gnu.org/hurd/gnumach.git
+ $ cd gnumach
+ $ autoreconf -i
+ $ mkdir build && cd build
+ $ CC=gcc ../configure --prefix=$PREFIX --host=i686-gnu
+ $ make install-data
+
+At configuring step, it will warn that "mig was not found, we will not
+be able to build a kernel, only install headers. Install or build mig
+against them, and run configure again". This is exactly how we want it
+at this first step.
+
+The trick here is to tell configure to use host's GCC instead of our
+previously built i686-gnu-gcc. This is because we are not yet building
+GNU Mach for real, we're only doing this to install the headers. But
+we need to appease configure into generating a Makefile for us, hence
+`CC=gcc`.
+
+Now we should have `$PREFIX/include/mach/message.h`,
+`$PREFIX/include/mach/i386/machine_types.defs` and suchlike.
+
+Now, onto building MIG:
+
+ $ git clone git://git.savannah.gnu.org/hurd/mig.git
+ $ cd mig
+ $ autoreconf -i
+ $ mkdir build && cd build
+ $ ../configure --target=i686-gnu --prefix=$PREFIX
+ $ make -j8
+ $ make install
+
+Now, before we build glibc, we should install Hurd headers similarly
+to how we've installed Mach headers above:
+
+ $ git clone git://git.savannah.gnu.org/hurd/hurd.git
+ $ cd hurd
+ $ autoreconf -i
+ $ mkdir build && cd build
+ $ CC=gcc ../configure --host=i686-gnu --without-parted \
+ --without-libcrypt --without-libbz2 --without-libz --without-rump
+ $ make no_deps=t prefix=$PREFIX install-headers
+
+Now, it's finally time to tweak glibc:
+
+ $ git clone https://sourceware.org/git/glibc.git
+ $ mkdir build && cd build
+ $ ../configure --build=$(../scripts/config.guess) --host=i686-gnu \
+ --prefix=$PREFIX --with-headers=$PREFIX/include
+ $ make install-headers
+
+We also need to do some hacky things manually in order for this to
+start looking enough like a real glibc installation:
+
+ $ touch $PREFIX/include/gnu/stubs.h $PREFIX/lib/libc.so
+ $ make csu/subdir_lib && install csu/crt1.o csu/crti.o csu/crtn.o
$PREFIX/lib
+
+Now we can go back to GCC and build libgcc:
+
+ $ make configure-target-libgcc
+ $ make -j8 all-target-libgcc
+ $ make install-target-libgcc
+
+And now we can once again go to glibc and build it for real:
+
+ $ make PARALLELMFLAGS=-j8
+ $ make install
+
+At this point it should be possible to cross-compile a C hello world
+for the Hurd with no ceremony:
-## Supported Versions of Source Packages
-
-/!\ This is outdated. Contact [[tschwinge]].
-
-The following ones are known to work. Others may work as well, but no
-guarantee is given. Always the preferred version is listed first.
-
- * [[`src/binutils`|binutils]]
-
- * CVS `binutils-2_20-branch`
-
- $ mkdir binutils-2_20-branch
- $ cd binutils-2_20-branch/
- $ cvs -d:pserver:anoncvs@sources.redhat.com:/cvs/src ↩
- co -r binutils-2_20-branch binutils
-
- The sources are rooted in `binutils-2_20-branch/src/`. Also use the
above
- commands for updating, instead of the usual `cvs update`.
-
- * Release 2.22 or later from <ftp://ftp.gnu.org/gnu/binutils/>
- should also be fine.
-
- * [[`src/gcc`|gcc]]
-
- * SVN `gcc-4_5-branch`
-
- $ svn co svn://gcc.gnu.org/svn/gcc/branches/gcc-4_5-branch
-
- Patches:
-
- * <http://gcc.gnu.org/ml/gcc-patches/2010-04/msg00602.html>
-
- Prepare:
-
- $ ( cd gcc-4_5-branch/ && contrib/gcc_update --touch )
-
- * SVN `gcc-4_4-branch`
-
- $ svn co svn://gcc.gnu.org/svn/gcc/branches/gcc-4_4-branch
-
- Patches:
-
- * <http://gcc.gnu.org/ml/gcc-patches/2010-04/msg00602.html>
-
- Prepare:
-
- $ ( cd gcc-4_4-branch/ && contrib/gcc_update --touch )
-
- * Releases of the 4.5 and 4.4 series from <ftp://ftp.gnu.org/gnu/gcc/>
- should also be fine, but need the same set of patches as the
- `gcc-4_5-branch` needs.
-
- * [[`src/gnumach`|microkernel/mach/gnumach]]
-
- * Git `master` branch
-
- $ git clone ↩
- git://git.sv.gnu.org/hurd/gnumach.git gnumach
-
- Prepare:
-
- $ ( cd gnumach/ && autoreconf -vi )
-
- * [[`src/mig`|microkernel/mach/mig/gnu_mig]]
-
- * Git `master` branch
-
- $ git clone ↩
- git://git.sv.gnu.org/hurd/mig.git mig
-
- Prepare:
-
- $ ( cd mig/ && autoreconf -vi )
-
- * [[`src/hurd`|hurd]]
-
- * Git `master` branch
-
- $ git clone ↩
- git://git.sv.gnu.org/hurd/hurd.git hurd
-
- * [[`src/libpthread`|libpthread]]
-
- * Git `tschwinge/Peter_Herbolzheimer` branch
-
- $ git clone --no-checkout ↩
- git://git.sv.gnu.org/hurd/libpthread.git libpthread
- $ cd libpthread/
- $ git checkout origin/tschwinge/Peter_Herbolzheimer
-
- Prepare:
-
- $ ( cd libpthread/ && autoreconf -vi )
-
- * [[`src/glibc`|glibc]]
-
- * Git `tschwinge/Roger_Whittaker` branch
-
- $ git clone --no-checkout ↩
- git://git.sv.gnu.org/hurd/glibc.git glibc
- $ cd glibc/
- $ git checkout origin/tschwinge/Roger_Whittaker
-
-<!--
-
- * [[`src/gdb`|gdb]]
-
- This is optional and will only be compiled if present.
-
- * CVS `gdb_6_6-branch`
-
- $ cvs -d:pserver:anoncvs@sources.redhat.com:/cvs/src ↩
- co -r gdb_6_6-branch gdb
- $ mv src gdb_6_6-branch
-
- Also needs some patch because of MIG changes, if I remember correctly.
-
- * Recent tarballs from <ftp://ftp.gnu.org/gnu/gdb/> should also work.
-
--->
-
-
-## Preparation
-
-The raw source code trees are about 1 GiB.
-
-Unpack the tarballs if you downloaded any.
-
-Create a directory where the cross build shall be rooted in, and a `src`
-subdirectory in there. Then create symbolic links for every of the above
-packages: from `src/PACKAGE` to where you stored or unpacked it. If you don't
-intend to build several cross compilers or use the source trees otherwise, you
-can also directly store the source trees in `src/`. The source trees can be
-shared between multiple cross build trees since the packages' build systems are
-supposed not to modify the files in the source trees. Not all packages adhere
-to that, but they fail to do so only for pre-processed documentation, etc.
-
-Either make sure that `cross-gnu-env` and `cross-gnu` are found in `$PATH`
-(`~/bin/`, for example) or alternatively remember to use their full paths in
-the following.
-
-The system you're running the script on (the *build* system) needs to have
-basic development tools installed, that is, a C compiler with libraries,
-`make`, and several more packages. If anything is missing, the *cross-gnu*
-build will abort, and you have to install the missing dependencies and resume
-the *cross-gnu* build.
-
-
-## Setting Up the Environment
-
-Do this every time you intend to use the cross compiler:
-
- $ ROOT=to/the/cross/build/root
- $ . cross-gnu-env
-
-This will set several environment variables, which are later used by (a) the
-`cross-gnu` script and (b) by you, the user of the cross compiler. `$TARGET`
-will be set by the script, `$PATH` will be adjusted, etc. See the
-`cross-gnu-env` file for all environment variables that are set, as well as
-their default values. `$ROOT` will be made an absolute path if it isn't
-already.
-
-Later, you'll be able to do things like `../configure --host="$TARGET"`, and
the
-cross compiler will be found automatically.
-
-
-## Creating the Cross Build Environment
-
-This will need an additional 2 GiB.
+ $ $PREFIX/bin/i686-gnu-gcc hello.c -o hello
-After setting up the environment, just run `cross-gnu` and watch the messages
-flow by. In the end you should see a message: *[...]/cross-gnu: Everything
-should be in place now.*
+Now we can rebuild Mach and Hurd properly, if we want to:
+
+ $ make distclean
+ $ ../configure --prefix=$PREFIX --host=i686-gnu
+ $ make -j8
+ $ make install
+ $ make distclean
+ $ ../configure --host=i686-gnu --without-parted --without-libcrypt \
+ --without-libbz2 --without-libz --without-rump
+ $ make -j8 DESTDIR=$PREFIX install
-## Staying Up-To-Date
+Now we can run boot the Hurd. Your [[qemu
+invocation|hurd/running/qemu]] will look different depending on what
+you want, but it will probably look a little like this (note I did not
+test this):
-You can re-run `cross-gnu` to rebuild the parts of the sources that have
-changed since the last run. This will save a lot of time compared to starting
-from scratch again. Also, it is especially useful if you aren't working with
-unpacked tarballs, but on CVS's / SVN's / Git's branches or want to quickly get
-a new toolchain
-with patches you applied to the source trees. However: do *not* use this
-technique when doing major changes to the source trees, like switching from GCC
-4.4 to GCC 4.5.
+ $ qemu-system-i386 -m 4GB -drive cache=writeback,file=hd.img -M q35
--
2.45.2