Skip to content

build: make GPUI an optional feature to allow TUI-only builds#136

Closed
yamaceay wants to merge 2 commits into
stippi:mainfrom
yamaceay:feat/optional-gpui-feature
Closed

build: make GPUI an optional feature to allow TUI-only builds#136
yamaceay wants to merge 2 commits into
stippi:mainfrom
yamaceay:feat/optional-gpui-feature

Conversation

@yamaceay

@yamaceay yamaceay commented Jun 11, 2026

Copy link
Copy Markdown

Problem

The GPUI desktop UI compiles Metal shaders at build time via a Cargo
build-script. This requires Xcode developer tools (xcrun must locate the
metal binary). On machines without Xcode, every cargo build failed —
including builds of the terminal TUI, which needs no Metal at all:

error: gpui_macos@0.1.0: metal shader compilation failed:
xcrun: error: unable to find utility "metal", not a developer tool or in PATH

The root cause was twofold:

  1. A transitive dependency chain pulling in gpui_macos unconditionally:
    code-assistant → terminal (crate) → gpui → gpui_macos (Metal build-script)
    code-assistant → terminal_view   → gpui → gpui_macos
    code-assistant → gpui, gpui_platform, gpui-component → gpui_macos
    
  2. terminal, terminal_test_app, and terminal_view were listed as unconditional workspace members, so Cargo always compiled them regardless of feature flags — even with --no-default-features.

Solution

Two complementary fixes:

  1. Introduce a gpui-ui Cargo feature that makes all GPUI-related code opt-in.
  2. Remove terminal, terminal_test_app, and terminal_view from the workspace members list so they are only compiled when pulled in transitively via the gpui-ui feature.
Build command Result
cargo build --no-default-features TUI-only binary — no Xcode required ✓
cargo build --features gpui-ui Full binary including desktop UI (requires Xcode)
cargo build Same as --no-default-features (default unchanged)

This PR is the foundation for the autocomplete PR series (#131#135), which
all depend on TUI-only builds working.


Changes

Cargo.toml (workspace)

  • Removed terminal, terminal_test_app, terminal_view from workspace members.
    They are still available as path dependencies when gpui-ui is active.

crates/code_assistant/Cargo.toml

  • gpui, gpui_platform, gpui-component, terminal, terminal_view
    all made optional = true.
  • New feature: gpui-ui = ["dep:gpui", "dep:gpui_platform", "dep:gpui-component", "dep:terminal", "dep:terminal_view"].
  • Removed unused gpui from [dev-dependencies].

src/app/mod.rs, src/ui/mod.rs

  • pub mod gpui gated with #[cfg(feature = "gpui-ui")].

src/ui/backend.rs

  • GpuiTerminalCommandExecutor import gated.
  • Usage site falls back to DefaultCommandExecutor when feature is off.

src/ui/ui_events.rs

  • terminal::StyledLine re-exported under #[cfg(feature = "gpui-ui")].
  • Zero-sized stub struct StyledLine; defined under #[cfg(not(feature = "gpui-ui"))].

src/main.rs

  • --ui logging, model resolution, and app::gpui::run() all gated.
  • Passing --ui without the feature prints a clear error.

src/cli.rs

  • UiSettings::load() gated; TUI-only builds fall through to alphabetical-first-model fallback.

Test plan

  • cargo build --no-default-features completes without Xcode/Metal tools.
  • ./target/debug/code-assistant launches the terminal TUI normally.
  • ./target/debug/code-assistant --version prints the version string.
  • ./target/debug/code-assistant --ui prints the feature-missing error message.
  • (On a machine with Xcode) cargo build --features gpui-ui succeeds and
    --ui launches the GPUI desktop interface.

The GPUI desktop UI depends on Metal shader compilation, which requires
Xcode developer tools to be installed (xcrun must find the `metal` binary).
On machines without Xcode this hard-blocked every `cargo build`, even when
only the terminal TUI was needed.

Introduce a `gpui-ui` Cargo feature that gates all GPUI-related code:

- `Cargo.toml`: `gpui`, `gpui_platform`, and `gpui-component` are now
  optional dependencies, activated only by `--features gpui-ui`.
  The gpui entry in `[dev-dependencies]` is removed (it was unused in
  the unit-test suite).

- `src/app/mod.rs`, `src/ui/mod.rs`: `pub mod gpui` gated behind
  `#[cfg(feature = "gpui-ui")]`.

- `src/ui/backend.rs`: The `GpuiTerminalCommandExecutor` import and its
  single usage site are gated; the TUI-only path falls back to
  `DefaultCommandExecutor` (which `GpuiTerminalCommandExecutor` itself
  delegates to internally).

- `src/main.rs`: The `--ui` code paths (logging setup, model resolution,
  `app::gpui::run()`) are gated.  Passing `--ui` without the feature
  produces a clear error message rather than a linker crash.

- `src/cli.rs`: The `UiSettings::load()` call that reads the GPUI-
  persisted default model is gated; TUI-only builds fall through to the
  alphabetical-first-model fallback.

Build commands:
  # TUI only (no Xcode required):
  cargo build --no-default-features

  # With GPUI desktop UI (requires Xcode / Metal):
  cargo build --features gpui-ui
@yamaceay yamaceay force-pushed the feat/optional-gpui-feature branch from 34c3a0c to 437551e Compare June 11, 2026 08:40
Remove terminal, terminal_test_app, and terminal_view from workspace
members so cargo build --no-default-features no longer triggers Metal
shader compilation. They are still pulled in transitively when building
with the gpui-ui feature flag.
@yamaceay

Copy link
Copy Markdown
Author

Potentially in conflict with #130, need to align first

@yamaceay yamaceay marked this pull request as draft June 11, 2026 09:47
@stippi

stippi commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Solved differently/again on main after the big crate restructuring.

@stippi stippi closed this Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants