From 238a6053c43f7ac2e3dcc3d3c7f29f1e0c0be589 Mon Sep 17 00:00:00 2001 From: Artturin Date: Wed, 1 Jun 2022 00:34:59 +0300 Subject: [PATCH 01/16] stdenv: support opt-in __structuredAttrs Co-authored-by: Robin Gloster stdenv: print message if structuredAttrs is enabled stdenv: add _append reduces the chance of a user doing it wrong fix nix develop issue output hooks don't work yet in nix develop though making $outputs be the same on non-structuredAttrs and structuredAttrs is too much trouble. lets instead make a function that gets the output names reading environment file '/nix/store/2x7m69a2sm2kh0r6v0q5s9z1dh41m4xf-xz-5.2.5-env-bin' nix: src/nix/develop.cc:299: std::string Common::makeRcScript(nix::ref, const BuildEnvironment&, const Path&): Assertion `outputs != buildEnvironment.vars.end()' failed. use a function to get all output names instead of using $outputs copy env functionality from https://github.com/NixOS/nixpkgs/pull/76732/commits --- .../cluster/nomad-autoscaler/default.nix | 2 +- .../bintools-wrapper/default.nix | 4 +- pkgs/build-support/release/nix-build.nix | 2 +- .../setup-hooks/auto-patchelf.sh | 2 +- pkgs/build-support/setup-hooks/move-docs.sh | 12 +- .../setup-hooks/multiple-outputs.sh | 32 ++- .../patch-ppd-files/patch-ppd-hook.sh | 2 +- pkgs/build-support/setup-hooks/strip.sh | 21 +- .../build-support/setup-hooks/win-dll-link.sh | 2 +- pkgs/build-support/testers/expect-failure.sh | 2 +- .../data/icons/catppuccin-cursors/default.nix | 2 +- pkgs/data/icons/comixcursors/default.nix | 2 +- pkgs/desktops/gnome/core/gdm/default.nix | 2 +- pkgs/development/compilers/openjdk/11.nix | 4 +- pkgs/development/compilers/openjdk/12.nix | 4 +- pkgs/development/compilers/openjdk/13.nix | 4 +- pkgs/development/compilers/openjdk/14.nix | 4 +- pkgs/development/compilers/openjdk/15.nix | 4 +- pkgs/development/compilers/openjdk/16.nix | 4 +- pkgs/development/compilers/openjdk/17.nix | 4 +- pkgs/development/compilers/openjdk/18.nix | 4 +- pkgs/development/compilers/openjdk/19.nix | 4 +- pkgs/development/compilers/openjdk/8.nix | 4 +- pkgs/development/libraries/polkit/default.nix | 2 +- .../darwin/signing-utils/auto-sign-hook.sh | 2 +- pkgs/stdenv/generic/default-builder.sh | 4 + pkgs/stdenv/generic/make-derivation.nix | 31 ++- pkgs/stdenv/generic/setup.sh | 222 +++++++++++++----- pkgs/tools/typesetting/tex/texlive/bin.nix | 2 +- 29 files changed, 271 insertions(+), 119 deletions(-) diff --git a/pkgs/applications/networking/cluster/nomad-autoscaler/default.nix b/pkgs/applications/networking/cluster/nomad-autoscaler/default.nix index 6329ff9ed11c..eb185f9743c1 100644 --- a/pkgs/applications/networking/cluster/nomad-autoscaler/default.nix +++ b/pkgs/applications/networking/cluster/nomad-autoscaler/default.nix @@ -45,7 +45,7 @@ let mv bin/nomad-autoscaler $bin/bin ln -s $bin/bin/nomad-autoscaler $out/bin/nomad-autoscaler - for d in $outputs; do + for d in $(getAllOutputNames); do mkdir -p ''${!d}/share done rmdir $bin/share diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index 121b50fe0f52..ea925e90fa47 100644 --- a/pkgs/build-support/bintools-wrapper/default.nix +++ b/pkgs/build-support/bintools-wrapper/default.nix @@ -68,7 +68,7 @@ let # The dynamic linker has different names on different platforms. This is a # shell glob that ought to match it. dynamicLinker = - /**/ if sharedLibraryLoader == null then null + /**/ if sharedLibraryLoader == null then "" else if targetPlatform.libc == "musl" then "${sharedLibraryLoader}/lib/ld-musl-*" else if targetPlatform.libc == "uclibc" then "${sharedLibraryLoader}/lib/ld*-uClibc.so.1" else if (targetPlatform.libc == "bionic" && targetPlatform.is32bit) then "/system/bin/linker" @@ -87,7 +87,7 @@ let else if targetPlatform.isDarwin then "/usr/lib/dyld" else if targetPlatform.isFreeBSD then "/libexec/ld-elf.so.1" else if lib.hasSuffix "pc-gnu" targetPlatform.config then "ld.so.1" - else null; + else ""; expand-response-params = if buildPackages ? stdenv && buildPackages.stdenv.hasCC && buildPackages.stdenv.cc != "/dev/null" diff --git a/pkgs/build-support/release/nix-build.nix b/pkgs/build-support/release/nix-build.nix index ac51b90e0163..5ed2b0752efc 100644 --- a/pkgs/build-support/release/nix-build.nix +++ b/pkgs/build-support/release/nix-build.nix @@ -124,7 +124,7 @@ stdenv.mkDerivation ( echo "$system" > $out/nix-support/system if [ -z "${toString doingAnalysis}" ]; then - for i in $outputs; do + for i in $(getAllOutputNames); do if [ "$i" = out ]; then j=none; else j="$i"; fi mkdir -p ''${!i}/nix-support echo "nix-build $j ''${!i}" >> ''${!i}/nix-support/hydra-build-products diff --git a/pkgs/build-support/setup-hooks/auto-patchelf.sh b/pkgs/build-support/setup-hooks/auto-patchelf.sh index 7f5ff146e30b..8a74a69bdceb 100644 --- a/pkgs/build-support/setup-hooks/auto-patchelf.sh +++ b/pkgs/build-support/setup-hooks/auto-patchelf.sh @@ -84,7 +84,7 @@ autoPatchelf() { # (Expressions don't expand in single quotes, use double quotes for that.) postFixupHooks+=(' if [ -z "${dontAutoPatchelf-}" ]; then - autoPatchelf -- $(for output in $outputs; do + autoPatchelf -- $(for output in $(getAllOutputNames); do [ -e "${!output}" ] || continue echo "${!output}" done) diff --git a/pkgs/build-support/setup-hooks/move-docs.sh b/pkgs/build-support/setup-hooks/move-docs.sh index e4460f98816d..833113aa0fc8 100644 --- a/pkgs/build-support/setup-hooks/move-docs.sh +++ b/pkgs/build-support/setup-hooks/move-docs.sh @@ -5,10 +5,17 @@ preFixupHooks+=(_moveToShare) _moveToShare() { - forceShare=${forceShare:=man doc info} + if [ -n "$__structuredAttrs" ]; then + if [ -z "${forceShare-}" ]; then + forceShare=( man doc info ) + fi + else + forceShare=( ${forceShare:-man doc info} ) + fi + if [[ -z "$out" ]]; then return; fi - for d in $forceShare; do + for d in "${forceShare[@]}"; do if [ -d "$out/$d" ]; then if [ -d "$out/share/$d" ]; then echo "both $d/ and share/$d/ exist!" @@ -20,4 +27,3 @@ _moveToShare() { fi done } - diff --git a/pkgs/build-support/setup-hooks/multiple-outputs.sh b/pkgs/build-support/setup-hooks/multiple-outputs.sh index 881cf6c90f48..8a2fc2f915e9 100644 --- a/pkgs/build-support/setup-hooks/multiple-outputs.sh +++ b/pkgs/build-support/setup-hooks/multiple-outputs.sh @@ -47,7 +47,7 @@ _overrideFirst outputInfo "info" "$outputBin" # Add standard flags to put files into the desired outputs. _multioutConfig() { - if [ "$outputs" = "out" ] || [ -z "${setOutputFlags-1}" ]; then return; fi; + if [ "$(getAllOutputNames)" = "out" ] || [ -z "${setOutputFlags-1}" ]; then return; fi; # try to detect share/doc/${shareDocName} # Note: sadly, $configureScript detection comes later in configurePhase, @@ -66,19 +66,17 @@ _multioutConfig() { fi fi - configureFlags="\ - --bindir=${!outputBin}/bin --sbindir=${!outputBin}/sbin \ - --includedir=${!outputInclude}/include --oldincludedir=${!outputInclude}/include \ - --mandir=${!outputMan}/share/man --infodir=${!outputInfo}/share/info \ - --docdir=${!outputDoc}/share/doc/${shareDocName} \ - --libdir=${!outputLib}/lib --libexecdir=${!outputLib}/libexec \ - --localedir=${!outputLib}/share/locale \ - $configureFlags" + prependToVar configureFlags \ + --bindir="${!outputBin}"/bin --sbindir="${!outputBin}"/sbin \ + --includedir="${!outputInclude}"/include --oldincludedir="${!outputInclude}"/include \ + --mandir="${!outputMan}"/share/man --infodir="${!outputInfo}"/share/info \ + --docdir="${!outputDoc}"/share/doc/"${shareDocName}" \ + --libdir="${!outputLib}"/lib --libexecdir="${!outputLib}"/libexec \ + --localedir="${!outputLib}"/share/locale - installFlags="\ - pkgconfigdir=${!outputDev}/lib/pkgconfig \ - m4datadir=${!outputDev}/share/aclocal aclocaldir=${!outputDev}/share/aclocal \ - $installFlags" + prependToVar installFlags \ + pkgconfigdir="${!outputDev}"/lib/pkgconfig \ + m4datadir="${!outputDev}"/share/aclocal aclocaldir="${!outputDev}"/share/aclocal } @@ -94,7 +92,7 @@ moveToOutput() { local patt="$1" local dstOut="$2" local output - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "${!output}" = "$dstOut" ]; then continue; fi local srcPath for srcPath in "${!output}"/$patt; do @@ -149,7 +147,7 @@ _multioutDocs() { # Move development-only stuff to the desired outputs. _multioutDevs() { - if [ "$outputs" = "out" ] || [ -z "${moveToDev-1}" ]; then return; fi; + if [ "$(getAllOutputNames)" = "out" ] || [ -z "${moveToDev-1}" ]; then return; fi; moveToOutput include "${!outputInclude}" # these files are sometimes provided even without using the corresponding tool moveToOutput lib/pkgconfig "${!outputDev}" @@ -166,10 +164,10 @@ _multioutDevs() { # Make the "dev" propagate other outputs needed for development. _multioutPropagateDev() { - if [ "$outputs" = "out" ]; then return; fi; + if [ "$(getAllOutputNames)" = "out" ]; then return; fi; local outputFirst - for outputFirst in $outputs; do + for outputFirst in $(getAllOutputNames); do break done local propagaterOutput="$outputDev" diff --git a/pkgs/build-support/setup-hooks/patch-ppd-files/patch-ppd-hook.sh b/pkgs/build-support/setup-hooks/patch-ppd-files/patch-ppd-hook.sh index a450ecd7f963..77322b245b27 100644 --- a/pkgs/build-support/setup-hooks/patch-ppd-files/patch-ppd-hook.sh +++ b/pkgs/build-support/setup-hooks/patch-ppd-files/patch-ppd-hook.sh @@ -70,7 +70,7 @@ patchPpdFileCommands () { # * outputs of current build before buildInputs # * `/lib/cups/filter' before `/bin` # * add HOST_PATH at end, so we don't miss anything - for path in $outputs; do + for path in $(getAllOutputNames); do addToSearchPath cupspath "${!path}/lib/cups/filter" addToSearchPath cupspath "${!path}/bin" done diff --git a/pkgs/build-support/setup-hooks/strip.sh b/pkgs/build-support/setup-hooks/strip.sh index 9bd7b24cab54..104b5515b3db 100644 --- a/pkgs/build-support/setup-hooks/strip.sh +++ b/pkgs/build-support/setup-hooks/strip.sh @@ -12,11 +12,20 @@ _doStrip() { local -ra stripCmds=(STRIP STRIP_FOR_TARGET) local -ra ranlibCmds=(RANLIB RANLIB_FOR_TARGET) + # TODO(structured-attrs): This doesn't work correctly if one of + # the items in strip*List or strip*Flags contains a space, + # even with structured attrs enabled. This is OK for now + # because very few packages set any of these, and it doesn't + # affect any of them. + # + # After __structuredAttrs = true is universal, come back and + # push arrays all the way through this logic. + # Strip only host paths by default. Leave targets as is. - stripDebugList=${stripDebugList:-lib lib32 lib64 libexec bin sbin} - stripDebugListTarget=${stripDebugListTarget:-} - stripAllList=${stripAllList:-} - stripAllListTarget=${stripAllListTarget:-} + stripDebugList=${stripDebugList[*]:-lib lib32 lib64 libexec bin sbin} + stripDebugListTarget=${stripDebugListTarget[*]:-} + stripAllList=${stripAllList[*]:-} + stripAllListTarget=${stripAllListTarget[*]:-} local i for i in ${!stripCmds[@]}; do @@ -30,8 +39,8 @@ _doStrip() { if [[ "${dontStrip-}" || "${flag-}" ]] || ! type -f "${stripCmd-}" 2>/dev/null then continue; fi - stripDirs "$stripCmd" "$ranlibCmd" "$debugDirList" "${stripDebugFlags:--S}" - stripDirs "$stripCmd" "$ranlibCmd" "$allDirList" "${stripAllFlags:--s}" + stripDirs "$stripCmd" "$ranlibCmd" "$debugDirList" "${stripDebugFlags[*]:--S}" + stripDirs "$stripCmd" "$ranlibCmd" "$allDirList" "${stripAllFlags[*]:--s}" done } diff --git a/pkgs/build-support/setup-hooks/win-dll-link.sh b/pkgs/build-support/setup-hooks/win-dll-link.sh index 6130f32bef86..ca4cbb349b6c 100644 --- a/pkgs/build-support/setup-hooks/win-dll-link.sh +++ b/pkgs/build-support/setup-hooks/win-dll-link.sh @@ -15,7 +15,7 @@ _linkDLLs() { # prefix $PATH by currently-built outputs local DLLPATH="" local outName - for outName in $outputs; do + for outName in $(getAllOutputNames); do addToSearchPath DLLPATH "${!outName}/bin" done DLLPATH="$DLLPATH:$PATH" diff --git a/pkgs/build-support/testers/expect-failure.sh b/pkgs/build-support/testers/expect-failure.sh index 0e1bbe9a678c..052ee8527176 100644 --- a/pkgs/build-support/testers/expect-failure.sh +++ b/pkgs/build-support/testers/expect-failure.sh @@ -35,7 +35,7 @@ echo "testBuildFailure: Original builder produced exit code: $r" # ----------------------------------------- # Write the build log to the default output -outs=( $outputs ) +outs=( $(getAllOutputNames) ) defOut=${outs[0]} defOutPath=${!defOut} diff --git a/pkgs/data/icons/catppuccin-cursors/default.nix b/pkgs/data/icons/catppuccin-cursors/default.nix index d9eccc96a029..4559705c169b 100644 --- a/pkgs/data/icons/catppuccin-cursors/default.nix +++ b/pkgs/data/icons/catppuccin-cursors/default.nix @@ -50,7 +50,7 @@ stdenvNoCC.mkDerivation { installPhase = '' runHook preInstall - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" != "out" ]; then local outputDir="''${!output}" local iconsDir="$outputDir"/share/icons diff --git a/pkgs/data/icons/comixcursors/default.nix b/pkgs/data/icons/comixcursors/default.nix index b63877b28209..1c4fdc195180 100644 --- a/pkgs/data/icons/comixcursors/default.nix +++ b/pkgs/data/icons/comixcursors/default.nix @@ -52,7 +52,7 @@ stdenvNoCC.mkDerivation rec { ''; installPhase = '' - for outputName in $outputs ; do + for outputName in $(getAllOutputNames) ; do if [ $outputName != out ]; then local outputDir=''${!outputName}; local iconsDir=$outputDir/share/icons diff --git a/pkgs/desktops/gnome/core/gdm/default.nix b/pkgs/desktops/gnome/core/gdm/default.nix index f1fbe7e49d30..a2265387e1ef 100644 --- a/pkgs/desktops/gnome/core/gdm/default.nix +++ b/pkgs/desktops/gnome/core/gdm/default.nix @@ -143,7 +143,7 @@ stdenv.mkDerivation rec { # We use rsync to merge the directories. rsync --archive "${DESTDIR}/etc" "$out" rm --recursive "${DESTDIR}/etc" - for o in $outputs; do + for o in $(getAllOutputNames); do if [[ "$o" = "debug" ]]; then continue; fi rsync --archive "${DESTDIR}/''${!o}" "$(dirname "''${!o}")" rm --recursive "${DESTDIR}/''${!o}" diff --git a/pkgs/development/compilers/openjdk/11.nix b/pkgs/development/compilers/openjdk/11.nix index 95abb373272c..33c3177d2927 100644 --- a/pkgs/development/compilers/openjdk/11.nix +++ b/pkgs/development/compilers/openjdk/11.nix @@ -132,12 +132,12 @@ let postFixup = '' # Build the set of output library directories to rpath against LIBDIRS="" - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi LIBDIRS="$(find $(eval echo \$$output) -name \*.so\* -exec dirname {} \+ | sort | uniq | tr '\n' ':'):$LIBDIRS" done # Add the local library paths to remove dependencies on the bootstrap - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi OUTPUTDIR=$(eval echo \$$output) BINLIBS=$(find $OUTPUTDIR/bin/ -type f; find $OUTPUTDIR -name \*.so\*) diff --git a/pkgs/development/compilers/openjdk/12.nix b/pkgs/development/compilers/openjdk/12.nix index 60100a5ecc16..f56cf4a79220 100644 --- a/pkgs/development/compilers/openjdk/12.nix +++ b/pkgs/development/compilers/openjdk/12.nix @@ -136,12 +136,12 @@ let postFixup = '' # Build the set of output library directories to rpath against LIBDIRS="" - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi LIBDIRS="$(find $(eval echo \$$output) -name \*.so\* -exec dirname {} \+ | sort | uniq | tr '\n' ':'):$LIBDIRS" done # Add the local library paths to remove dependencies on the bootstrap - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi OUTPUTDIR=$(eval echo \$$output) BINLIBS=$(find $OUTPUTDIR/bin/ -type f; find $OUTPUTDIR -name \*.so\*) diff --git a/pkgs/development/compilers/openjdk/13.nix b/pkgs/development/compilers/openjdk/13.nix index 68a0a9fa7007..ce84d334b426 100644 --- a/pkgs/development/compilers/openjdk/13.nix +++ b/pkgs/development/compilers/openjdk/13.nix @@ -136,12 +136,12 @@ let postFixup = '' # Build the set of output library directories to rpath against LIBDIRS="" - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi LIBDIRS="$(find $(eval echo \$$output) -name \*.so\* -exec dirname {} \+ | sort | uniq | tr '\n' ':'):$LIBDIRS" done # Add the local library paths to remove dependencies on the bootstrap - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi OUTPUTDIR=$(eval echo \$$output) BINLIBS=$(find $OUTPUTDIR/bin/ -type f; find $OUTPUTDIR -name \*.so\*) diff --git a/pkgs/development/compilers/openjdk/14.nix b/pkgs/development/compilers/openjdk/14.nix index 37c3a6a3de3a..8e92b906189c 100644 --- a/pkgs/development/compilers/openjdk/14.nix +++ b/pkgs/development/compilers/openjdk/14.nix @@ -132,12 +132,12 @@ let postFixup = '' # Build the set of output library directories to rpath against LIBDIRS="" - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi LIBDIRS="$(find $(eval echo \$$output) -name \*.so\* -exec dirname {} \+ | sort | uniq | tr '\n' ':'):$LIBDIRS" done # Add the local library paths to remove dependencies on the bootstrap - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi OUTPUTDIR=$(eval echo \$$output) BINLIBS=$(find $OUTPUTDIR/bin/ -type f; find $OUTPUTDIR -name \*.so\*) diff --git a/pkgs/development/compilers/openjdk/15.nix b/pkgs/development/compilers/openjdk/15.nix index 6ea1d0b1dd31..c33e937f9f24 100644 --- a/pkgs/development/compilers/openjdk/15.nix +++ b/pkgs/development/compilers/openjdk/15.nix @@ -131,12 +131,12 @@ let postFixup = '' # Build the set of output library directories to rpath against LIBDIRS="" - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi LIBDIRS="$(find $(eval echo \$$output) -name \*.so\* -exec dirname {} \+ | sort | uniq | tr '\n' ':'):$LIBDIRS" done # Add the local library paths to remove dependencies on the bootstrap - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi OUTPUTDIR=$(eval echo \$$output) BINLIBS=$(find $OUTPUTDIR/bin/ -type f; find $OUTPUTDIR -name \*.so\*) diff --git a/pkgs/development/compilers/openjdk/16.nix b/pkgs/development/compilers/openjdk/16.nix index 0e1911bb1a70..461cd724144e 100644 --- a/pkgs/development/compilers/openjdk/16.nix +++ b/pkgs/development/compilers/openjdk/16.nix @@ -138,12 +138,12 @@ let postFixup = '' # Build the set of output library directories to rpath against LIBDIRS="" - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi LIBDIRS="$(find $(eval echo \$$output) -name \*.so\* -exec dirname {} \+ | sort | uniq | tr '\n' ':'):$LIBDIRS" done # Add the local library paths to remove dependencies on the bootstrap - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi OUTPUTDIR=$(eval echo \$$output) BINLIBS=$(find $OUTPUTDIR/bin/ -type f; find $OUTPUTDIR -name \*.so\*) diff --git a/pkgs/development/compilers/openjdk/17.nix b/pkgs/development/compilers/openjdk/17.nix index bc92b1393fdb..6d8087d7e948 100644 --- a/pkgs/development/compilers/openjdk/17.nix +++ b/pkgs/development/compilers/openjdk/17.nix @@ -149,12 +149,12 @@ let postFixup = '' # Build the set of output library directories to rpath against LIBDIRS="" - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi LIBDIRS="$(find $(eval echo \$$output) -name \*.so\* -exec dirname {} \+ | sort -u | tr '\n' ':'):$LIBDIRS" done # Add the local library paths to remove dependencies on the bootstrap - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi OUTPUTDIR=$(eval echo \$$output) BINLIBS=$(find $OUTPUTDIR/bin/ -type f; find $OUTPUTDIR -name \*.so\*) diff --git a/pkgs/development/compilers/openjdk/18.nix b/pkgs/development/compilers/openjdk/18.nix index 5be60eb94875..fd620aaaf9a5 100644 --- a/pkgs/development/compilers/openjdk/18.nix +++ b/pkgs/development/compilers/openjdk/18.nix @@ -140,12 +140,12 @@ let postFixup = '' # Build the set of output library directories to rpath against LIBDIRS="" - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi LIBDIRS="$(find $(eval echo \$$output) -name \*.so\* -exec dirname {} \+ | sort -u | tr '\n' ':'):$LIBDIRS" done # Add the local library paths to remove dependencies on the bootstrap - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi OUTPUTDIR=$(eval echo \$$output) BINLIBS=$(find $OUTPUTDIR/bin/ -type f; find $OUTPUTDIR -name \*.so\*) diff --git a/pkgs/development/compilers/openjdk/19.nix b/pkgs/development/compilers/openjdk/19.nix index 11b2fa60c733..9537b0d3ce52 100644 --- a/pkgs/development/compilers/openjdk/19.nix +++ b/pkgs/development/compilers/openjdk/19.nix @@ -140,12 +140,12 @@ let postFixup = '' # Build the set of output library directories to rpath against LIBDIRS="" - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi LIBDIRS="$(find $(eval echo \$$output) -name \*.so\* -exec dirname {} \+ | sort -u | tr '\n' ':'):$LIBDIRS" done # Add the local library paths to remove dependencies on the bootstrap - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi OUTPUTDIR=$(eval echo \$$output) BINLIBS=$(find $OUTPUTDIR/bin/ -type f; find $OUTPUTDIR -name \*.so\*) diff --git a/pkgs/development/compilers/openjdk/8.nix b/pkgs/development/compilers/openjdk/8.nix index c232b1f01f16..5558a77ad90b 100644 --- a/pkgs/development/compilers/openjdk/8.nix +++ b/pkgs/development/compilers/openjdk/8.nix @@ -187,12 +187,12 @@ let postFixup = '' # Build the set of output library directories to rpath against LIBDIRS="" - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi LIBDIRS="$(find $(eval echo \$$output) -name \*.so\* -exec dirname {} \+ | sort | uniq | tr '\n' ':'):$LIBDIRS" done # Add the local library paths to remove dependencies on the bootstrap - for output in $outputs; do + for output in $(getAllOutputNames); do if [ "$output" = debug ]; then continue; fi OUTPUTDIR=$(eval echo \$$output) BINLIBS=$(find $OUTPUTDIR/bin/ -type f; find $OUTPUTDIR -name \*.so\*) diff --git a/pkgs/development/libraries/polkit/default.nix b/pkgs/development/libraries/polkit/default.nix index a0344d68a12b..6ab7a4bb9c3a 100644 --- a/pkgs/development/libraries/polkit/default.nix +++ b/pkgs/development/libraries/polkit/default.nix @@ -167,7 +167,7 @@ stdenv.mkDerivation rec { rsync --archive "${DESTDIR}${system}"/* "$out" rm --recursive "${DESTDIR}${system}"/* rmdir --parents --ignore-fail-on-non-empty "${DESTDIR}${system}" - for o in $outputs; do + for o in $(getAllOutputNames); do rsync --archive "${DESTDIR}/''${!o}" "$(dirname "''${!o}")" rm --recursive "${DESTDIR}/''${!o}" done diff --git a/pkgs/os-specific/darwin/signing-utils/auto-sign-hook.sh b/pkgs/os-specific/darwin/signing-utils/auto-sign-hook.sh index cca65661f8a9..6a254cd82123 100644 --- a/pkgs/os-specific/darwin/signing-utils/auto-sign-hook.sh +++ b/pkgs/os-specific/darwin/signing-utils/auto-sign-hook.sh @@ -25,7 +25,7 @@ signDarwinBinariesIn() { signDarwinBinariesInAllOutputs() { local output - for output in $outputs; do + for output in $(getAllOutputNames); do signDarwinBinariesIn "${!output}" done } diff --git a/pkgs/stdenv/generic/default-builder.sh b/pkgs/stdenv/generic/default-builder.sh index 273fc55c7552..8c6fec7873b6 100644 --- a/pkgs/stdenv/generic/default-builder.sh +++ b/pkgs/stdenv/generic/default-builder.sh @@ -1,2 +1,6 @@ +if [ -f .attrs.sh ]; then + . .attrs.sh +fi + source $stdenv/setup genericBuild diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index 510537aac9f3..09a71da93b6e 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -154,6 +154,12 @@ let (! attrs ? outputHash) # Fixed-output drvs can't be content addressed too && config.contentAddressedByDefault +# Experimental. For simple packages mostly just works, +# but for anything complex, be prepared to debug if enabling. +, __structuredAttrs ? false + +, env ? { } + , ... } @ attrs: let @@ -259,13 +265,16 @@ else let lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (lib.concatLists propagatedDependencies)); + envIsExportable = lib.isAttrs env && !lib.isDerivation env; + derivationArg = (removeAttrs attrs - ["meta" "passthru" "pos" + (["meta" "passthru" "pos" "checkInputs" "installCheckInputs" "__darwinAllowLocalNetworking" "__impureHostDeps" "__propagatedImpureHostDeps" - "sandboxProfile" "propagatedSandboxProfile"]) + "sandboxProfile" "propagatedSandboxProfile"] + ++ lib.optionals envIsExportable [ "env" ])) // (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) { name = let @@ -289,7 +298,7 @@ else let then attrs.name + hostSuffix else "${attrs.pname}${staticMarker}${hostSuffix}-${attrs.version}" ); - }) // { + }) // lib.optionalAttrs (envIsExportable && __structuredAttrs) { env = checkedEnv; } // { builder = attrs.realBuilder or stdenv.shell; args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)]; inherit stdenv; @@ -304,8 +313,7 @@ else let userHook = config.stdenv.userHook or null; __ignoreNulls = true; - - inherit strictDeps; + inherit __structuredAttrs strictDeps; depsBuildBuild = lib.elemAt (lib.elemAt dependencies 0) 0; nativeBuildInputs = lib.elemAt (lib.elemAt dependencies 0) 1; @@ -473,6 +481,17 @@ else let else true); }; + checkedEnv = + let + overlappingNames = lib.intersectLists (lib.attrNames env) (lib.attrNames derivationArg); + in + assert lib.assertMsg (overlappingNames == [ ]) + "The ‘env’ attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping: ${lib.concatStringsSep ", " overlappingNames}"; + lib.mapAttrs + (n: v: assert lib.assertMsg (lib.isString v || lib.isBool v || lib.isInt v) + "The ‘env’ attribute set can only contain string, boolean or integer attributes. The ‘${n}’ attribute is of type ${builtins.typeOf v}."; v) + env; + in lib.extendDerivation @@ -509,7 +528,7 @@ lib.extendDerivation # should be made available to Nix expressions using the # derivation (e.g., in assertions). passthru) - (derivation derivationArg); + (derivation (derivationArg // lib.optionalAttrs envIsExportable checkedEnv)); in fnOrAttrs: diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh index c6cdb6c3df75..de1dad5a1697 100644 --- a/pkgs/stdenv/generic/setup.sh +++ b/pkgs/stdenv/generic/setup.sh @@ -15,8 +15,29 @@ if (( "${NIX_DEBUG:-0}" >= 6 )); then set -x fi -: ${outputs:=out} +if [ -f .attrs.sh ]; then + __structuredAttrs=1 + echo "structuredAttrs is enabled" +else + __structuredAttrs= +fi +if [ -n "$__structuredAttrs" ]; then + for outputName in "${!outputs[@]}"; do + # ex: out=/nix/store/... + export "$outputName=${outputs[$outputName]}" + done +else + : ${outputs:=out} +fi + +getAllOutputNames() { + if [ -n "$__structuredAttrs" ]; then + echo "${!outputs[*]}" + else + echo "$outputs" + fi +} ###################################################################### # Hook handling. @@ -175,6 +196,63 @@ addToSearchPath() { addToSearchPathWithCustomDelimiter ":" "$@" } +# Prepend elements to variable "$1", which may come from an attr. +# +# This is useful in generic setup code, which must (for now) support +# both derivations with and without __structuredAttrs true, so the +# variable may be an array or a space-separated string. +# +# Expressions for individual packages should simply switch to array +# syntax when they switch to setting __structuredAttrs = true. +prependToVar() { + local -n nameref="$1"; shift + if [ -n "$__structuredAttrs" ]; then + nameref=( "$@" ${nameref+"${nameref[@]}"} ) + else + nameref="$* ${nameref-}" + fi +} + +# Same as above +appendToVar() { + local -n nameref="$1"; shift + if [ -n "$__structuredAttrs" ]; then + nameref=( ${nameref+"${nameref[@]}"} "$@" ) + else + nameref="${nameref-} $*" + fi +} + +# Accumulate into `flagsArray` the flags from the named variables. +# +# If __structuredAttrs, the variables are all treated as arrays +# and simply concatenated onto `flagsArray`. +# +# If not __structuredAttrs, then: +# * Each variable is treated as a string, and split on whitespace; +# * except variables whose names end in "Array", which are treated +# as arrays. +_accumFlagsArray() { + local name + if [ -n "$__structuredAttrs" ]; then + for name in "$@"; do + local -n nameref="$name" + flagsArray+=( ${nameref+"${nameref[@]}"} ) + done + else + for name in "$@"; do + local -n nameref="$name" + case "$name" in + *Array) + flagsArray+=( ${nameref+"${nameref[@]}"} ) ;; + *) + flagsArray+=( ${nameref-} ) ;; + esac + done + fi + +} + # Add $1/lib* into rpaths. # The function is used in multiple-outputs.sh hook, # so it is defined here but tried after the hook. @@ -255,6 +333,11 @@ printWords() { ###################################################################### # Initialisation. +# export all vars that should be in the ENV +for envVar in "${!env[@]}"; do + declare -x "${envVar}=${env[${envVar}]}" +done + # Set a fallback default value for SOURCE_DATE_EPOCH, used by some build tools # to provide a deterministic substitute for the "current" time. Note that @@ -469,6 +552,10 @@ findInputs() { done } +# The way we handle deps* and *Inputs works with structured attrs +# either enabled or disabled. For this it's convenient that the items +# in each list must be store paths, and therefore space-free. + # Make sure all are at least defined as empty : ${depsBuildBuild=} ${depsBuildBuildPropagated=} : ${nativeBuildInputs=} ${propagatedNativeBuildInputs=} ${defaultNativeBuildInputs=} @@ -477,29 +564,29 @@ findInputs() { : ${buildInputs=} ${propagatedBuildInputs=} ${defaultBuildInputs=} : ${depsTargetTarget=} ${depsTargetTargetPropagated=} -for pkg in $depsBuildBuild $depsBuildBuildPropagated; do +for pkg in ${depsBuildBuild[@]} ${depsBuildBuildPropagated[@]}; do findInputs "$pkg" -1 -1 done -for pkg in $nativeBuildInputs $propagatedNativeBuildInputs; do +for pkg in ${nativeBuildInputs[@]} ${propagatedNativeBuildInputs[@]}; do findInputs "$pkg" -1 0 done -for pkg in $depsBuildTarget $depsBuildTargetPropagated; do +for pkg in ${depsBuildTarget[@]} ${depsBuildTargetPropagated[@]}; do findInputs "$pkg" -1 1 done -for pkg in $depsHostHost $depsHostHostPropagated; do +for pkg in ${depsHostHost[@]} ${depsHostHostPropagated[@]}; do findInputs "$pkg" 0 0 done -for pkg in $buildInputs $propagatedBuildInputs ; do +for pkg in ${buildInputs[@]} ${propagatedBuildInputs[@]} ; do findInputs "$pkg" 0 1 done -for pkg in $depsTargetTarget $depsTargetTargetPropagated; do +for pkg in ${depsTargetTarget[@]} ${depsTargetTargetPropagated[@]}; do findInputs "$pkg" 1 1 done # Default inputs must be processed last -for pkg in $defaultNativeBuildInputs; do +for pkg in ${defaultNativeBuildInputs[@]}; do findInputs "$pkg" -1 0 done -for pkg in $defaultBuildInputs; do +for pkg in ${defaultBuildInputs[@]}; do findInputs "$pkg" 0 1 done @@ -909,6 +996,13 @@ unpackPhase() { srcs="$src" fi + local -a srcsArray + if [ -n "$__structuredAttrs" ]; then + srcsArray=( "${srcs[@]}" ) + else + srcsArray=( $srcs ) + fi + # To determine the source directory created by unpacking the # source archives, we record the contents of the current # directory, then look below which directory got added. Yeah, @@ -921,7 +1015,7 @@ unpackPhase() { done # Unpack all source archives. - for i in $srcs; do + for i in "${srcsArray[@]}"; do unpackFile "$i" done @@ -971,7 +1065,14 @@ unpackPhase() { patchPhase() { runHook prePatch - for i in ${patches:-}; do + local -a patchesArray + if [ -n "$__structuredAttrs" ]; then + patchesArray=( ${patches:+"${patches[@]}"} ) + else + patchesArray=( ${patches:-} ) + fi + + for i in "${patchesArray[@]}"; do header "applying patch $i" 3 local uncompress=cat case "$i" in @@ -988,9 +1089,17 @@ patchPhase() { uncompress="lzma -d" ;; esac + + local -a flagsArray + if [ -n "$__structuredAttrs" ]; then + flagsArray=( "${patchFlags[@]:--p1}" ) + else + # shellcheck disable=SC2086 + flagsArray=( ${patchFlags:--p1} ) + fi # "2>&1" is a hack to make patch fail if the decompressor fails (nonexistent patch, etc.) # shellcheck disable=SC2086 - $uncompress < "$i" 2>&1 | patch ${patchFlags:--p1} + $uncompress < "$i" 2>&1 | patch "${flagsArray[@]}" done runHook postPatch @@ -1018,7 +1127,6 @@ configurePhase() { # set to empty if unset : ${configureScript=} - : ${configureFlags=} if [[ -z "$configureScript" && -x ./configure ]]; then configureScript=./configure @@ -1049,31 +1157,29 @@ configurePhase() { fi if [[ -z "${dontAddPrefix:-}" && -n "$prefix" ]]; then - configureFlags="${prefixKey:---prefix=}$prefix $configureFlags" + prependToVar configureFlags "${prefixKey:---prefix=}$prefix" fi if [[ -f "$configureScript" ]]; then # Add --disable-dependency-tracking to speed up some builds. if [ -z "${dontAddDisableDepTrack:-}" ]; then if grep -q dependency-tracking "$configureScript"; then - configureFlags="--disable-dependency-tracking $configureFlags" + prependToVar configureFlags --disable-dependency-tracking fi fi # By default, disable static builds. if [ -z "${dontDisableStatic:-}" ]; then if grep -q enable-static "$configureScript"; then - configureFlags="--disable-static $configureFlags" + prependToVar configureFlags --disable-static fi fi fi if [ -n "$configureScript" ]; then - # Old bash empty array hack - # shellcheck disable=SC2086 - local flagsArray=( - $configureFlags "${configureFlagsArray[@]}" - ) + local -a flagsArray + _accumFlagsArray configureFlags configureFlagsArray + echoCmd 'configure flags' "${flagsArray[@]}" # shellcheck disable=SC2086 $configureScript "${flagsArray[@]}" @@ -1089,22 +1195,17 @@ configurePhase() { buildPhase() { runHook preBuild - # set to empty if unset - : ${makeFlags=} - - if [[ -z "$makeFlags" && -z "${makefile:-}" && ! ( -e Makefile || -e makefile || -e GNUmakefile ) ]]; then + if [[ -z "${makeFlags-}" && -z "${makefile:-}" && ! ( -e Makefile || -e makefile || -e GNUmakefile ) ]]; then echo "no Makefile, doing nothing" else foundMakefile=1 - # Old bash empty array hack # shellcheck disable=SC2086 local flagsArray=( ${enableParallelBuilding:+-j${NIX_BUILD_CORES}} SHELL=$SHELL - $makeFlags "${makeFlagsArray[@]}" - $buildFlags "${buildFlagsArray[@]}" ) + _accumFlagsArray makeFlags makeFlagsArray buildFlags buildFlagsArray echoCmd 'build flags' "${flagsArray[@]}" make ${makefile:+-f $makefile} "${flagsArray[@]}" @@ -1141,11 +1242,17 @@ checkPhase() { local flagsArray=( ${enableParallelChecking:+-j${NIX_BUILD_CORES}} SHELL=$SHELL - $makeFlags "${makeFlagsArray[@]}" - ${checkFlags:-VERBOSE=y} "${checkFlagsArray[@]}" - ${checkTarget} ) + _accumFlagsArray makeFlags makeFlagsArray + if [ -n "$__structuredAttrs" ]; then + flagsArray+=( "${checkFlags[@]:-VERBOSE=y}" ) + else + flagsArray+=( ${checkFlags:-VERBOSE=y} ) + fi + _accumFlagsArray checkFlagsArray + flagsArray+=( ${checkTarget} ) + echoCmd 'check flags' "${flagsArray[@]}" make ${makefile:+-f $makefile} "${flagsArray[@]}" @@ -1163,14 +1270,16 @@ installPhase() { mkdir -p "$prefix" fi - # Old bash empty array hack # shellcheck disable=SC2086 local flagsArray=( SHELL=$SHELL - $makeFlags "${makeFlagsArray[@]}" - $installFlags "${installFlagsArray[@]}" - ${installTargets:-install} ) + _accumFlagsArray makeFlags makeFlagsArray installFlags installFlagsArray + if [ -n "$__structuredAttrs" ]; then + flagsArray+=( "${installTargets[@]:-install}" ) + else + flagsArray+=( ${installTargets:-install} ) + fi echoCmd 'install flags' "${flagsArray[@]}" make ${makefile:+-f $makefile} "${flagsArray[@]}" @@ -1186,7 +1295,7 @@ installPhase() { fixupPhase() { # Make sure everything is writable so "strip" et al. work. local output - for output in $outputs; do + for output in $(getAllOutputNames); do if [ -e "${!output}" ]; then chmod -R u+w "${!output}"; fi done @@ -1194,7 +1303,7 @@ fixupPhase() { # Apply fixup to each output. local output - for output in $outputs; do + for output in $(getAllOutputNames); do prefix="${!output}" runHook fixupOutput done @@ -1239,7 +1348,10 @@ fixupPhase() { if [ -n "${setupHooks:-}" ]; then mkdir -p "${!outputDev}/nix-support" local hook - for hook in $setupHooks; do + # have to use ${setupHooks[@]} without quotes because it needs to support setupHooks being a array or a whitespace separated string + # # values of setupHooks won't have spaces so it won't cause problems + # shellcheck disable=2068 + for hook in ${setupHooks[@]}; do local content consumeEntire content < "$hook" substituteAllStream content "file '$hook'" >> "${!outputDev}/nix-support/setup-hook" @@ -1275,11 +1387,12 @@ installCheckPhase() { local flagsArray=( ${enableParallelChecking:+-j${NIX_BUILD_CORES}} SHELL=$SHELL - $makeFlags "${makeFlagsArray[@]}" - $installCheckFlags "${installCheckFlagsArray[@]}" - ${installCheckTarget:-installcheck} ) + _accumFlagsArray makeFlags makeFlagsArray \ + installCheckFlags installCheckFlagsArray + flagsArray+=( ${installCheckTarget:-installcheck} ) + echoCmd 'installcheck flags' "${flagsArray[@]}" make ${makefile:+-f $makefile} "${flagsArray[@]}" unset flagsArray @@ -1292,11 +1405,9 @@ installCheckPhase() { distPhase() { runHook preDist - # Old bash empty array hack - # shellcheck disable=SC2086 - local flagsArray=( - $distFlags "${distFlagsArray[@]}" ${distTarget:-dist} - ) + local flagsArray=() + _accumFlagsArray distFlags distFlagsArray + flagsArray+=( ${distTarget:-dist} ) echo 'dist flags: %q' "${flagsArray[@]}" make ${makefile:+-f $makefile} "${flagsArray[@]}" @@ -1307,7 +1418,7 @@ distPhase() { # Note: don't quote $tarballs, since we explicitly permit # wildcards in there. # shellcheck disable=SC2086 - cp -pvd ${tarballs:-*.tar.gz} "$out/tarballs" + cp -pvd ${tarballs[*]:-*.tar.gz} "$out/tarballs" fi runHook postDist @@ -1357,14 +1468,18 @@ genericBuild() { return fi - if [ -z "${phases:-}" ]; then - phases="${prePhases:-} unpackPhase patchPhase ${preConfigurePhases:-} \ - configurePhase ${preBuildPhases:-} buildPhase checkPhase \ - ${preInstallPhases:-} installPhase ${preFixupPhases:-} fixupPhase installCheckPhase \ - ${preDistPhases:-} distPhase ${postPhases:-}"; + if [ -z "${phases[*]:-}" ]; then + phases="${prePhases[*]:-} unpackPhase patchPhase ${preConfigurePhases[*]:-} \ + configurePhase ${preBuildPhases[*]:-} buildPhase checkPhase \ + ${preInstallPhases[*]:-} installPhase ${preFixupPhases[*]:-} fixupPhase installCheckPhase \ + ${preDistPhases[*]:-} distPhase ${postPhases[*]:-}"; fi - for curPhase in $phases; do + # The use of ${phases[*]} gives the correct behavior both with and + # without structured attrs. This relies on the fact that each + # phase name is space-free, which it must be because it's the name + # of either a shell variable or a shell function. + for curPhase in ${phases[*]}; do if [[ "$curPhase" = unpackPhase && -n "${dontUnpack:-}" ]]; then continue; fi if [[ "$curPhase" = patchPhase && -n "${dontPatch:-}" ]]; then continue; fi if [[ "$curPhase" = configurePhase && -n "${dontConfigure:-}" ]]; then continue; fi @@ -1414,6 +1529,7 @@ runHook userHook dumpVars + # Restore the original options for nix-shell [[ $__nixpkgs_setup_set_original == *e* ]] || set +e [[ $__nixpkgs_setup_set_original == *u* ]] || set +u diff --git a/pkgs/tools/typesetting/tex/texlive/bin.nix b/pkgs/tools/typesetting/tex/texlive/bin.nix index 6c7d8880a316..d874f443f4a3 100644 --- a/pkgs/tools/typesetting/tex/texlive/bin.nix +++ b/pkgs/tools/typesetting/tex/texlive/bin.nix @@ -247,7 +247,7 @@ core-big = stdenv.mkDerivation { #TODO: upmendex "xetex" ]; postInstall = '' - for output in $outputs; do + for output in $(getAllOutputNames); do mkdir -p "''${!output}/bin" done From 1c4820efdd26a7ff2a06871ccc614781c31bd4a3 Mon Sep 17 00:00:00 2001 From: Artturin Date: Wed, 29 Jun 2022 03:41:13 +0300 Subject: [PATCH 02/16] work around a nix bug --- pkgs/stdenv/generic/setup.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh index de1dad5a1697..40905c8dfd07 100644 --- a/pkgs/stdenv/generic/setup.sh +++ b/pkgs/stdenv/generic/setup.sh @@ -27,6 +27,10 @@ if [ -n "$__structuredAttrs" ]; then # ex: out=/nix/store/... export "$outputName=${outputs[$outputName]}" done + # $NIX_ATTRS_JSON_FILE points to the wrong location in sandbox + # https://github.com/NixOS/nix/issues/6736 + export NIX_ATTRS_JSON_FILE="$NIX_BUILD_TOP/.attrs.json" + export NIX_ATTRS_SH_FILE="$NIX_BUILD_TOP/.attrs.sh" else : ${outputs:=out} fi From 8ad0103a349b827b48bfaa908dbf5cd7a9371076 Mon Sep 17 00:00:00 2001 From: Artturin Date: Thu, 17 Nov 2022 18:30:58 +0200 Subject: [PATCH 03/16] config.structuredAttrsByDefault: add option --- pkgs/stdenv/generic/make-derivation.nix | 2 +- pkgs/top-level/config.nix | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index 09a71da93b6e..2f02bc7d1d78 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -156,7 +156,7 @@ let # Experimental. For simple packages mostly just works, # but for anything complex, be prepared to debug if enabling. -, __structuredAttrs ? false +, __structuredAttrs ? config.structuredAttrsByDefault or false , env ? { } diff --git a/pkgs/top-level/config.nix b/pkgs/top-level/config.nix index a47655f11424..1de93a9f3fde 100644 --- a/pkgs/top-level/config.nix +++ b/pkgs/top-level/config.nix @@ -47,6 +47,10 @@ let feature = "set `strictDeps` to true by default"; }; + structuredAttrsByDefault = mkMassRebuild { + feature = "set `__structuredAttrs` to true by default"; + }; + enableParallelBuildingByDefault = mkMassRebuild { feature = "set `enableParallelBuilding` to true by default"; }; From 734d7df2351ac1a10774e665447c5cdc286fc16e Mon Sep 17 00:00:00 2001 From: Artturin Date: Wed, 7 Dec 2022 00:08:33 +0200 Subject: [PATCH 04/16] allow derivation attributes in env derivations can be coerced to their output paths --- .../build-support/bintools-wrapper/default.nix | 18 +++++++++--------- pkgs/build-support/cc-wrapper/default.nix | 15 +++++++++------ pkgs/stdenv/generic/make-derivation.nix | 4 ++-- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index ea925e90fa47..d41eaabe51a1 100644 --- a/pkgs/build-support/bintools-wrapper/default.nix +++ b/pkgs/build-support/bintools-wrapper/default.nix @@ -103,15 +103,12 @@ stdenv.mkDerivation { preferLocalBuild = true; - inherit bintools_bin libc_bin libc_dev libc_lib coreutils_bin; - shell = getBin shell + shell.shellPath or ""; - gnugrep_bin = if nativeTools then "" else gnugrep; - - inherit targetPrefix suffixSalt; + inherit bintools_bin libc_bin libc_dev libc_lib; outputs = [ "out" ] ++ optionals propagateDoc ([ "man" ] ++ optional (bintools ? info) "info"); passthru = { + inherit targetPrefix suffixSalt; inherit bintools libc nativeTools nativeLibc nativePrefix; emacsBufferSetup = pkgs: '' @@ -366,10 +363,13 @@ stdenv.mkDerivation { ## + extraBuildCommands; - inherit dynamicLinker; - - # for substitution in utils.bash - expandResponseParams = "${expand-response-params}/bin/expand-response-params"; + env = { + # for substitution in utils.bash + expandResponseParams = "${expand-response-params}/bin/expand-response-params"; + shell = getBin shell + shell.shellPath or ""; + gnugrep_bin = if nativeTools then "" else gnugrep; + inherit dynamicLinker suffixSalt coreutils_bin; + }; meta = let bintools_ = if bintools != null then bintools else {}; in diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index a59505d08258..851b36fc2241 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -131,16 +131,14 @@ stdenv.mkDerivation { preferLocalBuild = true; - inherit cc libc_bin libc_dev libc_lib bintools coreutils_bin; - shell = getBin shell + shell.shellPath or ""; - gnugrep_bin = if nativeTools then "" else gnugrep; + inherit cc libc_bin libc_dev libc_lib; - inherit targetPrefix suffixSalt; inherit darwinPlatformForCC darwinMinVersion darwinMinVersionVariable; outputs = [ "out" ] ++ optionals propagateDoc [ "man" "info" ]; passthru = { + inherit targetPrefix suffixSalt; # "cc" is the generic name for a C compiler, but there is no one for package # providing the linker and related tools. The two we use now are GNU # Binutils, and Apple's "cctools"; "bintools" as an attempt to find an @@ -538,8 +536,13 @@ stdenv.mkDerivation { nixSupport); - # for substitution in utils.bash - expandResponseParams = "${expand-response-params}/bin/expand-response-params"; + env = { + # for substitution in utils.bash + expandResponseParams = "${expand-response-params}/bin/expand-response-params"; + shell = getBin shell + shell.shellPath or ""; + gnugrep_bin = if nativeTools then "" else gnugrep; + inherit suffixSalt coreutils_bin bintools; + }; meta = let cc_ = if cc != null then cc else {}; in diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index 2f02bc7d1d78..12aa25ac307c 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -488,8 +488,8 @@ else let assert lib.assertMsg (overlappingNames == [ ]) "The ‘env’ attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping: ${lib.concatStringsSep ", " overlappingNames}"; lib.mapAttrs - (n: v: assert lib.assertMsg (lib.isString v || lib.isBool v || lib.isInt v) - "The ‘env’ attribute set can only contain string, boolean or integer attributes. The ‘${n}’ attribute is of type ${builtins.typeOf v}."; v) + (n: v: assert lib.assertMsg (lib.isString v || lib.isBool v || lib.isInt v || lib.isDerivation v) + "The ‘env’ attribute set can only contain derivation, string, boolean or integer attributes. The ‘${n}’ attribute is of type ${builtins.typeOf v}."; v) env; in From adc8900df1758eda56abd68f7d781d1df74fa531 Mon Sep 17 00:00:00 2001 From: Artturin Date: Wed, 7 Dec 2022 06:16:50 +0200 Subject: [PATCH 05/16] treewide: fix some core package structuredAttrs --- .../bintools-wrapper/default.nix | 14 ++++++------- pkgs/build-support/cc-wrapper/default.nix | 19 ++++++++---------- .../build-support/nuke-references/default.nix | 10 ++++++---- .../pkg-config-wrapper/default.nix | 13 ++++++------ pkgs/development/compilers/gcc/builder.sh | 1 + .../interpreters/python/cpython/default.nix | 20 ++++++++++--------- .../interpreters/python/setup-hook.nix | 4 +++- .../development/libraries/gettext/default.nix | 4 +++- pkgs/development/libraries/glibc/common.nix | 15 +++++++------- .../perl-modules/generic/builder.sh | 3 +++ .../perl-modules/generic/default.nix | 9 ++++++--- 11 files changed, 62 insertions(+), 50 deletions(-) diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index d41eaabe51a1..be2e3567da85 100644 --- a/pkgs/build-support/bintools-wrapper/default.nix +++ b/pkgs/build-support/bintools-wrapper/default.nix @@ -55,9 +55,9 @@ let bintoolsVersion = lib.getVersion bintools; bintoolsName = lib.removePrefix targetPrefix (lib.getName bintools); - libc_bin = if libc == null then null else getBin libc; - libc_dev = if libc == null then null else getDev libc; - libc_lib = if libc == null then null else getLib libc; + libc_bin = if libc == null then "" else getBin libc; + libc_dev = if libc == null then "" else getDev libc; + libc_lib = if libc == null then "" else getLib libc; bintools_bin = if nativeTools then "" else getBin bintools; # The wrapper scripts use 'cat' and 'grep', so we may need coreutils. coreutils_bin = if nativeTools then "" else getBin coreutils; @@ -103,8 +103,6 @@ stdenv.mkDerivation { preferLocalBuild = true; - inherit bintools_bin libc_bin libc_dev libc_lib; - outputs = [ "out" ] ++ optionals propagateDoc ([ "man" ] ++ optional (bintools ? info) "info"); passthru = { @@ -190,8 +188,6 @@ stdenv.mkDerivation { strictDeps = true; depsTargetTargetPropagated = extraPackages; - wrapperName = "BINTOOLS_WRAPPER"; - setupHooks = [ ../setup-hooks/role.bash ./setup-hook.sh @@ -368,7 +364,9 @@ stdenv.mkDerivation { expandResponseParams = "${expand-response-params}/bin/expand-response-params"; shell = getBin shell + shell.shellPath or ""; gnugrep_bin = if nativeTools then "" else gnugrep; - inherit dynamicLinker suffixSalt coreutils_bin; + wrapperName = "BINTOOLS_WRAPPER"; + inherit dynamicLinker targetPrefix suffixSalt coreutils_bin; + inherit bintools_bin libc_bin libc_dev libc_lib; }; meta = diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 851b36fc2241..abc88910c36d 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -42,9 +42,9 @@ let ccVersion = lib.getVersion cc; ccName = lib.removePrefix targetPrefix (lib.getName cc); - libc_bin = if libc == null then null else getBin libc; - libc_dev = if libc == null then null else getDev libc; - libc_lib = if libc == null then null else getLib libc; + libc_bin = if libc == null then "" else getBin libc; + libc_dev = if libc == null then "" else getDev libc; + libc_lib = if libc == null then "" else getLib libc; cc_solib = getLib cc + optionalString (targetPlatform != hostPlatform) "/${targetPlatform.config}"; @@ -131,10 +131,6 @@ stdenv.mkDerivation { preferLocalBuild = true; - inherit cc libc_bin libc_dev libc_lib; - - inherit darwinPlatformForCC darwinMinVersion darwinMinVersionVariable; - outputs = [ "out" ] ++ optionals propagateDoc [ "man" "info" ]; passthru = { @@ -144,7 +140,7 @@ stdenv.mkDerivation { # Binutils, and Apple's "cctools"; "bintools" as an attempt to find an # unused middle-ground name that evokes both. inherit bintools; - inherit libc nativeTools nativeLibc nativePrefix isGNU isClang; + inherit cc libc nativeTools nativeLibc nativePrefix isGNU isClang; emacsBufferSetup = pkgs: '' ; We should handle propagation here too @@ -268,8 +264,6 @@ stdenv.mkDerivation { propagatedBuildInputs = [ bintools ] ++ extraTools ++ optionals cc.langD or false [ zlib ]; depsTargetTargetPropagated = optional (libcxx != null) libcxx ++ extraPackages; - wrapperName = "CC_WRAPPER"; - setupHooks = [ ../setup-hooks/role.bash ] ++ lib.optional (cc.langC or true) ./setup-hook.sh @@ -541,7 +535,10 @@ stdenv.mkDerivation { expandResponseParams = "${expand-response-params}/bin/expand-response-params"; shell = getBin shell + shell.shellPath or ""; gnugrep_bin = if nativeTools then "" else gnugrep; - inherit suffixSalt coreutils_bin bintools; + wrapperName = "CC_WRAPPER"; + inherit suffixSalt coreutils_bin bintools cc; + inherit libc_bin libc_dev libc_lib; + inherit darwinPlatformForCC darwinMinVersion darwinMinVersionVariable; }; meta = diff --git a/pkgs/build-support/nuke-references/default.nix b/pkgs/build-support/nuke-references/default.nix index 8dd9704aa4b4..c2dfe27b2c60 100644 --- a/pkgs/build-support/nuke-references/default.nix +++ b/pkgs/build-support/nuke-references/default.nix @@ -32,8 +32,10 @@ stdenvNoCC.mkDerivation { ''; # FIXME: get rid of perl dependency. - inherit perl; - inherit (builtins) storeDir; - shell = lib.getBin shell + (shell.shellPath or ""); - signingUtils = if darwinCodeSign then signingUtils else null; + env = { + inherit perl; + inherit (builtins) storeDir; + shell = lib.getBin shell + (shell.shellPath or ""); + signingUtils = if darwinCodeSign then signingUtils else ""; + }; } diff --git a/pkgs/build-support/pkg-config-wrapper/default.nix b/pkgs/build-support/pkg-config-wrapper/default.nix index 312d2fe02610..ca14a4495fed 100644 --- a/pkgs/build-support/pkg-config-wrapper/default.nix +++ b/pkgs/build-support/pkg-config-wrapper/default.nix @@ -36,13 +36,10 @@ stdenv.mkDerivation { preferLocalBuild = true; - shell = getBin stdenvNoCC.shell + stdenvNoCC.shell.shellPath or ""; - - inherit targetPrefix suffixSalt baseBinName; - outputs = [ "out" ] ++ optionals propagateDoc ([ "man" ] ++ optional (pkg-config ? doc) "doc"); passthru = { + inherit targetPrefix suffixSalt; inherit pkg-config; }; @@ -83,8 +80,6 @@ stdenv.mkDerivation { ln -s ${pkg-config}/share $out/share ''; - wrapperName = "PKG_CONFIG_WRAPPER"; - setupHooks = [ ../setup-hooks/role.bash ./setup-hook.sh @@ -120,6 +115,12 @@ stdenv.mkDerivation { ## + extraBuildCommands; + env = { + shell = getBin stdenvNoCC.shell + stdenvNoCC.shell.shellPath or ""; + wrapperName = "PKG_CONFIG_WRAPPER"; + inherit targetPrefix suffixSalt baseBinName; + }; + meta = let pkg-config_ = if pkg-config != null then pkg-config else {}; in (if pkg-config_ ? meta then removeAttrs pkg-config.meta ["priority"] else {}) // diff --git a/pkgs/development/compilers/gcc/builder.sh b/pkgs/development/compilers/gcc/builder.sh index c73e9e0c1075..113bd83ea53f 100644 --- a/pkgs/development/compilers/gcc/builder.sh +++ b/pkgs/development/compilers/gcc/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup diff --git a/pkgs/development/interpreters/python/cpython/default.nix b/pkgs/development/interpreters/python/cpython/default.nix index fb6bffd2594f..b99f3f40dfe7 100644 --- a/pkgs/development/interpreters/python/cpython/default.nix +++ b/pkgs/development/interpreters/python/cpython/default.nix @@ -281,15 +281,17 @@ in with passthru; stdenv.mkDerivation { substituteInPlace "Lib/tkinter/tix.py" --replace "os.environ.get('TIX_LIBRARY')" "os.environ.get('TIX_LIBRARY') or '${tix}/lib'" ''; - CPPFLAGS = concatStringsSep " " (map (p: "-I${getDev p}/include") buildInputs); - LDFLAGS = concatStringsSep " " (map (p: "-L${getLib p}/lib") buildInputs); - LIBS = "${optionalString (!stdenv.isDarwin) "-lcrypt"}"; - NIX_LDFLAGS = lib.optionalString (stdenv.cc.isGNU && !stdenv.hostPlatform.isStatic) ({ - "glibc" = "-lgcc_s"; - "musl" = "-lgcc_eh"; - }."${stdenv.hostPlatform.libc}" or ""); - # Determinism: We fix the hashes of str, bytes and datetime objects. - PYTHONHASHSEED=0; + env = { + CPPFLAGS = concatStringsSep " " (map (p: "-I${getDev p}/include") buildInputs); + LDFLAGS = concatStringsSep " " (map (p: "-L${getLib p}/lib") buildInputs); + LIBS = "${optionalString (!stdenv.isDarwin) "-lcrypt"}"; + NIX_LDFLAGS = lib.optionalString (stdenv.cc.isGNU && !stdenv.hostPlatform.isStatic) ({ + "glibc" = "-lgcc_s"; + "musl" = "-lgcc_eh"; + }."${stdenv.hostPlatform.libc}" or ""); + # Determinism: We fix the hashes of str, bytes and datetime objects. + PYTHONHASHSEED=0; + }; configureFlags = [ "--without-ensurepip" diff --git a/pkgs/development/interpreters/python/setup-hook.nix b/pkgs/development/interpreters/python/setup-hook.nix index 29ce079317f0..8cfb9dd46784 100644 --- a/pkgs/development/interpreters/python/setup-hook.nix +++ b/pkgs/development/interpreters/python/setup-hook.nix @@ -6,7 +6,9 @@ let hook = ./setup-hook.sh; in runCommand "python-setup-hook.sh" { strictDeps = true; - inherit sitePackages; + env = { + inherit sitePackages; + }; } '' cp ${hook} hook.sh substituteAllInPlace hook.sh diff --git a/pkgs/development/libraries/gettext/default.nix b/pkgs/development/libraries/gettext/default.nix index a1270af259cd..ae5b9f48293a 100644 --- a/pkgs/development/libraries/gettext/default.nix +++ b/pkgs/development/libraries/gettext/default.nix @@ -60,7 +60,9 @@ stdenv.mkDerivation rec { ../../../build-support/setup-hooks/role.bash ./gettext-setup-hook.sh ]; - gettextNeedsLdflags = stdenv.hostPlatform.libc != "glibc" && !stdenv.hostPlatform.isMusl; + env = { + gettextNeedsLdflags = stdenv.hostPlatform.libc != "glibc" && !stdenv.hostPlatform.isMusl; + }; enableParallelBuilding = true; enableParallelChecking = false; # fails sometimes diff --git a/pkgs/development/libraries/glibc/common.nix b/pkgs/development/libraries/glibc/common.nix index d7155ec946c9..db2ef06c0f59 100644 --- a/pkgs/development/libraries/glibc/common.nix +++ b/pkgs/development/libraries/glibc/common.nix @@ -54,9 +54,6 @@ assert withGd -> gd != null && libpng != null; stdenv.mkDerivation ({ version = version + patchSuffix; - linuxHeaders = if withLinuxHeaders then linuxHeaders else null; - - inherit (stdenv) is64bit; enableParallelBuilding = true; @@ -175,10 +172,14 @@ stdenv.mkDerivation ({ nativeBuildInputs = [ bison python3Minimal ] ++ extraNativeBuildInputs; buildInputs = [ linuxHeaders ] ++ lib.optionals withGd [ gd libpng ] ++ extraBuildInputs; - # Needed to install share/zoneinfo/zone.tab. Set to impure /bin/sh to - # prevent a retained dependency on the bootstrap tools in the stdenv-linux - # bootstrap. - BASH_SHELL = "/bin/sh"; + env = { + linuxHeaders = if withLinuxHeaders then linuxHeaders else ""; + inherit (stdenv) is64bit; + # Needed to install share/zoneinfo/zone.tab. Set to impure /bin/sh to + # prevent a retained dependency on the bootstrap tools in the stdenv-linux + # bootstrap. + BASH_SHELL = "/bin/sh"; + }; # Used by libgcc, elf-header, and others to determine ABI passthru = { inherit version; minorRelease = version; }; diff --git a/pkgs/development/perl-modules/generic/builder.sh b/pkgs/development/perl-modules/generic/builder.sh index 9b42401fc4dc..e56d7ec10b21 100644 --- a/pkgs/development/perl-modules/generic/builder.sh +++ b/pkgs/development/perl-modules/generic/builder.sh @@ -1,3 +1,6 @@ +if [ -f .attrs.sh ]; then + . .attrs.sh +fi source $stdenv/setup PERL5LIB="$PERL5LIB${PERL5LIB:+:}$out/lib/perl5/site_perl" diff --git a/pkgs/development/perl-modules/generic/default.nix b/pkgs/development/perl-modules/generic/default.nix index 2d1c550d3168..3dca6550ad68 100644 --- a/pkgs/development/perl-modules/generic/default.nix +++ b/pkgs/development/perl-modules/generic/default.nix @@ -24,6 +24,8 @@ # https://metacpan.org/pod/release/XSAWYERX/perl-5.26.0/pod/perldelta.pod#Removal-of-the-current-directory-%28%22.%22%29-from-@INC , PERL_USE_UNSAFE_INC ? "1" +, env ? {} + , ... }@attrs: @@ -43,10 +45,11 @@ lib.throwIf (attrs ? name) "buildPerlPackage: `name` (\"${attrs.name}\") is depr buildInputs = buildInputs ++ [ perl ]; nativeBuildInputs = nativeBuildInputs ++ [ (perl.mini or perl) ]; - fullperl = buildPerl; - inherit outputs src doCheck checkTarget enableParallelBuilding; - inherit PERL_AUTOINSTALL AUTOMATED_TESTING PERL_USE_UNSAFE_INC; + env = { + inherit PERL_AUTOINSTALL AUTOMATED_TESTING PERL_USE_UNSAFE_INC; + fullperl = buildPerl; + } // env; meta = defaultMeta // (attrs.meta or { }); }); From 18d00c5814ce49b64a228ab78b8e834900db0519 Mon Sep 17 00:00:00 2001 From: Artturin Date: Wed, 7 Dec 2022 05:55:45 +0200 Subject: [PATCH 06/16] tests.stdenv: add some env attrset tests --- pkgs/test/default.nix | 1 + pkgs/test/stdenv/default.nix | 107 +++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 pkgs/test/stdenv/default.nix diff --git a/pkgs/test/default.nix b/pkgs/test/default.nix index 3a39d247c8fe..6c89ba5638e0 100644 --- a/pkgs/test/default.nix +++ b/pkgs/test/default.nix @@ -21,6 +21,7 @@ with pkgs; cc-wrapper-clang-9 = callPackage ./cc-wrapper { stdenv = llvmPackages_9.stdenv; }; cc-wrapper-libcxx-9 = callPackage ./cc-wrapper { stdenv = llvmPackages_9.libcxxStdenv; }; stdenv-inputs = callPackage ./stdenv-inputs { }; + stdenv = callPackage ./stdenv { }; config = callPackage ./config.nix { }; diff --git a/pkgs/test/stdenv/default.nix b/pkgs/test/stdenv/default.nix new file mode 100644 index 000000000000..01f0e0fe8b83 --- /dev/null +++ b/pkgs/test/stdenv/default.nix @@ -0,0 +1,107 @@ +# To run these tests: +# nix-build -A tests.stdenv + +{ stdenv +, pkgs +, lib +, +}: + +let + # use a early stdenv so when hacking on stdenv this test can be run quickly + bootStdenv = stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv; + pkgsStructured = import pkgs.path { config = { structuredAttrsByDefault = true; }; inherit (stdenv.hostPlatform) system; }; + bootStdenvStructuredAttrsByDefault = pkgsStructured.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv; +in + +{ + test-env-attrset = bootStdenv.mkDerivation { + name = "test-env-attrset"; + dontUnpack = true; + dontConfigure = true; + dontBuild = true; + dontPatch = true; + dontFixup = true; + env = { + string = "testing-string"; + }; + + installPhase = '' + declare -p string + echo "env.string = $string" + [[ $string == "testing-string" ]] || (echo "string was not testing-string" && false) + touch $out + ''; + }; + + test-structured-env-attrset = bootStdenv.mkDerivation { + name = "test-structured-env-attrset"; + dontUnpack = true; + dontConfigure = true; + dontBuild = true; + dontPatch = true; + dontFixup = true; + __structuredAttrs = true; + env = { + string = "testing-string"; + }; + + installPhase = '' + declare -p string + echo "env.string = $string" + [[ $string == "testing-string" ]] || (echo "string was not testing-string" && false) + touch $out + ''; + }; + + test-cc-wrapper-substitutions = bootStdenv.cc.overrideAttrs (previousAttrs: { + name = "test-cc-wrapper-substitutions"; + + postFixup = previousAttrs.postFixup + '' + declare -p wrapperName + echo "env.wrapperName = $wrapperName" + [[ $wrapperName == "CC_WRAPPER" ]] || (echo "wrapperName was not CC_WRAPPER" && false) + touch $out + ''; + }); + + structuredAttrsByDefault = lib.recurseIntoAttrs { + + test-cc-wrapper-substitutions = bootStdenvStructuredAttrsByDefault.cc.overrideAttrs (previousAttrs: { + name = "test-cc-wrapper-substitutions-structuredAttrsByDefault"; + + postFixup = previousAttrs.postFixup + '' + declare -p wrapperName + echo "env.wrapperName = $wrapperName" + [[ $wrapperName == "CC_WRAPPER" ]] || (echo "wrapperName was not CC_WRAPPER" && false) + declare -p suffixSalt + echo "env.suffixSalt = $suffixSalt" + [[ $suffixSalt == "${bootStdenvStructuredAttrsByDefault.cc.suffixSalt}" ]] || (echo "wrapperName was not ${bootStdenvStructuredAttrsByDefault.cc.suffixSalt}" && false) + + grep -q "@out@" $out/bin/cc || echo "@out@ in $out/bin/cc was substituted" + grep -q "@suffixSalt@" $out/bin/cc && (echo "$out/bin/cc contains unsubstituted variables" && false) + + touch $out + ''; + }); + + test-structured-env-attrset = bootStdenvStructuredAttrsByDefault.mkDerivation { + name = "test-structured-env-attrset-structuredAttrsByDefault"; + dontUnpack = true; + dontConfigure = true; + dontBuild = true; + dontPatch = true; + dontFixup = true; + env = { + string = "testing-string"; + }; + + installPhase = '' + declare -p string + echo "env.string = $string" + [[ $string == "testing-string" ]] || (echo "string was not testing-string" && false) + touch $out + ''; + }; + }; +} From bb914d8676e8e0261bcd4d604c653618f53ffbd8 Mon Sep 17 00:00:00 2001 From: Artturin Date: Wed, 7 Dec 2022 23:49:00 +0200 Subject: [PATCH 07/16] stdenv: export system pname name version for substituteAll so we don't have to add these to the env attrset --- pkgs/stdenv/generic/setup.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh index 40905c8dfd07..182f849cf525 100644 --- a/pkgs/stdenv/generic/setup.sh +++ b/pkgs/stdenv/generic/setup.sh @@ -878,6 +878,10 @@ substituteInPlace() { } _allFlags() { + # export some local variables for the awk below + # so some substitutions such as name don't have to be in the env attrset + # when __structuredAttrs is enabled + export system pname name version for varName in $(awk 'BEGIN { for (v in ENVIRON) if (v ~ /^[a-z][a-zA-Z0-9_]*$/) print v }'); do if (( "${NIX_DEBUG:-0}" >= 1 )); then printf "@%s@ -> %q\n" "${varName}" "${!varName}" From c01f509e4438fd50faae0fa0175277b7b16728dc Mon Sep 17 00:00:00 2001 From: Artturin Date: Thu, 8 Dec 2022 01:51:03 +0200 Subject: [PATCH 08/16] treewide: source .attrs in builders if theres a source $stdenv then this is needed for structuredAttrs --- nixos/modules/services/networking/ircd-hybrid/builder.sh | 1 + nixos/modules/services/web-servers/jboss/builder.sh | 1 + pkgs/applications/misc/adobe-reader/builder.sh | 1 + pkgs/applications/office/libreoffice/download-list-builder.sh | 1 + pkgs/build-support/fetchbzr/builder.sh | 1 + pkgs/build-support/fetchcvs/builder.sh | 1 + pkgs/build-support/fetchdarcs/builder.sh | 1 + pkgs/build-support/fetchdocker/fetchdocker-builder.sh | 3 ++- pkgs/build-support/fetchfossil/builder.sh | 1 + pkgs/build-support/fetchgit/builder.sh | 2 ++ pkgs/build-support/fetchhg/builder.sh | 1 + pkgs/build-support/fetchipfs/builder.sh | 1 + pkgs/build-support/fetchmtn/builder.sh | 1 + pkgs/build-support/fetchsvn/builder.sh | 1 + pkgs/build-support/fetchsvnssh/builder.sh | 1 + pkgs/build-support/fetchurl/builder.sh | 1 + pkgs/desktops/gnustep/make/builder.sh | 1 + pkgs/development/compilers/aspectj/builder.sh | 1 + pkgs/development/compilers/chicken/4/fetchegg/builder.sh | 1 + pkgs/development/compilers/chicken/5/fetchegg/builder.sh | 1 + pkgs/development/compilers/fpc/binary-builder-darwin.sh | 1 + pkgs/development/compilers/fpc/binary-builder.sh | 1 + pkgs/development/compilers/ios-cross-compile/9.2_builder.sh | 1 + pkgs/development/compilers/ocaml/builder.sh | 1 + pkgs/development/libraries/glibc/locales-builder.sh | 1 + pkgs/development/libraries/gtk-sharp/builder.sh | 1 + pkgs/development/libraries/wtk/builder.sh | 1 + pkgs/development/nim-packages/fetch-nimble/builder.sh | 1 + pkgs/development/perl-modules/generic/builder.sh | 4 +--- pkgs/development/tools/build-managers/apache-maven/builder.sh | 1 + pkgs/development/tools/build-managers/boot/builder.sh | 1 + pkgs/development/tools/misc/automake/builder.sh | 1 + pkgs/development/tools/parsing/antlr/builder.sh | 1 + pkgs/misc/cups/drivers/samsung/4.00.39/builder.sh | 1 + pkgs/os-specific/linux/nvidia-x11/builder.sh | 1 + pkgs/os-specific/linux/opengl/xorg-sys/builder.sh | 1 + pkgs/servers/http/tomcat/axis2/builder.sh | 1 + pkgs/servers/x11/xorg/builder.sh | 1 + pkgs/test/simple/builder.sh | 1 + pkgs/tools/typesetting/lout/builder.sh | 1 + 40 files changed, 42 insertions(+), 4 deletions(-) diff --git a/nixos/modules/services/networking/ircd-hybrid/builder.sh b/nixos/modules/services/networking/ircd-hybrid/builder.sh index 38312210df25..d9d2e4264dfd 100644 --- a/nixos/modules/services/networking/ircd-hybrid/builder.sh +++ b/nixos/modules/services/networking/ircd-hybrid/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup doSub() { diff --git a/nixos/modules/services/web-servers/jboss/builder.sh b/nixos/modules/services/web-servers/jboss/builder.sh index 0e5af324c13f..ac573089cd5a 100644 --- a/nixos/modules/services/web-servers/jboss/builder.sh +++ b/nixos/modules/services/web-servers/jboss/builder.sh @@ -1,5 +1,6 @@ set -e +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup mkdir -p $out/bin diff --git a/pkgs/applications/misc/adobe-reader/builder.sh b/pkgs/applications/misc/adobe-reader/builder.sh index 41281385c990..6047c0826430 100644 --- a/pkgs/applications/misc/adobe-reader/builder.sh +++ b/pkgs/applications/misc/adobe-reader/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup echo "unpacking $src..." diff --git a/pkgs/applications/office/libreoffice/download-list-builder.sh b/pkgs/applications/office/libreoffice/download-list-builder.sh index c054e2c72cbe..31cab28fd82e 100644 --- a/pkgs/applications/office/libreoffice/download-list-builder.sh +++ b/pkgs/applications/office/libreoffice/download-list-builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup tar --extract --file=$src libreoffice-$version/download.lst -O > $out diff --git a/pkgs/build-support/fetchbzr/builder.sh b/pkgs/build-support/fetchbzr/builder.sh index e424fd92d51e..163f6fc60eea 100644 --- a/pkgs/build-support/fetchbzr/builder.sh +++ b/pkgs/build-support/fetchbzr/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source "$stdenv/setup" header "exporting \`$url' (revision $rev) into \`$out'" diff --git a/pkgs/build-support/fetchcvs/builder.sh b/pkgs/build-support/fetchcvs/builder.sh index fe1019aafc2f..90363275b973 100644 --- a/pkgs/build-support/fetchcvs/builder.sh +++ b/pkgs/build-support/fetchcvs/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup (echo "#!$SHELL"; \ diff --git a/pkgs/build-support/fetchdarcs/builder.sh b/pkgs/build-support/fetchdarcs/builder.sh index 301deb98307f..018852770504 100644 --- a/pkgs/build-support/fetchdarcs/builder.sh +++ b/pkgs/build-support/fetchdarcs/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup tagtext="" diff --git a/pkgs/build-support/fetchdocker/fetchdocker-builder.sh b/pkgs/build-support/fetchdocker/fetchdocker-builder.sh index 7443591e6569..e5a1a61b78d3 100644 --- a/pkgs/build-support/fetchdocker/fetchdocker-builder.sh +++ b/pkgs/build-support/fetchdocker/fetchdocker-builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source "${stdenv}/setup" header "exporting ${repository}/${imageName} (tag: ${tag}) into ${out}" mkdir -p "${out}" @@ -8,7 +9,7 @@ cat < "${out}/compositeImage.sh" # Create a tar archive of a docker image's layers, docker image config # json, manifest.json, and repositories json; this streams directly to # stdout and is intended to be used in concert with docker load, i.e: -# +# # ${out}/compositeImage.sh | docker load # The first character follow the 's' command for sed becomes the diff --git a/pkgs/build-support/fetchfossil/builder.sh b/pkgs/build-support/fetchfossil/builder.sh index 5f08aca424fe..009b23c406d6 100644 --- a/pkgs/build-support/fetchfossil/builder.sh +++ b/pkgs/build-support/fetchfossil/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup header "Cloning Fossil $url [$rev] into $out" diff --git a/pkgs/build-support/fetchgit/builder.sh b/pkgs/build-support/fetchgit/builder.sh index 66b6c168e41d..acb970639ab1 100644 --- a/pkgs/build-support/fetchgit/builder.sh +++ b/pkgs/build-support/fetchgit/builder.sh @@ -2,6 +2,8 @@ # - no revision specified and remote has a HEAD which is used # - revision specified and remote has a HEAD # - revision specified and remote without HEAD +# +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup header "exporting $url (rev $rev) into $out" diff --git a/pkgs/build-support/fetchhg/builder.sh b/pkgs/build-support/fetchhg/builder.sh index 847f18fa5975..cec0e441f229 100644 --- a/pkgs/build-support/fetchhg/builder.sh +++ b/pkgs/build-support/fetchhg/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup header "getting $url${rev:+ ($rev)} into $out" diff --git a/pkgs/build-support/fetchipfs/builder.sh b/pkgs/build-support/fetchipfs/builder.sh index 7a6a517566f5..ca77962b5384 100644 --- a/pkgs/build-support/fetchipfs/builder.sh +++ b/pkgs/build-support/fetchipfs/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup # Curl flags to handle redirects, not use EPSV, handle cookies for diff --git a/pkgs/build-support/fetchmtn/builder.sh b/pkgs/build-support/fetchmtn/builder.sh index 73eff9c27252..7db66730dab8 100644 --- a/pkgs/build-support/fetchmtn/builder.sh +++ b/pkgs/build-support/fetchmtn/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup set -x diff --git a/pkgs/build-support/fetchsvn/builder.sh b/pkgs/build-support/fetchsvn/builder.sh index ed3e65f07695..b58e5a88b3cd 100644 --- a/pkgs/build-support/fetchsvn/builder.sh +++ b/pkgs/build-support/fetchsvn/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup header "exporting $url (r$rev) into $out" diff --git a/pkgs/build-support/fetchsvnssh/builder.sh b/pkgs/build-support/fetchsvnssh/builder.sh index d9c6dc7da31a..b0441299dd2c 100644 --- a/pkgs/build-support/fetchsvnssh/builder.sh +++ b/pkgs/build-support/fetchsvnssh/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup header "exporting $url (r$rev) into $out" diff --git a/pkgs/build-support/fetchurl/builder.sh b/pkgs/build-support/fetchurl/builder.sh index 5ca09b6fc77d..dd987f41b446 100644 --- a/pkgs/build-support/fetchurl/builder.sh +++ b/pkgs/build-support/fetchurl/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup source $mirrorsFile diff --git a/pkgs/desktops/gnustep/make/builder.sh b/pkgs/desktops/gnustep/make/builder.sh index 39bd77038281..e5c277e796af 100644 --- a/pkgs/desktops/gnustep/make/builder.sh +++ b/pkgs/desktops/gnustep/make/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup preConfigure() { diff --git a/pkgs/development/compilers/aspectj/builder.sh b/pkgs/development/compilers/aspectj/builder.sh index 3b4393720042..7ea0a40d3748 100755 --- a/pkgs/development/compilers/aspectj/builder.sh +++ b/pkgs/development/compilers/aspectj/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup export JAVA_HOME=$jre diff --git a/pkgs/development/compilers/chicken/4/fetchegg/builder.sh b/pkgs/development/compilers/chicken/4/fetchegg/builder.sh index 204661063090..5f41a36263a9 100644 --- a/pkgs/development/compilers/chicken/4/fetchegg/builder.sh +++ b/pkgs/development/compilers/chicken/4/fetchegg/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup header "exporting egg ${eggName} (version $version) into $out" diff --git a/pkgs/development/compilers/chicken/5/fetchegg/builder.sh b/pkgs/development/compilers/chicken/5/fetchegg/builder.sh index d9adf510f22d..f02e01757787 100644 --- a/pkgs/development/compilers/chicken/5/fetchegg/builder.sh +++ b/pkgs/development/compilers/chicken/5/fetchegg/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup header "exporting egg ${eggName} (version $version) into $out" diff --git a/pkgs/development/compilers/fpc/binary-builder-darwin.sh b/pkgs/development/compilers/fpc/binary-builder-darwin.sh index f9bdf18e7d68..39db0518281d 100755 --- a/pkgs/development/compilers/fpc/binary-builder-darwin.sh +++ b/pkgs/development/compilers/fpc/binary-builder-darwin.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup pkgdir=$(pwd)/pkg diff --git a/pkgs/development/compilers/fpc/binary-builder.sh b/pkgs/development/compilers/fpc/binary-builder.sh index 4308c1ed211a..c471378c275f 100755 --- a/pkgs/development/compilers/fpc/binary-builder.sh +++ b/pkgs/development/compilers/fpc/binary-builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup tar xf $src diff --git a/pkgs/development/compilers/ios-cross-compile/9.2_builder.sh b/pkgs/development/compilers/ios-cross-compile/9.2_builder.sh index 68ba3ed3a920..47459664af0a 100644 --- a/pkgs/development/compilers/ios-cross-compile/9.2_builder.sh +++ b/pkgs/development/compilers/ios-cross-compile/9.2_builder.sh @@ -1,4 +1,5 @@ # -*- shell-script -*- +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup function extract diff --git a/pkgs/development/compilers/ocaml/builder.sh b/pkgs/development/compilers/ocaml/builder.sh index a1807682d867..88acc0654cf2 100644 --- a/pkgs/development/compilers/ocaml/builder.sh +++ b/pkgs/development/compilers/ocaml/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup configureFlags="-prefix $out $configureFlags" diff --git a/pkgs/development/libraries/glibc/locales-builder.sh b/pkgs/development/libraries/glibc/locales-builder.sh index d732e208fa22..d91f936c937b 100644 --- a/pkgs/development/libraries/glibc/locales-builder.sh +++ b/pkgs/development/libraries/glibc/locales-builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi # Glibc cannot have itself in its RPATH. export NIX_NO_SELF_RPATH=1 diff --git a/pkgs/development/libraries/gtk-sharp/builder.sh b/pkgs/development/libraries/gtk-sharp/builder.sh index 4b8f757540b5..73914495d6d4 100644 --- a/pkgs/development/libraries/gtk-sharp/builder.sh +++ b/pkgs/development/libraries/gtk-sharp/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup genericBuild diff --git a/pkgs/development/libraries/wtk/builder.sh b/pkgs/development/libraries/wtk/builder.sh index 86f2719537cd..c3ad173b0933 100644 --- a/pkgs/development/libraries/wtk/builder.sh +++ b/pkgs/development/libraries/wtk/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup mkdir unzipped diff --git a/pkgs/development/nim-packages/fetch-nimble/builder.sh b/pkgs/development/nim-packages/fetch-nimble/builder.sh index 693ab339408e..bc2f9bfc94f1 100644 --- a/pkgs/development/nim-packages/fetch-nimble/builder.sh +++ b/pkgs/development/nim-packages/fetch-nimble/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup export HOME=$NIX_BUILD_TOP diff --git a/pkgs/development/perl-modules/generic/builder.sh b/pkgs/development/perl-modules/generic/builder.sh index e56d7ec10b21..110094ad8a49 100644 --- a/pkgs/development/perl-modules/generic/builder.sh +++ b/pkgs/development/perl-modules/generic/builder.sh @@ -1,6 +1,4 @@ -if [ -f .attrs.sh ]; then - . .attrs.sh -fi +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup PERL5LIB="$PERL5LIB${PERL5LIB:+:}$out/lib/perl5/site_perl" diff --git a/pkgs/development/tools/build-managers/apache-maven/builder.sh b/pkgs/development/tools/build-managers/apache-maven/builder.sh index dcc38b9ec74a..96fe8ebfac29 100644 --- a/pkgs/development/tools/build-managers/apache-maven/builder.sh +++ b/pkgs/development/tools/build-managers/apache-maven/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup unpackPhase diff --git a/pkgs/development/tools/build-managers/boot/builder.sh b/pkgs/development/tools/build-managers/boot/builder.sh index c1481dc6a144..e007cbac9582 100644 --- a/pkgs/development/tools/build-managers/boot/builder.sh +++ b/pkgs/development/tools/build-managers/boot/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup boot_bin=$out/bin/boot diff --git a/pkgs/development/tools/misc/automake/builder.sh b/pkgs/development/tools/misc/automake/builder.sh index e54a2acca67e..0cb1d5d61e33 100644 --- a/pkgs/development/tools/misc/automake/builder.sh +++ b/pkgs/development/tools/misc/automake/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup # Wrap the given `aclocal' program, appending extra `-I' flags diff --git a/pkgs/development/tools/parsing/antlr/builder.sh b/pkgs/development/tools/parsing/antlr/builder.sh index b8e7791b6fc9..55259b932124 100644 --- a/pkgs/development/tools/parsing/antlr/builder.sh +++ b/pkgs/development/tools/parsing/antlr/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup tar zxvf $src diff --git a/pkgs/misc/cups/drivers/samsung/4.00.39/builder.sh b/pkgs/misc/cups/drivers/samsung/4.00.39/builder.sh index f750df6e5063..bdb522744182 100644 --- a/pkgs/misc/cups/drivers/samsung/4.00.39/builder.sh +++ b/pkgs/misc/cups/drivers/samsung/4.00.39/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup arch=$(uname -m) diff --git a/pkgs/os-specific/linux/nvidia-x11/builder.sh b/pkgs/os-specific/linux/nvidia-x11/builder.sh index eadf88fd1168..1cf1400f996b 100755 --- a/pkgs/os-specific/linux/nvidia-x11/builder.sh +++ b/pkgs/os-specific/linux/nvidia-x11/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup unpackManually() { diff --git a/pkgs/os-specific/linux/opengl/xorg-sys/builder.sh b/pkgs/os-specific/linux/opengl/xorg-sys/builder.sh index cd21899e60e7..34f9b1579455 100644 --- a/pkgs/os-specific/linux/opengl/xorg-sys/builder.sh +++ b/pkgs/os-specific/linux/opengl/xorg-sys/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup mkdir -p $out/lib diff --git a/pkgs/servers/http/tomcat/axis2/builder.sh b/pkgs/servers/http/tomcat/axis2/builder.sh index 2e36367e9dcf..d334ab6f927f 100644 --- a/pkgs/servers/http/tomcat/axis2/builder.sh +++ b/pkgs/servers/http/tomcat/axis2/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi source $stdenv/setup unzip $src diff --git a/pkgs/servers/x11/xorg/builder.sh b/pkgs/servers/x11/xorg/builder.sh index 5a832cb14d53..9ee81091584b 100644 --- a/pkgs/servers/x11/xorg/builder.sh +++ b/pkgs/servers/x11/xorg/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi # This is the builder for all X.org components. source $stdenv/setup diff --git a/pkgs/test/simple/builder.sh b/pkgs/test/simple/builder.sh index 65f7e4c11ba1..908faec3c388 100644 --- a/pkgs/test/simple/builder.sh +++ b/pkgs/test/simple/builder.sh @@ -1,3 +1,4 @@ +if [ -e .attrs.sh ]; then source .attrs.sh; fi set -x export NIX_DEBUG=1 diff --git a/pkgs/tools/typesetting/lout/builder.sh b/pkgs/tools/typesetting/lout/builder.sh index eab37c3c68fb..cd513337f6f3 100755 --- a/pkgs/tools/typesetting/lout/builder.sh +++ b/pkgs/tools/typesetting/lout/builder.sh @@ -1,6 +1,7 @@ # Prepare a makefile specifying the appropriate output directories. # # Written by Ludovic Courtès . +if [ -e .attrs.sh ]; then source .attrs.sh; fi source "$stdenv/setup" || exit 1 From 02e3f51d27417f2775982281fc39e31a4978ae39 Mon Sep 17 00:00:00 2001 From: Artturin Date: Thu, 8 Dec 2022 04:30:26 +0200 Subject: [PATCH 09/16] darwin: use // for binutils-unwrapped and cctools to preserve the other attributes --- pkgs/stdenv/darwin/default.nix | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix index 9a7cd9aa9dee..76c44870f4ad 100644 --- a/pkgs/stdenv/darwin/default.nix +++ b/pkgs/stdenv/darwin/default.nix @@ -262,11 +262,12 @@ rec { ln -s ${bootstrapTools}/bin/rewrite-tbd $out/bin ''; - binutils-unwrapped = { name = "bootstrap-stage0-binutils"; outPath = bootstrapTools; }; + binutils-unwrapped = bootstrapTools // { + name = "bootstrap-stage0-binutils"; + }; - cctools = { + cctools = bootstrapTools // { name = "bootstrap-stage0-cctools"; - outPath = bootstrapTools; targetPrefix = ""; }; From c41cc9e762a97c20ec3be01db254787c046510e2 Mon Sep 17 00:00:00 2001 From: Artturin Date: Thu, 8 Dec 2022 04:52:11 +0200 Subject: [PATCH 10/16] treewide: move some perl vars to env attrset --- pkgs/development/libraries/xapian/default.nix | 2 +- pkgs/servers/monitoring/munin/default.nix | 2 +- pkgs/top-level/perl-packages.nix | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/development/libraries/xapian/default.nix b/pkgs/development/libraries/xapian/default.nix index 700fa1d13dd1..3c0a555dd978 100644 --- a/pkgs/development/libraries/xapian/default.nix +++ b/pkgs/development/libraries/xapian/default.nix @@ -26,7 +26,7 @@ let nativeBuildInputs = [ autoreconfHook ]; doCheck = true; - AUTOMATED_TESTING = true; # https://trac.xapian.org/changeset/8be35f5e1/git + env.AUTOMATED_TESTING = true; # https://trac.xapian.org/changeset/8be35f5e1/git patches = lib.optionals stdenv.isDarwin [ ./skip-flaky-darwin-test.patch ]; diff --git a/pkgs/servers/monitoring/munin/default.nix b/pkgs/servers/monitoring/munin/default.nix index 0bfc868167cb..2016bbe9ed3b 100644 --- a/pkgs/servers/monitoring/munin/default.nix +++ b/pkgs/servers/monitoring/munin/default.nix @@ -55,7 +55,7 @@ stdenv.mkDerivation rec { ]; # needs to find a local perl module during build - PERL_USE_UNSAFE_INC = "1"; + env.PERL_USE_UNSAFE_INC = "1"; # TODO: tests are failing https://munin-monitoring.org/ticket/1390#comment:1 # NOTE: important, test command always exits with 0, think of a way to abort the build once tests pass diff --git a/pkgs/top-level/perl-packages.nix b/pkgs/top-level/perl-packages.nix index e0cecf43d264..63d31a6cf57f 100644 --- a/pkgs/top-level/perl-packages.nix +++ b/pkgs/top-level/perl-packages.nix @@ -23029,7 +23029,7 @@ let # For some crazy reason Makefile.PL doesn't generate a Makefile if # AUTOMATED_TESTING is set. - AUTOMATED_TESTING = false; + env.AUTOMATED_TESTING = false; # Makefile.PL looks for ncurses in Glibc's prefix. preConfigure = @@ -27058,7 +27058,7 @@ let hash = "sha256-gxxY8549/ebS3QORjSs8IgdBs2aD05Tu+9Bn70gu7gQ="; }) ]; - AUTOMATED_TESTING = false; + env.AUTOMATED_TESTING = false; nativeBuildInputs = [ pkgs.pkg-config ]; buildInputs = [ pkgs.xorg.libxcb pkgs.xorg.xcbproto pkgs.xorg.xcbutil pkgs.xorg.xcbutilwm ExtUtilsDepends ExtUtilsPkgConfig TestDeep TestException XSObjectMagic ]; propagatedBuildInputs = [ DataDump MouseXNativeTraits XMLDescent XMLSimple ]; From c577eb6892a1128c1dd52846596217653ea87f14 Mon Sep 17 00:00:00 2001 From: Artturin Date: Thu, 8 Dec 2022 04:59:55 +0200 Subject: [PATCH 11/16] wrapNonDeterministicGcc: fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nix-repl> legacyPackages.x86_64-linux.fastStdenv error: The ‘env’ attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping: cc «derivation --- pkgs/top-level/all-packages.nix | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 44de96911273..23db6e1f2f7a 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -13933,9 +13933,11 @@ with pkgs; wrapNonDeterministicGcc = stdenv: ccWrapper: if ccWrapper.isGNU then ccWrapper.overrideAttrs(old: { - cc = old.cc.override { - reproducibleBuild = false; - profiledCompiler = with stdenv; (!isDarwin && hostPlatform.isx86); + env = old.env // { + cc = old.env.cc.override { + reproducibleBuild = false; + profiledCompiler = with stdenv; (!isDarwin && hostPlatform.isx86); + }; }; }) else ccWrapper; From 89dc806f131ae9318d47d43befbe9a3ef7f7a765 Mon Sep 17 00:00:00 2001 From: Artturin Date: Thu, 8 Dec 2022 21:11:35 +0200 Subject: [PATCH 12/16] what to do about attrs.env or {} maybe have a empty env attrset always so no need to use `or` --- pkgs/stdenv/linux/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix index dbaff342fb1a..6a1211f9cc48 100644 --- a/pkgs/stdenv/linux/default.nix +++ b/pkgs/stdenv/linux/default.nix @@ -249,7 +249,7 @@ in # Apparently iconv won't work with bootstrap glibc, but it will be used # with glibc built later where we keep *this* build of libunistring, # so we need to trick it into supporting libiconv. - am_cv_func_iconv_works = "yes"; + env = attrs.env or {} // { am_cv_func_iconv_works = "yes"; }; }); libidn2 = super.libidn2.overrideAttrs (attrs: { postFixup = attrs.postFixup or "" + '' From fda61e9066f545fca1eb440d249131edac040c30 Mon Sep 17 00:00:00 2001 From: Artturin Date: Thu, 8 Dec 2022 21:50:32 +0200 Subject: [PATCH 13/16] add docs for prependToVar and appendToVar --- doc/stdenv/stdenv.chapter.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/doc/stdenv/stdenv.chapter.md b/doc/stdenv/stdenv.chapter.md index e3d874ef507e..78560a29a337 100644 --- a/doc/stdenv/stdenv.chapter.md +++ b/doc/stdenv/stdenv.chapter.md @@ -990,6 +990,32 @@ Convenience function for `makeWrapper` that replaces `<\executable\>` with a wra If you will apply it multiple times, it will overwrite the wrapper file and you will end up with double wrapping, which should be avoided. +### `prependToVar` \ \ {#fun-prependToVar} + +Prepend elements to a variable. + +Example: + +```shellSession +$ configureFlags="--disable-static" +$ prependToVar configureFlags --disable-dependency-tracking --enable-foo +$ echo $configureFlags +--disable-dependency-tracking --enable-foo --disable-static +``` + +### `appendToVar` \ \ {#fun-appendToVar} + +Append elements to a variable. + +Example: + +```shellSession +$ configureFlags="--disable-static" +$ appendToVar configureFlags --disable-dependency-tracking --enable-foo +$ echo $configureFlags +--disable-static --disable-dependency-tracking --enable-foo +``` + ## Package setup hooks {#ssec-setup-hooks} Nix itself considers a build-time dependency as merely something that should previously be built and accessible at build time—packages themselves are on their own to perform any additional setup. In most cases, that is fine, and the downstream derivation can deal with its own dependencies. But for a few common tasks, that would result in almost every package doing the same sort of setup work—depending not on the package itself, but entirely on which dependencies were used. From 68fb254bf22178bee1c3009348bc7206bac59fa6 Mon Sep 17 00:00:00 2001 From: Artturin Date: Fri, 9 Dec 2022 20:07:12 +0200 Subject: [PATCH 14/16] tests.stdenv: deduplicate --- pkgs/test/stdenv/default.nix | 107 +++++++++++------------------------ 1 file changed, 34 insertions(+), 73 deletions(-) diff --git a/pkgs/test/stdenv/default.nix b/pkgs/test/stdenv/default.nix index 01f0e0fe8b83..2af4bcdfb731 100644 --- a/pkgs/test/stdenv/default.nix +++ b/pkgs/test/stdenv/default.nix @@ -12,63 +12,12 @@ let bootStdenv = stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv; pkgsStructured = import pkgs.path { config = { structuredAttrsByDefault = true; }; inherit (stdenv.hostPlatform) system; }; bootStdenvStructuredAttrsByDefault = pkgsStructured.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv.__bootPackages.stdenv; -in -{ - test-env-attrset = bootStdenv.mkDerivation { - name = "test-env-attrset"; - dontUnpack = true; - dontConfigure = true; - dontBuild = true; - dontPatch = true; - dontFixup = true; - env = { - string = "testing-string"; - }; - installPhase = '' - declare -p string - echo "env.string = $string" - [[ $string == "testing-string" ]] || (echo "string was not testing-string" && false) - touch $out - ''; - }; + ccWrapperSubstitutionsTest = { name, stdenv', extraAttrs ? { } }: - test-structured-env-attrset = bootStdenv.mkDerivation { - name = "test-structured-env-attrset"; - dontUnpack = true; - dontConfigure = true; - dontBuild = true; - dontPatch = true; - dontFixup = true; - __structuredAttrs = true; - env = { - string = "testing-string"; - }; - - installPhase = '' - declare -p string - echo "env.string = $string" - [[ $string == "testing-string" ]] || (echo "string was not testing-string" && false) - touch $out - ''; - }; - - test-cc-wrapper-substitutions = bootStdenv.cc.overrideAttrs (previousAttrs: { - name = "test-cc-wrapper-substitutions"; - - postFixup = previousAttrs.postFixup + '' - declare -p wrapperName - echo "env.wrapperName = $wrapperName" - [[ $wrapperName == "CC_WRAPPER" ]] || (echo "wrapperName was not CC_WRAPPER" && false) - touch $out - ''; - }); - - structuredAttrsByDefault = lib.recurseIntoAttrs { - - test-cc-wrapper-substitutions = bootStdenvStructuredAttrsByDefault.cc.overrideAttrs (previousAttrs: { - name = "test-cc-wrapper-substitutions-structuredAttrsByDefault"; + stdenv'.cc.overrideAttrs (previousAttrs: ({ + inherit name; postFixup = previousAttrs.postFixup + '' declare -p wrapperName @@ -76,32 +25,44 @@ in [[ $wrapperName == "CC_WRAPPER" ]] || (echo "wrapperName was not CC_WRAPPER" && false) declare -p suffixSalt echo "env.suffixSalt = $suffixSalt" - [[ $suffixSalt == "${bootStdenvStructuredAttrsByDefault.cc.suffixSalt}" ]] || (echo "wrapperName was not ${bootStdenvStructuredAttrsByDefault.cc.suffixSalt}" && false) + [[ $suffixSalt == "${stdenv'.cc.suffixSalt}" ]] || (echo "wrapperName was not ${stdenv'.cc.suffixSalt}" && false) grep -q "@out@" $out/bin/cc || echo "@out@ in $out/bin/cc was substituted" grep -q "@suffixSalt@" $out/bin/cc && (echo "$out/bin/cc contains unsubstituted variables" && false) touch $out ''; - }); + } // extraAttrs)); - test-structured-env-attrset = bootStdenvStructuredAttrsByDefault.mkDerivation { - name = "test-structured-env-attrset-structuredAttrsByDefault"; - dontUnpack = true; - dontConfigure = true; - dontBuild = true; - dontPatch = true; - dontFixup = true; - env = { - string = "testing-string"; - }; + testEnvAttrset = { name, stdenv', extraAttrs ? { } }: + stdenv'.mkDerivation + ({ + inherit name; + env = { + string = "testing-string"; + }; - installPhase = '' - declare -p string - echo "env.string = $string" - [[ $string == "testing-string" ]] || (echo "string was not testing-string" && false) - touch $out - ''; - }; + passAsFile = [ "buildCommand" ]; + buildCommand = '' + declare -p string + echo "env.string = $string" + [[ $string == "testing-string" ]] || (echo "string was not testing-string" && false) + touch $out + ''; + } // extraAttrs); + +in + +{ + test-env-attrset = testEnvAttrset { name = "test-env-attrset"; stdenv' = bootStdenv; }; + + test-structured-env-attrset = testEnvAttrset { name = "test-structured-env-attrset"; stdenv' = bootStdenv; extraAttrs = { __structuredAttrs = true; }; }; + + test-cc-wrapper-substitutions = ccWrapperSubstitutionsTest { name = "test-cc-wrapper-substitutions"; stdenv' = bootStdenv; }; + + structuredAttrsByDefault = lib.recurseIntoAttrs { + test-cc-wrapper-substitutions = ccWrapperSubstitutionsTest { name = "test-cc-wrapper-substitutions-structuredAttrsByDefault"; stdenv' = bootStdenvStructuredAttrsByDefault; }; + + test-structured-env-attrset = testEnvAttrset { name = "test-structured-env-attrset-structuredAttrsByDefault"; stdenv' = bootStdenvStructuredAttrsByDefault; }; }; } From bf972f18736478dad213ce2c409239af36417787 Mon Sep 17 00:00:00 2001 From: Artturin Date: Fri, 9 Dec 2022 22:22:31 +0200 Subject: [PATCH 15/16] tests.stdenv: add tests for prependToVar and appendToVar --- pkgs/test/stdenv/default.nix | 94 +++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 7 deletions(-) diff --git a/pkgs/test/stdenv/default.nix b/pkgs/test/stdenv/default.nix index 2af4bcdfb731..c5af468655ff 100644 --- a/pkgs/test/stdenv/default.nix +++ b/pkgs/test/stdenv/default.nix @@ -22,10 +22,10 @@ let postFixup = previousAttrs.postFixup + '' declare -p wrapperName echo "env.wrapperName = $wrapperName" - [[ $wrapperName == "CC_WRAPPER" ]] || (echo "wrapperName was not CC_WRAPPER" && false) + [[ $wrapperName == "CC_WRAPPER" ]] || (echo "'\$wrapperName' was not 'CC_WRAPPER'" && false) declare -p suffixSalt echo "env.suffixSalt = $suffixSalt" - [[ $suffixSalt == "${stdenv'.cc.suffixSalt}" ]] || (echo "wrapperName was not ${stdenv'.cc.suffixSalt}" && false) + [[ $suffixSalt == "${stdenv'.cc.suffixSalt}" ]] || (echo "'\$suffxSalt' was not '${stdenv'.cc.suffixSalt}'" && false) grep -q "@out@" $out/bin/cc || echo "@out@ in $out/bin/cc was substituted" grep -q "@suffixSalt@" $out/bin/cc && (echo "$out/bin/cc contains unsubstituted variables" && false) @@ -46,7 +46,35 @@ let buildCommand = '' declare -p string echo "env.string = $string" - [[ $string == "testing-string" ]] || (echo "string was not testing-string" && false) + [[ $string == "testing-string" ]] || (echo "'\$string' was not 'testing-string'" && false) + touch $out + ''; + } // extraAttrs); + + testPrependAndAppendToVar = { name, stdenv', extraAttrs ? { } }: + stdenv'.mkDerivation + ({ + inherit name; + env = { + string = "testing-string"; + }; + + passAsFile = [ "buildCommand" ] ++ lib.optionals (extraAttrs ? extraTest) [ "extraTest" ]; + # FIXME: with structuredAttrs string is converted to a indexed array + # should a/pToVar check if the passed variable is a array or a string? + # declare -x string="testing-string" + # declare -ax string=([0]="world" [1]="testing-string" [2]="hello") + buildCommand = '' + declare -p string + appendToVar string hello + # test that quoted strings work + prependToVar string "world" + declare -p string + + [[ $string == "world testing-string hello" ]] || (echo "'\$string' was not 'world testing-string hello'" && false) + + eval "$extraTest" + touch $out ''; } // extraAttrs); @@ -56,13 +84,65 @@ in { test-env-attrset = testEnvAttrset { name = "test-env-attrset"; stdenv' = bootStdenv; }; - test-structured-env-attrset = testEnvAttrset { name = "test-structured-env-attrset"; stdenv' = bootStdenv; extraAttrs = { __structuredAttrs = true; }; }; + test-prepend-append-to-var = testPrependAndAppendToVar { + name = "test-prepend-append-to-var"; + stdenv' = bootStdenv; + }; - test-cc-wrapper-substitutions = ccWrapperSubstitutionsTest { name = "test-cc-wrapper-substitutions"; stdenv' = bootStdenv; }; + test-structured-env-attrset = testEnvAttrset { + name = "test-structured-env-attrset"; + stdenv' = bootStdenv; + extraAttrs = { __structuredAttrs = true; }; + }; + + test-cc-wrapper-substitutions = ccWrapperSubstitutionsTest { + name = "test-cc-wrapper-substitutions"; + stdenv' = bootStdenv; + }; structuredAttrsByDefault = lib.recurseIntoAttrs { - test-cc-wrapper-substitutions = ccWrapperSubstitutionsTest { name = "test-cc-wrapper-substitutions-structuredAttrsByDefault"; stdenv' = bootStdenvStructuredAttrsByDefault; }; + test-cc-wrapper-substitutions = ccWrapperSubstitutionsTest { + name = "test-cc-wrapper-substitutions-structuredAttrsByDefault"; + stdenv' = bootStdenvStructuredAttrsByDefault; + }; - test-structured-env-attrset = testEnvAttrset { name = "test-structured-env-attrset-structuredAttrsByDefault"; stdenv' = bootStdenvStructuredAttrsByDefault; }; + test-structured-env-attrset = testEnvAttrset { + name = "test-structured-env-attrset-structuredAttrsByDefault"; + stdenv' = bootStdenvStructuredAttrsByDefault; + }; + + test-prepend-append-to-var = testPrependAndAppendToVar { + name = "test-prepend-append-to-var-structuredAttrsByDefault"; + stdenv' = bootStdenvStructuredAttrsByDefault; + extraAttrs = { + # will be a bash indexed array in attrs.sh + # declare -a list=('a' 'b' ) + # and a json array in attrs.json + # "list":["a","b"] + list = [ "a" "b" ]; + # will be a bash associative array(dictionary) in attrs.sh + # declare -A array=(['a']='1' ['b']='2' ) + # and a json object in attrs.json + # {"array":{"a":"1","b":"2"} + array = { a = "1"; b = "2"; }; + extraTest = '' + declare -p array + array+=(["c"]="3") + declare -p array + + [[ "''${array[c]}" == "3" ]] || (echo "c element of '\$array' was not '3'" && false) + + declare -p list + prependToVar list hello + # test that quoted strings work + appendToVar list "world" + declare -p list + + [[ "''${list[0]}" == "hello" ]] || (echo "first element of '\$list' was not 'hello'" && false) + [[ "''${list[1]}" == "a" ]] || (echo "first element of '\$list' was not 'a'" && false) + [[ "''${list[-1]}" == "world" ]] || (echo "last element of '\$list' was not 'world'" && false) + ''; + }; + }; }; } From 11c3127e38dafdf95ca71a85b1591a29b67e0c09 Mon Sep 17 00:00:00 2001 From: Artturin Date: Sat, 10 Dec 2022 01:09:40 +0200 Subject: [PATCH 16/16] stdenv: detect the type of variable in {prepend,append}ToVar stdenv: error if using {prepend,append}ToVar on associative array i don't know how to prepend to associative array --- pkgs/stdenv/generic/setup.sh | 50 ++++++++++++++++++++++++++++++++++-- pkgs/test/stdenv/default.nix | 19 +++++++++++--- 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh index 182f849cf525..5a64625e10d1 100644 --- a/pkgs/stdenv/generic/setup.sh +++ b/pkgs/stdenv/generic/setup.sh @@ -209,8 +209,31 @@ addToSearchPath() { # Expressions for individual packages should simply switch to array # syntax when they switch to setting __structuredAttrs = true. prependToVar() { - local -n nameref="$1"; shift + local -n nameref="$1" + + useArray= if [ -n "$__structuredAttrs" ]; then + useArray=true + else + useArray=false + fi + + # check if variable already exist and if it does then do extra checks + if declare -p "$1" 2> /dev/null | grep -q '^'; then + type="$(declare -p "$1")" + if [[ "$type" =~ "declare -A" ]]; then + echo "prependToVar(): ERROR: trying to use prependToVar on an associative array." >&2 + return 1 + elif [[ "$type" =~ "declare -a" ]]; then + useArray=true + else + useArray=false + fi + fi + + shift + + if $useArray; then nameref=( "$@" ${nameref+"${nameref[@]}"} ) else nameref="$* ${nameref-}" @@ -219,8 +242,31 @@ prependToVar() { # Same as above appendToVar() { - local -n nameref="$1"; shift + local -n nameref="$1" + + useArray= if [ -n "$__structuredAttrs" ]; then + useArray=true + else + useArray=false + fi + + # check if variable already exist and if it does then do extra checks + if declare -p "$1" 2> /dev/null | grep -q '^'; then + type="$(declare -p "$1")" + if [[ "$type" =~ "declare -A" ]]; then + echo "appendToVar(): ERROR: trying to use appendToVar on an associative array, use variable+=([\"X\"]=\"Y\") instead." >&2 + return 1 + elif [[ "$type" =~ "declare -a" ]]; then + useArray=true + else + useArray=false + fi + fi + + shift + + if $useArray; then nameref=( ${nameref+"${nameref[@]}"} "$@" ) else nameref="${nameref-} $*" diff --git a/pkgs/test/stdenv/default.nix b/pkgs/test/stdenv/default.nix index c5af468655ff..08e8eed118f9 100644 --- a/pkgs/test/stdenv/default.nix +++ b/pkgs/test/stdenv/default.nix @@ -60,10 +60,6 @@ let }; passAsFile = [ "buildCommand" ] ++ lib.optionals (extraAttrs ? extraTest) [ "extraTest" ]; - # FIXME: with structuredAttrs string is converted to a indexed array - # should a/pToVar check if the passed variable is a array or a string? - # declare -x string="testing-string" - # declare -ax string=([0]="world" [1]="testing-string" [2]="hello") buildCommand = '' declare -p string appendToVar string hello @@ -71,8 +67,23 @@ let prependToVar string "world" declare -p string + declare -A associativeArray=(["X"]="Y") + [[ $(appendToVar associativeArray "fail" 2>&1) =~ "trying to use" ]] || (echo "prependToVar did not catch prepending associativeArray" && false) + [[ $(prependToVar associativeArray "fail" 2>&1) =~ "trying to use" ]] || (echo "prependToVar did not catch prepending associativeArray" && false) + [[ $string == "world testing-string hello" ]] || (echo "'\$string' was not 'world testing-string hello'" && false) + # test appending to a unset variable + appendToVar nonExistant created hello + typeset -p nonExistant + if [[ -n $__structuredAttrs ]]; then + [[ "''${nonExistant[@]}" == "created hello" ]] + else + # there's a extra " " in front here and a extra " " in the end of prependToVar + # shouldn't matter because these functions will mostly be used for $*Flags and the Flag variable will in most cases already exit + [[ "$nonExistant" == " created hello" ]] + fi + eval "$extraTest" touch $out