Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion crates/fbuild-build/src/compile_many.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ pub struct CompileManyRequest {
pub profile: BuildProfile,
/// Verbose compiler output.
pub verbose: bool,
/// `PLATFORMIO_*` env-var overlay forwarded to each per-sketch
/// `BuildParams.pio_env`. Empty by default. Used by `fbuild ci` to
/// surface `--lib` / `--project-conf` to the underlying orchestrator.
pub pio_env: HashMap<String, String>,
}

/// Result for a single sketch.
Expand Down Expand Up @@ -219,6 +223,7 @@ fn platform_for_board(board: &str) -> Result<Platform> {
///
/// `jobs` controls intra-build parallelism (passed through to the
/// orchestrator's per-build thread pool).
#[allow(clippy::too_many_arguments)]
fn build_one_sketch(
sketch: &Path,
env_name: &str,
Expand All @@ -227,6 +232,7 @@ fn build_one_sketch(
jobs: usize,
verbose: bool,
stage: Stage,
pio_env: HashMap<String, String>,
) -> SketchResult {
let start = Instant::now();
let build_dir = fbuild_packages::Cache::new(sketch).get_build_dir(env_name, profile);
Expand All @@ -245,7 +251,7 @@ fn build_one_sketch(
symbol_analysis_path: None,
no_timestamp: true,
src_dir: None,
pio_env: Default::default(),
pio_env: pio_env.into_iter().collect(),
extra_build_flags: Vec::new(),
watch_set_cache: None,
};
Expand Down Expand Up @@ -324,6 +330,8 @@ pub struct SketchBuildInputs {
pub jobs: usize,
pub verbose: bool,
pub stage: Stage,
/// `PLATFORMIO_*` env-var overlay forwarded to `BuildParams.pio_env`.
pub pio_env: HashMap<String, String>,
}

/// Trait used by [`compile_many_with`] to run a single sketch. Tests
Expand All @@ -348,6 +356,7 @@ impl SketchBuilder for OrchestratorBuilder {
inputs.jobs,
inputs.verbose,
inputs.stage,
inputs.pio_env,
)
}
}
Expand Down Expand Up @@ -413,6 +422,7 @@ pub fn compile_many_with(
jobs: framework_jobs,
verbose: req.verbose,
stage: Stage::Stage1Framework,
pio_env: req.pio_env.clone(),
});
let stage1_secs = stage1_start.elapsed().as_secs_f64();

Expand Down Expand Up @@ -445,6 +455,7 @@ pub fn compile_many_with(
sketch_jobs,
req.verbose,
builder,
&req.pio_env,
)
};
let stage2_secs = stage2_start.elapsed().as_secs_f64();
Expand Down Expand Up @@ -477,6 +488,7 @@ fn run_stage2(
sketch_jobs: usize,
verbose: bool,
builder: &dyn SketchBuilder,
pio_env: &HashMap<String, String>,
) -> Vec<SketchResult> {
let total = rest.len();
let cap = sketch_jobs.min(total).max(1);
Expand Down Expand Up @@ -516,6 +528,7 @@ fn run_stage2(
jobs: 1,
verbose,
stage: Stage::Stage2Sketch,
pio_env: pio_env.clone(),
});
*results_slot[idx].lock().unwrap() = Some(res);
})
Expand Down Expand Up @@ -602,6 +615,7 @@ mod tests {
sketch_jobs: None,
profile: BuildProfile::Release,
verbose: false,
pio_env: HashMap::new(),
};
assert!(compile_many(req).is_err());
}
Expand All @@ -617,6 +631,7 @@ mod tests {
sketch_jobs: None,
profile: BuildProfile::Release,
verbose: false,
pio_env: HashMap::new(),
};
assert!(compile_many(req).is_err());
}
Expand All @@ -636,6 +651,7 @@ mod tests {
sketch_jobs: None,
profile: BuildProfile::Release,
verbose: false,
pio_env: HashMap::new(),
};
assert!(compile_many(req).is_err());
}
Expand Down
1 change: 1 addition & 0 deletions crates/fbuild-build/tests/compile_many_two_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ fn make_request(
sketch_jobs: Some(sketch_jobs),
profile: BuildProfile::Release,
verbose: false,
pio_env: std::collections::HashMap::new(),
}
}

