about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Ericson <git@JohnEricson.me>2023-06-25 23:26:37 -0400
committerGitHub <noreply@github.com>2023-06-25 23:26:37 -0400
commitbcd0695735a8b3bcb5060b6099e22fb34bb9b545 (patch)
tree14a41c369bffc07912958189d37089831f30a950
parent67c352a9379226f786fd25d1eb3c54fa8d131ab4 (diff)
parenta6f479ad5316a3957a0329c6dbd50bbf4b2a09a5 (diff)
downloadnixlib-bcd0695735a8b3bcb5060b6099e22fb34bb9b545.tar
nixlib-bcd0695735a8b3bcb5060b6099e22fb34bb9b545.tar.gz
nixlib-bcd0695735a8b3bcb5060b6099e22fb34bb9b545.tar.bz2
nixlib-bcd0695735a8b3bcb5060b6099e22fb34bb9b545.tar.lz
nixlib-bcd0695735a8b3bcb5060b6099e22fb34bb9b545.tar.xz
nixlib-bcd0695735a8b3bcb5060b6099e22fb34bb9b545.tar.zst
nixlib-bcd0695735a8b3bcb5060b6099e22fb34bb9b545.zip
Merge pull request #239694 from emilytrau/minimal-binutils-1.20
minimal-bootstrap: init binutils, gcc2, glibc22, linux-headers
-rw-r--r--pkgs/os-specific/linux/minimal-bootstrap/binutils/default.nix118
-rw-r--r--pkgs/os-specific/linux/minimal-bootstrap/binutils/deterministic.patch12
-rw-r--r--pkgs/os-specific/linux/minimal-bootstrap/default.nix37
-rw-r--r--pkgs/os-specific/linux/minimal-bootstrap/gcc/2.nix140
-rw-r--r--pkgs/os-specific/linux/minimal-bootstrap/glibc/default.nix121
-rw-r--r--pkgs/os-specific/linux/minimal-bootstrap/linux-headers/default.nix49
-rw-r--r--pkgs/os-specific/linux/minimal-bootstrap/utils.nix4
7 files changed, 478 insertions, 3 deletions
diff --git a/pkgs/os-specific/linux/minimal-bootstrap/binutils/default.nix b/pkgs/os-specific/linux/minimal-bootstrap/binutils/default.nix
new file mode 100644
index 000000000000..8722ff818297
--- /dev/null
+++ b/pkgs/os-specific/linux/minimal-bootstrap/binutils/default.nix
@@ -0,0 +1,118 @@
+{ lib
+, buildPlatform
+, hostPlatform
+, fetchurl
+, bash
+, gnumake
+, gnupatch
+, gnugrep
+, gnutar
+, gawk
+, bzip2
+, sed
+, mesBootstrap ? false, tinycc ? null
+, gcc ? null, glibc ? null, binutils ? null, linux-headers
+}:
+assert mesBootstrap -> tinycc != null;
+assert !mesBootstrap -> gcc != null && glibc != null && binutils != null;
+let
+  pname = "binutils" + lib.optionalString mesBootstrap "-mes";
+  version = "2.20.1";
+  rev = "a";
+
+  src = fetchurl {
+    url = "mirror://gnu/binutils/binutils-${version}${rev}.tar.bz2";
+    sha256 = "0r7dr0brfpchh5ic0z9r4yxqn4ybzmlh25sbp30cacqk8nb7rlvi";
+  };
+
+  patches = [
+    # Enables building binutils using TCC and Mes C Library
+    (fetchurl {
+      url = "https://git.savannah.gnu.org/cgit/guix.git/plain/gnu/packages/patches/binutils-boot-2.20.1a.patch?id=50249cab3a98839ade2433456fe618acc6f804a5";
+      sha256 = "086sf6an2k56axvs4jlky5n3hs2l3rq8zq5d37h0b69cdyh7igpn";
+    })
+
+    # Make binutils output deterministic by default.
+    ./deterministic.patch
+  ];
+
+  configureFlags = [
+    "--disable-nls"
+    "--disable-shared"
+    "--disable-werror"
+    "--prefix=${placeholder "out"}"
+
+    "--build=${buildPlatform.config}"
+    "--host=${hostPlatform.config}"
+
+    # Turn on --enable-new-dtags by default to make the linker set
+    # RUNPATH instead of RPATH on binaries.  This is important because
+    # RUNPATH can be overridden using LD_LIBRARY_PATH at runtime.
+    "--enable-new-dtags"
+
+    # By default binutils searches $libdir for libraries. This brings in
+    # libbfd and libopcodes into a default visibility. Drop default lib
+    # path to force users to declare their use of these libraries.
+    "--with-lib-path=:"
+  ];
+in
+bash.runCommand "${pname}-${version}" {
+  inherit pname version;
+
+  nativeBuildInputs = [
+    (if mesBootstrap then tinycc.compiler else gcc)
+    gnumake
+    gnupatch
+    gnugrep
+    gnutar
+    gawk
+    bzip2
+    sed
+  ] ++ lib.optional (!mesBootstrap) binutils;
+
+  passthru.tests.get-version = result:
+    bash.runCommand "${pname}-get-version-${version}" {} ''
+      ${result}/bin/ld --version
+      mkdir $out
+    '';
+
+  meta = with lib; {
+    description = "Tools for manipulating binaries (linker, assembler, etc.)";
+    homepage = "https://www.gnu.org/software/binutils";
+    license = licenses.gpl3Plus;
+    maintainers = teams.minimal-bootstrap.members;
+    platforms = platforms.unix;
+  };
+} ''
+  # Unpack
+  cp ${src} binutils.tar.bz2
+  bunzip2 binutils.tar.bz2
+  tar xf binutils.tar
+  rm binutils.tar
+  cd binutils-${version}
+
+  # Patch
+  ${lib.concatMapStringsSep "\n" (f: "patch -Np1 -i ${f}") patches}
+  # Clear the default library search path.
+  echo 'NATIVE_LIB_DIRS=' >> ld/configure.tgt
+
+  # Configure
+  ${if mesBootstrap then ''
+    export CC="tcc -B ${tinycc.libs}/lib -D __GLIBC_MINOR__=6 -D MES_BOOTSTRAP=1"
+    export AR="tcc -ar"
+  '' else ''
+    export CC="gcc -B ${glibc}/lib -I${glibc}/include -I${linux-headers}/include"
+    export CPP="gcc -E -I${glibc}/include -I${linux-headers}/include"
+    export AR="ar"
+    export LIBRARY_PATH="${glibc}/lib"
+    export LIBS="-lc -lnss_files -lnss_dns -lresolv"
+  ''}
+  export SED=sed
+  bash ./configure ${lib.concatStringsSep " " configureFlags}
+
+  # Build
+  make
+
+  # Install
+  make install
+''
diff --git a/pkgs/os-specific/linux/minimal-bootstrap/binutils/deterministic.patch b/pkgs/os-specific/linux/minimal-bootstrap/binutils/deterministic.patch
new file mode 100644
index 000000000000..736e0aca6ce1
--- /dev/null
+++ b/pkgs/os-specific/linux/minimal-bootstrap/binutils/deterministic.patch
@@ -0,0 +1,12 @@
+diff -ur orig/binutils-2.23.1/ld/ldlang.c binutils-2.23.1/ld/ldlang.c
+--- orig/ld/ldlang.c
++++ new/ld/ldlang.c
+@@ -3095,6 +3095,8 @@
+                           ldfile_output_machine))
+     einfo (_("%P%F:%s: can not set architecture: %E\n"), name);
+ 
++  link_info.output_bfd->flags |= BFD_DETERMINISTIC_OUTPUT;
++
+   link_info.hash = bfd_link_hash_table_create (link_info.output_bfd);
+   if (link_info.hash == NULL)
+     einfo (_("%P%F: can not create hash table: %E\n"));
diff --git a/pkgs/os-specific/linux/minimal-bootstrap/default.nix b/pkgs/os-specific/linux/minimal-bootstrap/default.nix
index 9011c45a8fe3..45175b987cad 100644
--- a/pkgs/os-specific/linux/minimal-bootstrap/default.nix
+++ b/pkgs/os-specific/linux/minimal-bootstrap/default.nix
@@ -15,6 +15,20 @@ lib.makeScope
 
     bash_2_05 = callPackage ./bash/2.nix { tinycc = tinycc-mes; };
 
