mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
Merge yabridge-group.exe and yabridge-host.exe
They were 95% the same, so this makes a lot more sense this way. When group host processes were introduced yabridge only did VST2 bridging, but we already have a plugin type argument anyways so might as well reuse that for group hosts.
This commit is contained in:
@@ -49,11 +49,11 @@ jobs:
|
|||||||
meson setup build --buildtype=release --cross-file=cross-wine.conf --unity=on --unity-size=10000 -Dbitbridge=true -Dcpp_link_args='-mwindows -static-libstdc++' -Dbuild.cpp_link_args='-static-libstdc++'
|
meson setup build --buildtype=release --cross-file=cross-wine.conf --unity=on --unity-size=10000 -Dbitbridge=true -Dcpp_link_args='-mwindows -static-libstdc++' -Dbuild.cpp_link_args='-static-libstdc++'
|
||||||
ninja -C build
|
ninja -C build
|
||||||
- name: Strip remaining debug symbols
|
- name: Strip remaining debug symbols
|
||||||
run: strip build/libyabridge{,-chainloader}-{vst2,vst3}.so build/yabridge-{host,group}{,-32}.exe.so
|
run: strip build/libyabridge{,-chainloader}-{vst2,vst3}.so build/yabridge-host{,-32}.exe.so
|
||||||
- name: Create an archive for the binaries
|
- name: Create an archive for the binaries
|
||||||
run: |
|
run: |
|
||||||
mkdir yabridge
|
mkdir yabridge
|
||||||
cp build/libyabridge{,-chainloader}-{vst2,vst3}.so build/yabridge-{host,group}{,-32}.exe{,.so} yabridge
|
cp build/libyabridge{,-chainloader}-{vst2,vst3}.so build/yabridge-host{,-32}.exe{,.so} yabridge
|
||||||
cp CHANGELOG.md README.md yabridge
|
cp CHANGELOG.md README.md yabridge
|
||||||
|
|
||||||
tar -caf "$ARCHIVE_NAME" yabridge
|
tar -caf "$ARCHIVE_NAME" yabridge
|
||||||
@@ -87,11 +87,11 @@ jobs:
|
|||||||
meson setup build --buildtype=release --cross-file=cross-wine.conf --unity=on --unity-size=10000 -Dbitbridge=true
|
meson setup build --buildtype=release --cross-file=cross-wine.conf --unity=on --unity-size=10000 -Dbitbridge=true
|
||||||
ninja -C build
|
ninja -C build
|
||||||
- name: Strip remaining debug symbols
|
- name: Strip remaining debug symbols
|
||||||
run: strip build/libyabridge{,-chainloader}-{vst2,vst3}.so build/yabridge-{host,group}{,-32}.exe.so
|
run: strip build/libyabridge{,-chainloader}-{vst2,vst3}.so build/yabridge-host{,-32}.exe.so
|
||||||
- name: Create an archive for the binaries
|
- name: Create an archive for the binaries
|
||||||
run: |
|
run: |
|
||||||
mkdir yabridge
|
mkdir yabridge
|
||||||
cp build/libyabridge{,-chainloader}-{vst2,vst3}.so build/yabridge-{host,group}{,-32}.exe{,.so} yabridge
|
cp build/libyabridge{,-chainloader}-{vst2,vst3}.so build/yabridge-host{,-32}.exe{,.so} yabridge
|
||||||
cp CHANGELOG.md README.md yabridge
|
cp CHANGELOG.md README.md yabridge
|
||||||
|
|
||||||
tar -caf "$ARCHIVE_NAME" yabridge
|
tar -caf "$ARCHIVE_NAME" yabridge
|
||||||
@@ -127,11 +127,11 @@ jobs:
|
|||||||
meson setup build --buildtype=release --cross-file=cross-wine.conf --unity=on --unity-size=10000 -Dbitbridge=true -Dcpp_link_args='-mwindows -static-libstdc++' -Dbuild.cpp_args='-m32' -Dbuild.cpp_link_args='-m32 -static-libstdc++'
|
meson setup build --buildtype=release --cross-file=cross-wine.conf --unity=on --unity-size=10000 -Dbitbridge=true -Dcpp_link_args='-mwindows -static-libstdc++' -Dbuild.cpp_args='-m32' -Dbuild.cpp_link_args='-m32 -static-libstdc++'
|
||||||
ninja -C build
|
ninja -C build
|
||||||
- name: Strip remaining debug symbols
|
- name: Strip remaining debug symbols
|
||||||
run: strip build/libyabridge{,-chainloader}-{vst2,vst3}.so build/yabridge-{host,group}{,-32}.exe.so
|
run: strip build/libyabridge{,-chainloader}-{vst2,vst3}.so build/yabridge-host{,-32}.exe.so
|
||||||
- name: Create an archive for the binaries
|
- name: Create an archive for the binaries
|
||||||
run: |
|
run: |
|
||||||
mkdir yabridge
|
mkdir yabridge
|
||||||
cp build/libyabridge{,-chainloader}-{vst2,vst3}.so build/yabridge-{host,group}{,-32}.exe{,.so} yabridge
|
cp build/libyabridge{,-chainloader}-{vst2,vst3}.so build/yabridge-host{,-32}.exe{,.so} yabridge
|
||||||
cp CHANGELOG.md README.md yabridge
|
cp CHANGELOG.md README.md yabridge
|
||||||
|
|
||||||
tar -caf "$ARCHIVE_NAME" yabridge
|
tar -caf "$ARCHIVE_NAME" yabridge
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ Versioning](https://semver.org/spec/v2.0.0.html).
|
|||||||
gets rid of the runtime dependency on Boost.Filesystem for those builds, and
|
gets rid of the runtime dependency on Boost.Filesystem for those builds, and
|
||||||
it also makes compiling slightly faster and the binaries slightly smaller.
|
it also makes compiling slightly faster and the binaries slightly smaller.
|
||||||
Before this, yabridge would need to be rebuilt whenever Boost got updated.
|
Before this, yabridge would need to be rebuilt whenever Boost got updated.
|
||||||
|
- The functionality for the `yabridge-group` binaries has been merged into the
|
||||||
|
`yabridge-host` binaries.
|
||||||
- When mapping shared memory for audio and the user does not have permissions to
|
- When mapping shared memory for audio and the user does not have permissions to
|
||||||
lock the memory, yabridge will now retry mapping the memory without locking it
|
lock the memory, yabridge will now retry mapping the memory without locking it
|
||||||
instead of immediately terminating the process. An annoying desktop
|
instead of immediately terminating the process. An annoying desktop
|
||||||
@@ -55,6 +57,8 @@ Versioning](https://semver.org/spec/v2.0.0.html).
|
|||||||
|
|
||||||
- Removed the `with-static-boost` build option since there's no longer a
|
- Removed the `with-static-boost` build option since there's no longer a
|
||||||
dependency on Boost.Filesystem.
|
dependency on Boost.Filesystem.
|
||||||
|
- Removed the `yabridge-group*` binaries as they are now part of the
|
||||||
|
`yabridge-host*` binaries. This saves precious megabytes.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
@@ -80,6 +84,8 @@ Versioning](https://semver.org/spec/v2.0.0.html).
|
|||||||
|
|
||||||
- `libyabridge-chainloader-vst2.so` and `libyabridge-chainloader-vst3.so` are
|
- `libyabridge-chainloader-vst2.so` and `libyabridge-chainloader-vst3.so` are
|
||||||
new files that should be included in the package.
|
new files that should be included in the package.
|
||||||
|
- The `yabridge-group` binaries no longer exist as they are now part of the
|
||||||
|
`yabridge-host` binaries.
|
||||||
- The `with-bitbridge` build option has been renamed to just `bitbridge`.
|
- The `with-bitbridge` build option has been renamed to just `bitbridge`.
|
||||||
- Completely removed the dependency on all Boost libraries.
|
- Completely removed the dependency on all Boost libraries.
|
||||||
- Added a dependency on the headers-only
|
- Added a dependency on the headers-only
|
||||||
|
|||||||
@@ -819,11 +819,10 @@ meson setup build --buildtype=release --cross-file cross-wine.conf -Dbitbridge=t
|
|||||||
ninja -C build
|
ninja -C build
|
||||||
```
|
```
|
||||||
|
|
||||||
This will produce four files called `yabridge-host-32.exe`,
|
This will produce a second plugin host binary called `yabridge-host-32.exe`.
|
||||||
`yabridge-host-32.exe.so`, `yabridge-group-32.exe` and
|
Yabridge will detect whether the plugin you're trying to load is 32-bit or
|
||||||
`yabridge-group-32.exe.so`. Yabridge will detect whether the plugin you're
|
64-bit, and will run either the regular version or the `*-32.exe` variant
|
||||||
trying to load is 32-bit or 64-bit, and will run either the regular version or
|
accordingly.
|
||||||
the `*-32.exe` variant accordingly.
|
|
||||||
|
|
||||||
### 32-bit libraries
|
### 32-bit libraries
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ page lists some of those.
|
|||||||
- Replace the use of `notify-send` for notifications with using `libdbus`
|
- Replace the use of `notify-send` for notifications with using `libdbus`
|
||||||
directly. Most systems will have both available by default, but some less
|
directly. Most systems will have both available by default, but some less
|
||||||
common distros split `notify-send` from the rest of the `libnotify` package.
|
common distros split `notify-send` from the rest of the `libnotify` package.
|
||||||
- Possibly combine the `yabridge-host` and `yabridge-group` binaries to save
|
|
||||||
some disk space as 95% of their code overlaps.
|
|
||||||
- Consider adding an option for yabridgectl to set up VST2 plugins in `~/.vst`.
|
- Consider adding an option for yabridgectl to set up VST2 plugins in `~/.vst`.
|
||||||
As discussed in a couple places already doing so would come with a number of
|
As discussed in a couple places already doing so would come with a number of
|
||||||
downsides and potential pitfalls so this may not happen.
|
downsides and potential pitfalls so this may not happen.
|
||||||
|
|||||||
+17
-31
@@ -41,10 +41,8 @@ with_vst3 = get_option('vst3')
|
|||||||
# suffixed with `.exe`.
|
# suffixed with `.exe`.
|
||||||
vst2_plugin_name = 'yabridge-vst2'
|
vst2_plugin_name = 'yabridge-vst2'
|
||||||
vst3_plugin_name = 'yabridge-vst3'
|
vst3_plugin_name = 'yabridge-vst3'
|
||||||
individual_host_name_64bit = 'yabridge-host'
|
host_name_64bit = 'yabridge-host'
|
||||||
individual_host_name_32bit = 'yabridge-host-32'
|
host_name_32bit = 'yabridge-host-32'
|
||||||
group_host_name_64bit = 'yabridge-group'
|
|
||||||
group_host_name_32bit = 'yabridge-group-32'
|
|
||||||
|
|
||||||
compiler_options = [
|
compiler_options = [
|
||||||
'-fvisibility=hidden',
|
'-fvisibility=hidden',
|
||||||
@@ -231,11 +229,11 @@ endif
|
|||||||
# Binaries
|
# Binaries
|
||||||
#
|
#
|
||||||
# The application consists of a plugin (`libyabridge-{vst2,vst3}.so`) that calls
|
# The application consists of a plugin (`libyabridge-{vst2,vst3}.so`) that calls
|
||||||
# a Winelib application (`yabridge-{host,group}{,-32}.exe`) that can host
|
# a Winelib application (`yabridge-host{,-32}.exe`) that can host Windows VST2
|
||||||
# Windows VST2 and VST3 plugins. These plugins can in turn be loaded from small
|
# and VST3 plugins. These plugins can in turn be loaded from small stub
|
||||||
# stub libraries dubbed chainloaders to avoid having to copy large plugin
|
# libraries dubbed chainloaders to avoid having to copy large plugin libraries
|
||||||
# libraries around. More information about the way these two components work
|
# around. More information about the way these two components work together can
|
||||||
# together can be found in `docs/architecture.md`.
|
# be found in `docs/architecture.md`.
|
||||||
#
|
#
|
||||||
|
|
||||||
# Generate header files for configuration variables such as the current git tag
|
# Generate header files for configuration variables such as the current git tag
|
||||||
@@ -298,36 +296,24 @@ endif
|
|||||||
|
|
||||||
if is_64bit_system
|
if is_64bit_system
|
||||||
executable(
|
executable(
|
||||||
individual_host_name_64bit,
|
host_name_64bit,
|
||||||
individual_host_sources,
|
host_sources,
|
||||||
native : false,
|
native : false,
|
||||||
dependencies : host_common_64bit_dep,
|
include_directories : include_dir,
|
||||||
link_args : ['-m64'],
|
dependencies : host_64bit_deps,
|
||||||
)
|
cpp_args : compiler_options + wine_64bit_compiler_options,
|
||||||
|
|
||||||
executable(
|
|
||||||
group_host_name_64bit,
|
|
||||||
group_host_sources,
|
|
||||||
native : false,
|
|
||||||
dependencies : host_common_64bit_dep,
|
|
||||||
link_args : ['-m64'],
|
link_args : ['-m64'],
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if with_bitbridge
|
if with_bitbridge
|
||||||
executable(
|
executable(
|
||||||
individual_host_name_32bit,
|
host_name_32bit,
|
||||||
individual_host_sources,
|
host_sources,
|
||||||
native : false,
|
native : false,
|
||||||
dependencies : host_common_32bit_dep,
|
include_directories : include_dir,
|
||||||
link_args : ['-m32'],
|
dependencies : host_32bit_deps,
|
||||||
)
|
cpp_args : compiler_options + wine_32bit_compiler_options,
|
||||||
|
|
||||||
executable(
|
|
||||||
group_host_name_32bit,
|
|
||||||
group_host_sources,
|
|
||||||
native : false,
|
|
||||||
dependencies : host_common_32bit_dep,
|
|
||||||
link_args : ['-m32'],
|
link_args : ['-m32'],
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -36,15 +36,15 @@ void* find_plugin_library(const std::string& name) {
|
|||||||
// `dlopen()` for distro packaged versions of yabridge
|
// `dlopen()` for distro packaged versions of yabridge
|
||||||
const std::vector<fs::path> search_path = get_augmented_search_path();
|
const std::vector<fs::path> search_path = get_augmented_search_path();
|
||||||
if (const auto& yabridge_host_path =
|
if (const auto& yabridge_host_path =
|
||||||
search_in_path(search_path, yabridge_individual_host_name)) {
|
search_in_path(search_path, yabridge_host_name)) {
|
||||||
const fs::path candidate = yabridge_host_path->parent_path() / name;
|
const fs::path candidate = yabridge_host_path->parent_path() / name;
|
||||||
if (fs::exists(candidate)) {
|
if (fs::exists(candidate)) {
|
||||||
return dlopen(candidate.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
return dlopen(candidate.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto& yabridge_host_32_path = search_in_path(
|
if (const auto& yabridge_host_32_path =
|
||||||
search_path, yabridge_individual_host_name_32bit)) {
|
search_in_path(search_path, yabridge_host_name_32bit)) {
|
||||||
const fs::path candidate =
|
const fs::path candidate =
|
||||||
yabridge_host_32_path->parent_path() / name;
|
yabridge_host_32_path->parent_path() / name;
|
||||||
if (fs::exists(candidate)) {
|
if (fs::exists(candidate)) {
|
||||||
|
|||||||
@@ -30,26 +30,11 @@ constexpr char yabridge_vst3_plugin_name[] = "@vst3_plugin_name@";
|
|||||||
* The name of the Wine plugin host application, e.g. `yabridge-host.exe` for
|
* The name of the Wine plugin host application, e.g. `yabridge-host.exe` for
|
||||||
* the regular 64-bit build.
|
* the regular 64-bit build.
|
||||||
*/
|
*/
|
||||||
constexpr char yabridge_individual_host_name[] =
|
constexpr char yabridge_host_name[] = "@host_binary_64bit@";
|
||||||
"@individual_host_binary_64bit@";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the group host application, e.g. `yabridge-group.exe` for the
|
|
||||||
* regular 64-bit build.
|
|
||||||
*/
|
|
||||||
constexpr char yabridge_group_host_name[] = "@group_host_binary_64bit@";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the 32-bit Wine plugin host application, e.g.
|
* The name of the 32-bit Wine plugin host application, e.g.
|
||||||
* `yabridge-host-32.exe`.` This is used as a bitbridge to be able to load
|
* `yabridge-host-32.exe`.` This is used as a bitbridge to be able to load
|
||||||
* legacy 32-bit only Windows plugins from a 64-bit Linux host.
|
* legacy 32-bit only Windows plugins from a 64-bit Linux host.
|
||||||
*/
|
*/
|
||||||
constexpr char yabridge_individual_host_name_32bit[] =
|
constexpr char yabridge_host_name_32bit[] = "@host_binary_32bit@";
|
||||||
"@individual_host_binary_32bit@";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the 32-bit group host application, e.g. `yabridge-group-32.exe`.`
|
|
||||||
* This is used as a bitbridge to be able to load legacy 32-bit only Windows
|
|
||||||
* plugins from a 64-bit Linux host.
|
|
||||||
*/
|
|
||||||
constexpr char yabridge_group_host_name_32bit[] = "@group_host_binary_32bit@";
|
|
||||||
|
|||||||
@@ -7,10 +7,8 @@ config_header = configure_file(
|
|||||||
{
|
{
|
||||||
'vst2_plugin_name': 'lib' + vst2_plugin_name + '.so',
|
'vst2_plugin_name': 'lib' + vst2_plugin_name + '.so',
|
||||||
'vst3_plugin_name': 'lib' + vst3_plugin_name + '.so',
|
'vst3_plugin_name': 'lib' + vst3_plugin_name + '.so',
|
||||||
'individual_host_binary_32bit': individual_host_name_32bit + '.exe',
|
'host_binary_32bit': host_name_32bit + '.exe',
|
||||||
'individual_host_binary_64bit': individual_host_name_64bit + '.exe',
|
'host_binary_64bit': host_name_64bit + '.exe',
|
||||||
'group_host_binary_32bit': group_host_name_32bit + '.exe',
|
|
||||||
'group_host_binary_64bit': group_host_name_64bit + '.exe',
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -110,8 +110,7 @@ IndividualHost::IndividualHost(asio::io_context& io_context,
|
|||||||
: HostProcess(io_context, sockets),
|
: HostProcess(io_context, sockets),
|
||||||
plugin_info_(plugin_info),
|
plugin_info_(plugin_info),
|
||||||
host_path_(find_vst_host(plugin_info.native_library_path_,
|
host_path_(find_vst_host(plugin_info.native_library_path_,
|
||||||
plugin_info.plugin_arch_,
|
plugin_info.plugin_arch_)),
|
||||||
false)),
|
|
||||||
handle_(launch_host(
|
handle_(launch_host(
|
||||||
host_path_,
|
host_path_,
|
||||||
{
|
{
|
||||||
@@ -172,8 +171,7 @@ GroupHost::GroupHost(asio::io_context& io_context,
|
|||||||
: HostProcess(io_context, sockets),
|
: HostProcess(io_context, sockets),
|
||||||
plugin_info_(plugin_info),
|
plugin_info_(plugin_info),
|
||||||
host_path_(find_vst_host(plugin_info.native_library_path_,
|
host_path_(find_vst_host(plugin_info.native_library_path_,
|
||||||
plugin_info.plugin_arch_,
|
plugin_info.plugin_arch_)) {
|
||||||
true)) {
|
|
||||||
// When using plugin groups, we'll first try to connect to an existing group
|
// When using plugin groups, we'll first try to connect to an existing group
|
||||||
// host process and ask it to host our plugin. If no such process exists,
|
// host process and ask it to host our plugin. If no such process exists,
|
||||||
// then we'll start a new process. In the event that multiple yabridge
|
// then we'll start a new process. In the event that multiple yabridge
|
||||||
@@ -205,8 +203,8 @@ GroupHost::GroupHost(asio::io_context& io_context,
|
|||||||
// because it should run independently of this yabridge instance as
|
// because it should run independently of this yabridge instance as
|
||||||
// it will likely outlive it.
|
// it will likely outlive it.
|
||||||
Process::Handle group_host =
|
Process::Handle group_host =
|
||||||
launch_host(host_path_, {group_socket_path.string()}, logger,
|
launch_host(host_path_, {"group", group_socket_path.string()},
|
||||||
config, plugin_info);
|
logger, config, plugin_info);
|
||||||
group_host.detach();
|
group_host.detach();
|
||||||
|
|
||||||
group_host_connect_handler_ =
|
group_host_connect_handler_ =
|
||||||
|
|||||||
@@ -304,13 +304,10 @@ std::string create_logger_prefix(const fs::path& endpoint_base_dir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fs::path find_vst_host(const ghc::filesystem::path& this_plugin_path,
|
fs::path find_vst_host(const ghc::filesystem::path& this_plugin_path,
|
||||||
LibArchitecture plugin_arch,
|
LibArchitecture plugin_arch) {
|
||||||
bool use_plugin_groups) {
|
auto host_name = yabridge_host_name;
|
||||||
auto host_name = use_plugin_groups ? yabridge_group_host_name
|
|
||||||
: yabridge_individual_host_name;
|
|
||||||
if (plugin_arch == LibArchitecture::dll_32) {
|
if (plugin_arch == LibArchitecture::dll_32) {
|
||||||
host_name = use_plugin_groups ? yabridge_group_host_name_32bit
|
host_name = yabridge_host_name_32bit;
|
||||||
: yabridge_individual_host_name_32bit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If our `.so` file is a symlink, then search for the host in the directory
|
// If our `.so` file is a symlink, then search for the host in the directory
|
||||||
|
|||||||
+2
-5
@@ -181,7 +181,7 @@ std::string create_logger_prefix(
|
|||||||
const ghc::filesystem::path& endpoint_base_dir);
|
const ghc::filesystem::path& endpoint_base_dir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the Wine VST host (either `yabridge-host.exe` or `yabridge-host.exe`
|
* Finds the Wine VST host (either `yabridge-host.exe` or `yabridge-host-32.exe`
|
||||||
* depending on the plugin). For this we will search in two places:
|
* depending on the plugin). For this we will search in two places:
|
||||||
*
|
*
|
||||||
* 1. Alongside libyabridge-{vst2,vst3}.so if the file got symlinked. This is
|
* 1. Alongside libyabridge-{vst2,vst3}.so if the file got symlinked. This is
|
||||||
@@ -195,16 +195,13 @@ std::string create_logger_prefix(
|
|||||||
* from.
|
* from.
|
||||||
* @param plugin_arch The architecture of the plugin, either 64-bit or 32-bit.
|
* @param plugin_arch The architecture of the plugin, either 64-bit or 32-bit.
|
||||||
* Used to determine which host application to use, if available.
|
* Used to determine which host application to use, if available.
|
||||||
* @param use_plugin_groups Whether the plugin is using plugin groups and we
|
|
||||||
* should be looking for the group host instead of the individual plugin host.
|
|
||||||
*
|
*
|
||||||
* @return The a path to the VST host, if found.
|
* @return The a path to the VST host, if found.
|
||||||
* @throw std::runtime_error If the Wine VST host could not be found.
|
* @throw std::runtime_error If the Wine VST host could not be found.
|
||||||
*/
|
*/
|
||||||
ghc::filesystem::path find_vst_host(
|
ghc::filesystem::path find_vst_host(
|
||||||
const ghc::filesystem::path& this_plugin_path,
|
const ghc::filesystem::path& this_plugin_path,
|
||||||
LibArchitecture plugin_arch,
|
LibArchitecture plugin_arch);
|
||||||
bool use_plugin_groups);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the group socket endpoint name used based on the name of the group,
|
* Generate the group socket endpoint name used based on the name of the group,
|
||||||
|
|||||||
@@ -1,98 +0,0 @@
|
|||||||
// yabridge: a Wine plugin bridge
|
|
||||||
// Copyright (C) 2020-2022 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
// Generated inside of the build directory
|
|
||||||
#include <config.h>
|
|
||||||
#include <version.h>
|
|
||||||
|
|
||||||
#include "../common/utils.h"
|
|
||||||
#include "bridges/group.h"
|
|
||||||
#include "bridges/vst2.h"
|
|
||||||
|
|
||||||
static const std::string host_name = "yabridge group host version " +
|
|
||||||
std::string(yabridge_git_version)
|
|
||||||
#ifdef __i386__
|
|
||||||
+ " (32-bit compatibility mode)"
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This works very similar to the host application defined in
|
|
||||||
* `individual-host.cpp`, but instead of just loading a single plugin this will
|
|
||||||
* act as a daemon that can host multiple 'grouped' plugins. This works by
|
|
||||||
* allowing the `libyabridge-{vst2,vst3}.so` instance to connect this this
|
|
||||||
* process over a socket to ask this process to host a VST `.dll` file using a
|
|
||||||
* provided socket. After that initialization step both the regular individual
|
|
||||||
* plugin host and this group plugin host will function identically on both the
|
|
||||||
* plugin and the Wine VST host side.
|
|
||||||
*/
|
|
||||||
int YABRIDGE_EXPORT
|
|
||||||
#ifdef WINE_USE_CDECL
|
|
||||||
__cdecl
|
|
||||||
#endif
|
|
||||||
main(int argc, char* argv[]) {
|
|
||||||
// Instead of directly hosting a plugin, this process will receive a UNIX
|
|
||||||
// domain socket endpoint path that it should listen on to allow yabridge
|
|
||||||
// instances to spawn plugins in this process.
|
|
||||||
if (argc < 2) {
|
|
||||||
std::cerr << host_name << std::endl;
|
|
||||||
std::cerr << "Usage: "
|
|
||||||
#ifdef __i386__
|
|
||||||
<< yabridge_group_host_name_32bit
|
|
||||||
#else
|
|
||||||
<< yabridge_group_host_name
|
|
||||||
#endif
|
|
||||||
<< " <unix_domain_socket>" << std::endl;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string group_socket_endpoint_path(argv[1]);
|
|
||||||
|
|
||||||
std::cerr << "Initializing " << host_name << std::endl;
|
|
||||||
|
|
||||||
// NOTE: Some plugins use Microsoft COM, but don't initialize it first and
|
|
||||||
// just pray the host does it for them. Examples of this are
|
|
||||||
// PSPaudioware's InfiniStrip and Shattered Glass Audio Code Red Free.
|
|
||||||
OleInitialize(nullptr);
|
|
||||||
|
|
||||||
try {
|
|
||||||
GroupBridge bridge(group_socket_endpoint_path);
|
|
||||||
|
|
||||||
// Blocks the main thread until all plugins have exited
|
|
||||||
bridge.handle_incoming_connections();
|
|
||||||
} catch (const std::system_error& error) {
|
|
||||||
// If another process is already listening on the socket, we'll just
|
|
||||||
// print a message and exit quietly. This could happen if the host
|
|
||||||
// starts multiple yabridge instances that all use the same plugin group
|
|
||||||
// at the same time.
|
|
||||||
// The same error is also used if we could not create a pipe. Since that
|
|
||||||
// error is so rare, we'll just print to STDERR before that happens to
|
|
||||||
// differentiate the two cases.
|
|
||||||
std::cerr << "Another process is already listening on this group's "
|
|
||||||
"socket, connecting to the existing process:"
|
|
||||||
<< std::endl;
|
|
||||||
std::cerr << error.what() << std::endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Like in `individual-host.cpp`, this shouldn't be needed, but sometimes
|
|
||||||
// with Wine background threads will be kept alive while this process exits
|
|
||||||
TerminateProcess(GetCurrentProcess(), 0);
|
|
||||||
}
|
|
||||||
@@ -1,155 +0,0 @@
|
|||||||
// yabridge: a Wine plugin bridge
|
|
||||||
// Copyright (C) 2020-2022 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
// Generated inside of the build directory
|
|
||||||
#include <config.h>
|
|
||||||
#include <version.h>
|
|
||||||
|
|
||||||
#include "../common/utils.h"
|
|
||||||
#include "bridges/vst2.h"
|
|
||||||
#ifdef WITH_VST3
|
|
||||||
#include "bridges/vst3.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const std::string host_name = "yabridge host version " +
|
|
||||||
std::string(yabridge_git_version)
|
|
||||||
#ifdef __i386__
|
|
||||||
+ " (32-bit compatibility mode)"
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the default plugin host application. It will load the specified
|
|
||||||
* plugin plugin, and then connect back to the `libyabridge-{vst2,vst3}.so`
|
|
||||||
* instance that spawned this over the socket.
|
|
||||||
*/
|
|
||||||
int YABRIDGE_EXPORT
|
|
||||||
#ifdef WINE_USE_CDECL
|
|
||||||
__cdecl
|
|
||||||
#endif
|
|
||||||
main(int argc, char* argv[]) {
|
|
||||||
// We pass the plugin format, the name of the VST2 plugin .dll file or VST3
|
|
||||||
// bundle to load, the base directory for the Unix domain socket endpoints
|
|
||||||
// to connect to and the process ID of the process the native plugin is
|
|
||||||
// being hosted in as arguments for yabridge-host.exe
|
|
||||||
if (argc < 5) {
|
|
||||||
std::cerr << host_name << std::endl;
|
|
||||||
std::cerr << "Usage: "
|
|
||||||
#ifdef __i386__
|
|
||||||
<< yabridge_individual_host_name_32bit
|
|
||||||
#else
|
|
||||||
<< yabridge_individual_host_name
|
|
||||||
#endif
|
|
||||||
<< " <plugin_type> <plugin_location> "
|
|
||||||
"<endpoint_base_directory> <parent_pid>"
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string plugin_type_str(argv[1]);
|
|
||||||
const PluginType plugin_type = plugin_type_from_string(plugin_type_str);
|
|
||||||
const std::string plugin_location(argv[2]);
|
|
||||||
const std::string socket_endpoint_path(argv[3]);
|
|
||||||
const pid_t parent_pid = std::stoi(argv[4]);
|
|
||||||
|
|
||||||
std::cerr << "Initializing " << host_name << std::endl;
|
|
||||||
std::cerr << "Preparing to load " << plugin_type_to_string(plugin_type)
|
|
||||||
<< " plugin at '" << plugin_location << "'" << std::endl;
|
|
||||||
|
|
||||||
// NOTE: Some plugins use Microsoft COM, but don't initialize it first and
|
|
||||||
// just pray the host does it for them. Examples of this are
|
|
||||||
// PSPaudioware's InfiniStrip and Shattered Glass Audio Code Red Free.
|
|
||||||
OleInitialize(nullptr);
|
|
||||||
|
|
||||||
// As explained in `Vst2Bridge`, the plugin has to be initialized in the
|
|
||||||
// same thread as the one that calls `io_context.run()`. This setup is
|
|
||||||
// slightly more convoluted than it has to be, but doing it this way we
|
|
||||||
// don't need to differentiate between individually hosted plugins and
|
|
||||||
// plugin groups when it comes to event handling.
|
|
||||||
MainContext main_context{};
|
|
||||||
std::unique_ptr<HostBridge> bridge;
|
|
||||||
try {
|
|
||||||
switch (plugin_type) {
|
|
||||||
case PluginType::vst2:
|
|
||||||
bridge = std::make_unique<Vst2Bridge>(
|
|
||||||
main_context, plugin_location, socket_endpoint_path,
|
|
||||||
parent_pid);
|
|
||||||
break;
|
|
||||||
case PluginType::vst3:
|
|
||||||
#ifdef WITH_VST3
|
|
||||||
bridge = std::make_unique<Vst3Bridge>(
|
|
||||||
main_context, plugin_location, socket_endpoint_path,
|
|
||||||
parent_pid);
|
|
||||||
#else
|
|
||||||
std::cerr << "This version of yabridge has not been compiled "
|
|
||||||
"with VST3 support"
|
|
||||||
<< std::endl;
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case PluginType::unknown:
|
|
||||||
std::cerr << "Unknown plugin type '" << plugin_type_str << "'"
|
|
||||||
<< std::endl;
|
|
||||||
return 1;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
} catch (const std::exception& error) {
|
|
||||||
std::cerr << "Error while initializing the Wine plugin host:"
|
|
||||||
<< std::endl;
|
|
||||||
std::cerr << error.what() << std::endl;
|
|
||||||
|
|
||||||
// See below, just returning from `main()` isn't enough to terminate the
|
|
||||||
// process
|
|
||||||
TerminateProcess(GetCurrentProcess(), 0);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let the plugin receive and handle its events on its own thread. Some
|
|
||||||
// potentially unsafe events that should always be run from the UI thread
|
|
||||||
// will be posted to `main_context`.
|
|
||||||
Win32Thread worker_thread([&]() {
|
|
||||||
pthread_setname_np(pthread_self(), "worker");
|
|
||||||
|
|
||||||
bridge->run();
|
|
||||||
|
|
||||||
// // When the sockets get closed, this application should
|
|
||||||
// // terminate gracefully
|
|
||||||
// main_context.stop();
|
|
||||||
// FIXME: So some of the background threads spawned by the plugin may
|
|
||||||
// get stuck if the host got terminated abruptly. After an entire
|
|
||||||
// day of debugging I still have no idea whether this is a bug in
|
|
||||||
// yabridge, Wine, or those plugins, but just killing off this
|
|
||||||
// process and all of its threads 'fixes' the issue.
|
|
||||||
//
|
|
||||||
// https://github.com/robbert-vdh/yabridge/issues/69
|
|
||||||
TerminateProcess(GetCurrentProcess(), 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
std::cerr << "Finished initializing '" << plugin_location << "'"
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
// Handle Win32 messages and X11 events on a timer, just like in
|
|
||||||
// `GroupBridge::async_handle_events()``
|
|
||||||
main_context.async_handle_events(
|
|
||||||
[&]() { bridge->handle_events(); },
|
|
||||||
[&]() { return !bridge->inhibits_event_loop(); });
|
|
||||||
main_context.run();
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,7 @@
|
|||||||
# The plugin host applications come on four flavours: hosting a single plugin
|
|
||||||
# and hosting multiple plugins within a single process, and 32-bit and 64-bit.
|
|
||||||
# We will compile the shared parts for the individual an plugin group hosts as a
|
|
||||||
# static library first to cut down on compile times.
|
|
||||||
#
|
|
||||||
# As with the libraries, we cannot call `executable()` here since we would like
|
# As with the libraries, we cannot call `executable()` here since we would like
|
||||||
# to keep all relevant files in the root of the build directory, and Meson
|
# to keep all relevant files in the root of the build directory, and Meson
|
||||||
# doesn't have a way to customize that yet.
|
# doesn't have a way to customize that yet.
|
||||||
|
|
||||||
if is_64bit_system
|
if is_64bit_system
|
||||||
host_64bit_deps = [
|
host_64bit_deps = [
|
||||||
configuration_dep,
|
configuration_dep,
|
||||||
@@ -54,7 +50,7 @@ if with_bitbridge
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
host_common_sources = files(
|
host_sources = files(
|
||||||
'../common/communication/vst2.cpp',
|
'../common/communication/vst2.cpp',
|
||||||
'../common/serialization/vst2.cpp',
|
'../common/serialization/vst2.cpp',
|
||||||
'../common/configuration.cpp',
|
'../common/configuration.cpp',
|
||||||
@@ -67,14 +63,16 @@ host_common_sources = files(
|
|||||||
'../common/utils.cpp',
|
'../common/utils.cpp',
|
||||||
'../include/llvm/small-vector.cpp',
|
'../include/llvm/small-vector.cpp',
|
||||||
'bridges/common.cpp',
|
'bridges/common.cpp',
|
||||||
|
'bridges/group.cpp',
|
||||||
'bridges/vst2.cpp',
|
'bridges/vst2.cpp',
|
||||||
'editor.cpp',
|
'editor.cpp',
|
||||||
|
'host.cpp',
|
||||||
'utils.cpp',
|
'utils.cpp',
|
||||||
'xdnd-proxy.cpp',
|
'xdnd-proxy.cpp',
|
||||||
)
|
)
|
||||||
|
|
||||||
if with_vst3
|
if with_vst3
|
||||||
host_common_sources += files(
|
host_sources += files(
|
||||||
'../common/logging/vst3.cpp',
|
'../common/logging/vst3.cpp',
|
||||||
'../common/serialization/vst3/component-handler/component-handler.cpp',
|
'../common/serialization/vst3/component-handler/component-handler.cpp',
|
||||||
'../common/serialization/vst3/component-handler/component-handler-2.cpp',
|
'../common/serialization/vst3/component-handler/component-handler-2.cpp',
|
||||||
@@ -139,48 +137,3 @@ if with_vst3
|
|||||||
'bridges/vst3.cpp',
|
'bridges/vst3.cpp',
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# These will be linked against a static library made from `host_common_sources`
|
|
||||||
individual_host_sources = files(
|
|
||||||
'individual-host.cpp',
|
|
||||||
)
|
|
||||||
group_host_sources = files(
|
|
||||||
'bridges/group.cpp',
|
|
||||||
'group-host.cpp',
|
|
||||||
)
|
|
||||||
|
|
||||||
if is_64bit_system
|
|
||||||
host_common_64bit = static_library(
|
|
||||||
'host_common_64bit',
|
|
||||||
host_common_sources,
|
|
||||||
native : false,
|
|
||||||
include_directories : include_dir,
|
|
||||||
dependencies : host_64bit_deps,
|
|
||||||
cpp_args : compiler_options + wine_64bit_compiler_options,
|
|
||||||
link_args : ['-m64'],
|
|
||||||
)
|
|
||||||
host_common_64bit_dep = declare_dependency(
|
|
||||||
link_with : host_common_64bit,
|
|
||||||
include_directories : include_dir,
|
|
||||||
dependencies : host_64bit_deps,
|
|
||||||
compile_args : compiler_options + wine_64bit_compiler_options,
|
|
||||||
)
|
|
||||||
endif
|
|
||||||
|
|
||||||
if with_bitbridge
|
|
||||||
host_common_32bit = static_library(
|
|
||||||
'host_common_32bit',
|
|
||||||
host_common_sources,
|
|
||||||
native : false,
|
|
||||||
include_directories : include_dir,
|
|
||||||
dependencies : host_32bit_deps,
|
|
||||||
cpp_args : compiler_options + wine_32bit_compiler_options,
|
|
||||||
link_args : ['-m32'],
|
|
||||||
)
|
|
||||||
host_common_32bit_dep = declare_dependency(
|
|
||||||
link_with : host_common_32bit,
|
|
||||||
include_directories : include_dir,
|
|
||||||
dependencies : host_32bit_deps,
|
|
||||||
compile_args : compiler_options + wine_32bit_compiler_options,
|
|
||||||
)
|
|
||||||
endif
|
|
||||||
|
|||||||
Reference in New Issue
Block a user