mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-08 04:20:13 +02:00
Always search for host in ~/.local/share/yabridge
This commit is contained in:
@@ -8,6 +8,12 @@ Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
|
||||
- Yabridge will now always search for `yabridge-host.exe` in
|
||||
`~/.local/share/yabridge`, even if that directory is not in the search path.
|
||||
This should make setup easier.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed an issue where _Renoise_ would show an error message when trying to load
|
||||
|
||||
@@ -83,12 +83,12 @@ or by running `yabridgectl --help`.
|
||||
|
||||
First, yabridgectl needs to know where it can find yabridge's files. If you have
|
||||
downloaded the prebuilt binaries, then you can simply extract the archive to
|
||||
`~/.local/share` and yabridgectl will pick up the files in
|
||||
`~/.local/share/yabridge` automatically[\*](#why-local-share-yabridge). You also
|
||||
won't have to do any additional work if you're using one of the AUR packages. If
|
||||
you have compiled yabridge from source or if you installed the files to some
|
||||
other location, then you can use `yabridgectl set --path=<path>` to tell
|
||||
yabridgectl where it can find the files.
|
||||
`~/.local/share` and both yabridge and yabridgectl will pick up the files in
|
||||
`~/.local/share/yabridge` automatically. You also won't have to do any
|
||||
additional work if you're using one of the AUR packages. If you have compiled
|
||||
yabridge from source or if you installed the files to some other location, then
|
||||
you can use `yabridgectl set --path=<path>` to tell yabridgectl where it can
|
||||
find the files.
|
||||
|
||||
Secondly, yabridgectl will default to the copy-based installation method. If you
|
||||
are using a VST host with individually sandboxed plugins such as Bitwig Studio
|
||||
@@ -107,16 +107,6 @@ tell your VST host to search for plugins in the directories you just added and
|
||||
you'll be good to go. _Don't forget to rerun `yabridgectl sync` whenever you
|
||||
update yabridge if you are using the copy-based installation method._
|
||||
|
||||
<sup id="why-local-share-yabridge">
|
||||
*Instead of copying yabridge's files to <code>~/.local/share</code>, it would
|
||||
also be possible to install yabridge to <code>/usr/local/bin</code> and
|
||||
<code>/usr/local/lib</code>. While this does avoid the need to modify your
|
||||
<code>PATH</code> environment variable when using the copy-based installation
|
||||
method, it could also cause other issues if you're not careful. This is why
|
||||
it's recommended to install yabridge to your home directory if you're not
|
||||
using one of the AUR packages.
|
||||
</sup>
|
||||
|
||||
### Manual setup
|
||||
|
||||
To set up yabridge without using yabridgectl, first download and extract
|
||||
@@ -143,15 +133,21 @@ update yabridge.
|
||||
|
||||
### Search path setup
|
||||
|
||||
If you're using the _copy-based_ installation method and you're not using any of
|
||||
the AUR packages, then you may have to modify your _login shell_'s `PATH`
|
||||
environment variable so that yabridge is able to find the files in the directory
|
||||
you've extracted yabridge's files to. Yabridgectl will automatically check
|
||||
whether this is set up correctly when you run `yabridgectl sync`, and it will
|
||||
show a warning if it detects any issues. _If you do not see such a warning after
|
||||
running `yabridgectl sync`, then you can skip this section._
|
||||
This section is only relevant if you're using the _copy-based_ installation
|
||||
method and your yabridge files are located somewhere other than in
|
||||
`~/.local/share/yabridge`. If you're using one of the AUR packages then you can
|
||||
also skip this section.
|
||||
|
||||
To do this, you'll want to add yabridge's installation directory to your login
|
||||
Yabridge needs to know where it can find `yabridge-host.exe`. By default
|
||||
yabridge will search your through search path as well as in
|
||||
`~/.local/share/yabridge` if that exists. When loading yabridge from a
|
||||
non-standard location, such as when building from source, you may have to modify
|
||||
your _login shell_'s `PATH` environment variable so that yabridge is able to
|
||||
find its files. Yabridgectl will automatically check whether this is set up
|
||||
correctly when you run `yabridgectl sync`, and it will show a warning if it
|
||||
detects any issues. _If you do not see such a warning after running `yabridgectl sync`, then you can skip this section._
|
||||
|
||||
To set this, you'll want to add yabridge's installation directory to your login
|
||||
shell's `PATH` environment variable. If you're unsure what your login shell is,
|
||||
then you can open a terminal and run `echo $SHELL` to find out. For the below
|
||||
examples I'll assume you're using the default installation location at
|
||||
|
||||
+16
-1
@@ -118,7 +118,8 @@ fs::path find_vst_host(PluginArchitecture plugin_arch, bool use_plugin_groups) {
|
||||
|
||||
// Boost will return an empty path if the file could not be found in the
|
||||
// search path
|
||||
const fs::path vst_host_path = bp::search_path(host_name);
|
||||
const fs::path vst_host_path =
|
||||
bp::search_path(host_name, get_modified_search_path());
|
||||
if (vst_host_path == "") {
|
||||
throw std::runtime_error("Could not locate '" + std::string(host_name) +
|
||||
"'");
|
||||
@@ -176,6 +177,20 @@ boost::filesystem::path generate_group_endpoint(
|
||||
return get_temporary_directory() / socket_name.str();
|
||||
}
|
||||
|
||||
std::vector<boost::filesystem::path> get_modified_search_path() {
|
||||
std::vector<boost::filesystem::path> search_path =
|
||||
boost::this_process::path();
|
||||
|
||||
const bp::environment environment = boost::this_process::environment();
|
||||
if (auto home_directory = environment.find("HOME");
|
||||
home_directory != environment.end()) {
|
||||
search_path.push_back(fs::path(home_directory->to_string()) / ".local" /
|
||||
"share" / "yabridge");
|
||||
}
|
||||
|
||||
return search_path;
|
||||
}
|
||||
|
||||
fs::path get_this_file_location() {
|
||||
// HACK: Not sure why, but `boost::dll::this_line_location()` returns a path
|
||||
// starting with a double slash on some systems. I've seen this happen
|
||||
|
||||
+12
-1
@@ -80,7 +80,8 @@ PluginArchitecture find_vst_architecture(boost::filesystem::path);
|
||||
* when developing, as you can simply symlink the the libyabridge.so
|
||||
* file in the build directory without having to install anything to
|
||||
* /usr.
|
||||
* 2. In the regular search path.
|
||||
* 2. In the regular search path, augmented with `~/.local/share/yabridge` to
|
||||
* ease the setup process.
|
||||
*
|
||||
* @param plugin_arch The architecture of the plugin, either 64-bit or 32-bit.
|
||||
* Used to determine which host application to use, if available.
|
||||
@@ -143,6 +144,16 @@ boost::filesystem::path generate_group_endpoint(
|
||||
const boost::filesystem::path& wine_prefix,
|
||||
const PluginArchitecture architecture);
|
||||
|
||||
/**
|
||||
* Return the search path as defined in `$PATH`, with `~/.local/share/yabridge`
|
||||
* appended to the end. I'd rather not do this since more magic makes things
|
||||
* harder to comprehend, but I can understand that modifying your login shell's
|
||||
* `PATH` environment variable can be a big hurdle if you've never done anything
|
||||
* like that before. And since this is the recommended installation location, it
|
||||
* makes sense to also search there by default.
|
||||
*/
|
||||
std::vector<boost::filesystem::path> get_modified_search_path();
|
||||
|
||||
/**
|
||||
* Return a path to this `.so` file. This can be used to find out from where
|
||||
* this link to or copy of `libyabridge.so` was loaded.
|
||||
|
||||
Generated
+10
@@ -242,6 +242,15 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_executable"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "302d553b8abc8187beb7d663e34c065ac4570b273bc9511a50e940e99409c577"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
@@ -704,6 +713,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"colored",
|
||||
"is_executable",
|
||||
"lazy_static",
|
||||
"promptly",
|
||||
"rayon",
|
||||
|
||||
@@ -10,10 +10,11 @@ repository = "https://github.com/robbert-vdh/yabridge"
|
||||
license = "GPL-3.0-or-later"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.31"
|
||||
aho-corasick = "0.7.13"
|
||||
colored = "2.0.0"
|
||||
anyhow = "1.0.31"
|
||||
clap = { version = "3.0.0-beta.1", features = ["wrap_help"] }
|
||||
colored = "2.0.0"
|
||||
is_executable = "0.1.2"
|
||||
lazy_static = "1.4.0"
|
||||
promptly = "0.3.0"
|
||||
rayon = "1.3.1"
|
||||
|
||||
@@ -29,15 +29,15 @@ use xdg::BaseDirectories;
|
||||
use crate::files::{self, SearchResults};
|
||||
|
||||
/// The name of the config file, relative to `$XDG_CONFIG_HOME/CONFIG_PREFIX`.
|
||||
const CONFIG_FILE_NAME: &str = "config.toml";
|
||||
pub const CONFIG_FILE_NAME: &str = "config.toml";
|
||||
/// The name of the XDG base directory prefix for yabridgectl, relative to `$XDG_CONFIG_HOME` and
|
||||
/// `$XDG_DATA_HOME`.
|
||||
const YABRIDGECTL_PREFIX: &str = "yabridgectl";
|
||||
|
||||
/// The name of the library file we're searching for.
|
||||
const LIBYABRIDGE_NAME: &str = "libyabridge.so";
|
||||
pub const LIBYABRIDGE_NAME: &str = "libyabridge.so";
|
||||
/// The name of the script we're going to run to verify that everything's working correctly.
|
||||
const YABRIDGE_HOST_EXE_NAME: &str = "yabridge-host.exe";
|
||||
pub const YABRIDGE_HOST_EXE_NAME: &str = "yabridge-host.exe";
|
||||
/// The name of the XDG base directory prefix for yabridge's own files, relative to
|
||||
/// `$XDG_CONFIG_HOME` and `$XDG_DATA_HOME`.
|
||||
const YABRIDGE_PREFIX: &str = "yabridge";
|
||||
@@ -191,8 +191,8 @@ impl Config {
|
||||
}
|
||||
|
||||
Err(anyhow!(
|
||||
"Could not find '{}' in either '{}' or '{}'. You can tell yabridgectl where \
|
||||
to search for it using 'yabridgectl set --path=<path>'.",
|
||||
"Could not find '{}' in either '{}' or '{}'. You can override the default \
|
||||
search path using 'yabridgectl set --path=<path>'.",
|
||||
LIBYABRIDGE_NAME,
|
||||
system_path.display(),
|
||||
user_path.display()
|
||||
@@ -229,12 +229,12 @@ impl Config {
|
||||
/// Fetch the XDG base directories for yabridge's own files, converting any error messages if this
|
||||
/// somehow fails into a printable string to reduce boiler plate. This is only used when searching
|
||||
/// for `libyabridge.so` when no explicit search path has been set.
|
||||
fn yabridge_directories() -> Result<BaseDirectories> {
|
||||
pub fn yabridge_directories() -> Result<BaseDirectories> {
|
||||
BaseDirectories::with_prefix(YABRIDGE_PREFIX).context("Error while parsing base directories")
|
||||
}
|
||||
|
||||
/// Fetch the XDG base directories used for yabridgectl, converting any error messages if this
|
||||
/// somehow fails into a printable string to reduce boiler plate.
|
||||
fn yabridgectl_directories() -> Result<BaseDirectories> {
|
||||
pub fn yabridgectl_directories() -> Result<BaseDirectories> {
|
||||
BaseDirectories::with_prefix(YABRIDGECTL_PREFIX).context("Error while parsing base directories")
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
use anyhow::Result;
|
||||
use clap::{app_from_crate, App, AppSettings, Arg};
|
||||
use colored::Colorize;
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::config::Config;
|
||||
@@ -27,6 +28,17 @@ mod files;
|
||||
mod utils;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// We'll modify our `PATH` environment variable so it matches up with
|
||||
// `get_modified_search_path()` from `src/plugin/utils.h` for easier setup
|
||||
let yabridge_home = config::yabridge_directories()?.get_data_home();
|
||||
env::set_var(
|
||||
"PATH",
|
||||
match env::var("PATH") {
|
||||
Ok(path) => format!("{}:{}", path, yabridge_home.display()),
|
||||
_ => format!("{}", yabridge_home.display()),
|
||||
},
|
||||
);
|
||||
|
||||
let mut config = Config::read()?;
|
||||
|
||||
// Used for validation in `yabridgectl rm <path>`
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use colored::Colorize;
|
||||
use is_executable::IsExecutable;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
@@ -28,7 +29,7 @@ use std::path::Path;
|
||||
use std::process::{Command, Stdio};
|
||||
use textwrap::Wrapper;
|
||||
|
||||
use crate::config::{Config, KnownConfig};
|
||||
use crate::config::{self, Config, KnownConfig, YABRIDGE_HOST_EXE_NAME};
|
||||
|
||||
/// (Part of) the expected output when running `yabridge-host.exe`. Used to verify that everything's
|
||||
/// working correctly. We'll only match this prefix so we can modify the exact output at a later
|
||||
@@ -82,15 +83,33 @@ pub fn hash_file(file: &Path) -> Result<i64> {
|
||||
Ok(hasher.finish() as i64)
|
||||
}
|
||||
|
||||
/// Verify that `yabridge-host.exe` is accessible in a login shell. Returns unit if it is, or if we
|
||||
/// the login shell is set to an unknown shell. In the last case we'll just print a warning since we
|
||||
/// don't know how to invoke the shell as a login shell. This is needed when using copies to ensure
|
||||
/// that yabridge can find the host binaries when the VST host is launched from the desktop
|
||||
/// enviornment.
|
||||
/// Verify that `yabridge-host.exe` can be found when yabridge is run in a host launched from the
|
||||
/// GUI. We do this by launching a login shell, appending `~/.local/share/yabridge` to the login
|
||||
/// shell's search path since that's what yabridge also does, and then making the the file can be
|
||||
/// found. Returns unit if it can be found, or if we the login shell is set to an unknown shell. In
|
||||
/// the last case we'll just print a warning since we don't know how to invoke the shell as a login
|
||||
/// shell. This is needed when using copies to ensure that yabridge can find the host binaries when
|
||||
/// the VST host is launched from the desktop enviornment.
|
||||
///
|
||||
/// When we could not find `yabridge-host.exe`, we'll return `Err(shell_name)` so we can print a
|
||||
/// descriptive warning message.
|
||||
pub fn verify_path_setup() -> Result<(), String> {
|
||||
// First we'll check `~/.local/share/yabridge`, since that's a special location where yabridge
|
||||
// will always search
|
||||
if config::yabridge_directories()
|
||||
.ok()
|
||||
.and_then(|dirs| {
|
||||
dirs.get_data_home()
|
||||
.push(YABRIDGE_HOST_EXE_NAME)
|
||||
.is_executable()
|
||||
})
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Then we'll check the login shell, since DAWs launched from the GUI will have the same
|
||||
// environment
|
||||
match env::var("SHELL") {
|
||||
Ok(shell_path) => {
|
||||
// `$SHELL` will often contain a full path, but it doesn't have to
|
||||
@@ -113,13 +132,20 @@ pub fn verify_path_setup() -> Result<(), String> {
|
||||
| "zsh" => command
|
||||
.arg("-l")
|
||||
.arg("-c")
|
||||
.arg("command -v yabridge-host.exe"),
|
||||
.arg(format!("command -v {}", YABRIDGE_HOST_EXE_NAME)),
|
||||
// These shells either have their own implementation of `which` and don't support
|
||||
// `command`, or they don't have a seperate login shell flag
|
||||
"elvish" | "oil" => command.arg("-c").arg("command -v yabridge-host.exe"),
|
||||
"elvish" | "oil" => command
|
||||
.arg("-c")
|
||||
.arg(format!("command -v {}", YABRIDGE_HOST_EXE_NAME)),
|
||||
// xonsh's which implementation is broken as of writing this, so I left it out
|
||||
"pwsh" => command.arg("-l").arg("-c").arg("which yabridge-host.exe"),
|
||||
"nu" => command.arg("-c").arg("which yabridge-host.exe"),
|
||||
"pwsh" => command
|
||||
.arg("-l")
|
||||
.arg("-c")
|
||||
.arg(format!("which {}", YABRIDGE_HOST_EXE_NAME)),
|
||||
"nu" => command
|
||||
.arg("-c")
|
||||
.arg(format!("which {}", YABRIDGE_HOST_EXE_NAME)),
|
||||
shell => {
|
||||
eprintln!(
|
||||
"\n{}",
|
||||
|
||||
Reference in New Issue
Block a user