Unverified Commit b2817534 authored by h7x4's avatar h7x4 Committed by GitHub
Browse files

Merge pull request #323866 from h7x4/pkgs-fixup-vcpkg-vcpkg-tool

vcpkg{,-tool}: miscellaneous fixups
parents 886af4d3 cce9bb28
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
```
+24 −0
Original line number Diff line number Diff line
# 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 = <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.
+118 −6
Original line number Diff line number Diff line
{ 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;
  };
})
+26 −21
Original line number Diff line number Diff line
@@ -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/"

      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 \
        "$@"
  nativeBuildInputs = [ makeWrapper ];

  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++"
  '';
    in ''

  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;
  };
})
+2 −0
Original line number Diff line number Diff line
@@ -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 { };