Support building with corgi (#63396)

[corgi](https://github.com/ConradIrwin/corgi) is a cargo-compatible
build tool that runs `build.rs` scripts and proc-macros in a sandbox (no
network, no ambient env, reads limited to a package's own `.rs` sources
unless declared). This makes Zed buildable under it. Cargo builds (dev
and release) are unaffected.

### Changes

- **`scratch` patch**: patch `scratch` to a small local copy
(`corgi-patches/scratch`) that reads `OUT_DIR` at runtime instead of
baking it in at compile time. `cxx-build` writes its shared cxxbridge
headers into `scratch::path(...)`; upstream returns a single global dir
(outside any action's `OUT_DIR`) that the sandbox can't grant, while
this patch gives each build script a private, writable dir in its own
entry. webrtc-sys is self-contained, so per-crate scratch dirs are
sufficient. Kept local rather than a cxx git fork because a git checkout
of cxx needs symlink support that Windows cargo CI lacks.
- **Dev asset loading**: add `util::dev_fs_embed!` and switch dev-mode
`rust_embed` asset sources (`assets`, `settings`, `grammars`, `agent`,
`edit_prediction_cli`) to read from the checkout at runtime, locating
the repo root by walking from the executable up to the enclosing `.git`.
This avoids baking `CARGO_MANIFEST_DIR` into the binary (corgi rejects
artifacts that embed the build-time checkout path, and it's wrong in any
other worktree). Release builds still embed via `#[derive(RustEmbed)]`.
- **Stop baking checkout paths into artifacts**: drop
`gpui::GPUI_MANIFEST_DIR`; resolve `../gpui` from `gpui_apple`'s build
script; stage the metal shader into `OUT_DIR` before compiling so the
`.metallib` records the output dir, not the checkout; resolve the repo
root at runtime in `remote` and `inspector_ui` (removing
`inspector_ui`'s `build.rs` / `ZED_REPO_DIR`).
- **corgi.toml**: declare the pinned tools (`cmake`, prebuilt libwebrtc
via `LK_CUSTOM_WEBRTC`), a release-only `ZED_COMMIT_SHA` probe, and the
non-`.rs` / cross-package reads each package performs.

### Validation

- `corgi check` + `corgi build`, dev and release, for `zed` (plus `cli`,
`remote_server`, `ep`) with a warm C++ cache — clean; built binaries
embed no checkout path.
- `corgi fmt --check`, `corgi clippy`, and `corgi test` on the changed
crates (922 tests pass).
- `cargo check -p util` locally; relying on CI for the full cargo
build/test matrix.

### Notes for the reviewer

- Per the repo rule, the first two lines of `README.md` are the
review-confirmation marker; remove them before merging (this is what
Danger is failing on).
- `remote_server` cross-compilation (linux-musl via zigbuild) is not yet
covered by `corgi.toml` — host (macOS arm64) only for now.

### Suggested .rules additions

Only if the team wants corgi guidance in `.rules` (it recurred several
times here): dev builds must not bake the checkout path into artifacts —
no `env!("CARGO_MANIFEST_DIR")` or `file!()`-derived absolute paths in
library/binary output. Resolve the repo root at runtime via
`util::dev_repo_root()` (walks to `.git`), and use `util::dev_fs_embed!`
for dev-mode `rust_embed` sources.

Release Notes:

- N/A

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
This commit is contained in:
Conrad IrwinandBen Kunkle authored and GitHub committed 2026-08-31 17:37:00 +00:00
1 parent 87222d1d29
commit 72dc742101
25 files changed
+422 -95

No files matched your search

+10 -4
View File
@@ -246,7 +246,6 @@ async fn build_remote_server_from_source(
cx: &mut AsyncApp,
) -> Result<Option<std::path::PathBuf>> {
use std::env::VarError;
use std::path::Path;
use util::command::{Command, Stdio, new_command};
if let Ok(path) = std::env::var("ZED_COPY_REMOTE_SERVER") {
@@ -328,7 +327,10 @@ async fn build_remote_server_from_source(
log::info!("building remote server binary from source");
run_cmd(
new_command("cargo")
.current_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/../.."))
.current_dir(
util::dev_repo_root()
.context("locating the zed checkout to build remote_server from source")?,
)
.args([
"build",
"--package",
@@ -374,7 +376,10 @@ async fn build_remote_server_from_source(
log::info!("building remote binary from source for {triple} with Zig");
run_cmd(
new_command("cargo")
.current_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/../.."))
.current_dir(
util::dev_repo_root()
.context("locating the zed checkout to build remote_server from source")?,
)
.args([
"zigbuild",
"--package",
@@ -390,7 +395,8 @@ async fn build_remote_server_from_source(
)
.await?;
};
let bin_path = Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../.."))
let bin_path = util::dev_repo_root()
.context("locating the zed checkout that built remote_server from source")?
.join("target")
.join("remote_server")
.join(&triple)