Expand Down
29 changes: 28 additions & 1 deletion crates/fbuild-cli/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# fbuild-cli

Clap-based CLI for fbuild. Thin HTTP client that delegates all work to the daemon. Subcommands: build, deploy, test-emu, monitor, reset, purge, daemon, device, show, mcp, clang-tidy, iwyu, clang-query.
Clap-based CLI for fbuild. Thin HTTP client that delegates most work to the daemon. Subcommands: build, deploy, test-emu, monitor, reset, purge, daemon, device, show, mcp, clang-tidy, iwyu, clang-query, compile-many, ci.

## Key Types

Expand All @@ -25,3 +25,30 @@ Clap-based CLI for fbuild. Thin HTTP client that delegates all work to the daemo
- `device` -- list/status/lease/release/preempt connected devices
- `show` -- display daemon logs
- `mcp` -- start MCP server for AI assistants
- `compile-many` -- two-stage compile of many sketches against the same board (FastLED/fbuild#238, PR #241)
- `ci` -- PlatformIO-compatible CI command (drop-in for `pio ci`, FastLED/fbuild#242)

## `fbuild ci` -- PlatformIO-compatible CI command

`fbuild ci` is a drop-in replacement for [`pio ci`](https://docs.platformio.org/en/latest/core/userguide/cmd_ci.html) that delegates to the two-stage `compile-many` primitive shipped in PR [#241](https://github.com/FastLED/fbuild/pull/241). It lets existing CI workflows swap `s/pio ci/fbuild ci/` without other changes. Tracking issue: [#242](https://github.com/FastLED/fbuild/issues/242).

### Flag mapping

| `fbuild ci` flag | `pio ci` equivalent | Behavior |
|---|---|---|
| `--board <b>` / `-b <b>` | `--board` / `-b` | Required. Board id (e.g. `uno`, `teensy41`). |
| `--lib <path>` / `-l <path>` (repeatable) | `--lib` / `-l` | Mapped to `PLATFORMIO_LIB_EXTRA_DIRS`; joined with `;` on Windows, `:` elsewhere. |
| `--project-conf <path>` / `-c <path>` | `--project-conf` / `-c` | Mapped to `PLATFORMIO_PROJECT_CONFIG`. Canonicalized when possible. |
| `--keep-build-dir` | `--keep-build-dir` | Accepted for compatibility; no-op (fbuild always keeps build dirs under `.fbuild/build/...`). |
| `--build-dir <path>` | `--build-dir` | Accepted for compatibility; not yet honored. Emits a warning when set. |
| `--framework-jobs` / `--sketch-jobs` / `--quick` / `--release` / `--verbose` (-v) | n/a | fbuild-native; see `compile-many`. |
| positional sketches | positional | Each entry may be a project dir or a `.ino` file (its parent dir is used). |

### Example

```bash
fbuild ci --board uno --lib ./libs --lib ./more -c custom.ini \
examples/Blink/Blink.ino examples/Fire2012/Fire2012.ino
```

Exits 0 when every sketch builds, non-zero on any failure.
14 changes: 14 additions & 0 deletions crates/fbuild-cli/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! Build script for `fbuild`.
//!
//! On `*-pc-windows-msvc` we ask the linker to reserve an 8 MiB stack for the
//! `fbuild.exe` binary (default is 1 MiB). The clap-generated argument-parser
//! state machine has grown deep enough that debug builds overflow the default
//! Windows stack when rendering `--help` (FastLED/fbuild#242). Release builds
//! are unaffected; this only changes the PE header's reserved stack size.

fn main() {
let target = std::env::var("TARGET").unwrap_or_default();
if target.contains("pc-windows-msvc") {
println!("cargo:rustc-link-arg-bin=fbuild=/STACK:8388608");
}
}
Loading