diff --git a/tools/yabridgectl/Cargo.lock b/tools/yabridgectl/Cargo.lock
index 094db8c0..7fc29473 100644
--- a/tools/yabridgectl/Cargo.lock
+++ b/tools/yabridgectl/Cargo.lock
@@ -269,6 +269,15 @@ dependencies = [
"num_cpus",
]
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
[[package]]
name = "scopeguard"
version = "1.1.0"
@@ -366,6 +375,17 @@ version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
+[[package]]
+name = "walkdir"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
+dependencies = [
+ "same-file",
+ "winapi",
+ "winapi-util",
+]
+
[[package]]
name = "winapi"
version = "0.3.9"
@@ -397,6 +417,12 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+[[package]]
+name = "xdg"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"
+
[[package]]
name = "yabridgectl"
version = "1.2.1"
@@ -405,4 +431,6 @@ dependencies = [
"clap",
"rayon",
"toml",
+ "walkdir",
+ "xdg",
]
diff --git a/tools/yabridgectl/Cargo.toml b/tools/yabridgectl/Cargo.toml
index 5917925e..c9afb3ad 100644
--- a/tools/yabridgectl/Cargo.toml
+++ b/tools/yabridgectl/Cargo.toml
@@ -9,10 +9,10 @@ description = "Optional command line helper to set up yabridge"
repository = "https://github.com/robbert-vdh/yabridge"
license = "GPL-3.0-or-later"
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
[dependencies]
aho-corasick = "0.7.13"
clap = "3.0.0-beta.1"
rayon = "1.3.1"
toml = "0.5.6"
+walkdir = "2.3.1"
+xdg = "2.2.0"
diff --git a/tools/yabridgectl/src/config.rs b/tools/yabridgectl/src/config.rs
new file mode 100644
index 00000000..6909e959
--- /dev/null
+++ b/tools/yabridgectl/src/config.rs
@@ -0,0 +1,89 @@
+// yabridge: a Wine VST bridge
+// Copyright (C) 2020 Robbert van der Helm
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+use std::path::{Path, PathBuf};
+use xdg::BaseDirectories;
+
+const LIBYABRIDGE_NAME: &str = "libyabridge.so";
+
+/// The configuration used for yabridgectl. This will be serialized to and deserialized from
+/// `$XDG_CONFIG_HOME/yabridge/config.toml`.
+pub struct Config {
+ /// The installation method to use. We will default to creating copies since that works
+ /// everywehre.
+ pub method: InstallationMethod,
+ /// The path to the directory containing `libyabridge.so`. If not set, then yabridgectl will
+ /// look in `/usr/lib` and `$XDG_DATA_HOME/yabridge` since those are the expected locations for
+ /// yabridge to be installed in.
+ pub yabridge_home: Option,
+ /// Directories to search for Windows VST plugins.
+ pub plugin_dirs: Vec,
+}
+
+impl Config {
+ /// Return the path to `libyabridge.so`, or a descriptive error if it can't be found. If
+ /// `yabridge_home` is `None`, then we'll search in both `/usr/lib` and
+ /// `$XDG_DATA_HOME/yabridge`.
+ pub fn libyabridge(&self) -> Result {
+ match &self.yabridge_home {
+ Some(directory) => {
+ let candidate = directory.join(LIBYABRIDGE_NAME);
+ if candidate.exists() {
+ Ok(candidate)
+ } else {
+ Err(format!(
+ "Could not find {} in '{}'.",
+ LIBYABRIDGE_NAME,
+ directory.display()
+ ))
+ }
+ }
+ None => {
+ // Search in the two common installation locations if no path was set explicitely
+ let system_path = Path::new("/usr/lib");
+ let user_path = BaseDirectories::new()
+ .map_err(|err| format!("Error while parsing base directories:\n{}", err))?
+ .get_data_home();
+ for directory in &[system_path, &user_path] {
+ let candidate = directory.join(LIBYABRIDGE_NAME);
+ if candidate.exists() {
+ return Ok(candidate);
+ }
+ }
+
+ Err(format!(
+ "Could not find {} in either '{}' or '{}'. You can tell yabridgectl where \
+ to search for it using 'yabridgectl set --path='.",
+ LIBYABRIDGE_NAME,
+ system_path.display(),
+ user_path.display()
+ ))
+ }
+ }
+ }
+}
+
+/// Specifies how yabridge will be set up for the found plugins.
+pub enum InstallationMethod {
+ /// Create a copy of `libyabridge.so` for every Windows VST2 plugin .dll file found. After
+ /// updating yabridge, the user will have to rerun `yabridgectl sync` to copy over the new
+ /// version.
+ Copy,
+ /// This will create a symlink to `libyabridge.so` for every VST2 .dll file in the plugin
+ /// directories. As explained in the readme, this makes updating easier and remvoes the need to
+ /// modify the `PATH` environment variable.
+ Symlink,
+}
diff --git a/tools/yabridgectl/src/main.rs b/tools/yabridgectl/src/main.rs
index bdaf5c9d..02a1189e 100644
--- a/tools/yabridgectl/src/main.rs
+++ b/tools/yabridgectl/src/main.rs
@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+mod config;
+
fn main() {
println!("Hello, world!");
}