mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-08 12:30:12 +02:00
Replace Boost.Process for the Wine plugin host
Now we use our own library for this, so we can drop the Boost.Filesystem dependency after a couple more changes.
This commit is contained in:
+91
-45
@@ -17,24 +17,72 @@
|
||||
#include "host-process.h"
|
||||
|
||||
#include <asio/read_until.hpp>
|
||||
#include <boost/process/env.hpp>
|
||||
#include <boost/process/start_dir.hpp>
|
||||
|
||||
#include "../common/utils.h"
|
||||
|
||||
namespace bp = boost::process;
|
||||
namespace fs = ghc::filesystem;
|
||||
|
||||
HostProcess::HostProcess(asio::io_context& io_context,
|
||||
Logger& logger,
|
||||
const Configuration& config,
|
||||
Sockets& sockets)
|
||||
: stdout_pipe_(io_context),
|
||||
stderr_pipe_(io_context),
|
||||
config_(config),
|
||||
sockets_(sockets),
|
||||
logger_(logger) {
|
||||
// See the comment above the `on_exec_setup` in `launch_host()`
|
||||
HostProcess::HostProcess(asio::io_context& io_context, Sockets& sockets)
|
||||
: sockets_(sockets), stdout_pipe_(io_context), stderr_pipe_(io_context) {}
|
||||
|
||||
HostProcess::~HostProcess() noexcept {}
|
||||
|
||||
Process::Handle HostProcess::launch_host(
|
||||
const ghc::filesystem::path& host_path,
|
||||
std::initializer_list<std::string> args,
|
||||
Logger& logger,
|
||||
const Configuration& config,
|
||||
const PluginInfo& plugin_info) {
|
||||
#ifdef WITH_WINEDBG
|
||||
// This is set up for KDE Plasma. Other desktop environments and window
|
||||
// managers require some slight modifications to spawn a detached terminal
|
||||
// emulator. Alternatively, you can spawn `winedbg` with the `--no-start`
|
||||
// option to launch a gdb server and then connect to it from another
|
||||
// terminal.
|
||||
Process child("kstart5");
|
||||
child.arg("konsole").arg("--").arg("-e").arg("winedbg").arg("--gdb");
|
||||
#ifdef WINEDBG_LEGACY_ARGUMENT_QUOTING
|
||||
// Note the double quoting here. Old versions of winedbg didn't
|
||||
// respect `argv` and instead expected a pre-quoted Win32 command
|
||||
// line as its arguments.
|
||||
child.arg("\"" + host_path.string() + ".so\""),
|
||||
#else
|
||||
child.arg(host_path.string() + ".so");
|
||||
#endif // WINEDBG_LEGACY_ARGUMENT_QUOTING
|
||||
#else
|
||||
Process child(host_path);
|
||||
#endif // WITH_WINEDBG
|
||||
|
||||
// What's up with this indentation
|
||||
for (const auto& arg : args) {
|
||||
child.arg(arg);
|
||||
}
|
||||
|
||||
child.environment(plugin_info.create_host_env());
|
||||
Process::Handle child_handle = std::visit(
|
||||
overload{
|
||||
[](Process::Handle handle) -> Process::Handle { return handle; },
|
||||
[&host_path](const Process::CommandNotFound&) -> Process::Handle {
|
||||
throw std::runtime_error("Could not launch '" +
|
||||
host_path.string() +
|
||||
"', command not found");
|
||||
},
|
||||
[](const std::error_code& err) -> Process::Handle {
|
||||
throw std::runtime_error("Error spawning Wine process: " +
|
||||
err.message());
|
||||
},
|
||||
},
|
||||
// HACK: If the `disable_pipes` option is enabled, then we'll redirect
|
||||
// the plugin's output to a file instead of using pipes to blend
|
||||
// it in with the rest of yabridge's output. This is for some
|
||||
// reason necessary for ujam's plugins and all other plugins made
|
||||
// with Gorilla Engine to function. Otherwise they'll print a
|
||||
// nondescriptive `JS_EXEC_FAILED` error message.
|
||||
config.disable_pipes
|
||||
? child.spawn_child_redirected(*config.disable_pipes)
|
||||
: child.spawn_child_piped(stdout_pipe_, stderr_pipe_));
|
||||
|
||||
// See the above comment
|
||||
if (config.disable_pipes) {
|
||||
logger.log("");
|
||||
logger.log("WARNING: All Wine output will be written to");
|
||||
@@ -49,9 +97,9 @@ HostProcess::HostProcess(asio::io_context& io_context,
|
||||
logger.async_log_pipe_lines(stderr_pipe_, stderr_buffer_,
|
||||
"[Wine STDERR] ");
|
||||
}
|
||||
}
|
||||
|
||||
HostProcess::~HostProcess() noexcept {}
|
||||
return child_handle;
|
||||
}
|
||||
|
||||
IndividualHost::IndividualHost(asio::io_context& io_context,
|
||||
Logger& logger,
|
||||
@@ -59,28 +107,32 @@ IndividualHost::IndividualHost(asio::io_context& io_context,
|
||||
Sockets& sockets,
|
||||
const PluginInfo& plugin_info,
|
||||
const HostRequest& host_request)
|
||||
: HostProcess(io_context, logger, config, sockets),
|
||||
: HostProcess(io_context, sockets),
|
||||
plugin_info_(plugin_info),
|
||||
host_path_(find_vst_host(plugin_info.native_library_path_,
|
||||
plugin_info.plugin_arch_,
|
||||
false)),
|
||||
host_(
|
||||
launch_host(host_path_,
|
||||
plugin_type_to_string(host_request.plugin_type),
|
||||
handle_(launch_host(
|
||||
host_path_,
|
||||
{
|
||||
plugin_type_to_string(host_request.plugin_type),
|
||||
#if defined(WITH_WINEDBG) && defined(WINEDBG_LEGACY_ARGUMENT_QUOTING)
|
||||
// Old versions of winedbg flattened all command line
|
||||
// arguments to a single space separated Win32 command
|
||||
// line, so we had to do our own quoting
|
||||
"\"" + plugin_info.windows_plugin_path + "\"",
|
||||
// Old versions of winedbg flattened all command line
|
||||
// arguments to a single space separated Win32 command line,
|
||||
// so we had to do our own quoting
|
||||
"\"" + plugin_info.windows_plugin_path + "\"",
|
||||
#else
|
||||
host_request.plugin_path,
|
||||
host_request.plugin_path,
|
||||
#endif
|
||||
host_request.endpoint_base_dir,
|
||||
// We pass this process' process ID as an argument so we
|
||||
// can run a watchdog on the Wine plugin host process that
|
||||
// shuts down the sockets after this process shuts down
|
||||
std::to_string(getpid()),
|
||||
bp::env = plugin_info.create_host_env())) {
|
||||
host_request.endpoint_base_dir,
|
||||
// We pass this process' process ID as an argument so we can
|
||||
// run a watchdog on the Wine plugin host process that shuts
|
||||
// down the sockets after this process shuts down
|
||||
std::to_string(getpid())
|
||||
},
|
||||
logger,
|
||||
config,
|
||||
plugin_info)) {
|
||||
#ifdef WITH_WINEDBG
|
||||
if (plugin_info.windows_plugin_path_.string().find('"') !=
|
||||
std::string::npos) {
|
||||
@@ -96,9 +148,7 @@ fs::path IndividualHost::path() {
|
||||
}
|
||||
|
||||
bool IndividualHost::running() {
|
||||
// NOTE: `boost::process::child::running()` still considers zombies as
|
||||
// running, so it's useless for our purposes.
|
||||
return pid_running(host_.id());
|
||||
return handle_.running();
|
||||
}
|
||||
|
||||
void IndividualHost::terminate() {
|
||||
@@ -109,10 +159,8 @@ void IndividualHost::terminate() {
|
||||
// prevents us from joining our `std::jthread`s on the plugin side.
|
||||
sockets_.close();
|
||||
|
||||
host_.terminate();
|
||||
// NOTE: This leaves a zombie, because Boost.Process will actually not call
|
||||
// `wait()` after we have terminated the process.
|
||||
host_.wait();
|
||||
// This will also reap the terminated process
|
||||
handle_.terminate();
|
||||
}
|
||||
|
||||
GroupHost::GroupHost(asio::io_context& io_context,
|
||||
@@ -121,7 +169,7 @@ GroupHost::GroupHost(asio::io_context& io_context,
|
||||
Sockets& sockets,
|
||||
const PluginInfo& plugin_info,
|
||||
const HostRequest& host_request)
|
||||
: HostProcess(io_context, logger, config, sockets),
|
||||
: HostProcess(io_context, sockets),
|
||||
plugin_info_(plugin_info),
|
||||
host_path_(find_vst_host(plugin_info.native_library_path_,
|
||||
plugin_info.plugin_arch_,
|
||||
@@ -156,15 +204,13 @@ GroupHost::GroupHost(asio::io_context& io_context,
|
||||
// new group host process. This process is detached immediately
|
||||
// because it should run independently of this yabridge instance as
|
||||
// it will likely outlive it.
|
||||
bp::child group_host =
|
||||
// FIXME: Boost.Filesystem conversion
|
||||
launch_host(host_path_, group_socket_path.string(),
|
||||
bp::env = plugin_info.create_host_env());
|
||||
Process::Handle group_host =
|
||||
launch_host(host_path_, {group_socket_path.string()}, logger,
|
||||
config, plugin_info);
|
||||
group_host.detach();
|
||||
|
||||
const pid_t group_host_pid = group_host.id();
|
||||
group_host_connect_handler_ =
|
||||
std::jthread([this, connect, group_host_pid]() {
|
||||
std::jthread([this, connect, group_host = std::move(group_host)]() {
|
||||
set_realtime_priority(true);
|
||||
pthread_setname_np(pthread_self(), "group-connect");
|
||||
|
||||
@@ -172,7 +218,7 @@ GroupHost::GroupHost(asio::io_context& io_context,
|
||||
|
||||
// We'll first try to connect to the group host we just spawned
|
||||
// TODO: Replace this polling with inotify
|
||||
while (pid_running(group_host_pid)) {
|
||||
while (group_host.running()) {
|
||||
std::this_thread::sleep_for(20ms);
|
||||
|
||||
try {
|
||||
|
||||
+34
-98
@@ -19,10 +19,8 @@
|
||||
#include <thread>
|
||||
|
||||
#include <asio/local/stream_protocol.hpp>
|
||||
#include <asio/posix/stream_descriptor.hpp>
|
||||
#include <asio/streambuf.hpp>
|
||||
#include <boost/process/child.hpp>
|
||||
#include <boost/process/extend.hpp>
|
||||
#include <boost/process/io.hpp>
|
||||
#include <ghc/filesystem.hpp>
|
||||
|
||||
#include "../common/communication/common.h"
|
||||
@@ -59,108 +57,42 @@ class HostProcess {
|
||||
*/
|
||||
virtual void terminate() = 0;
|
||||
|
||||
/**
|
||||
* Simple helper function around `boost::process::child` that launches the
|
||||
* host application (`*.exe`) with some basic setup. This includes setting
|
||||
* up the asynchronous pipes for STDIO redirection, closing file descriptors
|
||||
* to prevent leaks, and wrapping everything in winedbg if we're compiling
|
||||
* with `-Dwith-winedbg=true`. Keep in mind that winedbg does not handle
|
||||
* arguments containing spaces, so most Windows paths will be split up into
|
||||
* multiple arugments.
|
||||
*/
|
||||
template <typename... Args>
|
||||
boost::process::child launch_host(ghc::filesystem::path host_path,
|
||||
Args&&... args) {
|
||||
return boost::process::child(
|
||||
#ifdef WITH_WINEDBG
|
||||
// This is set up for KDE Plasma. Other desktop environments and
|
||||
// window managers require some slight modifications to spawn a
|
||||
// detached terminal emulator. Alternatively, you can spawn
|
||||
// `/usr/bin/winedbg` with the `--no-start` option to launch a gdb
|
||||
// server and then connect to it from another terminal.
|
||||
"/usr/bin/kstart5", "konsole", "--", "-e", "winedbg", "--gdb",
|
||||
#ifdef WINEDBG_LEGACY_ARGUMENT_QUOTING
|
||||
// Note the double quoting here. Old versions of winedbg didn't
|
||||
// respect `argv` and instead expected a pre-quoted Win32 command
|
||||
// line as its arguments.
|
||||
"\"" + host_path.string() + ".so\"",
|
||||
#else
|
||||
host_path.string() + ".so",
|
||||
#endif // WINEDBG_LEGACY_ARGUMENT_QUOTING
|
||||
#else
|
||||
// FIXME: Replace Boost.Filesystem
|
||||
host_path.string(),
|
||||
#endif // WITH_WINEDBG
|
||||
// FIXME: This won't work with our patched async_pipe version
|
||||
// boost::process::std_out = stdout_pipe_,
|
||||
// boost::process::std_err = stderr_pipe_,
|
||||
patched_async_pipe_out<1, -1>(stdout_pipe_),
|
||||
patched_async_pipe_out<2, -1>(stderr_pipe_),
|
||||
// NOTE: If the Wine process outlives the host, then it may cause
|
||||
// issues if our process is still keeping the host's file
|
||||
// descriptors alive that. This can prevent Ardour from
|
||||
// restarting after an unexpected shutdown. Because of this we
|
||||
// won't use `vfork()`, but instead we'll just manually close
|
||||
// all non-STDIO file descriptors.
|
||||
// HACK: If the `disable_pipes` option is enabled, then we'll
|
||||
// redirect the plugin's output to a file instead of using
|
||||
// pipes to blend it in with the rest of yabridge's output.
|
||||
// This is for some reason necessary for ujam's plugins and
|
||||
// all other plugins made with Gorilla Engine to function.
|
||||
// Otherwise they'll print a nondescriptive `JS_EXEC_FAILED`
|
||||
// error message.
|
||||
boost::process::extend::on_exec_setup =
|
||||
[this](auto& /*executor*/) {
|
||||
const int max_fds = static_cast<int>(sysconf(_SC_OPEN_MAX));
|
||||
for (int fd = STDERR_FILENO + 1; fd < max_fds; fd++) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
// See above
|
||||
if (config_.disable_pipes) {
|
||||
const int redirect_fd =
|
||||
open(config_.disable_pipes->c_str(),
|
||||
O_CREAT | O_APPEND | O_WRONLY, 0640);
|
||||
|
||||
assert(redirect_fd != -1);
|
||||
dup2(redirect_fd, STDOUT_FILENO);
|
||||
dup2(redirect_fd, STDERR_FILENO);
|
||||
close(redirect_fd);
|
||||
}
|
||||
},
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Initialize the host process by setting up the STDIO redirection.
|
||||
* The actual process initialization and everything involved in that process
|
||||
* is done in `launch_host()` since a new process may not be required
|
||||
* when using plugin groups.
|
||||
*
|
||||
* @param io_context The IO context that the STDIO redurection will be
|
||||
* handled on.
|
||||
* @param logger The `Logger` instance the redirected STDIO streams will be
|
||||
* written to.
|
||||
* @param io_context The IO context that the STDIO redirection pipes will be
|
||||
* bound to. The logging for these pipes is set up in `launch_host()`.
|
||||
* @param sockets The socket endpoints that will be used for communication
|
||||
* with the plugin. When the plugin shuts down, we'll close all of the
|
||||
* sockets used by the plugin.
|
||||
*/
|
||||
HostProcess(asio::io_context& io_context,
|
||||
Logger& logger,
|
||||
const Configuration& config,
|
||||
Sockets& sockets);
|
||||
HostProcess(asio::io_context& io_context, Sockets& sockets);
|
||||
|
||||
/**
|
||||
* The STDOUT stream of the Wine process we can forward to the logger.
|
||||
* Helper function that launches the Wine host application (`*.exe`) with
|
||||
* all of the correct environment setup. This includes setting the correct
|
||||
* environment variables for the Wine prefix the plugin is in, setting up
|
||||
* pipes or files for STDIO redirection, closing file descriptors to prevent
|
||||
* leaks, and wrapping all of that in a terminal process running winedbg if
|
||||
* we're compiling with `-Dwith-winedbg=true`. Keep in mind that winedbg
|
||||
* does not handle arguments containing spaces, so most Windows paths will
|
||||
* be split up into multiple arguments.
|
||||
*
|
||||
* @param logger The `Logger` instance the redirected STDIO streams will be
|
||||
* written to.
|
||||
* @param config The plugin's configuration, used to determine whether to
|
||||
* use pipes or to redirect the output to a file instead.
|
||||
* @param plugin_info Information about the plugin, used to determine the
|
||||
* plugin's Wine prefix.
|
||||
*/
|
||||
patched_async_pipe stdout_pipe_;
|
||||
/**
|
||||
* The STDERR stream of the Wine process we can forward to the logger.
|
||||
*/
|
||||
patched_async_pipe stderr_pipe_;
|
||||
|
||||
/**
|
||||
* The current plugin instance's configuration.
|
||||
*/
|
||||
const Configuration& config_;
|
||||
Process::Handle launch_host(const ghc::filesystem::path& host_path,
|
||||
std::initializer_list<std::string> args,
|
||||
Logger& logger,
|
||||
const Configuration& config,
|
||||
const PluginInfo& plugin_info);
|
||||
|
||||
/**
|
||||
* The associated sockets for the plugin we're hosting. This is used to
|
||||
@@ -170,9 +102,13 @@ class HostProcess {
|
||||
|
||||
private:
|
||||
/**
|
||||
* The logger the Wine output will be written to.
|
||||
* The STDOUT stream of the Wine process we can forward to the logger.
|
||||
*/
|
||||
Logger& logger_;
|
||||
asio::posix::stream_descriptor stdout_pipe_;
|
||||
/**
|
||||
* The STDERR stream of the Wine process we can forward to the logger.
|
||||
*/
|
||||
asio::posix::stream_descriptor stderr_pipe_;
|
||||
|
||||
asio::streambuf stdout_buffer_;
|
||||
asio::streambuf stderr_buffer_;
|
||||
@@ -218,7 +154,7 @@ class IndividualHost : public HostProcess {
|
||||
private:
|
||||
const PluginInfo& plugin_info_;
|
||||
ghc::filesystem::path host_path_;
|
||||
boost::process::child host_;
|
||||
Process::Handle handle_;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+20
-46
@@ -20,23 +20,14 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include <boost/dll/runtime_symbol_info.hpp>
|
||||
#include <boost/process/io.hpp>
|
||||
#include <boost/process/pipe.hpp>
|
||||
#include <boost/process/search_path.hpp>
|
||||
#include <boost/process/system.hpp>
|
||||
#include <sstream>
|
||||
|
||||
// XXX: With Boost 1.75 at least, this header cannot be included in alphabetical
|
||||
// order because it's missing some includes
|
||||
#include <boost/process/env.hpp>
|
||||
|
||||
// Generated inside of the build directory
|
||||
#include <config.h>
|
||||
|
||||
#include "../common/configuration.h"
|
||||
#include "../common/utils.h"
|
||||
|
||||
namespace bp = boost::process;
|
||||
namespace fs = ghc::filesystem;
|
||||
|
||||
// These functions are used to populate the fields in `PluginInfo`. See the
|
||||
@@ -65,25 +56,7 @@ PluginInfo::PluginInfo(PluginType plugin_type, bool prefer_32bit_vst3)
|
||||
normalize_plugin_path(windows_library_path_, plugin_type)),
|
||||
wine_prefix_(find_wine_prefix(windows_plugin_path_)) {}
|
||||
|
||||
bp::environment PluginInfo::create_host_env() const {
|
||||
bp::environment env = boost::this_process::environment();
|
||||
|
||||
// Only set the prefix when could auto detect it and it's not being
|
||||
// overridden (this entire `std::visit` instead of `std::has_alternative` is
|
||||
// just for clarity's sake)
|
||||
std::visit(overload{
|
||||
[](const OverridenWinePrefix&) {},
|
||||
[&](const ghc::filesystem::path& prefix) {
|
||||
env["WINEPREFIX"] = prefix.string();
|
||||
},
|
||||
[](const DefaultWinePrefix&) {},
|
||||
},
|
||||
wine_prefix_);
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
ProcessEnvironment PluginInfo::create_host_env_2() const {
|
||||
ProcessEnvironment PluginInfo::create_host_env() const {
|
||||
ProcessEnvironment env(environ);
|
||||
|
||||
// Only set the prefix when could auto detect it and it's not being
|
||||
@@ -130,7 +103,7 @@ std::string PluginInfo::wine_version() const {
|
||||
|
||||
Process process(wine_path);
|
||||
process.arg("--version");
|
||||
process.environment(create_host_env_2());
|
||||
process.environment(create_host_env());
|
||||
|
||||
const auto result = process.spawn_get_stdout_line();
|
||||
return std::visit(
|
||||
@@ -345,7 +318,6 @@ std::string create_logger_prefix(const fs::path& endpoint_base_dir) {
|
||||
fs::path find_vst_host(const ghc::filesystem::path& this_plugin_path,
|
||||
LibArchitecture plugin_arch,
|
||||
bool use_plugin_groups) {
|
||||
// FIXME: Anything using `this_plugin_path` and similar needs to be changed
|
||||
auto host_name = use_plugin_groups ? yabridge_group_host_name
|
||||
: yabridge_individual_host_name;
|
||||
if (plugin_arch == LibArchitecture::dll_32) {
|
||||
@@ -361,17 +333,13 @@ fs::path find_vst_host(const ghc::filesystem::path& this_plugin_path,
|
||||
return host_path;
|
||||
}
|
||||
|
||||
// Boost will return an empty path if the file could not be found in the
|
||||
// search path
|
||||
const boost::filesystem::path vst_host_path =
|
||||
bp::search_path(host_name, get_augmented_search_path());
|
||||
if (vst_host_path == "") {
|
||||
if (const std::optional<fs::path> vst_host_path =
|
||||
search_in_path(get_augmented_search_path(), host_name)) {
|
||||
return *vst_host_path;
|
||||
} else {
|
||||
throw std::runtime_error("Could not locate '" + std::string(host_name) +
|
||||
"'");
|
||||
}
|
||||
|
||||
// FIXME: Replace Boost.Filesystem usage requiring this conversion
|
||||
return vst_host_path.string();
|
||||
}
|
||||
|
||||
ghc::filesystem::path generate_group_endpoint(
|
||||
@@ -396,8 +364,7 @@ ghc::filesystem::path generate_group_endpoint(
|
||||
return get_temporary_directory() / socket_name.str();
|
||||
}
|
||||
|
||||
// FIXME: Replace Boost.Filesystem
|
||||
std::vector<boost::filesystem::path> get_augmented_search_path() {
|
||||
std::vector<fs::path> get_augmented_search_path() {
|
||||
// HACK: `std::locale("")` would return the current locale, but this
|
||||
// overload is implementation specific, and libstdc++ returns an error
|
||||
// when this happens and one of the locale variables (or `LANG`) is
|
||||
@@ -411,6 +378,11 @@ std::vector<boost::filesystem::path> get_augmented_search_path() {
|
||||
// https://svn.boost.org/trac10/changeset/72855
|
||||
//
|
||||
// https://github.com/boostorg/process/pull/179
|
||||
// FIXME: As mentioned above, we did this in the past to work around a
|
||||
// Boost.Process bug. Since we no longer use Boost.Process, we can
|
||||
// technically get rid of this, but we could also leave it in place
|
||||
// since this may still cause other crashes for the user if we don't
|
||||
// do it.
|
||||
try {
|
||||
std::locale("");
|
||||
} catch (const std::runtime_error&) {
|
||||
@@ -431,17 +403,19 @@ std::vector<boost::filesystem::path> get_augmented_search_path() {
|
||||
setenv("LC_ALL", "C", true); // NOLINT(concurrency-mt-unsafe)
|
||||
}
|
||||
|
||||
std::vector<boost::filesystem::path> search_path =
|
||||
boost::this_process::path();
|
||||
// NOLINTNEXTLINE(concurrency-mt-unsafe)
|
||||
const char* path_env = getenv("PATH");
|
||||
assert(path_env);
|
||||
|
||||
std::vector<fs::path> search_path = split_path(path_env);
|
||||
|
||||
// NOLINTNEXTLINE(concurrency-mt-unsafe)
|
||||
if (const char* xdg_data_home = getenv("XDG_DATA_HOME")) {
|
||||
search_path.push_back(boost::filesystem::path(xdg_data_home) /
|
||||
"yabridge");
|
||||
search_path.push_back(fs::path(xdg_data_home) / "yabridge");
|
||||
// NOLINTNEXTLINE(concurrency-mt-unsafe)
|
||||
} else if (const char* home_directory = getenv("HOME")) {
|
||||
search_path.push_back(boost::filesystem::path(home_directory) /
|
||||
".local" / "share" / "yabridge");
|
||||
search_path.push_back(fs::path(home_directory) / ".local" / "share" /
|
||||
"yabridge");
|
||||
}
|
||||
|
||||
return search_path;
|
||||
|
||||
+2
-8
@@ -18,8 +18,6 @@
|
||||
|
||||
#include <variant>
|
||||
|
||||
#include <boost/process/environment.hpp>
|
||||
|
||||
#include "../common/configuration.h"
|
||||
#include "../common/plugins.h"
|
||||
#include "../common/process.h"
|
||||
@@ -76,9 +74,7 @@ struct PluginInfo {
|
||||
* we'll set `WINEPREFIX` to the detected Wine prefix, or it will be left
|
||||
* unset if we could not detect a prefix.
|
||||
*/
|
||||
boost::process::environment create_host_env() const;
|
||||
// FIXME: Replace create_host_env with this one
|
||||
ProcessEnvironment create_host_env_2() const;
|
||||
ProcessEnvironment create_host_env() const;
|
||||
|
||||
/**
|
||||
* Return the path to the actual Wine prefix in use, taking into account
|
||||
@@ -236,10 +232,8 @@ ghc::filesystem::path generate_group_endpoint(
|
||||
* 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.
|
||||
*
|
||||
* FIXME: Replace Boost.Filesystem
|
||||
*/
|
||||
std::vector<boost::filesystem::path> get_augmented_search_path();
|
||||
std::vector<ghc::filesystem::path> get_augmented_search_path();
|
||||
|
||||
/**
|
||||
* Return a path to this `.so` file. This can be used to find out from where
|
||||
|
||||
Reference in New Issue
Block a user