Introduction
|
|
Motivation
Developing REAPER extension plugins requires intimate knowledge about REAPER and its behavior on each platform that it supports.
This information is somewhat esoteric and not listed in the development docs, making extension plugin development a trial-and-error ordeal.
cargo-reaper aims to simplify the learning curve by providing an easy-to-use, intuitive interface for initializing, building,
testing and publishing REAPER extension plugins.
Throughout this book are references to REAPER specific terminology, most of which you may safely ignore since cargo-reaper
handles it for you, however, if you wish to know more the Glossary section contains detailed documentation
that may aid you in understanding how cargo-reaper works. It is recommended to have a once-over for anyone creating a non-trivial
extension plugin.
Platform Support
Any platform which is both supported by Rust and REAPER should work.
Important: extension plugins built for Windows must be built with MSVC.
The following are the canonical sources of truth for REAPER platform support:
Which can then be cross referenced against the Rust target list:
Or via rustc from the terminal:
rustc --print target-list
Configuration File
cargo-reaper requires a configuration file in the project root that conforms to the following
naming convention (in precedence order):
reaper.toml.reaper.toml
This file is created automatically for projects initialized by
cargo-reaper-new.
Declaring Extension Plugins
cargo-reaper expects a key-value pair mapping of reaper extension plugins, where the key is the finalized name of the
plugin and the value is the path to a directory containing a cargo manifest. All other information cargo-reaper needs
is gathered from the manifest file.
A minimal reaper.toml, for a single cargo package could look like the following:
[extension_plugins]
reaper_hello_world_extension = "./."
Important: REAPER requires that extension plugins be prefixed by
reaper_, otherwise REAPER will not recognize it.
cargo-reaperwill throw an error and refuse to compile if an extension plugin listed does not meet this condition.
Plugin Manifest
There are a few necessities for cargo-reaper to recognize an extension plugin that is declared in a configuration file.
- The cargo manifest must be a package.
- The package must include a library target.
- The library target must include a
namefield. - The library target must include
cdylibin thecrate-typefield.
The above should be true whether the project is a single package, workspace with multiple packages or workspace package.
Package Manifest
An example of a single package manifest and its corresponding configuration file.
# Cargo.toml
[package]
name = "my_package"
version = "0.1.0"
edition = "2024"
[lib]
name = "my_extension_plugin"
crate-type = ["cdylib"]
# reaper.toml
[extension_plugins]
reaper_my_plugin = "./."
Workspace Manifests
Examples of acceptable workspace patterns and their corresponding configuration files.
Workspace Manifest
An example of a virtual workspace that does not contain a package attribute, but consists of multiple members, each of which being a package manifest meeting the plugin manifest criteria.
# Cargo.toml
[workspace]
resolver = "2"
members = ["crates/*"]
# reaper.toml
[extension_plugins]
reaper_my_plugin_1 = "./crates/my_plugin_1"
reaper_my_plugin_2 = "./crates/my_plugin_2"
Workspace Package Manifest
An example of a workspace package manifest and its corresponding configuration file.
# Cargo.toml
[workspace]
resolver = "2"
members = ["crates/*"]
[package]
name = "my_workspace_package"
version = "0.1.0"
edition = "2024"
[lib]
name = "my_extension_plugin"
crate-type = ["cdylib"]
# reaper.toml
[extension_plugins]
reaper_my_plugin = "./."
cargo-reaper
NAME
cargo-reaper -- A Cargo plugin for developing REAPER extension plugins with Rust.
SYNOPSIS
cargo-reaper command
DESCRIPTION
cargo-reaper is a convenience wrapper around Cargo that adds a post-build hook to streamline REAPER extension development. It automatically renames the compiled plugin to include the required reaper_ prefix and symlinks it to REAPER’s UserPlugins directory.
By default, Cargo prefixes dynamic libraries with lib, which REAPER does not recognize. Manually renaming the plugin and keeping the UserPlugins directory up-to-date can be tedious -- cargo-reaper takes care of all that for you, across all supported platforms.
COMMANDS
Each command is documented in its own section:
stdout.UserPlugins directory.help
OPTIONS
-h
--help
--help).-V
--version
cargo-reaper-new
NAME
cargo-reaper-new -- Create a new REAPER extension plugin.
SYNOPSIS
cargo-reaper new [options] path
DESCRIPTION
This command will create a new Cargo package in the given directory that is set up for use with cargo-reaper.
This includes a simple template with a Cargo.toml manifest, sample source file, reaper.toml configuration file, and a .gitignore file.
OPTIONS
-t
--template
-h
--help
EXAMPLES
- Initialize a new extension plugin.
cargo reaper new reaper_my_plugin
Important: REAPER requires that extension plugins be prefixed by
reaper_, otherwise REAPER will not recognize it.The
reaper_prefix is added by default in thecargo-reaperconfiguration file that is generated bycargo-reaper-new, however,cargo-reaperwill throw an error and refuse to compile if an extension plugin listed does not meet this condition.
- Initialize a new VST plugin.
cargo reaper new --template vst reaper_my_plugin
[!WARNING] Currently the
reaper-rslibrary supports using thevstcrate which is deprecated. In an effort to maintain support forreaper-rs,cargo-reapercan initialize VST plugins, but it does not add any conveniences like it does for extension development.
cargo-reaper-list
NAME
cargo-reaper-list -- List all detected REAPER plugin packages in a cargo-reaper project.
SYNOPSIS
cargo-reaper list
DESCRIPTION
This command prints a list of available plugins and their version, description and author information
in a human-readable format to the terminal via stdout.
OPTIONS
-h
--help
EXAMPLES
cargo reaper list
cargo-reaper-build
NAME
cargo-reaper-build -- Compile REAPER extension plugin(s).
SYNOPSIS
cargo-reaper build [options] [cargo_build_args]...
DESCRIPTION
Compiles, renames and symlinks REAPER extension plugins, forwarding trailing arguments to the cargo-build invocation.
The resulting target is renamed to its corresponding key specified in the cargo-reaper configuration file.
Symlinks to plugins in REAPER's UserPlugins directory are managed automatically, unless specified otherwise. This ensures that a new plugin
that is built with the release profile, does not fail to be symlinked if a symlink with the same name already exists for the debug profile.
If for whatever reason symlinking fails, and the build command is unable to remove a stale symlink, use cargo-reaper-clean.
OPTIONS
--no-symlink
UserPlugins directory.-h
--help
EXAMPLES
- Build a package or workspace containing a REAPER extension plugin, and all of its dependencies.
cargo reaper build
- Build a package or workspace containing a REAPER extension plugin and all of its dependencies, but do not create symlinks to the
UserPluginsdirectory.
cargo reaper build --no-symlink
- Build only the specified package in a workspace containing a REAPER extension plugin with optimizations for x86_64 Windows.
cargo reaper build -p reaper_my_plugin --lib --release --target x86_64-pc-windows-msvc
cargo reaper build -- -p reaper_my_plugin --lib --release --target x86_64-pc-windows-msvc
Note that arguments passed to the
cargo-buildinvocation must be trailing. These may be passed directly, or as positional arguments.
cargo-reaper-link
NAME
cargo-reaper-link -- Manually symlink extension plugin(s) to REAPER's UserPlugins directory.
SYNOPSIS
cargo-reaper link [path]...
DESCRIPTION
Manually symlink one or more extension plugins to REAPER's UserPlugins directory.
This may be useful in circumstances where finer grain control is necessary between building and symlinking the plugin, for instance, in CI or when using build tools like Nix or Docker.
By default
cargo-reaper-buildwill symlink extension plugins automatically, unless specified otherwise.
OPTIONS
-h
--help
EXAMPLES
- Create a symlink from an absolute path to a compiled REAPER extension plugin to REAPER's
UserPluginsdirectory.
cargo reaper link /absolute/path/to/target/release/reaper_my_plugin.{so|dylib|dll}
- Create a symlink from a relative path to a compiled REAPER extension plugin to REAPER's
UserPluginsdirectory, using shell scripting (Linux and MacOS only).
cargo reaper link $(realpath target/release/reaper_my_plugin.*)
REAPER extension plugins are dynamically linked libraries, which have differing extension names depending on their target platform. Below is a list of platforms and their corresponding extension names, though in most cases, a regex catchall will suffice (
reaper_my_plugin.*).
- Linux --
.so- Darwin (MacOS) --
.dylib- Windows --
.dll
cargo-reaper-run
NAME
cargo-reaper-run -- Run REAPER extension plugin(s).
SYNOPSIS
cargo-reaper run [options] [cargo_build_args]...
DESCRIPTION
Compile extension plugins and open REAPER.
This is effectively shorthand for running cargo-reaper-build then opening REAPER, which will make
changes to your extension plugins take immediate effect.
cargo-reaper-run will attempt to use the REAPER binary executable on $PATH if it's available, otherwise falling
back to the platform specific default global installation path. If for some reason the default installation is not
working, please see the options below for manually specifying a path to a REAPER binary executable.
OPTIONS
-e path
--exec path
-o path
--open path
--open-project path
--no-build
-t duration
--timeout duration
--stdin stdio
--stdout stdio
--stderr stdio
-h
--help
ADDITIONAL LINUX OPTIONS
The following options require xserver to be configured and have Xvfb and xdotool installed.
These options are intended to enable testing in headless environments and to make it easier to
assert the state an extension plugin reaches.
--headless
-D display
--display display
DISPLAY environment variable, e.g. DISPLAY=:99.-w title
--locate-window title
--keep-going
EXAMPLES
- Build a package or workspace containing a REAPER extension plugin and all of its dependencies, and open REAPER.
cargo reaper run
- Build only the specified package in a workspace containing a REAPER extension plugin with optimizations for x86_64 Windows, and open REAPER.
cargo reaper run -p reaper_my_plugin --lib --release --target x86_64-pc-windows-msvc
cargo reaper run -- -p reaper_my_plugin --lib --release --target x86_64-pc-windows-msvc
Note that arguments passed to the
cargo-buildinvocation must be trailing. These may be passed directly, or as positional arguments.
- Run REAPER in a headless environment through
Xvfbon Linux, and attempt to locate a window.
DISPLAY=:99 cargo-reaper run --headless \ # open REAPER on Xvfb display 99
--no-build \ # but don't build any plugins
--open /path/to/my_project.RPP \ # open a pre-saved project (maybe with state that affects how the plugin behaves)
--locate-window "error: expected ..." \ # and locate an error window and exit successfully
--timeout 15s \ # but only run REAPER for a maximum of 15 seconds
--keep-going \ # and don't exit until the timeout is reached (even if the window is found)
--stdout null \ # do not print Xvfb or REAPER info to stdout
--stderr null # do not print Xvfb or REAPER errors to stderr
TIP: The above assumes the extension plugin is already installed, skipping the build phase. This can be particularly useful since it doesn't require configuring a rust toolchain in order to build the plugin prior to testing it.
cargo-reaper-clean
NAME
cargo-reaper-clean -- Remove plugin(s) from the UserPlugins directory that cargo-reaper has generated in the past.
SYNOPSIS
cargo-reaper clean [options]
DESCRIPTION
Clean plugin symlinks from REAPER's UserPlugins directory, and optionally artifacts generated by cargo-reaper.
OPTIONS
-p key
--plugin key
-n
--dry-run
-a
--remove-artifacts
-h
--help
EXAMPLES
- Remove all plugin symlinks whose keys exist in the
cargo-reaperconfiguration file.
cargo reaper clean
- Remove specific plugin symlinks by referencing its key in the
cargo-reaperconfiguration file.
cargo reaper clean -p reaper_my_plugin
- Display cargo artifacts generated by
cargo-reaperand symlinks for plugins whose keys exist in thecargo-reaperconfiguration file without removing them.
cargo reaper clean --remove-artifacts --dry-run
cargo-reaper-completions
NAME
cargo-reaper-completions -- Generate shell completion scripts.
SYNOPSIS
cargo-reaper completions shell
DESCRIPTION
Generate shell completions for the cargo-reaper command line application.
The following shells are supported:
OPTIONS
-h
--help
EXAMPLES
Below are examples of how to generate completion scripts for the supported shells. Note that this does not include instructions for sourcing the scripts or configuring your shell to enable completions. Please refer to your shell’s documentation for details.
Bash
cargo-reaper completions bash > /usr/share/bash-completion/completions/cargo-reaper.bash
Elvish
cargo-reaper completions elvish > ~/.elvish/lib/cargo-reaper.elv
Fish
cargo-reaper completions fish > /usr/share/fish/vendor_completions.d/cargo-reaper.fish
PowerShell
cargo-reaper completions powershell > $HOME/Documents/PowerShell/cargo-reaper.ps1
Zsh
cargo-reaper completions zsh > /usr/share/zsh/site-functions/_cargo-reaper
Glossary
Default Global Installation Path
This is the system-wide path where the REAPER binary executable is installed. This is different for each supported platform:
- Linux:
- A global default is not predictable since Linux does not have a canonical package manager. Instead,
cargo-reaperuses thewhichcrate'swhich::which_globalfunction to determine its location.
- A global default is not predictable since Linux does not have a canonical package manager. Instead,
- Darwin (MacOS) --
/Applications/REAPER.app - Windows:
- x86 (32bit) --
C:\Program Files (x86)\REAPER\reaper.exe - x86_64 (64bit) --
C:\Program Files\REAPER (x64)\reaper.exe - aarch64 (ARM) --
C:\Program Files\REAPER (ARM64)\reaper.exe
- x86 (32bit) --
Extension Plugin
A C/C++ dynamically linked library that when placed in REAPER's UserPlugins directory, is loaded as part of the REAPER
application thread on launch, adding additional functionality to the program.
Dynamically Linked Library
A compiled collection of code and data that is loaded into a program at runtime, rather than being statically included in the final executable during compilation.
REAPER extension plugins are dynamically linked libraries, which have differing extension names depending on their target platform:
- Linux --
.so - Darwin (MacOS) --
.dylib - Windows --
.dll
User Plugins
The UserPlugins directory is the file system location created the first time REAPER is launched that the REAPER application thread loads extension plugins from.
This is different for each supported platform:
- Linux --
~/.config/REAPER/UserPlugins - Darwin (MacOS) --
~/Library/Application\ Support/REAPER/UserPlugins - Windows --
%APPDATA%\REAPER\UserPlugins
Plugin Manifest
A plugin manifest, in the context of cargo-reaper, is the same as a Cargo manifest, which contains
a package with a library target of crate-type cdylib.
See the Plugin Manifest section for detailed information on configuring a cargo-reaper plugin manifest.