+    binutils = callPackage ./binutils {
+      bash = bash_2_05;
+      gcc = gcc2;
+      binutils = binutils-mes;
+      glibc = glibc22;
+      sed = heirloom.sed;
+    };
+    binutils-mes = callPackage ./binutils {
+      bash = bash_2_05;
+      tinycc = tinycc-mes;
+      sed = heirloom.sed;
+      mesBootstrap = true;
+    };
+
     bzip2 = callPackage ./bzip2 {
       bash = bash_2_05;
       tinycc = tinycc-mes;
@@ -27,6 +41,23 @@ lib.makeScope
       tinycc = tinycc-mes;
     };
 
+    gcc2 = callPackage ./gcc/2.nix {
+      bash = bash_2_05;
+      gcc = gcc2-mes;
+      binutils = binutils-mes;
+      glibc = glibc22;
+    };
+    gcc2-mes = callPackage ./gcc/2.nix {
+      bash = bash_2_05;
+      tinycc = tinycc-mes;
+      binutils = binutils-mes;
+      mesBootstrap = true;
+    };
+
+    inherit (callPackage ./glibc {
+      bash = bash_2_05;
+    }) glibc22;
+
     gnugrep = callPackage ./gnugrep {
       bash = bash_2_05;
       tinycc = tinycc-mes;
@@ -58,6 +89,8 @@ lib.makeScope
 
     heirloom-devtools = callPackage ./heirloom-devtools { tinycc = tinycc-mes; };
 
+    linux-headers = callPackage ./linux-headers { bash = bash_2_05; };
+
     ln-boot = callPackage ./ln-boot { };
 
     mes = lib.recurseIntoAttrs (callPackage ./mes { });
@@ -80,8 +113,12 @@ lib.makeScope
 
     test = kaem.runCommand "minimal-bootstrap-test" {} ''
       echo ${bash_2_05.tests.get-version}
+      echo ${binutils.tests.get-version}
+      echo ${binutils-mes.tests.get-version}
       echo ${bzip2.tests.get-version}
       echo ${gawk.tests.get-version}
+      echo ${gcc2.tests.get-version}
+      echo ${gcc2-mes.tests.get-version}
       echo ${gnugrep.tests.get-version}
       echo ${gnused.tests.get-version}
       echo ${gnutar.tests.get-version}
diff --git a/pkgs/os-specific/linux/minimal-bootstrap/gcc/2.nix b/pkgs/os-specific/linux/minimal-bootstrap/gcc/2.nix
new file mode 100644
index 000000000000..0a79c97e75af
--- /dev/null
+++ b/pkgs/os-specific/linux/minimal-bootstrap/gcc/2.nix
@@ -0,0 +1,140 @@
+{ lib
+, buildPlatform
+, hostPlatform
+, fetchurl
+, bash
+, gnumake
+, gnupatch
+, gnugrep
+, gnutar
+, gzip
+, heirloom
+, binutils
+, mesBootstrap ? false, tinycc ? null, mes-libc
+, gcc ? null, glibc ? null, linux-headers
+}:
+assert mesBootstrap -> tinycc != null;
+assert !mesBootstrap -> gcc != null && glibc != null;
+let
+  # Gcc-2.95.3 is the most recent GCC that is supported by what the Mes C
+  # Library v0.16 offers.  Gcc-3.x (and 4.x) place higher demands on a C
+  # library, such as dir.h/struct DIR/readdir, locales, signals...  Also,
+  # with gcc-2.95.3, binutils (2.14.0, 2.20.1a) and glibc-2.2.5 we found a
+  # GNU toolchain triplet "that works".
+  #   - from guix/gnu/packages/commencement.scm
+  pname = "gcc" + lib.optionalString mesBootstrap "-mes";
+  version = "2.95.3";
+
+  src = fetchurl {
+    url = "mirror://gnu/gcc/gcc-${version}/gcc-core-${version}.tar.gz";
+    sha256 = "1xvfy4pqhrd5v2cv8lzf63iqg92k09g6z9n2ah6ndd4h17k1x0an";
+  };
+
+  patches = [
+    # This patch enables building gcc-2.95.3 using TCC and Mes C Library.
+    #   * Disable building DOC
+    #   * Avoid running `fixproto'.
+    #   * Force running `fixinc'.
+    #   * Replace Makefile trickery of creating an libgcc1.a archive, then
+    #     extracting the .o files later to create a new libgcc2.a archive.
+    #     Instead, keep temporary .o files.
+    (fetchurl {
+      url = "https://git.savannah.gnu.org/cgit/guix.git/plain/gnu/packages/patches/gcc-boot-2.95.3.patch?id=50249cab3a98839ade2433456fe618acc6f804a5";
+      sha256 = "03l3jaxch6d76mx4zkn6ky64paj58jk0biddck01qd4bnw9z8hiw";
+    })
+  ];
+
+  makeFlags = [
+    "LANGUAGES=c"
+  ] ++ lib.optionals mesBootstrap [
+    "LIBGCC2_INCLUDES=\"-I ${mes-libc}/include\""
+    "BOOT_LDFLAGS=\" -B ${tinycc.libs}/lib\""
+  ] ++ lib.optionals (!mesBootstrap) [
+    "LIBGCC2_INCLUDES=\"-I ${glibc}/include -I ${linux-headers}/include\""
+  ];
+in
+bash.runCommand "${pname}-${version}" {
+  inherit pname version;
+
+  nativeBuildInputs = [
+    (if mesBootstrap then tinycc.compiler else gcc)
+    gnumake
+    gnupatch
+    gnugrep
+    gnutar
+    gzip
+    heirloom.sed
+    binutils
+  ];
+
+  passthru.tests.get-version = result:
+    bash.runCommand "${pname}-get-version-${version}" {} ''
+      ${result}/bin/gcc --version
+      mkdir $out
+    '';
+
+  meta = with lib; {
+    description = "GNU Compiler Collection, version ${version}";
+    homepage = "https://gcc.gnu.org";
+    license = licenses.gpl3Plus;
+    maintainers = teams.minimal-bootstrap.members;
+    platforms = platforms.unix;
+  };
+} ''
+  # Unpack
+  tar xzf ${src}
+  cd gcc-${version}
+
+  # Patch
+  ${lib.concatMapStringsSep "\n" (f: "patch -Np1 -i ${f}") patches}
+  # /build/glibc-2.2.5/intl/loadmsgcat.c:334: multiple definition of `_nl_load_domain'
+  # ../intl/libintl.a(loadmsgcat.o):/build/gcc-2.95.3/texinfo/intl/loadmsgcat.c:66: first defined here
+  rm -R texinfo
+  mkdir -p texinfo
+  echo 'all:'>texinfo/Makefile.in
+  echo 'install:'>>texinfo/Makefile.in
+
+  # Configure
+  ${if mesBootstrap then ''
+    export CC="tcc -B ${tinycc.libs}/lib -D __GLIBC_MINOR__=6"
+    export CPP="tcc -E"
+    export ac_cv_func_setlocale=no
+  '' else ''
+    export CC="gcc -I${glibc}/include -I${linux-headers}/include -I${gcc}/lib/gcc-lib/${hostPlatform.config}/${version}/include"
+    export CPP="gcc -E -I${glibc}/include -I${linux-headers}/include -I${gcc}/lib/gcc-lib/${hostPlatform.config}/${version}/include"
+    export LIBRARY_PATH="${glibc}/lib"
+    export LIBS="-lc -lnss_files -lnss_dns -lresolv"
+  ''}
+  export OLDCC="$CC"
+  export CC_FOR_BUILD="$CC"
+  export AR=ar
+  export RANLIB=ranlib
+  export ac_cv_c_float_format='IEEE (little-endian)'
+  bash ./configure \
+    --build=${buildPlatform.config} \
+    --host=${hostPlatform.config} \
+    --enable-static \
+    --disable-shared \
+    --disable-werror \
+    --prefix=$out
+  # no info at this stage
+  touch gcc/cpp.info gcc/gcc.info
+
+  # Build
+  make ${lib.concatStringsSep " " makeFlags}
+
+  # Install
+  make install
+  mkdir tmp
+  cd tmp
+  ar x ../gcc/libgcc2.a
+  ${lib.optionalString mesBootstrap "ar x ${tinycc.libs}/lib/libtcc1.a"}
+  ar r $out/lib/gcc-lib/${hostPlatform.config}/${version}/libgcc.a *.o
+  cd ..
+  ${lib.optionalString mesBootstrap ''
+    cp gcc/libgcc2.a $out/lib/libgcc2.a
+    ar x ${tinycc.libs}/lib/libtcc1.a
+    ar x ${tinycc.libs}/lib/libc.a
+    ar r $out/lib/gcc-lib/${hostPlatform.config}/${version}/libc.a libc.o libtcc1.o
+  ''}
+''
diff --git a/pkgs/os-specific/linux/minimal-bootstrap/glibc/default.nix b/pkgs/os-specific/linux/minimal-bootstrap/glibc/default.nix
new file mode 100644
index 000000000000..5c4ff386add5
--- /dev/null
+++ b/pkgs/os-specific/linux/minimal-bootstrap/glibc/default.nix
@@ -0,0 +1,121 @@
+{ lib
+, buildPlatform
+, hostPlatform
+, fetchurl
+, bash
+, gcc2-mes
+, gnumake
+, gnupatch
+, gnused
+, gnugrep
+, gnutar
+, gzip
+, gawk
+, heirloom
+, binutils-mes
+, linux-headers
+}:
+let
+  pname = "glibc";
+
+  buildGlibc = { version, src, patches, configureFlags, gcc, binutils, CC, CPP }:
+    bash.runCommand "${pname}-${version}" {
+      inherit pname version;
+
+      nativeBuildInputs = [
+        gcc
+        gnumake
+        gnupatch
+        gnused
+        gnugrep
+        gnutar
+        gzip
+        gawk
+        binutils
+      ];
+
+      meta = with lib; {
+        description = "The GNU C Library";
+        homepage = "https://www.gnu.org/software/libc";
+        license = licenses.lgpl2Plus;
+        maintainers = teams.minimal-bootstrap.members;
+        platforms = platforms.linux;
+      };
+    } ''
+      # Unpack
+      tar xzf ${src}
+      cd glibc-${version}
+
+      # Patch
+      ${lib.concatMapStringsSep "\n" (f: "patch -Np1 -i ${f}") patches}
+
+      # Configure
+      export CC="${CC}"
+      export CPP="${CPP}"
+      bash ./configure --prefix=$out ${lib.concatStringsSep " " (
+        [
+          "--build=${buildPlatform.config}"
+          "--host=${hostPlatform.config}"
+          "--with-headers=${linux-headers}/include"
+          "--enable-static"
+          "--disable-shared"
+        ] ++ configureFlags)}
+
+      # Build
+      make
+
+      # Install
+      # GNU sed w/ mes-libc crashes on certain stdio actions
+      export PATH="${heirloom.sed}/bin:$PATH"
+      make install
+    '';
+in
+{
+  glibc22 = buildGlibc rec {
+    # GNU C Library 2.2.5 is the most recent glibc that we managed to build
+    # using gcc-2.95.3.  Newer versions (2.3.x, 2.6, 2.1x) seem to need a newer
+    # gcc.
+    #   - from guix/gnu/packages/commencement.scm
+    version = "2.2.5";
+    src = fetchurl {
+      url = "mirror://gnu/glibc/glibc-${version}.tar.gz";
+      sha256 = "1vl48i16gx6h68whjyhgnn1s57vqq32f9ygfa2fls7pdkbsqvp2q";
+    };
+
+    patches = [
+      # This patch enables building glibc-2.2.5 using TCC and GNU Make 4.x and Mes C Library.
+      #   * Makefile: Do not assemble from stdin, use file indirection.
+      #   * Makefile: Add new target: install-lib-all.
+      #   * Makefile: Avoid building stub DOC.
+      #   * [_LIBC_REENTRANT]: Add missing guarding.
+      #   * [MES_BOOTSTRAP]: Disable some GCC extensions.
+      #   * [MES_BOOTSTRAP]: Add missing GCC div/mod defines.
+      (fetchurl {
+        url = "https://git.savannah.gnu.org/cgit/guix.git/plain/gnu/packages/patches/glibc-boot-${version}.patch?id=50249cab3a98839ade2433456fe618acc6f804a5";
+        sha256 = "1nyz2dr9g7scqwwygd6jvbl7xxpwh11ryvgdz8aikkkna02q1pm8";
+      })
+      # We want to allow builds in chroots that lack /bin/sh.  Thus, system(3)
+      # and popen(3) need to be tweaked to use the right shell.  For the bootstrap
+      # glibc, we just use whatever `sh' can be found in $PATH.  The final glibc
+      # instead uses the hard-coded absolute file name of `bash'.
+      (fetchurl {
+        url = "https://git.savannah.gnu.org/cgit/guix.git/plain/gnu/packages/patches/glibc-bootstrap-system-${version}.patch?id=50249cab3a98839ade2433456fe618acc6f804a5";
+        sha256 = "1l67w9rysrlsg2i0r210qxxn37h2969ba9lx7pp3ywlnikvi98m8";
+      })
+    ];
+
+    configureFlags = [
+      "--disable-sanity-checks"
+      "--enable-static-nss"
+      "--without-__thread"
+      "--without-cvs"
+      "--without-gd"
+      "--without-tls"
+    ];
+
+    gcc = gcc2-mes;
+    binutils = binutils-mes;
+    CC = "gcc -D MES_BOOTSTRAP=1 -D BOOTSTRAP_GLIBC=1 -L $(pwd)";
+    CPP = "gcc -E -D MES_BOOTSTRAP=1 -D BOOTSTRAP_GLIBC=1";
+  };
+}
diff --git a/pkgs/os-specific/linux/minimal-bootstrap/linux-headers/default.nix b/pkgs/os-specific/linux/minimal-bootstrap/linux-headers/default.nix
new file mode 100644
index 000000000000..6addd11554d0
--- /dev/null
+++ b/pkgs/os-specific/linux/minimal-bootstrap/linux-headers/default.nix
@@ -0,0 +1,49 @@
+{ lib
+, fetchurl
+, bash
+, gnutar
+, xz
+}:
+let
+  # WARNING: You probably don't want to use this package outside minimal-bootstrap
+  #
+  # We need some set of Linux kernel headers to build our bootstrap packages
+  # (gcc/binutils/glibc etc.) against. As long as it compiles it is "good enough".
+  # Therefore the requirement for correctness, completeness, platform-specific
+  # features, and being up-to-date, are very loose.
+  #
+  # Rebuilding the Linux headers from source correctly is something we can defer
+  # till we have access to gcc/binutils/perl. For now we can use Guix's assembled
+  # kernel header distribution and assume it's good enough.
+  pname = "linux-headers";
+  version = "4.14.67";
+
+  src = fetchurl {
+    url = "mirror://gnu/gnu/guix/bootstrap/i686-linux/20190815/linux-libre-headers-stripped-4.14.67-i686-linux.tar.xz";
+    sha256 = "0sm2z9x4wk45bh6qfs94p0w1d6hsy6dqx9sw38qsqbvxwa1qzk8s";
+  };
+in
+bash.runCommand "${pname}-${version}" {
+  inherit pname version;
+
+  nativeBuildInputs = [
+    gnutar
+    xz
+  ];
+
+  meta = with lib; {
+    description = "Header files and scripts for Linux kernel";
+    license = licenses.gpl2;
+    maintainers = teams.minimal-bootstrap.members;
+    platforms = platforms.linux;
+  };
+} ''
+  # Unpack
+  cp ${src} linux-headers.tar.xz
+  unxz linux-headers.tar.xz
+  tar xf linux-headers.tar
+
+  # Install
+  mkdir $out
+  cp -r include $out
+''
diff --git a/pkgs/os-specific/linux/minimal-bootstrap/utils.nix b/pkgs/os-specific/linux/minimal-bootstrap/utils.nix
index bba6edae973a..cc8c04619169 100644
--- a/pkgs/os-specific/linux/minimal-bootstrap/utils.nix
+++ b/pkgs/os-specific/linux/minimal-bootstrap/utils.nix
@@ -29,11 +29,9 @@ rec {
     , text
     , executable ? false # run chmod +x ?
     , destination ? ""   # relative path appended to $out eg "/bin/foo"
-    , allowSubstitutes ? false
-    , preferLocalBuild ? true
     }:
     derivationWithMeta {
-      inherit name text allowSubstitutes preferLocalBuild;
+      inherit name text;
       passAsFile = [ "text" ];
 
       builder = "${kaem}/bin/kaem";