anvil-editor: init at 0.4
[NixPkgs.git] / pkgs / tools / misc / grub / default.nix
blobb5998456798d30cac8e7fadd98cc3b71d842e23b
1 { lib, stdenv, fetchFromSavannah, flex, bison, python3, autoconf, automake, libtool, bash
2 , gettext, ncurses, libusb-compat-0_1, freetype, qemu, lvm2, unifont, pkg-config
3 , help2man
4 , fetchzip
5 , buildPackages
6 , nixosTests
7 , fuse # only needed for grub-mount
8 , runtimeShell
9 , zfs ? null
10 , efiSupport ? false
11 , zfsSupport ? false
12 , xenSupport ? false
13 , kbdcompSupport ? false, ckbcomp
16 let
17   pcSystems = {
18     i686-linux.target = "i386";
19     x86_64-linux.target = "i386";
20   };
22   efiSystemsBuild = {
23     i686-linux.target = "i386";
24     x86_64-linux.target = "x86_64";
25     armv7l-linux.target = "arm";
26     aarch64-linux.target = "aarch64";
27     riscv32-linux.target = "riscv32";
28     riscv64-linux.target = "riscv64";
29   };
31   # For aarch64, we need to use '--target=aarch64-efi' when building,
32   # but '--target=arm64-efi' when installing. Insanity!
33   efiSystemsInstall = {
34     i686-linux.target = "i386";
35     x86_64-linux.target = "x86_64";
36     armv7l-linux.target = "arm";
37     aarch64-linux.target = "arm64";
38     riscv32-linux.target = "riscv32";
39     riscv64-linux.target = "riscv64";
40   };
42   canEfi = lib.any (system: stdenv.hostPlatform.system == system) (lib.mapAttrsToList (name: _: name) efiSystemsBuild);
43   inPCSystems = lib.any (system: stdenv.hostPlatform.system == system) (lib.mapAttrsToList (name: _: name) pcSystems);
45   gnulib = fetchFromSavannah {
46     repo = "gnulib";
47     # NOTE: keep in sync with bootstrap.conf!
48     rev = "9f48fb992a3d7e96610c4ce8be969cff2d61a01b";
49     hash = "sha256-mzbF66SNqcSlI+xmjpKpNMwzi13yEWoc1Fl7p4snTto=";
50   };
52   src = fetchFromSavannah {
53     repo = "grub";
54     rev = "grub-2.12";
55     hash = "sha256-lathsBb2f7urh8R86ihpTdwo3h1hAHnRiHd5gCLVpBc=";
56   };
58   # The locales are fetched from translationproject.org at build time,
59   # but those translations are not versioned/stable. For that reason
60   # we take them from the nearest release tarball instead:
61   locales = fetchzip {
62     url = "https://ftp.gnu.org/gnu/grub/grub-2.12.tar.gz";
63     hash = "sha256-IoRiJHNQ58y0UhCAD0CrpFiI8Mz1upzAtyh5K4Njh/w=";
64   };
65 in (
67 assert efiSupport -> canEfi;
68 assert zfsSupport -> zfs != null;
69 assert !(efiSupport && xenSupport);
71 stdenv.mkDerivation rec {
72   pname = "grub";
73   version = "2.12";
74   inherit src;
76   patches = [
77     ./fix-bash-completion.patch
78     ./add-hidden-menu-entries.patch
79   ];
81   postPatch = if kbdcompSupport then ''
82     sed -i util/grub-kbdcomp.in -e 's@\bckbcomp\b@${ckbcomp}/bin/ckbcomp@'
83   '' else ''
84     echo '#! ${runtimeShell}' > util/grub-kbdcomp.in
85     echo 'echo "Compile grub2 with { kbdcompSupport = true; } to enable support for this command."' >> util/grub-kbdcomp.in
86   '';
88   depsBuildBuild = [ buildPackages.stdenv.cc ];
89   nativeBuildInputs = [ bison flex python3 pkg-config gettext freetype autoconf automake help2man ];
90   buildInputs = [ ncurses libusb-compat-0_1 freetype lvm2 fuse libtool bash ]
91     ++ lib.optional doCheck qemu
92     ++ lib.optional zfsSupport zfs;
94   strictDeps = true;
96   hardeningDisable = [ "all" ];
98   separateDebugInfo = !xenSupport;
100   preConfigure = ''
101        for i in "tests/util/"*.in
102        do
103          sed -i "$i" -e's|/bin/bash|${stdenv.shell}|g'
104        done
106        # Apparently, the QEMU executable is no longer called
107        # `qemu-system-i386', even on i386.
108        #
109        # In addition, use `-nodefaults' to avoid errors like:
110        #
111        #  chardev: opening backend "stdio" failed
112        #  qemu: could not open serial device 'stdio': Invalid argument
113        #
114        # See <http://www.mail-archive.com/qemu-devel@nongnu.org/msg22775.html>.
115        sed -i "tests/util/grub-shell.in" \
116            -e's/qemu-system-i386/qemu-system-x86_64 -nodefaults/g'
118       unset CPP # setting CPP intereferes with dependency calculation
120       patchShebangs .
122       GNULIB_REVISION=$(. bootstrap.conf; echo $GNULIB_REVISION)
123       if [ "$GNULIB_REVISION" != ${gnulib.rev} ]; then
124         echo "This version of GRUB requires a different gnulib revision!"
125         echo "We have: ${gnulib.rev}"
126         echo "GRUB needs: $GNULIB_REVISION"
127         exit 1
128       fi
130       cp -f --no-preserve=mode ${locales}/po/LINGUAS ${locales}/po/*.po po
132       ./bootstrap --no-git --gnulib-srcdir=${gnulib}
134       substituteInPlace ./configure --replace '/usr/share/fonts/unifont' '${unifont}/share/fonts'
135     '';
137   postConfigure = ''
138     # make sure .po files are up to date to workaround
139     # parallel `msgmerge --update` on autogenerated .po files:
140     #   https://github.com/NixOS/nixpkgs/pull/248747#issuecomment-1676301670
141     make dist
142   '';
144   configureFlags = [
145     "--enable-grub-mount" # dep of os-prober
146   ] ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
147     # grub doesn't do cross-compilation as usual and tries to use unprefixed
148     # tools to target the host. Provide toolchain information explicitly for
149     # cross builds.
150     #
151     # Ref: # https://github.com/buildroot/buildroot/blob/master/boot/grub2/grub2.mk#L108
152     "TARGET_CC=${stdenv.cc.targetPrefix}cc"
153     "TARGET_NM=${stdenv.cc.targetPrefix}nm"
154     "TARGET_OBJCOPY=${stdenv.cc.targetPrefix}objcopy"
155     "TARGET_RANLIB=${stdenv.cc.targetPrefix}ranlib"
156     "TARGET_STRIP=${stdenv.cc.targetPrefix}strip"
157   ] ++ lib.optional zfsSupport "--enable-libzfs"
158     ++ lib.optionals efiSupport [ "--with-platform=efi" "--target=${efiSystemsBuild.${stdenv.hostPlatform.system}.target}" "--program-prefix=" ]
159     ++ lib.optionals xenSupport [ "--with-platform=xen" "--target=${efiSystemsBuild.${stdenv.hostPlatform.system}.target}"];
161   # save target that grub is compiled for
162   grubTarget = if efiSupport
163                then "${efiSystemsInstall.${stdenv.hostPlatform.system}.target}-efi"
164                else lib.optionalString inPCSystems "${pcSystems.${stdenv.hostPlatform.system}.target}-pc";
166   doCheck = false;
167   enableParallelBuilding = true;
169   postInstall = ''
170     # Avoid a runtime reference to gcc
171     sed -i $out/lib/grub/*/modinfo.sh -e "/grub_target_cppflags=/ s|'.*'|' '|"
172     # just adding bash to buildInputs wasn't enough to fix the shebang
173     substituteInPlace $out/lib/grub/*/modinfo.sh \
174       --replace ${buildPackages.bash} "/usr/bin/bash"
175   '';
177   passthru.tests = {
178     nixos-grub = nixosTests.grub;
179     nixos-install-simple = nixosTests.installer.simple;
180     nixos-install-grub-uefi = nixosTests.installer.simpleUefiGrub;
181     nixos-install-grub-uefi-spec = nixosTests.installer.simpleUefiGrubSpecialisation;
182   };
184   meta = with lib; {
185     description = "GNU GRUB, the Grand Unified Boot Loader";
187     longDescription = ''
188       GNU GRUB is a Multiboot boot loader. It was derived from GRUB, GRand
189       Unified Bootloader, which was originally designed and implemented by
190       Erich Stefan Boleyn.
192       Briefly, the boot loader is the first software program that runs when a
193       computer starts.  It is responsible for loading and transferring
194       control to the operating system kernel software (such as the Hurd or
195       the Linux).  The kernel, in turn, initializes the rest of the
196       operating system (e.g., GNU).
197     '';
199     homepage = "https://www.gnu.org/software/grub/";
201     license = licenses.gpl3Plus;
203     platforms = if xenSupport then [ "x86_64-linux" "i686-linux" ] else platforms.gnu ++ platforms.linux;
205     maintainers = [ ];
206   };