Compiling with old glibc

It works! This is the code that I used. Bear in mind that it’s designed to fit into a flake, so it will require some modification. nixpkgs refers to current master (though I’m hoping this is somewhat flexible) and nixpkgs-old refers to nixpkgs 16.09 (which used glibc 2.24).

Soon I’m going to add this to my pull request for nix-bundle (revamp appimage functionality by Radvendii · Pull Request #76 · matthewbauer/nix-bundle · GitHub), if you want an easy way to pull it in to your flake. It’ll be nix-bundle.overlays.glibc_2_24.${system} (once the pull request is merged).

{ system
, nixpkgs
, nixpkgs-old
}:
self: super:
  let
    # takes in a *string* name of a glibc package e.g. "glibcInfo"
    #
    # the general idea is to mix the attributes from the old glibc an from the
    # the new glibc in a way that gets us an older version of glibc but is
    # compatible with the new gcc and the changes to nixpkgs. this took a lot of
    # trial and error, and will probably have to be updated as nixpkgs
    # progresses.
    glibcAdapter = glibcPkg: super.${glibcPkg}.overrideAttrs (attrs:
      let
        oldGlibcPkg = (import nixpkgs-old { inherit system; }).${glibcPkg};
        glibcDir = "pkgs/development/libraries/glibc";
        oldGlibcDir = "${nixpkgs-old}/${glibcDir}";
        newGlibcDir = "${nixpkgs}/${glibcDir}";
      in {
        inherit (oldGlibcPkg) name src;

        # version wasn't an attribute back then, so we can't inherit
        version = "2.24";

        patches = oldGlibcPkg.patches ++ [
          # from current glibc (can't use fetchurl from here)
          ./locale-C.diff

          # has to do with new gcc not new glibc
          "${newGlibcDir}/fix-x64-abi.patch"

          # newer ld does something different with .symver
          ./common-symbol.patch

          # update to allow a special case empty string
          ./ld-monetary.patch
        ];

      postPatch =
        oldGlibcPkg.postPatch
        # from current glibc
        + ''
          # Needed for glibc to build with the gnumake 3.82
          # http://comments.gmane.org/gmane.linux.lfs.support/31227
          sed -i 's/ot \$/ot:\n\ttouch $@\n$/' manual/Makefile
          # nscd needs libgcc, and we don't want it dynamically linked
          # because we don't want it to depend on bootstrap-tools libs.
          echo "LDFLAGS-nscd += -static-libgcc" >> nscd/Makefile
        '';

      # modifications from old glibc
      configureFlags =
        # we can maintain compatiblity with older kernel (see below)
        super.lib.remove "--enable-kernel=3.2.0" (attrs.configureFlags or [])
        ++ [ "--enable-obsolete-rpc" ]
        ++ super.lib.optionals
          # (we don't have access to withLinuxHeaders from here)
          (attrs.linuxHeaders != null) [
            "--enable-kernel=2.6.32"
          ];

      NIX_CFLAGS_COMPILE =
        (attrs.NIX_CFLAGS_COMPILE or "")
        # from old glibc
        + " -Wno-error=strict-prototypes"
        # new gcc introduces new warnings which we must disable
        # (see https://github.com/NixOS/nixpkgs/pull/71480)
        + " -Wno-error=stringop-truncation -Wno-error=attribute-alias"
        # I also had to disable these <.< >.>
        + " -Wno-error=multistatement-macros"
        + " -Wno-error=int-in-bool-context"
        + " -Wno-error=format-truncation"
        + " -Wno-error=nonnull"
        + " -Wno-error=restrict"
        + " -Wno-error=unused-const-variable"
        + " -Wno-error=int-conversion"
        + " -Wno-error=unused-function";
      }
    );
  in {
    glibc = glibcAdapter "glibc";
    glibcLocales = glibcAdapter "glibcLocales";
    glibcInfo = glibcAdapter "glibcInfo";
    llvmPackages_11.llvm = super.llvmPackages_11.llvm.overrideAttrs (attrs: {
      doCheck = false; # test fails: intrinsics.ll
    });
  }
4 Likes