|
96 | 96 | rustc = toolchains.stable.rust; |
97 | 97 | }; |
98 | 98 |
|
| 99 | + # Script snippet, used in the cargo/rustc wrappers below, |
| 100 | + # which creates a number of .cargo/config.toml files in |
| 101 | + # order to allow using Nix-fetched dependencies (this must |
| 102 | + # be done for the guests, as well as for the main |
| 103 | + # workspace). Ideally, we would just use environment |
| 104 | + # variables or the --config option to Cargo, but |
| 105 | + # unfortunately that tends not to play well with subcommands |
| 106 | + # like `cargo clippy` and `cargo hyperlight` (see |
| 107 | + # https://github.com/rust-lang/cargo/issues/11031). |
| 108 | + materialiseDeps = deps: let |
| 109 | + sortedNames = lib.lists.reverseList (builtins.attrNames deps); |
| 110 | + matchClause = path: '' */${path}) root="''${manifest%${path}}" ;;''; |
| 111 | + matchClauses = lib.strings.concatStringsSep "\n" |
| 112 | + (builtins.map matchClause sortedNames); |
| 113 | + makeClause = manifest: vendor: let |
| 114 | + dir = builtins.dirOf manifest; |
| 115 | + gitExclude = builtins.toString (/. + "${dir}/.cargo"); |
| 116 | + in '' |
| 117 | + mkdir -p $root/${dir}/.cargo |
| 118 | + cat >$root/${dir}/.cargo/config.toml <<EOF |
| 119 | + [source.crates-io] |
| 120 | + replace-with = "vendored-sources" |
| 121 | +
|
| 122 | + [source.vendored-sources] |
| 123 | + directory = "${vendor}" |
| 124 | + EOF |
| 125 | + printf "# vendor dependency configuration generated by nix\n%s\n" "${gitExclude}" >> $root/.git/info/exclude |
| 126 | + ''; |
| 127 | + makeClauses = lib.strings.concatStringsSep "\n" |
| 128 | + (lib.mapAttrsToList makeClause deps); |
| 129 | + in '' |
| 130 | + manifest=$(''${base}/bin/cargo locate-project --message-format plain --workspace) |
| 131 | + case "$manifest" in |
| 132 | + ${matchClauses} |
| 133 | + esac |
| 134 | + if [ -f ''${root}/flake.nix ]; then |
| 135 | + sed -i '/# vendor dependency configuration generated by nix/{N;d;}' $root/.git/info/exclude |
| 136 | + ${makeClauses} |
| 137 | + fi |
| 138 | + ''; |
| 139 | + |
99 | 140 | # Hyperlight scripts use cargo in a bunch of ways that don't |
100 | 141 | # make sense for Nix cargo, including the `rustup +toolchain` |
101 | 142 | # syntax to use a specific toolchain and `cargo install`, so we |
102 | 143 | # build wrappers for rustc and cargo that enable this. The |
103 | 144 | # scripts also use `rustup toolchain install` in some cases, in |
104 | 145 | # order to work in CI, so we provide a fake rustup that does |
105 | 146 | # nothing as well. |
106 | | - rustup-like-wrapper = name: pkgs.writeShellScriptBin name |
| 147 | + rustup-like-wrapper = name: deps: pkgs.writeShellScriptBin name |
107 | 148 | (let |
108 | 149 | clause = name: toolchain: |
109 | 150 | "+${name}) base=\"${toolchain.rust}\"; shift 1; ;;"; |
110 | 151 | clauses = lib.strings.concatStringsSep "\n" |
111 | 152 | (lib.mapAttrsToList clause toolchains); |
112 | 153 | in '' |
113 | 154 | base="${toolchains.stable.rust}" |
| 155 | + ${materialiseDeps deps} |
114 | 156 | case "$1" in |
115 | 157 | ${clauses} |
116 | 158 | install) exit 0; ;; |
117 | 159 | esac |
118 | 160 | export PATH="$base/bin:$PATH" |
119 | 161 | exec "$base/bin/${name}" "$@" |
120 | 162 | ''); |
121 | | - fake-rustup = pkgs.symlinkJoin { |
| 163 | + fake-rustup = deps: pkgs.symlinkJoin { |
122 | 164 | name = "fake-rustup"; |
123 | 165 | paths = [ |
124 | 166 | (pkgs.writeShellScriptBin "rustup" "") |
125 | | - (rustup-like-wrapper "rustc") |
126 | | - (rustup-like-wrapper "cargo") |
| 167 | + (rustup-like-wrapper "rustc" deps) |
| 168 | + (rustup-like-wrapper "cargo" deps) |
127 | 169 | ]; |
128 | 170 | }; |
129 | 171 |
|
130 | 172 | buildRustPackageClang = rust-platform.buildRustPackage.override { stdenv = clangStdenv; }; |
| 173 | + |
131 | 174 | cargo-hyperlight = buildRustPackageClang rec { |
132 | 175 | pname = "cargo-hyperlight"; |
133 | 176 | version = "0.1.5"; |
|
139 | 182 | }; |
140 | 183 | cargoHash = "sha256-muiMVrK1TydQiMitihfo7xYidqUIIQ+Hw3BIeo5rLFw="; |
141 | 184 | }; |
| 185 | + # when building a guest with cargo-hyperlight, we need to |
| 186 | + # include any crates.io dependencies of the standard library |
| 187 | + # (e.g. rustc-literal-escaper) |
| 188 | + stdlibLocks = lib.mapAttrsToList (_: toolchain: |
| 189 | + "${toolchain.rust}/lib/rustlib/src/rust/library/Cargo.lock" |
| 190 | + ) toolchains; |
| 191 | + stdlibDeps = builtins.map (lockFile: |
| 192 | + rust-platform.importCargoLock { inherit lockFile; }) stdlibLocks; |
| 193 | + withStdlibLock = lockFile: |
| 194 | + pkgs.symlinkJoin { |
| 195 | + name = "cargo-deps"; |
| 196 | + paths = stdlibDeps ++ [ |
| 197 | + (rust-platform.importCargoLock { |
| 198 | + inherit lockFile; |
| 199 | + }) |
| 200 | + ]; |
| 201 | + }; |
| 202 | + deps = finalRootVendor: { |
| 203 | + "Cargo.toml" = finalRootVendor; |
| 204 | + "src/tests/rust_guests/dummyguest/Cargo.toml" = withStdlibLock ./src/tests/rust_guests/dummyguest/Cargo.lock; |
| 205 | + "src/tests/rust_guests/simpleguest/Cargo.toml" = withStdlibLock ./src/tests/rust_guests/simpleguest/Cargo.lock; |
| 206 | + "src/tests/rust_guests/witguest/Cargo.toml" = withStdlibLock ./src/tests/rust_guests/witguest/Cargo.lock; |
| 207 | + }; |
142 | 208 | in (buildRustPackageClang (mkDerivationAttrs: { |
143 | 209 | pname = "hyperlight"; |
144 | 210 | version = "0.0.0"; |
|
179 | 245 | # Set this through shellHook rather than nativeBuildInputs to be |
180 | 246 | # really sure that it overrides the real cargo. |
181 | 247 | postHook = '' |
182 | | - export PATH="${fake-rustup}/bin:$PATH" |
| 248 | + export PATH="${fake-rustup (deps mkDerivationAttrs.cargoDeps)}/bin:$PATH" |
183 | 249 | ''; |
184 | 250 | })).overrideAttrs(oA: { |
185 | 251 | hardeningDisable = [ "all" ]; |
|
0 commit comments