gnome.gdm: Simplify DESTDIR hack

Let’s point `DESTDIR` to a path under the build directory rather than under "$out".
This will prevent `installPhase` from creating `$out` or any other output directory,
allowing us to install the outputs just by moving them out of `$DESTDIR` directly into the store with `mv`.
Of course, that will also require moving the installing of `etc` after the outputs are installed.

Since `$out` does not currently contain `etc` subdirectory, we can also just move `$DESTDIR/etc` directly to `$out` rather than copying it.
And even if `$out/etc` existed, we could just merge it with `cp --recursive` instead of `rsync` so `rsync` is not actually necessary.

The code remains written defensively against files accidentally being misplaced while shuffling them around – parent directories of targets are used as `mv` destinations so that the move fails loudly if the directory already exists, rather than being moved inside as e.g. `$out/etc/etc`.

While at it let’s also improve practices a bit:
- Quote command arguments.
- Move `DESTDIR` definition into `env` block.
- Add vertical space and clearer comments.
- Handle non-standard Nix store paths.
This commit is contained in:
Jan Tojnar 2023-11-19 17:05:49 +01:00
parent c757e9bd77
commit ff61f2bb3f

View File

@ -5,7 +5,6 @@
, substituteAll , substituteAll
, meson , meson
, ninja , ninja
, rsync
, pkg-config , pkg-config
, glib , glib
, itstool , itstool
@ -70,7 +69,6 @@ stdenv.mkDerivation (finalAttrs: {
meson meson
ninja ninja
pkg-config pkg-config
rsync
gobject-introspection gobject-introspection
]; ];
@ -131,33 +129,36 @@ stdenv.mkDerivation (finalAttrs: {
''; '';
preInstall = '' preInstall = ''
install -D ${override} $DESTDIR/$out/share/glib-2.0/schemas/org.gnome.login-screen.gschema.override install -D ${override} "$DESTDIR/$out/share/glib-2.0/schemas/org.gnome.login-screen.gschema.override"
''; '';
postInstall = '' postInstall = ''
# Move stuff from DESTDIR to proper location. # Move stuff from DESTDIR to proper location.
# We use rsync to merge the directories.
rsync --archive "$DESTDIR/etc" "$out"
rm --recursive "$DESTDIR/etc"
for o in $(getAllOutputNames); do for o in $(getAllOutputNames); do
# debug is created later by _separateDebugInfo hook.
if [[ "$o" = "debug" ]]; then continue; fi if [[ "$o" = "debug" ]]; then continue; fi
rsync --archive "$DESTDIR/''${!o}" "$(dirname "''${!o}")" mv "$DESTDIR''${!o}" "$(dirname "''${!o}")"
rm --recursive "$DESTDIR/''${!o}"
done done
# Ensure the DESTDIR is removed.
rmdir "$DESTDIR/nix/store" "$DESTDIR/nix" "$DESTDIR" mv "$DESTDIR/etc" "$out"
# Ensure we did not forget to install anything.
rmdir --parents --ignore-fail-on-non-empty "$DESTDIR${builtins.storeDir}"
! test -e "$DESTDIR"
# We are setting DESTDIR so the post-install script does not compile the schemas. # We are setting DESTDIR so the post-install script does not compile the schemas.
glib-compile-schemas "$out/share/glib-2.0/schemas" glib-compile-schemas "$out/share/glib-2.0/schemas"
''; '';
# HACK: We want to install configuration files to $out/etc env = {
# but GDM should read them from /etc on a NixOS system. # HACK: We want to install configuration files to $out/etc
# With autotools, it was possible to override Make variables # but GDM should read them from /etc on a NixOS system.
# at install time but Meson does not support this # With autotools, it was possible to override Make variables
# so we need to convince it to install all files to a temporary # at install time but Meson does not support this
# location using DESTDIR and then move it to proper one in postInstall. # so we need to convince it to install all files to a temporary
DESTDIR = "${placeholder "out"}/dest"; # location using DESTDIR and then move it to proper one in postInstall.
DESTDIR = "dest";
};
separateDebugInfo = true; separateDebugInfo = true;