feat: make VST3 an opt-in cargo feature

Cargo.toml declared Apache-2.0 while the default build linked vst3-sys,
whose bindings are GPLv3 — so the artifact a fresh clone produced could
not legally be distributed under the licence the repo claimed. A template
should not hand that trap to every project cloned from it.

NIH-plug already anticipates this: its `vst3` feature exists, in upstream's
own words, "mostly for GPL-compliance reasons". Taking `default-features =
false` and re-exporting `vst3` as a local opt-in makes the default build
CLAP-only and genuinely Apache-2.0 clean, while `--features vst3` remains
one flag away for anyone who accepts GPLv3.

Gating the feature rather than relicensing keeps the decision with whoever
uses the template. Reversing it is a one-line default plus removing two
cfg attributes, where relicensing to GPLv3 now would commit every
downstream plugin to that choice.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WHt4DykxXaQnyaJfyS8KCn
This commit is contained in:
2026-08-29 10:24:33 +09:00
parent fc45d3eec0
commit c6f2f32fb3
3 changed files with 40 additions and 14 deletions
+10 -1
View File
@@ -10,6 +10,14 @@ license = "Apache-2.0"
[workspace]
members = ["xtask"]
[features]
# CLAP only by default. NIH-plug's VST3 bindings (vst3-sys) are GPLv3, so linking
# them makes the resulting binary GPLv3 regardless of what this package declares.
# Opt in explicitly — and relicense this crate — if you intend to ship a VST3:
# cargo xtask bundle nih_plug_template --release --features vst3
default = []
vst3 = ["nih_plug/vst3"]
[lib]
# `cdylib` is the plugin binary; `lib` (rlib) lets `cargo test` link the unit tests.
crate-type = ["cdylib", "lib"]
@@ -17,7 +25,8 @@ crate-type = ["cdylib", "lib"]
[dependencies]
# Pinned to the same commit as musiikki/codename-206.
# Update the `rev` when you want to update NIH-plug.
nih_plug = { git = "https://github.com/robbert-vdh/nih-plug.git", rev = "f36931f7af4646065488a9845d8f8c2f95252c23", features = ["assert_process_allocs"] }
# `default-features = false` drops nih_plug's default `vst3` feature; see [features] above.
nih_plug = { git = "https://github.com/robbert-vdh/nih-plug.git", rev = "f36931f7af4646065488a9845d8f8c2f95252c23", default-features = false, features = ["assert_process_allocs"] }
nih_plug_egui = { git = "https://github.com/robbert-vdh/nih-plug.git", rev = "f36931f7af4646065488a9845d8f8c2f95252c23" }
[profile.release]
+28 -13
View File
@@ -21,13 +21,16 @@ cd my-plugin
# Install Rust via rustup: https://rustup.rs
# No VST3 SDK needed — NIH-plug bundles its own bindings.
# Build + bundle the VST3 and CLAP
# Build + bundle the CLAP (default)
cargo xtask bundle nih_plug_template --release
# Add the VST3 as well — see the licensing note below before you do this
cargo xtask bundle nih_plug_template --release --features vst3
```
**Output:** `target/bundled/<name>.vst3` and `<name>.clap`, where `<name>` is the `name` set
in `bundler.toml` — **not** the crate name. Out of the box that means
`target/bundled/Plugin Name.vst3`.
**Output:** `target/bundled/<name>.clap` (and `<name>.vst3` with `--features vst3`), where
`<name>` is the `name` set in `bundler.toml` — **not** the crate name. Out of the box that
means `target/bundled/Plugin Name.clap`.
On Linux the egui editor needs the GUI development headers:
@@ -40,6 +43,8 @@ sudo apt install pkg-config libgl-dev libx11-dev libxcursor-dev libxcb1-dev \
### FL Studio
Build with `--features vst3` first if you want the VST3 (see the licensing note below).
FL Studio scans `C:\Program Files\Common Files\VST3` by default, **ignores directory junctions**
(so a symlinked bundle is invisible to its scanner), and caches failed scans.
@@ -50,23 +55,23 @@ FL Studio scans `C:\Program Files\Common Files\VST3` by default, **ignores direc
### Linux
```bash
# VST3
cp -r "target/bundled/Plugin Name.vst3" ~/.vst3/
# CLAP
cp -r "target/bundled/Plugin Name.clap" ~/.clap/
# VST3 (only exists if you built with --features vst3)
cp -r "target/bundled/Plugin Name.vst3" ~/.vst3/
# Or globally:
# sudo cp -r "target/bundled/Plugin Name.vst3" /usr/lib/vst3/
# sudo cp -r "target/bundled/Plugin Name.clap" /usr/lib/clap/
# sudo cp -r "target/bundled/Plugin Name.vst3" /usr/lib/vst3/
```
## Project Structure
```
Cargo.toml # Package deps — NIH-plug pinned to codename-206's rev
Cargo.toml # Package deps + the opt-in `vst3` feature — NIH-plug pinned to codename-206's rev
bundler.toml # Bundle name for `cargo xtask bundle`
src/lib.rs # Plugin skeleton — fill in params, DSP, editor
src/lib.rs # Plugin skeleton — params, DSP, and egui editor, with one example gain param
xtask/ # Bundler xtask (cargo xtask bundle)
.cargo/config.toml # xtask alias
```
@@ -77,6 +82,16 @@ Apache-2.0
## VST3 Licensing Note
You must accept Steinberg's VST3 SDK licence before distributing VST3 binaries.
NIH-plug's VST3 bindings are GPLv3; if you distribute, the plugin must also be GPLv3
(or you need a commercial Steinberg licence). CLAP has no such restriction.
NIH-plug's VST3 bindings (`vst3-sys`) are GPLv3. Linking them makes the resulting binary
GPLv3 regardless of what `Cargo.toml` declares, so **VST3 is behind an opt-in `vst3` feature
and this template builds CLAP only by default.** That keeps the default build consistent with
the Apache-2.0 licence in `Cargo.toml`/`LICENSE`.
If you want to ship a VST3:
1. Build with `--features vst3`.
2. Relicense your plugin as GPLv3 (or obtain a commercial Steinberg licence) and update
`Cargo.toml`, `LICENSE`, and the SPDX headers in `src/`.
3. Accept Steinberg's VST3 SDK licence.
CLAP has no such restriction.
+2
View File
@@ -133,6 +133,7 @@ impl ClapPlugin for MyPlugin {
const CLAP_FEATURES: &'static [ClapFeature] = &[ClapFeature::AudioEffect];
}
#[cfg(feature = "vst3")]
impl Vst3Plugin for MyPlugin {
// TODO: Replace with a unique 16-byte Class ID.
// Must be exactly 16 bytes — padded with '!' if shorter.
@@ -141,4 +142,5 @@ impl Vst3Plugin for MyPlugin {
}
nih_export_clap!(MyPlugin);
#[cfg(feature = "vst3")]
nih_export_vst3!(MyPlugin);