Skip to content

Commit 70aaaa3

Browse files
staging-devin-ai-integration[bot]streamkit-devinstreamer45
authored
build: optimize Rust build caching with sccache, shared plugin target dir, and cargo-sweep (#224)
* build: optimize Rust build caching with sccache, shared plugin target dir, and cargo-sweep - Add .cargo/config.toml with sccache as default rustc-wrapper for transparent compilation caching across cargo clean cycles - Add shared CARGO_TARGET_DIR for all native plugin builds, deduplicating common dependency compilation (serde, tokio, etc.) across 11 plugins - Add 'just sweep' recipe as a lightweight alternative to cargo clean, pruning only stale artifacts older than N days (default: 7) - Update all plugin build, lint, fix, upload, and copy recipes to use the shared target/plugins/ directory - Update plugin.yml artifact paths, official-plugins.json, docs, READMEs, and build_official_plugins.sh to reflect new shared target layout Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> * fix(build): comment out sccache in .cargo/config.toml to avoid breaking CI CI runners don't have sccache installed, so a hard-coded rustc-wrapper breaks all cargo invocations. Keep the config as a commented-out opt-in that developers can enable locally after installing sccache. Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> * fix(build): set CARGO_TARGET_DIR in sweep recipe for plugin loop The plugin sweep loop was running cargo sweep without CARGO_TARGET_DIR, targeting nonexistent per-plugin target/ dirs instead of the shared target/plugins/ directory. Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> * fix(ci): update marketplace-build rust-cache for shared plugin target dir The marketplace build now uses CARGO_TARGET_DIR=target/plugins, so the rust-cache workspace config needs to point to the shared target dir instead of per-plugin workspace entries. Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> * fix(build): update gen-docs-reference and marketplace CI for shared plugin target dir - gen-docs-reference.rs: also search target/plugins/release/ for plugin artifacts alongside the legacy per-plugin target dirs - marketplace-build.yml: restore dynamic workspace collection but point each plugin workspace to the shared target dir (../../../target/plugins) so rust-cache correctly hashes plugin Cargo.lock files for cache keys Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> * refactor(build): simplify sweep to single invocation on shared plugin target dir Since all plugins share target/plugins/, the per-plugin loop was redundant — each iteration swept the same directory. Replace with a single cargo sweep call using CARGO_TARGET_DIR. Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> * fix(build): deduplicate plugin artifacts by filename in gen-docs-reference During transition from per-plugin to shared target dir, both paths may contain the same plugin .so. Add dedup_by filename after sort+dedup to prevent duplicate plugin entries in generated docs. Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> * fix(build): use HashSet for filename dedup in gen-docs-reference dedup_by only removes consecutive duplicates, but same-filename paths from different directories are not adjacent after sorting by full path. Use a HashSet to properly deduplicate by filename regardless of order. Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> * style: format gen-docs-reference.rs Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> * fix(build): use is_some_and instead of map_or to satisfy clippy Replace map_or(false, ...) with is_some_and(...) per clippy::unnecessary_map_or lint. Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> * style: format gen-docs-reference.rs Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> * ci: install sccache on all CI runners via mozilla-actions/sccache-action Enable sccache as the default rustc wrapper in .cargo/config.toml (previously commented out) now that all CI jobs that compile Rust have mozilla-actions/sccache-action@v0.0.9 installed. This caches compiled crate artifacts by input hash, making rebuilds after cargo clean near-instant for cached crates. Affected workflows: skit.yml (lint, test, test-gpu, build), plugins.yml (lint-simple, lint-whisper, lint-nllb, lint-sherpa), e2e.yml, release.yml, marketplace-build.yml. The format job in plugins.yml is excluded since cargo fmt doesn't invoke rustc and thus doesn't need the wrapper. Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> * docs: add sccache as a prerequisite in CONTRIBUTING.md Document sccache as a required build tool alongside Rust, Bun, and Just. Include installation command and RUSTC_WRAPPER escape hatch tip. Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> * fix: address review findings for build caching PR - Make sccache env-based opt-in instead of hard requirement in .cargo/config.toml (CI sets RUSTC_WRAPPER via sccache-action) - Document cargo-sweep as optional prerequisite in CONTRIBUTING.md - Add guard to sweep recipe checking for cargo-sweep installation - Remove no-op CARGO_TARGET_DIR from cargo fmt invocations - Add TODO comment for legacy per-plugin target search removal Signed-off-by: Devin AI <devin@streamkit.dev> Signed-off-by: StreamKit Devin <devin@streamkit.dev> Co-Authored-By: Claudio Costa <cstcld91@gmail.com> --------- Signed-off-by: StreamKit Devin <devin@streamkit.dev> Signed-off-by: Devin AI <devin@streamkit.dev> Co-authored-by: StreamKit Devin <devin@streamkit.dev> Co-authored-by: Claudio Costa <cstcld91@gmail.com>
1 parent f832f42 commit 70aaaa3

33 files changed

+163
-83
lines changed

.cargo/config.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# SPDX-FileCopyrightText: © 2025 StreamKit Contributors
2+
#
3+
# SPDX-License-Identifier: MPL-2.0
4+
5+
# sccache is recommended for faster rebuilds. CI enables it automatically
6+
# via mozilla-actions/sccache-action. For local development, install sccache
7+
# and export RUSTC_WRAPPER=sccache in your shell (see CONTRIBUTING.md).
8+
# Uncomment below to enable it repo-wide instead of via environment:
9+
# [build]
10+
# rustc-wrapper = "sccache"

.github/workflows/e2e.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ jobs:
4444
with:
4545
toolchain: "1.92.0"
4646

47+
- uses: mozilla-actions/sccache-action@v0.0.9
48+
4749
- uses: Swatinem/rust-cache@v2
4850

4951
- name: Install system dependencies (libvpx for VP9, nasm for AV1 assembly)

.github/workflows/marketplace-build.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ jobs:
8585
with:
8686
toolchain: "1.92.0"
8787

88+
- uses: mozilla-actions/sccache-action@v0.0.9
89+
8890
- name: Verify official plugins metadata is current
8991
run: |
9092
python3 scripts/marketplace/generate_official_plugins.py
@@ -110,7 +112,7 @@ jobs:
110112
with open(out_path, "a", encoding="utf-8") as handle:
111113
handle.write("workspaces<<EOF\n")
112114
for plugin_id in plugin_ids:
113-
handle.write(f"plugins/native/{plugin_id}\n")
115+
handle.write(f"plugins/native/{plugin_id} -> ../../../target/plugins\n")
114116
handle.write("EOF\n")
115117
PY
116118

.github/workflows/plugins.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ jobs:
7373
toolchain: "1.92.0"
7474
components: clippy
7575

76+
- uses: mozilla-actions/sccache-action@v0.0.9
77+
7678
- uses: Swatinem/rust-cache@v2
7779
with:
7880
workspaces: |
@@ -101,6 +103,8 @@ jobs:
101103
toolchain: "1.92.0"
102104
components: clippy
103105

106+
- uses: mozilla-actions/sccache-action@v0.0.9
107+
104108
- uses: Swatinem/rust-cache@v2
105109
with:
106110
workspaces: |
@@ -153,6 +157,8 @@ jobs:
153157
toolchain: "1.92.0"
154158
components: clippy
155159

160+
- uses: mozilla-actions/sccache-action@v0.0.9
161+
156162
- uses: Swatinem/rust-cache@v2
157163
with:
158164
workspaces: |
@@ -198,6 +204,8 @@ jobs:
198204
toolchain: "1.92.0"
199205
components: clippy
200206

207+
- uses: mozilla-actions/sccache-action@v0.0.9
208+
201209
- uses: Swatinem/rust-cache@v2
202210
with:
203211
workspaces: |

.github/workflows/release.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ jobs:
3636
with:
3737
toolchain: "1.92.0"
3838

39+
- uses: mozilla-actions/sccache-action@v0.0.9
40+
3941
- uses: Swatinem/rust-cache@v2
4042

4143
- name: Install system dependencies (libvpx for VP9, nasm for AV1 assembly)

.github/workflows/skit.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ jobs:
4545
toolchain: "1.92.0"
4646
components: rustfmt, clippy
4747

48+
- uses: mozilla-actions/sccache-action@v0.0.9
49+
4850
- uses: Swatinem/rust-cache@v2
4951

5052
- name: Check formatting
@@ -100,6 +102,8 @@ jobs:
100102
with:
101103
toolchain: "1.92.0"
102104

105+
- uses: mozilla-actions/sccache-action@v0.0.9
106+
103107
- uses: Swatinem/rust-cache@v2
104108

105109
- name: Run tests (GPU tests run separately on self-hosted runner)
@@ -122,6 +126,8 @@ jobs:
122126
with:
123127
toolchain: "1.92.0"
124128

129+
- uses: mozilla-actions/sccache-action@v0.0.9
130+
125131
- uses: Swatinem/rust-cache@v2
126132

127133
- name: Run GPU tests
@@ -173,6 +179,8 @@ jobs:
173179
with:
174180
toolchain: "1.92.0"
175181

182+
- uses: mozilla-actions/sccache-action@v0.0.9
183+
176184
- uses: Swatinem/rust-cache@v2
177185

178186
- name: Build all crates

CONTRIBUTING.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,25 @@ curl -fsSL https://bun.sh/install | bash
4747
cargo install just
4848
```
4949

50+
### sccache (build cache — recommended)
51+
52+
[sccache](https://github.com/mozilla/sccache) caches compiled crate artifacts by input hash, making rebuilds significantly faster. CI uses it automatically; for local development:
53+
54+
```bash
55+
cargo install sccache --locked
56+
export RUSTC_WRAPPER=sccache # add to your shell profile
57+
```
58+
59+
> **Note:** You can also uncomment the `rustc-wrapper` line in `.cargo/config.toml` to enable it repo-wide instead of via environment variable.
60+
61+
### cargo-sweep (build cleanup — optional)
62+
63+
Used by `just sweep` to prune stale build artifacts without a full `cargo clean`:
64+
65+
```bash
66+
cargo install cargo-sweep --locked
67+
```
68+
5069
### Linting tools
5170

5271
Required by `just lint`:

apps/skit/src/bin/gen-docs-reference.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,9 @@ fn find_official_native_plugin_artifacts(repo_root: &Path) -> Result<Vec<PathBuf
12931293
continue;
12941294
}
12951295

1296+
// TODO: remove legacy per-plugin target search once transition is complete.
12961297
// Prefer release artifacts; fall back to debug if release isn't present.
1298+
// Check both per-plugin target dirs (legacy) and the shared target/plugins/ dir.
12971299
let release_dir = plugin_dir.join("target/release");
12981300
let debug_dir = plugin_dir.join("target/debug");
12991301

@@ -1304,6 +1306,15 @@ fn find_official_native_plugin_artifacts(repo_root: &Path) -> Result<Vec<PathBuf
13041306
}
13051307
}
13061308

1309+
// Also search the shared plugin target directory (target/plugins/).
1310+
let shared_release = repo_root.join("target/plugins/release");
1311+
let shared_debug = repo_root.join("target/plugins/debug");
1312+
if shared_release.exists() {
1313+
paths.extend(find_so_files(&shared_release)?);
1314+
} else if shared_debug.exists() {
1315+
paths.extend(find_so_files(&shared_debug)?);
1316+
}
1317+
13071318
// Filter out debug symbol files (.d), deps folder artifacts, and proc-macro libraries
13081319
// Keep only the main plugin library (e.g., libkokoro.so) not dependency artifacts
13091320
#[allow(clippy::case_sensitive_file_extension_comparisons)]
@@ -1319,6 +1330,11 @@ fn find_official_native_plugin_artifacts(repo_root: &Path) -> Result<Vec<PathBuf
13191330
});
13201331
paths.sort();
13211332
paths.dedup();
1333+
// Deduplicate by filename to handle the transition period where both
1334+
// legacy per-plugin target dirs and the shared target/plugins/ dir coexist.
1335+
// Use a HashSet since same-filename paths are not adjacent after sorting by full path.
1336+
let mut seen_filenames = std::collections::HashSet::new();
1337+
paths.retain(|p| p.file_name().is_some_and(|name| seen_filenames.insert(name.to_os_string())));
13221338

13231339
Ok(paths)
13241340
}

docs/src/content/docs/reference/plugins/plugin-native-helsinki.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ description: "Neural machine translation using Helsinki-NLP OPUS-MT models. Supp
99

1010
Neural machine translation using Helsinki-NLP OPUS-MT models. Supports bidirectional EN<->ES translation with Apache 2.0 licensed models. Powered by Candle (pure Rust ML framework).
1111

12-
Source: `plugins/native/helsinki/target/release/libhelsinki.so`
12+
Source: `target/plugins/release/libhelsinki.so`
1313

1414
## Categories
1515
- `ml`

docs/src/content/docs/reference/plugins/plugin-native-kokoro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ description: "High-quality text-to-speech synthesis using the Kokoro TTS model.
99

1010
High-quality text-to-speech synthesis using the Kokoro TTS model. Supports 103 voices across Chinese and English with streaming output. Outputs 24kHz mono audio for real-time playback or further processing.
1111

12-
Source: `plugins/native/kokoro/target/release/libkokoro.so`
12+
Source: `target/plugins/release/libkokoro.so`
1313

1414
## Categories
1515
- `audio`

0 commit comments

Comments
 (0)