Odd uses of $src in packages

I noticed that a package I was trying to patch was installing scripts directly from $src/ → $out/bin/, so my patches weren’t applying.

I grepped around (naively!) to see if this was common and found \$src[/] in 81 other files.

I thought about opening an issue for this, but it felt a little too diffuse to expect someone doing issue triage to handle. But the general sentiment from IRC did seem to be that it’s odd or a smell, so I didn’t want to let it pass unmentioned.

Feel free to tell me to go file an issue! :slight_smile:

pkgs/os-specific/linux/dbus-broker/default.nix-  postInstall = ''
pkgs/os-specific/linux/dbus-broker/default.nix:    install -Dm644 $src/README.md $out/share/doc/dbus-broker/README
pkgs/os-specific/linux/dbus-broker/default.nix-
--
pkgs/os-specific/darwin/osxfuse/default.nix-    mkdir -p $out/include
pkgs/os-specific/darwin/osxfuse/default.nix:    cp --target-directory=$out/include $src/common/*.h
pkgs/os-specific/darwin/osxfuse/default.nix-  '';
--
pkgs/tools/misc/togglesg-download/default.nix-    mkdir -p $out/{bin,share/doc/togglesg-download}
pkgs/tools/misc/togglesg-download/default.nix:    substitute $src/download_toggle_video2.py $out/bin/download_toggle_video2.py \
pkgs/tools/misc/togglesg-download/default.nix-      --replace "ffmpeg_download_cmd = 'ffmpeg" "ffmpeg_download_cmd = '${lib.getBin ffmpeg_3}/bin/ffmpeg"
--
pkgs/tools/misc/odroid-xu3-bootloader/default.nix-  buildCommand = ''
pkgs/tools/misc/odroid-xu3-bootloader/default.nix:    install -Dm644 -t $out/lib/sd_fuse-xu3 $src/sd_fuse/hardkernel_1mb_uboot/{bl2,tzsw}.*
pkgs/tools/misc/odroid-xu3-bootloader/default.nix:    install -Dm644 -t $out/lib/sd_fuse-xu3 $src/sd_fuse/hardkernel/bl1.*
pkgs/tools/misc/odroid-xu3-bootloader/default.nix-    ln -sf ${ubootOdroidXU3}/u-boot-dtb.bin $out/lib/sd_fuse-xu3/u-boot-dtb.bin
pkgs/tools/misc/odroid-xu3-bootloader/default.nix-
pkgs/tools/misc/odroid-xu3-bootloader/default.nix:    install -Dm755 $src/sd_fuse/hardkernel_1mb_uboot/sd_fusing.1M.sh $out/bin/sd_fuse-xu3
pkgs/tools/misc/odroid-xu3-bootloader/default.nix-    sed -i \
--
pkgs/tools/misc/nginx-config-formatter/default.nix-  checkPhase = ''
pkgs/tools/misc/nginx-config-formatter/default.nix:    python3 $src/test_nginxfmt.py
pkgs/tools/misc/nginx-config-formatter/default.nix-  '';
--
pkgs/tools/misc/nginx-config-formatter/default.nix-    mkdir -p $out/bin
pkgs/tools/misc/nginx-config-formatter/default.nix:    install -m 0755 $src/nginxfmt.py $out/bin/nginxfmt
pkgs/tools/misc/nginx-config-formatter/default.nix-  '';
--
pkgs/tools/misc/fd/default.nix-  preFixup = ''
pkgs/tools/misc/fd/default.nix:    installManPage "$src/doc/fd.1"
pkgs/tools/misc/fd/default.nix-
--
pkgs/tools/misc/noti/default.nix-  postInstall = ''
pkgs/tools/misc/noti/default.nix:    install -Dm444 -t $out/share/man/man1 $src/docs/man/*.1
pkgs/tools/misc/noti/default.nix:    install -Dm444 -t $out/share/man/man5 $src/docs/man/*.5
pkgs/tools/misc/noti/default.nix-  '';
--
pkgs/tools/misc/memtest86-efi/default.nix-    # usb image so that it can be installed directly on the hard drive.
pkgs/tools/misc/memtest86-efi/default.nix:    7z x -o$TEMP/temp-efi-dirs $src/memtest86-usb.img
pkgs/tools/misc/memtest86-efi/default.nix-    7z x -o$TEMP/memtest86-files $TEMP/temp-efi-dirs/EFI\ System\ Partition.img
--
pkgs/tools/misc/git-fire/default.nix-  installPhase = ''
pkgs/tools/misc/git-fire/default.nix:    install -D -m755 $src/git-fire $out/bin/git-fire
pkgs/tools/misc/git-fire/default.nix-  '';
--
pkgs/tools/video/untrunc/default.nix-        -Wno-deprecated-declarations \
pkgs/tools/video/untrunc/default.nix:        $src/file.cpp $src/main.cpp $src/track.cpp $src/atom.cpp $src/mp4.cpp \
pkgs/tools/video/untrunc/default.nix-        -I$libavConfiguredSrc -lavformat -lavcodec -lavutil
--
pkgs/tools/nix/nix-script/default.nix-    mkdir -p $out/bin
pkgs/tools/nix/nix-script/default.nix:    ghc -O2 $src/nix-script.hs -o $out/bin/nix-script -odir . -hidir .
pkgs/tools/nix/nix-script/default.nix-  '';
--
pkgs/tools/security/enchive/default.nix-    mkdir -p $out/share/emacs/site-lisp/
pkgs/tools/security/enchive/default.nix:    cp -v "$src/enchive-mode.el" "$out/share/emacs/site-lisp/"
pkgs/tools/security/enchive/default.nix-  '';
--
pkgs/tools/networking/amass/default.nix-    mkdir -p $wordlists
pkgs/tools/networking/amass/default.nix:    cp -R $src/examples/wordlists/*.txt $wordlists
pkgs/tools/networking/amass/default.nix-    gzip $wordlists/*.txt
--
pkgs/tools/networking/dd-agent/datadog-agent.nix-    mkdir -p $bin/${python.sitePackages} $bin/share/datadog-agent
pkgs/tools/networking/dd-agent/datadog-agent.nix:    cp -R $src/cmd/agent/dist/conf.d $bin/share/datadog-agent
pkgs/tools/networking/dd-agent/datadog-agent.nix:    cp -R $src/cmd/agent/dist/{checks,utils,config.py} $bin/${python.sitePackages}
pkgs/tools/networking/dd-agent/datadog-agent.nix-
pkgs/tools/networking/dd-agent/datadog-agent.nix:    cp -R $src/pkg/status/dist/templates $bin/share/datadog-agent
pkgs/tools/networking/dd-agent/datadog-agent.nix-
--
pkgs/tools/networking/tlspool/default.nix-    mkdir -p $out/include/${pname}/pulleyback $out/etc/tlspool
pkgs/tools/networking/tlspool/default.nix:    cp -R $src/etc/* $out/etc/tlspool/
pkgs/tools/networking/tlspool/default.nix:    cp $src/include/tlspool/*.h $out/include/${pname}
pkgs/tools/networking/tlspool/default.nix:    cp $src/pulleyback/*.h $out/include/${pname}/pulleyback/
pkgs/tools/networking/tlspool/default.nix:    cp $src/src/*.h $out/include/${pname}
pkgs/tools/networking/tlspool/default.nix-  '';
--
pkgs/tools/networking/persepolis/default.nix-     mkdir -p $out/share/applications
pkgs/tools/networking/persepolis/default.nix:     cp $src/xdg/com.github.persepolisdm.persepolis.desktop $out/share/applications
pkgs/tools/networking/persepolis/default.nix-     wrapProgram $out/bin/persepolis --prefix PATH : "${lib.makeBinPath [aria libnotify ]}"
--
pkgs/tools/networking/carddav-util/default.nix-    mkdir -p $out/bin
pkgs/tools/networking/carddav-util/default.nix:    cp $src/carddav-util.py $out/bin
pkgs/tools/networking/carddav-util/default.nix-
--
pkgs/tools/networking/carddav-util/default.nix-    mkdir -p "$pythondir"
pkgs/tools/networking/carddav-util/default.nix:    cp $src/carddav.py "$pythondir"
pkgs/tools/networking/carddav-util/default.nix-  '';
--
pkgs/tools/admin/daemontools/default.nix-
pkgs/tools/admin/daemontools/default.nix:    sed -ie "s_^PATH=.*_PATH=$src/${name}/compile:''${PATH}_" src/rts.tests
pkgs/tools/admin/daemontools/default.nix-
--
pkgs/tools/admin/acme.sh/default.nix-    mkdir -p $out $out/bin $out/libexec
pkgs/tools/admin/acme.sh/default.nix:    cp -R $src/* $_
pkgs/tools/admin/acme.sh/default.nix-    makeWrapper $out/libexec/acme.sh $out/bin/acme.sh \
--
pkgs/tools/package-management/cde/default.nix-  patchBuild = ''
pkgs/tools/package-management/cde/default.nix:    sed '/install/d' $src/Makefile > $src/Makefile
pkgs/tools/package-management/cde/default.nix-  '';
--
pkgs/tools/package-management/morph/default.nix-    mkdir -p $lib
pkgs/tools/package-management/morph/default.nix:    cp -v $src/data/*.nix $lib
pkgs/tools/package-management/morph/default.nix-    wrapProgram $bin/bin/morph --prefix PATH : ${lib.makeBinPath [ openssh ]};
--
pkgs/tools/text/jsawk/default.nix-    mkdir -p $out/bin
pkgs/tools/text/jsawk/default.nix:    cp $src/jsawk $out/bin/
pkgs/tools/text/jsawk/default.nix-    wrapProgram $out/bin/jsawk \
--
pkgs/tools/text/ripgrep/default.nix-    installShellCompletion rg.{bash,fish})
pkgs/tools/text/ripgrep/default.nix:    installShellCompletion --zsh "$src/complete/_rg"
pkgs/tools/text/ripgrep/default.nix-  '';
--
pkgs/development/misc/msp430/gcc-support.nix-  buildCommand = ''
pkgs/development/misc/msp430/gcc-support.nix:    find $src/include -name '*.ld' | xargs install -Dm0644 -t $out/lib
pkgs/development/misc/msp430/gcc-support.nix:    find $src/include -name '*.h' | xargs install -Dm0644 -t $out/include
pkgs/development/misc/msp430/gcc-support.nix:    install -Dm0644 -t $out/include $src/include/devices.csv
pkgs/development/misc/msp430/gcc-support.nix-
--
pkgs/development/interpreters/php/default.nix-
pkgs/development/interpreters/php/default.nix:      if test -f $src/genfiles; then
pkgs/development/interpreters/php/default.nix-        ./genfiles
--
pkgs/development/tools/git-series/default.nix-  postBuild = ''
pkgs/development/tools/git-series/default.nix:    install -D "$src/git-series.1" "$out/man/man1/git-series.1"
pkgs/development/tools/git-series/default.nix-  '';
--
pkgs/development/tools/analysis/radare2/default.nix-      postInstall = ''
pkgs/development/tools/analysis/radare2/default.nix:        install -D -m755 $src/binr/r2pm/r2pm $out/bin/r2pm
pkgs/development/tools/analysis/radare2/default.nix-      '';
--
pkgs/development/tools/analysis/garcosim/tracefilegen/default.nix-    mkdir -p $out/share/doc/${name}/
pkgs/development/tools/analysis/garcosim/tracefilegen/default.nix:    cp -ar $src/Documentation/html $out/share/doc/${name}/.
pkgs/development/tools/analysis/garcosim/tracefilegen/default.nix-  '';
--
pkgs/development/tools/flamegraph/default.nix-    mkdir -p $out/bin
pkgs/development/tools/flamegraph/default.nix:    for x in $src/*.pl $src/*.awk $src/dev/*.pl $src/dev/*.d; do
pkgs/development/tools/flamegraph/default.nix-      cp $x $out/bin
--
pkgs/development/tools/haskell/hyper-haskell/default.nix-    # Electron app
pkgs/development/tools/haskell/hyper-haskell/default.nix:    cp -R $src/app $out
pkgs/development/tools/haskell/hyper-haskell/default.nix-
pkgs/development/tools/haskell/hyper-haskell/default.nix-    # Desktop Launcher
pkgs/development/tools/haskell/hyper-haskell/default.nix:    cp $src/resources/hyper-haskell.desktop $out/share/applications/hyper-haskell.desktop
pkgs/development/tools/haskell/hyper-haskell/default.nix:    cp $src/resources/icons/icon.svg $out/share/icons/hicolor/scalable/apps/hyper-haskell.svg
pkgs/development/tools/haskell/hyper-haskell/default.nix:    cp $src/resources/shared-mime-info.xml $out/share/mime/packages/hyper-haskell.xml
pkgs/development/tools/haskell/hyper-haskell/default.nix-
pkgs/development/tools/haskell/hyper-haskell/default.nix-    # install example worksheets with backend set to nix
pkgs/development/tools/haskell/hyper-haskell/default.nix:    for worksheet in "$src/worksheets/"*.hhs; do
pkgs/development/tools/haskell/hyper-haskell/default.nix-      ${jshon}/bin/jshon -e settings -s nix -i packageTool -p < $worksheet > $out/share/hyper-haskell/worksheets/`basename $worksheet`
--
pkgs/development/tools/rund/default.nix-    echo Using DCompiler $candidate
pkgs/development/tools/rund/default.nix:    $dc -I=$src/src -i -run $src/make.d build --out $NIX_BUILD_TOP
pkgs/development/tools/rund/default.nix-  '';
--
pkgs/development/tools/cloudfoundry-cli/default.nix-    install -Dm555 out/cf "$bin/bin/cf"
pkgs/development/tools/cloudfoundry-cli/default.nix:    install -Dm444 -t "$bin/share/bash-completion/completions/" "$src/ci/installers/completion/cf"
pkgs/development/tools/cloudfoundry-cli/default.nix-  '';
--
pkgs/development/tools/poetry/update-src=$(nix-build --expr 'with import ../../../../. {}; fetchFromGitHub (lib.importJSON ./src.json)')
pkgs/development/tools/poetry/update:cp $src/pyproject.toml $src/poetry.lock .
pkgs/development/tools/poetry/update-nix-build --show-trace --no-out-link ../../../../. -A poetry
--
pkgs/development/tools/parsing/tree-sitter/library.nix-    runHook preBuild
pkgs/development/tools/parsing/tree-sitter/library.nix:    $CC -I$src/src/ -shared -o parser -Os $src/src/parser.c
pkgs/development/tools/parsing/tree-sitter/library.nix-    runHook postBuild
--
pkgs/development/tools/go2nix/default.nix-    mkdir -p $man/share/man/man1
pkgs/development/tools/go2nix/default.nix:    cp $src/go2nix.1 $man/share/man/man1
pkgs/development/tools/go2nix/default.nix-  '';
--
pkgs/development/python-modules/arelle/default.nix-    targetDir=$out/${python.sitePackages}
pkgs/development/python-modules/arelle/default.nix:    cp -vr $src/arelle $targetDir
pkgs/development/python-modules/arelle/default.nix-  '';
--
pkgs/development/libraries/half/default.nix-    mkdir -p $out/include $out/share/doc
pkgs/development/libraries/half/default.nix:    cp $src/include/half.hpp               $out/include/
pkgs/development/libraries/half/default.nix:    cp $src/{ChangeLog,LICENSE,README}.txt $out/share/doc/
pkgs/development/libraries/half/default.nix-  '';
--
pkgs/development/libraries/dotnetfx40/default.nix-      mkdir -p $out/bin
pkgs/development/libraries/dotnetfx40/default.nix:      ln -s $src/MSBuild.exe $out/bin
pkgs/development/libraries/dotnetfx40/default.nix-    '';
--
pkgs/development/libraries/dotnetfx35/default.nix-      mkdir -p $out/bin
pkgs/development/libraries/dotnetfx35/default.nix:      ln -s $src/MSBuild.exe $out/bin
pkgs/development/libraries/dotnetfx35/default.nix-    '';
--
pkgs/development/libraries/libui/default.nix-  '' + ''
pkgs/development/libraries/libui/default.nix:    cp $src/ui.h $out/include
pkgs/development/libraries/libui/default.nix:    cp $src/ui_${backend}.h $out/include
pkgs/development/libraries/libui/default.nix-
--
pkgs/development/libraries/lyra/default.nix-    mkdir -p $out/include
pkgs/development/libraries/lyra/default.nix:    cp -R $src/include/* $out/include
pkgs/development/libraries/lyra/default.nix-  '';
--
pkgs/development/mobile/adb-sync/default.nix-    mkdir -p $out/bin
pkgs/development/mobile/adb-sync/default.nix:    cp $src/adb-channel $src/adb-sync $out/bin/
pkgs/development/mobile/adb-sync/default.nix-    patchShebangs $out/bin
--
pkgs/development/lisp-modules/lisp-packages.nix-    buildPhase = ''
pkgs/development/lisp-modules/lisp-packages.nix:      ${sbcl}/bin/sbcl --eval '(load #P"${asdf}/lib/common-lisp/asdf/build/asdf.lisp")' --load $src/system-info.lisp --eval '(ql-to-nix-system-info::dump-image)'
pkgs/development/lisp-modules/lisp-packages.nix-    '';
--
pkgs/development/lisp-modules/lisp-packages.nix-    buildPhase = ''
pkgs/development/lisp-modules/lisp-packages.nix:      ${clwrapper}/bin/cl-wrapper.sh "${sbcl}/bin/sbcl" --eval '(load #P"${asdf}/lib/common-lisp/asdf/build/asdf.lisp")' --load $src/ql-to-nix.lisp --eval '(ql-to-nix::dump-image)'
pkgs/development/lisp-modules/lisp-packages.nix-    '';
--
pkgs/development/bower-modules/generic/default.nix-      # The project's bower.json is required
pkgs/development/bower-modules/generic/default.nix:      cp $src/bower.json .
pkgs/development/bower-modules/generic/default.nix-
--
pkgs/development/compilers/emscripten/default.nix-    mkdir -p $out/${appdir}
pkgs/development/compilers/emscripten/default.nix:    cp -r $src/* $out/${appdir}
pkgs/development/compilers/emscripten/default.nix-    chmod -R +w $out/${appdir}
--
pkgs/development/compilers/emscripten/default.nix-    #export EMCC_DEBUG=2  
pkgs/development/compilers/emscripten/default.nix:    ${python}/bin/python $src/tests/runner.py test_hello_world
pkgs/development/compilers/emscripten/default.nix-    echo "--------------- /running test -----------------"
--
pkgs/development/java-modules/postgresql_jdbc/default.nix-  installPhase = ''
pkgs/development/java-modules/postgresql_jdbc/default.nix:    install -m444 -D $src/share/java/*postgresql-${version}.jar $out/share/java/postgresql-jdbc.jar
pkgs/development/java-modules/postgresql_jdbc/default.nix-  '';
--
pkgs/shells/pash/default.nix-
pkgs/shells/pash/default.nix:  preConfigure = "rm -rvf $src/Source/PashConsole/bin/*";
pkgs/shells/pash/default.nix-
--
pkgs/shells/zsh/zsh-command-time/default.nix-  installPhase = ''
pkgs/shells/zsh/zsh-command-time/default.nix:    install -Dm0444 $src/command-time.plugin.zsh --target-directory=$out/share/zsh/plugins/command-time
pkgs/shells/zsh/zsh-command-time/default.nix-  '';
--
pkgs/shells/zsh/oh-my-zsh/default.nix-  mkdir -p $outdir
pkgs/shells/zsh/oh-my-zsh/default.nix:  cp -r $src/* $outdir
pkgs/shells/zsh/oh-my-zsh/default.nix-  cd $outdir
--
pkgs/top-level/haxe-packages.nix-            if [ $(ls $src | wc -l) == 1 ]; then
pkgs/top-level/haxe-packages.nix:              cd $src/* || cd $src
pkgs/top-level/haxe-packages.nix-            else
--
pkgs/applications/misc/xpdf/default.nix-    install -Dm644 ${desktopItem}/share/applications/xpdf.desktop $out/share/applications/xpdf.desktop
pkgs/applications/misc/xpdf/default.nix:    install -Dm644 $src/xpdf-qt/xpdf-icon.svg $out/share/pixmaps/xpdf.svg
pkgs/applications/misc/xpdf/default.nix-  '';
--
pkgs/applications/video/kodi/plugins.nix-    installPhase = ''
pkgs/applications/video/kodi/plugins.nix:      ${if sourceDir == null then "" else "cd $src/$sourceDir"}
pkgs/applications/video/kodi/plugins.nix-      d=$out${pluginDir}/${namespace}
--
pkgs/applications/radio/gqrx/default.nix-  postInstall = ''
pkgs/applications/radio/gqrx/default.nix:    install -vD $src/gqrx.desktop -t "$out/share/applications/"
pkgs/applications/radio/gqrx/default.nix:    install -vD $src/resources/icons/gqrx.svg -t "$out/share/icons/"
pkgs/applications/radio/gqrx/default.nix-  '';
--
pkgs/applications/virtualization/driver/win-pvdrivers/default.nix-  buildPhase =
pkgs/applications/virtualization/driver/win-pvdrivers/default.nix:    let unpack = x: "tar xf $src/${x}.tar; mkdir -p x86/${x} amd64/${x}; cp ${x}/x86/* x86/${x}/.; cp ${x}/x64/* amd64/${x}/.";
pkgs/applications/virtualization/driver/win-pvdrivers/default.nix-    in stdenv.lib.concatStringsSep "\n" (map unpack ["xenbus" "xeniface" "xenvif" "xennet" "xenvbd"]);
--
pkgs/applications/office/paperless/default.nix-      mkdir -p $srcDir
pkgs/applications/office/paperless/default.nix:      cp -r --no-preserve=mode $src/src/* $src/LICENSE $srcDir
pkgs/applications/office/paperless/default.nix-    '';
--
pkgs/applications/networking/irc/weechat/scripts/weechat-matrix/default.nix-    mkdir -p $out/share $out/bin
pkgs/applications/networking/irc/weechat/scripts/weechat-matrix/default.nix:    cp $src/main.py $out/share/matrix.py
pkgs/applications/networking/irc/weechat/scripts/weechat-matrix/default.nix-
pkgs/applications/networking/irc/weechat/scripts/weechat-matrix/default.nix-    cp \
pkgs/applications/networking/irc/weechat/scripts/weechat-matrix/default.nix:      $src/contrib/matrix_upload \
pkgs/applications/networking/irc/weechat/scripts/weechat-matrix/default.nix:      $src/contrib/matrix_decrypt \
pkgs/applications/networking/irc/weechat/scripts/weechat-matrix/default.nix:      $src/contrib/matrix_sso_helper \
pkgs/applications/networking/irc/weechat/scripts/weechat-matrix/default.nix-      $out/bin/
--
pkgs/applications/networking/irc/weechat/scripts/weechat-matrix/default.nix-    mkdir -p $out/${python.sitePackages}
pkgs/applications/networking/irc/weechat/scripts/weechat-matrix/default.nix:    cp -r $src/matrix $out/${python.sitePackages}/matrix
pkgs/applications/networking/irc/weechat/scripts/weechat-matrix/default.nix-  '';
--
pkgs/applications/networking/browsers/palemoon/default.nix-  buildPhase = ''
pkgs/applications/networking/browsers/palemoon/default.nix:    $src/mach build
pkgs/applications/networking/browsers/palemoon/default.nix-  '';
--
pkgs/applications/networking/browsers/palemoon/default.nix-  installPhase = ''
pkgs/applications/networking/browsers/palemoon/default.nix:    $src/mach install
pkgs/applications/networking/browsers/palemoon/default.nix-
--
pkgs/applications/networking/browsers/palemoon/default.nix-      mkdir -p $out/share/icons/hicolor/$size/apps
pkgs/applications/networking/browsers/palemoon/default.nix:      cp $src/application/palemoon/branding/official/default$n.png \
pkgs/applications/networking/browsers/palemoon/default.nix-         $out/share/icons/hicolor/$size/apps/palemoon.png
--
pkgs/applications/networking/sync/rclone/default.nix-      ''
pkgs/applications/networking/sync/rclone/default.nix:        install -D -m644 $src/rclone.1 $man/share/man/man1/rclone.1
pkgs/applications/networking/sync/rclone/default.nix-        mkdir -p $bin/share/zsh/site-functions $bin/share/bash-completion/completions/
--
pkgs/applications/networking/remote/xrdp/default.nix-
pkgs/applications/networking/remote/xrdp/default.nix:      cp $src/keygen/openssl.conf $out/share/xrdp/openssl.conf
pkgs/applications/networking/remote/xrdp/default.nix-
--
pkgs/applications/science/programming/scyther/default.nix-    installCheckPhase = ''
pkgs/applications/science/programming/scyther/default.nix:      "$out/gui/scyther.py" "$src/gui/Protocols/Demo/ns3.spdl"
pkgs/applications/science/programming/scyther/default.nix-    '';
--
pkgs/applications/audio/stone-phaser/default.nix-  postPatch = ''
pkgs/applications/audio/stone-phaser/default.nix:    patch -d dpf -p 1 -i "$src/resources/patch/DPF-bypass.patch"
pkgs/applications/audio/stone-phaser/default.nix-    patchShebangs ./dpf/utils/generate-ttl.sh
--
pkgs/applications/version-management/gitlab/gitaly/default.nix-    mkdir -p $ruby
pkgs/applications/version-management/gitlab/gitaly/default.nix:    cp -rv $src/ruby/{bin,lib,proto,git-hooks,gitlab-shell} $ruby
pkgs/applications/version-management/gitlab/gitaly/default.nix-
--
pkgs/applications/version-management/gitkraken/default.nix-    mkdir -p $out/share/gitkraken/
pkgs/applications/version-management/gitkraken/default.nix:    cp -R $src/* $out/share/gitkraken/
pkgs/applications/version-management/gitkraken/default.nix-
--
pkgs/applications/version-management/gogs/default.nix-    mkdir $data
pkgs/applications/version-management/gogs/default.nix:    cp -R $src/{public,templates} $data
pkgs/applications/version-management/gogs/default.nix-
--
pkgs/applications/graphics/rx/default.nix-    mkdir -p $out/share/applications
pkgs/applications/graphics/rx/default.nix:    cp $src/rx.desktop $out/share/applications
pkgs/applications/graphics/rx/default.nix-    wrapProgram $out/bin/rx --prefix LD_LIBRARY_PATH : ${libGL}/lib
--
pkgs/applications/blockchains/monero-gui/default.nix-      mkdir -p $out/share/icons/hicolor/$size/apps
pkgs/applications/blockchains/monero-gui/default.nix:      cp $src/images/appicons/$size.png \
pkgs/applications/blockchains/monero-gui/default.nix-         $out/share/icons/hicolor/$size/apps/monero.png
--
pkgs/data/fonts/inconsolata/default.nix-  installPhase = ''
pkgs/data/fonts/inconsolata/default.nix:    install -m644 --target $out/share/fonts/truetype/inconsolata -D $src/ofl/inconsolata/*.ttf
pkgs/data/fonts/inconsolata/default.nix-  '';
--
pkgs/data/fonts/gohufont/default.nix-    cd ${bdf2psf}/share/bdf2psf
pkgs/data/fonts/gohufont/default.nix:    for i in $src/*.bdf; do
pkgs/data/fonts/gohufont/default.nix-      name=$(basename $i .bdf)
--
pkgs/data/fonts/gohufont/default.nix-    # convert bdf fonts to pcf
pkgs/data/fonts/gohufont/default.nix:    for i in *.bdf $src/hidpi/*.bdf; do
pkgs/data/fonts/gohufont/default.nix-        name=$(basename $i .bdf)
--
pkgs/data/fonts/gohufont/default.nix-    # convert unicode bdf fonts to otb
pkgs/data/fonts/gohufont/default.nix:    for i in *-uni*.bdf $src/hidpi/*-uni*.bdf; do
pkgs/data/fonts/gohufont/default.nix-        name=$(basename $i .bdf)
--
pkgs/games/openxray/default.nix-    install -Dm755 $out/games/xr_3da $out/bin/xr_3da
pkgs/games/openxray/default.nix:    install -Dm644 $src/License.txt $out/share/licenses/openxray/License.txt
pkgs/games/openxray/default.nix-    rm -r $out/var $out/games
--
pkgs/games/openjk/default.nix-
pkgs/games/openjk/default.nix:    cp $src/shared/icons/OpenJK_Icon_128.png $out/share/icons/hicolor/128x128/apps
pkgs/games/openjk/default.nix-    ln -s ${jamp}/share/applications/* $out/share/applications
--
pkgs/games/quake2/yquake2/default.nix-      ln -s $out/lib/yquake2/q2ded $out/bin/yq2ded
pkgs/games/quake2/yquake2/default.nix:      cp $src/stuff/yq2.cfg $out/share/games/quake2
pkgs/games/quake2/yquake2/default.nix-    '';
--
pkgs/games/teeworlds/default.nix-    mkdir -p $out/share/pixmaps
pkgs/games/teeworlds/default.nix:    icotool --extract --index 1 --output $out/share/pixmaps/teeworlds.png $src/other/icons/teeworlds.ico
pkgs/games/teeworlds/default.nix-
pkgs/games/teeworlds/default.nix-    # Install menu item
pkgs/games/teeworlds/default.nix:    install -D $src/other/teeworlds.desktop $out/share/applications/teeworlds.desktop
pkgs/games/teeworlds/default.nix-  '';
--
pkgs/games/eternity-engine/default.nix-    install -Dm755 source/eternity $out/lib/eternity/eternity
pkgs/games/eternity-engine/default.nix:    cp -r $src/base $out/lib/eternity/base
pkgs/games/eternity-engine/default.nix-    mkdir $out/bin
--
pkgs/games/ivan/default.nix-    mkdir -p $out/share/icons/hicolor/32x32/apps
pkgs/games/ivan/default.nix:    gm convert $src/Graphics/Icon.bmp $out/share/icons/hicolor/32x32/apps/ivan.png
pkgs/games/ivan/default.nix-    cp ${ivanDesktop}/share/applications/* $out/share/applications
--
pkgs/servers/icingaweb2/theme-unicorn/default.nix-        *)
pkgs/servers/icingaweb2/theme-unicorn/default.nix:          cp -r $src/* .
pkgs/servers/icingaweb2/theme-unicorn/default.nix-          ;;
--
pkgs/servers/echoip/default.nix-    mkdir -p $index
pkgs/servers/echoip/default.nix:    cp $src/index.html $index/index.html
pkgs/servers/echoip/default.nix-  '';
--
pkgs/servers/nginx-sso/default.nix-    mkdir -p $bin/share
pkgs/servers/nginx-sso/default.nix:    cp -R $src/frontend $bin/share
pkgs/servers/nginx-sso/default.nix-  '';
--
pkgs/servers/dex/default.nix-    mkdir -p $bin/share
pkgs/servers/dex/default.nix:    cp -r $src/web $bin/share/web
pkgs/servers/dex/default.nix-  '';
--
pkgs/servers/monitoring/prometheus/default.nix-    mkdir -p "$bin/share/doc/prometheus" "$bin/etc/prometheus"
pkgs/servers/monitoring/prometheus/default.nix:    cp -a $src/documentation/* $bin/share/doc/prometheus
pkgs/servers/monitoring/prometheus/default.nix:    cp -a $src/console_libraries $src/consoles $bin/etc/prometheus
pkgs/servers/monitoring/prometheus/default.nix-  '';
--
pkgs/servers/monitoring/prometheus/mail-exporter.nix-  postInstall = ''
pkgs/servers/monitoring/prometheus/mail-exporter.nix:    install -D -m 0444 -t $bin/share/man/man1 $src/man/mailexporter.1
pkgs/servers/monitoring/prometheus/mail-exporter.nix:    install -D -m 0444 -t $bin/share/man/man5 $src/man/mailexporter.conf.5
pkgs/servers/monitoring/prometheus/mail-exporter.nix-  '';
2 Likes

I noticed that a package I was trying to patch was installing scripts
directly from $src/ → $out/bin/, so my patches
weren’t applying.

I grepped around (naively!) to see if this was common and found
\$src[/] in 81 other files.

I thought about opening an issue for this, but it felt a little too
diffuse to expect someone doing issue triage to handle. But the
general sentiment from IRC did seem to be that it’s odd or a smell, so
I didn’t want to let it pass unmentioned.

Feel free to tell me to go file an issue! :slight_smile:

Thank you for this investigation. I think you should try just replacing
all of those with “$sourceRoot” or just “.”, and checking if the
packages still build. I think most of them will. Could be a nice easy
PR. :slight_smile:

1 Like

Good catch! If we ever get a nixpkgs linter, that should probably be one of the things to check for. Alternatively, I think it may have been a design decision to expose all arguments to mkDerivation as environment variables in the first place.

I agree with @qyliss. If you have the time to work on this, just replace usages by $sourceRoot. But please test your changes, this shouldn’t lead to unnecessary breakage.

Some packages are really large, and need mostly to be copied over from $src to $out. For example when you package close-source games. We had a short discussion about that with @aszlig in vuizvui[1]. When a game contains several GB to unpack from $src, it feels like a useless waste of resources to first unpack in $sourceRoot and then copy again to $out. Some machines may not even have enough space to contain the source archive and two unpacks at the same time on disk.

More generally, when $src is not an archive, using the files there may seem more efficient than copying everything to a local folder.
We could get some inspiration from libostree, and use the same underlying files for all the stages ($src, $srcRoot, $out). If we do that it would make sense to store $src in an unpacked form.

For example nix-script from your list bypasses the unpack phase. It then directly compiles from $src to $out, and moves some other files.

Another example is dotnetfx40 where mkDerivation is seemingly (ab)used to mimic runCommandNoCC.

Reworking these packages to use a more classical build process would be a good idea, but I would not trust too much an automated process.

Also, what is your feeling about the 690 \$src[^/] instances ? We find interesting phase-bypassing stuff like dpkg -x $src $out and some cp -r "$src" "$out/..."

[1] Add Spacechem as an humblebundle game by layus · Pull Request #18 · openlab-aux/vuizvui · GitHub

Thanks for posting. I suspected, from the number, that there were probably at least a few legitimate reasons lurking in the haystack.

I wonder if it’s tractable to reliably identify these (the set of packages packaged in such a way that a naive end-user trying to patch/substitute from a phase hook will have trouble) from within a build? Perhaps lazily with a check that warns at build time if a substitution appears to have no effect on the output, or more actively with a build-breaking test.

In an ideal world, the only legitimate uses for $src are in unpackPhase and preferably in unpackCmd. We could at least filter these out.

As for your other idea, it only applies to packages built with mkDerivation in the classic way. If you try to patch firefox for example, you will soon realize that you need to patch firefox-unwrapped. I would never dare to apply a patch to a package without looking first at the .nix files that defines it. Reading that you do so shows that nixpkgs is in a better shape than what I usually assume.

For the packages that are built in a vanilla mkDerivation, with no tricks, we could certainly devise some tests.

1 Like

I’ve thought for a while that patching should be part of the src
derivation (but fixed-output hashes were still calculated before
applying them). That way, there’d be no need for an unpackPhase at all
in lots of cases, and it would be easy to access the patched source
(which is currently quite difficult), which can be important for AGPL
compliance and I’m sure other cases where you want to find exactly what
code you’re running.

4 Likes