diff --git a/src/common/linking.cpp b/src/common/linking.cpp
new file mode 100644
index 00000000..a70f3163
--- /dev/null
+++ b/src/common/linking.cpp
@@ -0,0 +1,58 @@
+// yabridge: a Wine VST 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 .
+
+#include "linking.h"
+
+#include
+
+#include
+
+std::string get_this_file_location() {
+ // We'll try to find the library this function was defined in. When called
+ // from a copy of `libyabridge-*.so` this will return that library. Because
+ // the chainloader libraries load the plugin libraries from fixed locations,
+ // the plugin libraries cannot use this function directly when using the
+ // chainloaders.
+
+ // On success this returns a non-zero value, just to keep you on your toes
+ Dl_info info;
+ assert(dladdr(reinterpret_cast(get_this_file_location), &info) != 0);
+ assert(info.dli_fname);
+
+ std::string this_file(info.dli_fname);
+
+ // HACK: Not sure why, but `boost::dll::this_line_location()` used to return
+ // a path starting with a double slash on some systems. I've seen this
+ // happen on both Ubuntu 18.04 and 20.04, but not on Arch based
+ // distros. Under Linux a path starting with two slashes is treated
+ // the same as a path starting with only a single slash, but Wine will
+ // refuse to load any files when the path starts with two slashes. The
+ // easiest way to work around this if this happens is to just add
+ // another leading slash and then normalize the path, since three or
+ // more slashes will be coerced into a single slash. We no longer use
+ // Boost.Dll, but unless this was an obscure Boost.Filesystem bug it
+ // sounds more likely that it was caused by some `ld.so` setting.
+ // Unless we can really figure out what was causing this, it seems
+ // best to still account for it
+ if (this_file.starts_with("//")) {
+ const size_t path_start_pos = this_file.find_first_not_of('/');
+ if (path_start_pos != std::string::npos) {
+ this_file = "/" + this_file.substr(path_start_pos);
+ }
+ }
+
+ return this_file;
+}
diff --git a/src/common/linking.h b/src/common/linking.h
new file mode 100644
index 00000000..0eb595a1
--- /dev/null
+++ b/src/common/linking.h
@@ -0,0 +1,32 @@
+// yabridge: a Wine VST 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 .
+
+#pragma once
+
+// This header is completely standalone so the chainloading libraries can
+// retrieve their file path without pulling in a lot of additional dependencies
+
+#include
+
+/**
+ * Return a path to this `.so` file. This can be used to find out from where
+ * this copy of `libyabridge-{vst2,vst3}.so` or `libyabridge-chainloader-*.so`
+ * was loaded so we can search for a matching Windows plugin library. When the
+ * chainloaders are used, this path should be passed to the chainloaded plugin
+ * library using the provided exported functions since they can't detect the
+ * path themselves.
+ */
+std::string get_this_file_location();
diff --git a/src/plugin/bridges/common.h b/src/plugin/bridges/common.h
index b771f0a4..640a5177 100644
--- a/src/plugin/bridges/common.h
+++ b/src/plugin/bridges/common.h
@@ -29,6 +29,9 @@
#include "../../common/utils.h"
#include "../host-process.h"
+// FIXME: This should be passed as an argument instead
+#include "../../common/linking.h"
+
/**
* If the amount of lockable memory is below this, then we'll warn about it
* during startup. Otherwise we may run into issues when mapping shared memory
@@ -73,9 +76,8 @@ class PluginBridge {
* @throw std::runtime_error Thrown when the Wine plugin host could not be
* found, or if it could not locate and load a VST3 module.
*/
- template F>
+ template <
+ invocable_returning F>
PluginBridge(PluginType plugin_type, F&& create_socket_instance)
// This is still correct for VST3 plugins because we can configure an
// entire directory (the module's bundle) at once
diff --git a/src/plugin/meson.build b/src/plugin/meson.build
index b582ee28..287ae11a 100644
--- a/src/plugin/meson.build
+++ b/src/plugin/meson.build
@@ -9,6 +9,7 @@ vst2_plugin_sources = files(
'../common/logging/common.cpp',
'../common/logging/vst2.cpp',
'../common/audio-shm.cpp',
+ '../common/linking.cpp',
'../common/plugins.cpp',
'../common/process.cpp',
'../common/utils.cpp',
@@ -80,6 +81,7 @@ vst3_plugin_sources = files(
'../common/serialization/vst3/process-data.cpp',
'../common/audio-shm.cpp',
'../common/configuration.cpp',
+ '../common/linking.cpp',
'../common/plugins.cpp',
'../common/process.cpp',
'../common/utils.cpp',
diff --git a/src/plugin/utils.cpp b/src/plugin/utils.cpp
index af4a6ec5..087f3822 100644
--- a/src/plugin/utils.cpp
+++ b/src/plugin/utils.cpp
@@ -19,7 +19,6 @@
#include
#include
-#include
#include
// Generated inside of the build directory
@@ -28,6 +27,9 @@
#include "../common/configuration.h"
#include "../common/utils.h"
+// FIXME: This should be passed as an argument instead
+#include "../common/linking.h"
+
namespace fs = ghc::filesystem;
// These functions are used to populate the fields in `PluginInfo`. See the
@@ -271,25 +273,6 @@ std::variant find_wine_prefix(
return dosdevices_dir->parent_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
- // on both Ubuntu 18.04 and 20.04, but not on Arch based distros.
- // Under Linux a path starting with two slashes is treated the same as
- // a path starting with only a single slash, but Wine will refuse to
- // load any files when the path starts with two slashes. The easiest
- // way to work around this if this happens is to just add another
- // leading slash and then normalize the path, since three or more
- // slashes will be coerced into a single slash.
- // FIXME: Replace Boost.Filesystem usage
- fs::path this_file = boost::dll::this_line_location().string();
- if (this_file.string().starts_with("//")) {
- this_file = ("/" / this_file).lexically_normal();
- }
-
- return this_file;
-}
-
bool equals_case_insensitive(const std::string& a, const std::string& b) {
return std::equal(a.begin(), a.end(), b.begin(),
[](const char& a_char, const char& b_char) {
diff --git a/src/plugin/utils.h b/src/plugin/utils.h
index ea2c9630..34f1f189 100644
--- a/src/plugin/utils.h
+++ b/src/plugin/utils.h
@@ -235,12 +235,6 @@ ghc::filesystem::path generate_group_endpoint(
*/
std::vector get_augmented_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-{vst2,vst3}.so` was loaded.
- */
-ghc::filesystem::path get_this_file_location();
-
/**
* Load the configuration that belongs to a copy of or symlink to
* `libyabridge-{vst2,vst3}.so`. If no configuration file could be found then