diff --git a/Cargo.lock b/Cargo.lock index 704f2b09..1c016dfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anyhow" +version = "1.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" + [[package]] name = "gain" version = "0.1.0" @@ -159,3 +165,6 @@ checksum = "e6f1efe828a707edf85994a4501734ac1c1b9d244cfcf4de235f11c4125ace8f" [[package]] name = "xtask" version = "0.1.0" +dependencies = [ + "anyhow", +] diff --git a/README.md b/README.md index b614f49c..3ad143a3 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,16 @@ not meant for general use (yet), the plugin API is limited to the functionality I needed, and I'll expose more functionality as I need it. See the doc comment in the `Plugin` trait for an incomplete list of missing functionality. +## Building + +After installing [https://rustup.rs/](Rust) you can compile any of the plugins +in the `plugins` directory in the following way, replacing `gain` with the name +of the plugin: + +```shell +cargo xtask bundle gain --release --bundle-vst3 +``` + ## Licensing Right now everything is licensed under the GPLv3+ license, partly because the diff --git a/src/wrapper/vst3.rs b/src/wrapper/vst3.rs index d8de33e9..90695377 100644 --- a/src/wrapper/vst3.rs +++ b/src/wrapper/vst3.rs @@ -969,9 +969,6 @@ impl IPluginFactory3 for Factory

{ } /// Export a VST3 plugin from this library using the provided plugin type. -/// -/// TODO: Come up with some way to hae Cargo spit out a VST3 module. Is that possible without a -/// custom per-plugin build script? #[macro_export] macro_rules! nih_export_vst3 { ($plugin_ty:ty) => { diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index d9dff721..b0cd7b2c 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -2,7 +2,8 @@ name = "xtask" version = "0.1.0" edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +authors = ["Robbert van der Helm "] +license = "ISC" [dependencies] +anyhow = "1.0" diff --git a/xtask/src/main.rs b/xtask/src/main.rs index e7a11a96..312e2177 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,3 +1,120 @@ -fn main() { - println!("Hello, world!"); +use anyhow::{bail, Context, Result}; +use std::fs; +use std::path::Path; +use std::process::Command; + +const USAGE_STRING: &'static str = "Usage: cargo xtask bundle [--release] [--bundle-vst3]"; + +fn main() -> Result<()> { + let project_root = Path::new(env!("CARGO_MANIFEST_DIR")) + .parent() + .context("Could not find project root")?; + std::env::set_current_dir(project_root) + .context("Could not change to project root directory")?; + + let mut args = std::env::args().skip(1); + let command = args + .next() + .context(format!("Missing command name\n\n{USAGE_STRING}"))?; + match command.as_str() { + "bundle" => { + let target = args + .next() + .context(format!("Missing target name\n\n{USAGE_STRING}"))?; + let other_args: Vec<_> = args.collect(); + + bundle(&target, other_args) + } + _ => bail!("Unknown command '{command}'\n\n{USAGE_STRING}"), + } +} + +// TODO: This probably needs more work for macOS. I don't know, I don't have a Mac. +fn bundle(target: &str, mut args: Vec) -> Result<()> { + let mut is_release_build = false; + let mut bundle_vst3 = false; + for arg_idx in (0..args.len()).rev() { + let arg = &args[arg_idx]; + match arg.as_str() { + "--bundle-vst3" => { + bundle_vst3 = true; + args.remove(arg_idx); + } + "--release" => is_release_build = true, + _ => (), + } + } + + Command::new("cargo") + .arg("build") + .arg("-p") + .arg(target) + .args(args) + .status() + .context(format!("Could not build {target}"))?; + + let lib_path = Path::new("target") + .join(if is_release_build { "release" } else { "debug" }) + .join(library_name(target)); + if !lib_path.exists() { + bail!("Could not find built library at {}", lib_path.display()); + } + + if bundle_vst3 { + let vst3_lib_path = Path::new("target").join(vst3_bundle_library_name(target)); + let vst3_bundle_home = vst3_lib_path.parent().unwrap().parent().unwrap(); + + fs::create_dir_all(vst3_lib_path.parent().unwrap()) + .context("Could not create bundle directory")?; + fs::copy(&lib_path, &vst3_lib_path).context("Could not copy library to bundle")?; + + eprintln!("Created a VST3 bundle at '{}'", vst3_bundle_home.display()); + } else { + eprintln!("Not creating any plugin bundles") + } + + Ok(()) +} + +#[cfg(target_os = "linux")] +fn library_name(target: &str) -> String { + format!("lib{target}.so") +} + +#[cfg(target_os = "macos")] +fn library_name(target: &str) -> String { + format!("lib{target}.dylib") +} + +#[cfg(target_os = "windows")] +fn library_name(target: &str) -> String { + format!("{target}.dll") +} + +// See https://developer.steinberg.help/display/VST/Plug-in+Format+Structure + +#[cfg(all(target_os = "linux", target_arch = "x86_64"))] +fn vst3_bundle_library_name(target: &str) -> String { + format!("{target}.vst3/x86_64-linux/{target}.so") +} + +#[cfg(all(target_os = "linux", target_arch = "x86"))] +fn vst3_bundle_library_name(target: &str) -> String { + format!("{target}.vst3/i386-linux/{target}.so") +} + +// TODO: This should be a Mach-O bundle, not sure how that works +#[cfg(target_os = "macos")] +fn vst3_bundle_library_name(target: &str) -> String { + format!("{target}.vst3/MacOS/{target}") +} + +#[cfg(all(target_os = "windows", target_arch = "x86_64"))] +fn vst3_bundle_library_name(target: &str) -> String { + format!("{target}.vst3/x86_64-win/{target}.vst3") +} + +#[cfg(all(target_os = "windows", target_arch = "x86"))] +fn vst3_bundle_library_name(target: &str) -> String { + format!("{target}.vst3/x86-win/{target}.vst3") }