Skip to content

Make Perry builds lighter for development and explicit for release artifacts #5422

Description

@TheHypnoo

Problem

Perry's current build path is too heavy for day-to-day development and mixes local feedback-loop needs with official distribution needs.

Observed locally on commit 6482c8757:

  • A cold cargo build --release -p perry --timings took roughly five minutes across an interrupted first run plus a resumed run.
  • The final perry bin crate was the long pole in the timing report, taking about 118.4s after dependencies were already built.
  • The workspace currently has a large default build surface: 76 workspace members and 58 default members.
  • Root [profile.release] is intentionally distribution-grade: ThinLTO, codegen-units = 1, opt-level = 3, and stripping.
  • perry-runtime and perry-stdlib both declare crate-type = ["rlib", "staticlib"], so CLI builds can produce large static archives even when the Rust CLI only needs rlibs.
  • The perry CLI compiles all commands and backends unconditionally, including publish/mobile/updater/native flows that are not needed for most compiler development loops.

Goal

Create a clear build taxonomy that makes Perry light for local development while keeping official release artifacts optimized, explicit, and measurable.

Ideal plan

1. Add a fast developer profile

Add a named profile such as perry-dev that inherits from release but disables the expensive release-only settings:

[profile.perry-dev]
inherits = "release"
lto = false
codegen-units = 16
incremental = true
strip = false
opt-level = 1

Document the intended local loop:

  • cargo check -p perry for fastest correctness feedback.
  • cargo build --profile perry-dev -p perry for optimized local development.
  • Keep cargo build --release / future dist builds for final artifact validation.

2. Split runtime/stdlib staticlibs from rlib consumers

Stop perry-runtime and perry-stdlib from producing static archives as a side effect of CLI builds.

Proposed shape:

  • Make perry-runtime and perry-stdlib rlib-only crates.
  • Add wrapper crates such as:
    • perry-runtime-static
    • perry-stdlib-static
  • Release/linking workflows build the wrapper crates explicitly when .a artifacts are needed.
  • Validate exported symbols with the existing symbol-checking scripts.

3. Add a slim developer CLI feature set

Keep the default official CLI full-featured, but add feature groups so contributors can build a smaller CLI for compiler work.

Suggested shape:

  • default = ["full-cli"]
  • full-cli = ["dev-cli", "publish-cli", "mobile-cli", "updater-cli", "native-cli", "audit-cli", "all-codegen-backends"]
  • dev-cli = ["compile-cli", "check-cli", "types-cli", "cache-cli"]
  • Backend features such as backend-js, backend-swiftui, backend-arkts, backend-wasm, etc.

The slim CLI should either omit disabled commands from --help or return clear feature-disabled errors. The default build must preserve today's full CLI behavior.

4. Make official release builds explicit and measured

Add a dedicated distribution profile, for example dist, that preserves current release optimization semantics:

[profile.dist]
inherits = "release"
lto = "thin"
codegen-units = 1
panic = "unwind"
strip = true
opt-level = 3

Then update release workflows/scripts to use --profile dist for official artifacts. Add a small timing-summary helper for Cargo --timings output so release build regressions are visible without weakening optimization settings.

Acceptance criteria

  • Developers have a documented fast path: cargo check -p perry and cargo build --profile perry-dev -p perry.
  • Official artifact builds remain optimized and explicit, preferably via --profile dist.
  • CLI-only builds no longer generate runtime/stdlib static archives unless explicitly requested.
  • Staticlib wrapper builds still produce valid archives with the required exported symbols.
  • A slim dev CLI can be built with --no-default-features --features dev-cli without changing the default full CLI.
  • Release workflows and docs clearly distinguish dev, release-compatible, and distribution builds.
  • Build timing reports identify the top slow units so future regressions are measurable.

Non-goals

  • Do not weaken the official release artifact optimization settings silently.
  • Do not remove commands or backends from the default CLI.
  • Do not force a repository-wide CARGO_TARGET_DIR; document shared target directories instead.
  • Do not bundle broad warning cleanup into this work; warning cleanup should be a separate hygiene issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions