aboutsummaryrefslogtreecommitdiff
path: root/zkvmLib.nix
blob: 5bdd8903d9cbcba6239c64b8f900bbb34fed156c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
pkgs: guest: let
  generateCargoLocks = craneLib: args: rec {
    cargoLockDrv = pkgs.stdenv.mkDerivation {
        name = "CargoLocks-${args.pname}";
        src = pkgs.lib.fileset.toSource {
          root = ./.;
          fileset = ./.;
        };

        installPhase = ''
          mkdir -p "$out"
          cd zkvms/${args.pname}

          cat ./host/Cargo.lock > "$out/Cargo.lock"
          tail -n +4 ./guest/Cargo.lock >> "$out/Cargo.lock"
          tail -n +4 ../../guests/${guest}/Cargo.lock >> "$out/Cargo.lock"

          cp ./guest/Cargo.lock "$out/Guest-Cargo.lock"
        '';
      };

    cargoVendorDir = craneLib.vendorCargoDeps {
      src = cargoLockDrv;
    };
  };
in {
  buildDepsOnly = craneLib: args: let
    cargoLocks = generateCargoLocks craneLib args;
  in craneLib.buildDepsOnly (cargoLocks // args // {
      postUnpack = ''
        ${args.postUnpack or ""}
        ln -s ../../../guests ./source/zkvms/${args.pname}/guest/
        ln -s ../../../guests_macro ./source/zkvms/${args.pname}/guest/
        ln -s '${cargoLocks.cargoLockDrv}/Guest-Cargo.lock' ./source/zkvms/${args.pname}/guest/Cargo.lock
      '';

      preBuild = ''
        ${args.preBuild or ""}
        cd zkvms/${args.pname}/guest
        cargo check --release --offline --all-targets
      '';
  } // {
    pname = "${args.pname}_${guest}";
  });

  buildPackage = craneLib: args: let
    pname = "${args.pname}_${guest}";
  in craneLib.buildPackage ((generateCargoLocks craneLib args) // {
    phases = [
      "unpackPhase" # Standard phases
      "linkGuest" # Custom phase
      "patchPhase" "configurePhase" # Standard phases
      "buildGuestPhase" # Custom phase
      "buildPhase" "checkPhase" "installPhase" "fixupPhase" # Standard phases
    ];

    linkGuest = ''
      echo 'zkp = { path = "../../../guests/${guest}", package = "${guest}" }' >> zkvms/${args.pname}/guest/Cargo.toml
    '';

    buildGuestPhase = ''
      pushd zkvms/${args.pname}/guest
      runHook preBuildGuest

      ${args.buildGuestCommand or "cargo build --release"} \
          ${if args ? guestTarget then "--target " + args.guestTarget else ""} \
          ${args.guestExtraArgs or ""}

      ${if args ? guestTarget then "ln -s ../../guest/target/${args.guestTarget}/release/guest ../host/src/guest" else ""}
      unset RUSTUP_TOOLCHAIN RUSTFLAGS CARGO_ENCODED_RUSTFLAGS

      runHook postBuildGuest
      popd
    '';

    buildPhase = ''
      export INPUTS_DIR="$PWD/guests/${guest}"

      pushd zkvms/${args.pname}/host
      runHook preBuild

      cargo build --release

      runHook postBuild
      popd
    '';

    installPhase = let
      preRunBinaries =
        if args ? preRunBinaries && builtins.length args.preRunBinaries > 0 then
          "export PATH=\"\\$PATH:" + pkgs.lib.makeBinPath args.preRunBinaries + "\""
        else
          "";
      preRunLibraries =
        if args ? preRunLibraries && builtins.length args.preRunLibraries > 0 then
          "export LD_LIBRARY_PATH=\"\\$LD_LIBRARY_PATH:" + pkgs.lib.makeLibraryPath args.preRunLibraries + "\""
        else
          "";
    in ''
      runHook preInstall

      mkdir -p "$out"/bin
      for bin in $(find . -type f -regex "./zkvms/.*release/[^/]*" -executable -print)
      do
        mv "$bin" "$out"/bin/
      done

      cat <<EOF > "$out"/bin/${pname}
      #!/usr/bin/env sh
      ${preRunBinaries}
      ${preRunLibraries}
      ${args.preRun or ""}
      "$out"/bin/host-${args.pname} \$@
      EOF
      chmod +x "$out"/bin/${pname}

      runHook postInstall
    '';

    doNotPostBuildInstallCargoBinaries = true;
  } // args // { inherit pname; });
}