diff --git a/doc/packages/index.md b/doc/packages/index.md index 38dba5b3498f..69dd8c3b3bff 100644 --- a/doc/packages/index.md +++ b/doc/packages/index.md @@ -24,6 +24,7 @@ shell-helpers.section.md steam.section.md cataclysm-dda.section.md urxvt.section.md +vcpkg.section.md weechat.section.md xorg.section.md ``` diff --git a/doc/packages/vcpkg.section.md b/doc/packages/vcpkg.section.md new file mode 100644 index 000000000000..b0fa5fd22fd4 --- /dev/null +++ b/doc/packages/vcpkg.section.md @@ -0,0 +1,24 @@ +# VCPKG {#sec-vcpkg} + +The `vcpkg-tool` package has a wrapper around the `vcpkg` executable to avoid writing to the nix store. +The wrapper will also be present in `vcpkg`, unless you specify `vcpkg.override { vcpkg-tool = vcpkg-tool-unwrapped; }` + +The wrapper has been made in a way so that it will provide default cli arguments, but tries not to interfere if the user provides the same arguments. +The arguments also have corresponding environment variables that can be used as an alternative way of overriding these paths. + +Run the wrapper with the environment variable `NIX_VCPKG_DEBUG_PRINT_ENVVARS=true` to get a full list of corresponding environment variables. + +## Nix specific environment variables {#sec-vcpkg-nix-envvars} + +The wrapper also provides some new nix-specific environment variables that lets you control some of the wrapper functionality. + +- `NIX_VCPKG_WRITABLE_PATH = ` + + Set this environment variable to specify the path where `vcpkg` will store buildtime artifacts. + This will become the base path for all of the other paths. + +- `NIX_VCPKG_DEBUG_PRINT_ENVVARS = true | false` + + Set this to `true` for the wrapper to print the corresponding environment variables for the arguments that will be provided to the unwrapped executable. + The list of variables will be printed right before invoking `vcpkg`. + This can be useful if you suspect that the wrapper for some reason was unable to prioritize user-provided cli args over its default ones, or for fixing other issues like typos or unexpanded environment variables. diff --git a/pkgs/by-name/vc/vcpkg-tool/package.nix b/pkgs/by-name/vc/vcpkg-tool/package.nix index 6882589f2c13..5d6608e96cbc 100644 --- a/pkgs/by-name/vc/vcpkg-tool/package.nix +++ b/pkgs/by-name/vc/vcpkg-tool/package.nix @@ -1,20 +1,25 @@ { lib , stdenv , fetchFromGitHub +, runtimeShell , cacert , cmake , cmakerc +, curl , fmt , git , gzip -, makeWrapper , meson , ninja , openssh , python3 +, unzip , zip , zstd +, runCommand +, writeText , extraRuntimeDeps ? [] +, doWrap ? true }: stdenv.mkDerivation (finalAttrs: { pname = "vcpkg-tool"; @@ -30,7 +35,6 @@ stdenv.mkDerivation (finalAttrs: { nativeBuildInputs = [ cmake ninja - makeWrapper ]; buildInputs = [ @@ -47,31 +51,139 @@ stdenv.mkDerivation (finalAttrs: { "-DVCPKG_DEPENDENCY_CMAKERC=ON" ]; - postFixup = let + + passAsFile = [ "vcpkgWrapper" ]; + vcpkgWrapper = let # These are the most common binaries used by vcpkg - # Extra binaries can be added via overlay when needed + # Extra binaries can be added through override when needed runtimeDeps = [ cacert cmake + curl git gzip meson ninja openssh python3 + unzip zip zstd ] ++ extraRuntimeDeps; + + # Apart from adding the runtime dependencies to $PATH, + # the wrapper will also override these arguments by default. + # This is to ensure that the executable does not try to + # write to the nix store. If the user tries to set any of the + # arguments themself, the wrapper will detect that the + # arguments are present, and prefer the user-provided value. + # + # It is also possible to override the cli arguments by + # settings either of the nix-specific environment variables. + argsWithDefault = [ + { + arg = "--downloads-root"; + env = "NIX_VCPKG_DOWNLOADS_ROOT"; + default = "$NIX_VCPKG_WRITABLE_PATH/downloads"; + } + { + arg = "--x-buildtrees-root"; + env = "NIX_VCPKG_BUILDTREES_ROOT"; + default = "$NIX_VCPKG_WRITABLE_PATH/buildtrees"; + } + { + arg = "--x-packages-root"; + env = "NIX_VCPKG_PACKAGES_ROOT"; + default = "$NIX_VCPKG_WRITABLE_PATH/packages"; + } + { + arg = "--x-install-root"; + env = "NIX_VCPKG_INSTALL_ROOT"; + default = "$NIX_VCPKG_WRITABLE_PATH/installed"; + } + ]; in '' - wrapProgram $out/bin/vcpkg --prefix PATH ${lib.makeBinPath runtimeDeps} + #!${runtimeShell} + + get_vcpkg_path() { + if [[ -n $NIX_VCPKG_WRITABLE_PATH ]]; then + echo "$NIX_VCPKG_WRITABLE_PATH" + elif [[ -n $XDG_CACHE_HOME ]]; then + echo "$XDG_CACHE_HOME/vcpkg" + elif [[ -n $HOME ]]; then + echo "$HOME/.vcpkg/root" + elif [[ -n $TMP ]]; then + echo "$TMP" + else + echo "/tmp" + fi + } + + NIX_VCPKG_WRITABLE_PATH=$(get_vcpkg_path) + + ${lib.concatMapStringsSep "\n" ({ env, default, ... }: ''${env}=''${${env}-"${default}"}'') argsWithDefault} + + export PATH="${lib.makeBinPath runtimeDeps}''${PATH:+":$PATH"}" + + ARGS=( "$@" ) + FINAL_NONMODIFIED_ARGS=() + + for (( i=0; i<''${#ARGS[@]}; i++ )); + do + case "''${ARGS[i]%%=*}" in + ${let + f = { arg, env, ... }: '' + '${arg}') + ${env}="''${ARGS[i]#*=}" + if [ "''$${env}" = '${arg}' ]; then + ${env}="''${ARGS[i+1]}" + ((i++)) + fi + ;; + ''; + in lib.concatMapStringsSep "\n" f argsWithDefault} + *) + FINAL_NONMODIFIED_ARGS+=(''${ARGS[i]}) + ;; + esac + done + + if [ "''${NIX_VCPKG_DEBUG_PRINT_ENVVARS-'false'}" = 'true' ]; then + ${lib.concatMapStringsSep "\n" ({ env, ... }: " " + ''echo "${env} = ''$${env}"'') argsWithDefault} + echo "" + fi + + exec -a "$0" "${placeholder "out"}/bin/.vcpkg-wrapped" \ + ${lib.concatMapStringsSep "\n" ({ arg, env, ... }: " " + ''${arg}="''$${env}" \'') argsWithDefault} + "''${FINAL_NONMODIFIED_ARGS[@]}" ''; + postFixup = lib.optionalString doWrap '' + mv "$out/bin/vcpkg" "$out/bin/.vcpkg-wrapped" + install -Dm555 "$vcpkgWrapperPath" "$out/bin/vcpkg" + ''; + + passthru.tests = { + testWrapper = runCommand "vcpkg-tool-test-wrapper" { buildInputs = [ finalAttrs.finalPackage ]; } '' + export NIX_VCPKG_DEBUG_PRINT_ENVVARS=true + vcpkg --x-packages-root="test" --x-install-root="test2" contact > "$out" + + cat "$out" | head -n 4 | diff - ${writeText "vcpkg-tool-test-wrapper-expected" '' + NIX_VCPKG_DOWNLOADS_ROOT = /homeless-shelter/.vcpkg/root/downloads + NIX_VCPKG_BUILDTREES_ROOT = /homeless-shelter/.vcpkg/root/buildtrees + NIX_VCPKG_PACKAGES_ROOT = test + NIX_VCPKG_INSTALL_ROOT = test2 + ''} + ''; + }; + meta = { description = "Components of microsoft/vcpkg's binary"; mainProgram = "vcpkg"; homepage = "https://github.com/microsoft/vcpkg-tool"; + changelog = "https://github.com/microsoft/vcpkg-tool/releases/tag/${finalAttrs.src.rev}"; license = lib.licenses.mit; - maintainers = with lib.maintainers; [ guekka gracicot ]; + maintainers = with lib.maintainers; [ guekka gracicot h7x4 ]; platforms = lib.platforms.all; }; }) diff --git a/pkgs/by-name/vc/vcpkg/package.nix b/pkgs/by-name/vc/vcpkg/package.nix index ed2df2e36f76..74e16ebf8465 100644 --- a/pkgs/by-name/vc/vcpkg/package.nix +++ b/pkgs/by-name/vc/vcpkg/package.nix @@ -2,7 +2,8 @@ , stdenvNoCC , lib , vcpkg-tool -, writeShellScript +, makeWrapper +, doWrap ? true }: stdenvNoCC.mkDerivation (finalAttrs: { @@ -16,27 +17,31 @@ stdenvNoCC.mkDerivation (finalAttrs: { hash = "sha256-eDpMGDtC44eh0elLWV0r1H/WbpVdZ5qMedKh7Ct50Cs="; }; - installPhase = let - # vcpkg needs two directories to write to that is independent of installation directory. - # Since vcpkg already creates $HOME/.vcpkg/ we use that to create a root where vcpkg can write into. - vcpkgScript = writeShellScript "vcpkg" '' - vcpkg_writable_path="$HOME/.vcpkg/root/" + nativeBuildInputs = [ makeWrapper ]; - VCPKG_ROOT="@out@/share/vcpkg" ${vcpkg-tool}/bin/vcpkg \ - --x-downloads-root="$vcpkg_writable_path"/downloads \ - --x-buildtrees-root="$vcpkg_writable_path"/buildtrees \ - --x-packages-root="$vcpkg_writable_path"/packages \ - "$@" - ''; - in '' + postPatch = '' + substituteInPlace scripts/toolchains/linux.cmake \ + --replace-fail "aarch64-linux-gnu-as" "aarch64-unknown-linux-gnu-as" \ + --replace-fail "aarch64-linux-gnu-gcc" "aarch64-unknown-linux-gnu-gcc" \ + --replace-fail "aarch64-linux-gnu-g++" "aarch64-unknown-linux-gnu-g++" \ + --replace-fail "arm-linux-gnueabihf-as" "armv7l-unknown-linux-gnueabihf-as" \ + --replace-fail "arm-linux-gnueabihf-gcc" "armv7l-unknown-linux-gnueabihf-gcc" \ + --replace-fail "arm-linux-gnueabihf-g++" "armv7l-unknown-linux-gnueabihf-g++" + ''; + + installPhase = '' runHook preInstall - mkdir -p $out/bin $out/share/vcpkg/scripts/buildsystems - cp --preserve=mode -r ./{docs,ports,triplets,scripts,.vcpkg-root,versions,LICENSE.txt} $out/share/vcpkg/ - substitute ${vcpkgScript} $out/bin/vcpkg --subst-var-by out $out - chmod +x $out/bin/vcpkg - ln -s $out/bin/vcpkg $out/share/vcpkg/vcpkg - touch $out/share/vcpkg/vcpkg.disable-metrics + mkdir -p "$out/bin" "$out/share/vcpkg/scripts/buildsystems" + cp --preserve=mode -r ./{docs,ports,triplets,scripts,.vcpkg-root,versions,LICENSE.txt} "$out/share/vcpkg/" + + ${lib.optionalString doWrap '' + makeWrapper "${vcpkg-tool}/bin/vcpkg" "$out/bin/vcpkg" \ + --set-default VCPKG_ROOT "$out/share/vcpkg" + ''} + + ln -s "$out/bin/vcpkg" "$out/share/vcpkg/vcpkg" + touch "$out/share/vcpkg/vcpkg.disable-metrics" runHook postInstall ''; @@ -46,7 +51,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { mainProgram = "vcpkg"; homepage = "https://vcpkg.io/"; license = lib.licenses.mit; - maintainers = with lib.maintainers; [ guekka gracicot ]; + maintainers = with lib.maintainers; [ guekka gracicot h7x4 ]; platforms = lib.platforms.all; }; }) diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index c313b1680a6d..f6876296c4f9 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -19572,6 +19572,8 @@ with pkgs; qcachegrind = libsForQt5.callPackage ../development/tools/analysis/qcachegrind { }; + vcpkg-tool-unwrapped = callPackage ../by-name/vc/vcpkg-tool/package.nix { doWrap = false; }; + visualvm = callPackage ../development/tools/java/visualvm { }; volta = callPackage ../development/tools/volta { };