diff --git a/meson.build b/meson.build index 5d4741b4..99281fa0 100644 --- a/meson.build +++ b/meson.build @@ -46,8 +46,10 @@ compiler_options = [ '-fvisibility-inlines-hidden', # Disable the use of concepts in Boost.Asio until Boost 1.73 gets released # https://github.com/boostorg/asio/issues/312 + # TODO: Rename after switching to non-Boost ASIO '-DBOOST_ASIO_DISABLE_CONCEPTS', # Boost.Process's auto detection for vfork() support doesn't seem to work + # TODO: Remove after adding our own library '-DBOOST_POSIX_HAS_VFORK=1', # We use an intrinsic to force flush-to-zero. SSE2 is always enabled in x86_64 # CPUs, but when we're compiling the 32-bit bitbridge we need to manually add @@ -242,6 +244,7 @@ else bitsery_dep = dependency('bitsery', version : '>=5.2.0') endif function2_dep = dependency('function2', version : '>=4.0.0') +ghc_filesystem_dep = dependency('ghc_filesystem', version : '>=1.5.0') threads_dep = dependency('threads') tomlplusplus_dep = dependency('tomlplusplus', version : '>=2.0.0') @@ -298,6 +301,7 @@ shared_library( : boost_filesystem_64bit_dep, bitsery_dep, dl_dep, + ghc_filesystem_dep, rt_dep, threads_dep, tomlplusplus_dep, @@ -323,6 +327,7 @@ if with_vst3 bitsery_dep, dl_dep, function2_dep, + ghc_filesystem_dep, rt_dep, threads_dep, tomlplusplus_dep, diff --git a/src/common/bitsery/ext/boost-path.h b/src/common/bitsery/ext/ghc-path.h similarity index 79% rename from src/common/bitsery/ext/boost-path.h rename to src/common/bitsery/ext/ghc-path.h index d96e2c57..7cf6db55 100644 --- a/src/common/bitsery/ext/boost-path.h +++ b/src/common/bitsery/ext/ghc-path.h @@ -16,10 +16,7 @@ #pragma once -#ifdef __WINE__ -#include "../wine-host/boost-fix.h" -#endif -#include +#include #include #include @@ -31,17 +28,17 @@ namespace ext { * An adapter for serializing and deserializing filesystem paths since they're * not mutable. */ -class BoostPath { +class GhcPath { public: template - void serialize(Ser& ser, const boost::filesystem::path& path, Fnc&&) const { + void serialize(Ser& ser, const ghc::filesystem::path& path, Fnc&&) const { auto path_str = path.string(); ser.text1b(path_str, 4096); } template - void deserialize(Des& des, boost::filesystem::path& path, Fnc&&) const { - boost::filesystem::path::string_type path_str{}; + void deserialize(Des& des, ghc::filesystem::path& path, Fnc&&) const { + ghc::filesystem::path::string_type path_str{}; des.text1b(path_str, 4096); path = path_str; } @@ -52,7 +49,7 @@ class BoostPath { namespace traits { template <> -struct ExtensionTraits { +struct ExtensionTraits { using TValue = void; static constexpr bool SupportValueOverload = false; static constexpr bool SupportObjectOverload = true; diff --git a/src/common/communication/common.cpp b/src/common/communication/common.cpp index a1eecd98..a2b9068f 100644 --- a/src/common/communication/common.cpp +++ b/src/common/communication/common.cpp @@ -20,7 +20,7 @@ #include "../utils.h" -namespace fs = boost::filesystem; +namespace fs = ghc::filesystem; /** * Used for generating random identifiers. @@ -28,7 +28,7 @@ namespace fs = boost::filesystem; constexpr char alphanumeric_characters[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; -boost::filesystem::path generate_endpoint_base(const std::string& plugin_name) { +ghc::filesystem::path generate_endpoint_base(const std::string& plugin_name) { fs::path temp_directory = get_temporary_directory(); std::random_device random_device; diff --git a/src/common/communication/common.h b/src/common/communication/common.h index 724cf122..fb030bec 100644 --- a/src/common/communication/common.h +++ b/src/common/communication/common.h @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include "../bitsery/traits/small-vector.h" #include "../logging/common.h" @@ -268,7 +268,7 @@ inline T read_object(Socket& socket) { * @param plugin_name The name of the plugin we're generating endpoints for. * Used as a visual indication of what plugin is using this endpoint. */ -boost::filesystem::path generate_endpoint_base(const std::string& plugin_name); +ghc::filesystem::path generate_endpoint_base(const std::string& plugin_name); /** * Manages all the sockets used for communicating between the plugin and the @@ -287,7 +287,7 @@ class Sockets { * * @see Sockets::connect */ - Sockets(const boost::filesystem::path& endpoint_base_dir) + Sockets(const ghc::filesystem::path& endpoint_base_dir) : base_dir_(endpoint_base_dir) {} /** @@ -305,9 +305,9 @@ class Sockets { // there's now a safeguard against that very thing. Hopefully // this should never be needed, but if it is, then I'm glad // we'll have it! - const boost::filesystem::path temp_dir = get_temporary_directory(); + const ghc::filesystem::path temp_dir = get_temporary_directory(); if (base_dir_.string().starts_with(temp_dir.string())) { - boost::filesystem::remove_all(base_dir_); + ghc::filesystem::remove_all(base_dir_); } else { Logger logger = Logger::create_exception_logger(); @@ -317,7 +317,7 @@ class Sockets { "'"); logger.log(""); } - } catch (const boost::filesystem::filesystem_error&) { + } catch (const ghc::filesystem::filesystem_error&) { // There should not be any filesystem errors since only one side // removes the files, but if we somehow can't delete the file // then we can just silently ignore this @@ -351,7 +351,7 @@ class Sockets { * The base directory for our socket endpoints. All `*_endpoint` variables * below are files within this directory. */ - const boost::filesystem::path base_dir_; + const ghc::filesystem::path base_dir_; }; /** @@ -376,8 +376,8 @@ class SocketHandler { bool listen) : endpoint_(endpoint), socket_(io_context) { if (listen) { - boost::filesystem::create_directories( - boost::filesystem::path(endpoint.path()).parent_path()); + ghc::filesystem::create_directories( + ghc::filesystem::path(endpoint.path()).parent_path()); acceptor_.emplace(io_context, endpoint); } } @@ -577,8 +577,8 @@ class AdHocSocketHandler { bool listen) : io_context_(io_context), endpoint_(endpoint), socket_(io_context) { if (listen) { - boost::filesystem::create_directories( - boost::filesystem::path(endpoint.path()).parent_path()); + ghc::filesystem::create_directories( + ghc::filesystem::path(endpoint.path()).parent_path()); acceptor_.emplace(io_context, endpoint); } } @@ -598,7 +598,7 @@ class AdHocSocketHandler { // potentially on the other side of the connection in the case // where we're handling `vst_host_callback_` VST2 events acceptor_.reset(); - boost::filesystem::remove(endpoint_.path()); + ghc::filesystem::remove(endpoint_.path()); } else { socket_.connect(endpoint_); } diff --git a/src/common/communication/vst2.h b/src/common/communication/vst2.h index 71e752a4..39df3ad1 100644 --- a/src/common/communication/vst2.h +++ b/src/common/communication/vst2.h @@ -343,7 +343,7 @@ class Vst2Sockets final : public Sockets { * @see Vst2Sockets::connect */ Vst2Sockets(boost::asio::io_context& io_context, - const boost::filesystem::path& endpoint_base_dir, + const ghc::filesystem::path& endpoint_base_dir, bool listen) : Sockets(endpoint_base_dir), host_vst_dispatch_(io_context, diff --git a/src/common/communication/vst3.h b/src/common/communication/vst3.h index 27170ff4..be75d5cc 100644 --- a/src/common/communication/vst3.h +++ b/src/common/communication/vst3.h @@ -311,7 +311,7 @@ class Vst3Sockets final : public Sockets { * @see Vst3Sockets::connect */ Vst3Sockets(boost::asio::io_context& io_context, - const boost::filesystem::path& endpoint_base_dir, + const ghc::filesystem::path& endpoint_base_dir, bool listen) : Sockets(endpoint_base_dir), host_vst_control_(io_context, diff --git a/src/common/configuration.cpp b/src/common/configuration.cpp index db772674..eed2320d 100644 --- a/src/common/configuration.cpp +++ b/src/common/configuration.cpp @@ -26,7 +26,7 @@ #include "utils.h" -namespace fs = boost::filesystem; +namespace fs = ghc::filesystem; Configuration::Configuration() noexcept {} diff --git a/src/common/configuration.h b/src/common/configuration.h index c0bad2f9..111e6983 100644 --- a/src/common/configuration.h +++ b/src/common/configuration.h @@ -16,15 +16,12 @@ #pragma once -#ifdef __WINE__ -#include "../wine-host/boost-fix.h" -#endif -#include - #include #include -#include "bitsery/ext/boost-path.h" +#include + +#include "bitsery/ext/ghc-path.h" #include "bitsery/ext/in-place-optional.h" /** @@ -71,8 +68,8 @@ class Configuration { * * @see ../plugin/utils.h:load_config_for */ - Configuration(const boost::filesystem::path& config_path, - const boost::filesystem::path& yabridge_path); + Configuration(const ghc::filesystem::path& config_path, + const ghc::filesystem::path& yabridge_path); /** * The name of the plugin group that should be used for the plugin this @@ -92,7 +89,7 @@ class Configuration { * `/yabridge-plugin-output.log`, or it can be set to * an absolute path. (we don't try to expand tildes) */ - std::optional disable_pipes; + std::optional disable_pipes; /** * If this is set to `true`, then the after every resize we will move the @@ -167,7 +164,7 @@ class Configuration { /** * The path to the configuration file that was parsed. */ - std::optional matched_file; + std::optional matched_file; /** * The matched glob pattern in the above configuration file. @@ -199,7 +196,7 @@ class Configuration { [](S& s, auto& v) { s.text1b(v, 4096); }); s.ext(disable_pipes, bitsery::ext::InPlaceOptional(), - [](S& s, auto& v) { s.ext(v, bitsery::ext::BoostPath{}); }); + [](S& s, auto& v) { s.ext(v, bitsery::ext::GhcPath{}); }); s.value1b(editor_coordinate_hack); s.value1b(editor_force_dnd); s.value1b(editor_xembed); @@ -210,7 +207,7 @@ class Configuration { s.value1b(vst3_prefer_32bit); s.ext(matched_file, bitsery::ext::InPlaceOptional(), - [](S& s, auto& v) { s.ext(v, bitsery::ext::BoostPath{}); }); + [](S& s, auto& v) { s.ext(v, bitsery::ext::GhcPath{}); }); s.ext(matched_pattern, bitsery::ext::InPlaceOptional(), [](S& s, auto& v) { s.text1b(v, 4096); }); diff --git a/src/common/plugins.cpp b/src/common/plugins.cpp index 0acc9c17..b4b59634 100644 --- a/src/common/plugins.cpp +++ b/src/common/plugins.cpp @@ -19,7 +19,7 @@ #include #include -namespace fs = boost::filesystem; +namespace fs = ghc::filesystem; LibArchitecture find_dll_architecture(const fs::path& plugin_path) { std::ifstream file(plugin_path, std::ifstream::binary | std::ifstream::in); diff --git a/src/common/plugins.h b/src/common/plugins.h index c22bd047..13364820 100644 --- a/src/common/plugins.h +++ b/src/common/plugins.h @@ -16,10 +16,7 @@ #pragma once -#ifdef __WINE__ -#include "../wine-host/boost-fix.h" -#endif -#include +#include // Utilities and tags for plugin types and architectures @@ -58,7 +55,7 @@ void serialize(S& s, PluginType& plugin_type) { * @return The detected architecture. * @throw std::runtime_error If the file is not a .dll file. */ -LibArchitecture find_dll_architecture(const boost::filesystem::path&); +LibArchitecture find_dll_architecture(const ghc::filesystem::path&); PluginType plugin_type_from_string(const std::string& plugin_type) noexcept; std::string plugin_type_to_string(const PluginType& plugin_type); diff --git a/src/common/utils.cpp b/src/common/utils.cpp index 465ecb5e..975773b1 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -16,12 +16,12 @@ #include "utils.h" +#include + #include #include -#include -namespace bp = boost::process; -namespace fs = boost::filesystem; +namespace fs = ghc::filesystem; using namespace std::literals::string_view_literals; @@ -40,13 +40,12 @@ constexpr char disable_watchdog_timer_env_var[] = "YABRIDGE_NO_WATCHDOG"; constexpr char temp_dir_override_env_var[] = "YABRIDGE_TEMP_DIR"; fs::path get_temporary_directory() { - const bp::environment env = boost::this_process::environment(); - if (const auto directory = env.find(temp_dir_override_env_var); - directory != env.end()) { - return directory->to_string(); - } else if (const auto directory = env.find("XDG_RUNTIME_DIR"); - directory != env.end()) { - return directory->to_string(); + // NOLINTNEXTLINE(concurrency-mt-unsafe) + if (const auto directory = getenv(temp_dir_override_env_var)) { + return fs::path(directory); + // NOLINTNEXTLINE(concurrency-mt-unsafe) + } else if (const auto directory = getenv("XDG_RUNTIME_DIR")) { + return fs::path(directory); } else { return fs::temp_directory_path(); } @@ -105,13 +104,13 @@ bool pid_running(pid_t pid) { // processes and zombies, and a terminated group host process will always be // left as a zombie process. If the process is active, then // `/proc//{cwd,exe,root}` will be valid symlinks. - boost::system::error_code err; + std::error_code err; fs::canonical("/proc/" + std::to_string(pid) + "/exe", err); // NOTE: We can get a `EACCES` here if we don't have permissions to read // this process's memory. This does mean that the process is still // running. - return !err.failed() || err.value() == EACCES; + return !err || err.value() == EACCES; } std::string url_encode_path(std::string path) { diff --git a/src/common/utils.h b/src/common/utils.h index d9c688c7..db8530fd 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -19,11 +19,7 @@ #include #include - -#ifdef __WINE__ -#include "../wine-host/boost-fix.h" -#endif -#include +#include /** * The interval in seconds between synchronizing the Wine plugin host's audio @@ -79,7 +75,7 @@ overload(Ts...) -> overload; * Return the path to the directory for story temporary files. This will be * `$XDG_RUNTIME_DIR` if set, and `/tmp` otherwise. */ -boost::filesystem::path get_temporary_directory(); +ghc::filesystem::path get_temporary_directory(); /** * Get the current thread's scheduling priority if the thread is using diff --git a/src/plugin/bridges/common.h b/src/plugin/bridges/common.h index a2fca5f7..9792f41e 100644 --- a/src/plugin/bridges/common.h +++ b/src/plugin/bridges/common.h @@ -236,7 +236,7 @@ class PluginBridge { [&](const OverridenWinePrefix& prefix) { init_msg << prefix.value.string() << " "; }, - [&](const boost::filesystem::path& prefix) { + [&](const ghc::filesystem::path& prefix) { init_msg << prefix.string(); }, [&](const DefaultWinePrefix&) { init_msg << ""; }, diff --git a/src/plugin/host-process.cpp b/src/plugin/host-process.cpp index 113ad5f0..febdc619 100644 --- a/src/plugin/host-process.cpp +++ b/src/plugin/host-process.cpp @@ -23,7 +23,7 @@ #include "../common/utils.h" namespace bp = boost::process; -namespace fs = boost::filesystem; +namespace fs = ghc::filesystem; HostProcess::HostProcess(boost::asio::io_context& io_context, Logger& logger, @@ -157,7 +157,8 @@ GroupHost::GroupHost(boost::asio::io_context& io_context, // because it should run independently of this yabridge instance as // it will likely outlive it. bp::child group_host = - launch_host(host_path_, group_socket_path, + // FIXME: Boost.Filesystem conversion + launch_host(host_path_, group_socket_path.string(), bp::env = plugin_info.create_host_env()); group_host.detach(); diff --git a/src/plugin/host-process.h b/src/plugin/host-process.h index 3483bf99..509ed71f 100644 --- a/src/plugin/host-process.h +++ b/src/plugin/host-process.h @@ -20,10 +20,10 @@ #include #include -#include #include #include #include +#include #include "../common/communication/common.h" #include "../common/logging/common.h" @@ -46,7 +46,7 @@ class HostProcess { * is chosen depending on the architecture of the plugin's DLL file and on * the hosting mode. */ - virtual boost::filesystem::path path() = 0; + virtual ghc::filesystem::path path() = 0; /** * Return true if the host process is still running. Used during startup to @@ -69,7 +69,7 @@ class HostProcess { * multiple arugments. */ template - boost::process::child launch_host(boost::filesystem::path host_path, + boost::process::child launch_host(ghc::filesystem::path host_path, Args&&... args) { return boost::process::child( #ifdef WITH_WINEDBG @@ -88,7 +88,8 @@ class HostProcess { host_path.string() + ".so", #endif // WINEDBG_LEGACY_ARGUMENT_QUOTING #else - host_path, + // FIXME: Replace Boost.Filesystem + host_path.string(), #endif // WITH_WINEDBG boost::process::std_out = stdout_pipe_, boost::process::std_err = stderr_pipe_, @@ -207,13 +208,13 @@ class IndividualHost : public HostProcess { const PluginInfo& plugin_info, const HostRequest& host_request); - boost::filesystem::path path() override; + ghc::filesystem::path path() override; bool running() override; void terminate() override; private: const PluginInfo& plugin_info_; - boost::filesystem::path host_path_; + ghc::filesystem::path host_path_; boost::process::child host_; }; @@ -255,13 +256,13 @@ class GroupHost : public HostProcess { const PluginInfo& plugin_info, const HostRequest& host_request); - boost::filesystem::path path() override; + ghc::filesystem::path path() override; bool running() noexcept override; void terminate() override; private: const PluginInfo& plugin_info_; - boost::filesystem::path host_path_; + ghc::filesystem::path host_path_; /** * We want to either connect to an existing group host process, or spawn a diff --git a/src/plugin/utils.cpp b/src/plugin/utils.cpp index fc2c8b25..62d1c2f9 100644 --- a/src/plugin/utils.cpp +++ b/src/plugin/utils.cpp @@ -38,7 +38,7 @@ #include "../common/utils.h" namespace bp = boost::process; -namespace fs = boost::filesystem; +namespace fs = ghc::filesystem; // These functions are used to populate the fields in `PluginInfo`. See the // docstrings for the corresponding fields for more information on what we're @@ -74,7 +74,7 @@ bp::environment PluginInfo::create_host_env() const { // just for clarity's sake) std::visit(overload{ [](const OverridenWinePrefix&) {}, - [&](const boost::filesystem::path& prefix) { + [&](const ghc::filesystem::path& prefix) { env["WINEPREFIX"] = prefix.string(); }, [](const DefaultWinePrefix&) {}, @@ -84,11 +84,11 @@ bp::environment PluginInfo::create_host_env() const { return env; } -boost::filesystem::path PluginInfo::normalize_wine_prefix() const { +ghc::filesystem::path PluginInfo::normalize_wine_prefix() const { return std::visit( overload{ [](const OverridenWinePrefix& prefix) { return prefix.value; }, - [](const boost::filesystem::path& prefix) { return prefix; }, + [](const ghc::filesystem::path& prefix) { return prefix; }, [](const DefaultWinePrefix&) { const bp::environment env = boost::this_process::environment(); return fs::path(env.at("HOME").to_string()) / ".wine"; @@ -101,7 +101,8 @@ std::string PluginInfo::wine_version() const { // The '*.exe' scripts generated by winegcc allow you to override the binary // used to run Wine, so will will handle this in the same way for our Wine // version detection - fs::path wine_path; + // FIXME: Replace Boost.Filesystem usage + boost::filesystem::path wine_path; bp::environment env = create_host_env(); if (const std::string wineloader_path = env["WINELOADER"].to_string(); access(wineloader_path.c_str(), X_OK) == 0) { @@ -280,7 +281,8 @@ fs::path get_this_file_location() { // 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. - fs::path this_file = boost::dll::this_line_location(); + // 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(); } @@ -318,9 +320,10 @@ std::string create_logger_prefix(const fs::path& endpoint_base_dir) { return "[" + endpoint_name + "] "; } -fs::path find_vst_host(const boost::filesystem::path& this_plugin_path, +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) { @@ -338,19 +341,20 @@ fs::path find_vst_host(const boost::filesystem::path& this_plugin_path, // Boost will return an empty path if the file could not be found in the // search path - const fs::path vst_host_path = + const boost::filesystem::path vst_host_path = bp::search_path(host_name, get_augmented_search_path()); if (vst_host_path == "") { throw std::runtime_error("Could not locate '" + std::string(host_name) + "'"); } - return vst_host_path; + // FIXME: Replace Boost.Filesystem usage requiring this conversion + return vst_host_path.string(); } -boost::filesystem::path generate_group_endpoint( +ghc::filesystem::path generate_group_endpoint( const std::string& group_name, - const boost::filesystem::path& wine_prefix, + const ghc::filesystem::path& wine_prefix, const LibArchitecture architecture) { std::ostringstream socket_name; socket_name << "yabridge-group-" << group_name << "-" @@ -370,6 +374,7 @@ boost::filesystem::path generate_group_endpoint( return get_temporary_directory() / socket_name.str(); } +// FIXME: Replace Boost.Filesystem std::vector get_augmented_search_path() { // HACK: `std::locale("")` would return the current locale, but this // overload is implementation specific, and libstdc++ returns an error @@ -410,12 +415,13 @@ std::vector get_augmented_search_path() { const bp::environment environment = boost::this_process::environment(); if (auto xdg_data_home = environment.find("XDG_DATA_HOME"); xdg_data_home != environment.end()) { - search_path.push_back(fs::path(xdg_data_home->to_string()) / - "yabridge"); + search_path.push_back( + boost::filesystem::path(xdg_data_home->to_string()) / "yabridge"); } else if (auto home_directory = environment.find("HOME"); home_directory != environment.end()) { - search_path.push_back(fs::path(home_directory->to_string()) / ".local" / - "share" / "yabridge"); + search_path.push_back( + boost::filesystem::path(home_directory->to_string()) / ".local" / + "share" / "yabridge"); } return search_path; @@ -436,7 +442,9 @@ Configuration load_config_for(const fs::path& yabridge_path) { bool send_notification(const std::string& title, const std::string body, bool append_origin) { - const fs::path notify_send_path = bp::search_path("notify-send"); + // FIXME: Replace Boost.Filesystem + const boost::filesystem::path notify_send_path = + bp::search_path("notify-send"); if (notify_send_path.empty()) { return false; } diff --git a/src/plugin/utils.h b/src/plugin/utils.h index db61c3c7..9eeedc7f 100644 --- a/src/plugin/utils.h +++ b/src/plugin/utils.h @@ -34,7 +34,7 @@ struct DefaultWinePrefix {}; * environment variable. */ struct OverridenWinePrefix { - boost::filesystem::path value; + ghc::filesystem::path value; }; /** @@ -81,7 +81,7 @@ struct PluginInfo { * Return the path to the actual Wine prefix in use, taking into account * `WINEPREFIX` overrides and the default `~/.wine` fallback. */ - boost::filesystem::path normalize_wine_prefix() const; + ghc::filesystem::path normalize_wine_prefix() const; /** * Return the installed Wine version. This is obtained by from `wine @@ -103,7 +103,7 @@ struct PluginInfo { * module (since that has to be bundle on Linux) but rather the .so file * contained in that bundle. */ - const boost::filesystem::path native_library_path_; + const ghc::filesystem::path native_library_path_; private: /** @@ -113,7 +113,7 @@ struct PluginInfo { * instead. We store this intermediate value so we can determine the * plugin's architecture. */ - const boost::filesystem::path windows_library_path_; + const ghc::filesystem::path windows_library_path_; public: const LibArchitecture plugin_arch_; @@ -132,7 +132,7 @@ struct PluginInfo { * * https://developer.steinberg.help/pages/viewpage.action?pageId=9798275 */ - const boost::filesystem::path windows_plugin_path_; + const ghc::filesystem::path windows_plugin_path_; /** * The Wine prefix to use for hosting `windows_plugin_path_`. If the @@ -144,7 +144,7 @@ struct PluginInfo { * prefix will be used instead. */ const std:: - variant + variant wine_prefix_; }; @@ -174,7 +174,7 @@ std::string join_quoted_strings(std::vector& strings); * @return A prefix string for log messages. */ std::string create_logger_prefix( - const boost::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` @@ -197,8 +197,8 @@ std::string create_logger_prefix( * @return The a path to the VST host, if found. * @throw std::runtime_error If the Wine VST host could not be found. */ -boost::filesystem::path find_vst_host( - const boost::filesystem::path& this_plugin_path, +ghc::filesystem::path find_vst_host( + const ghc::filesystem::path& this_plugin_path, LibArchitecture plugin_arch, bool use_plugin_groups); @@ -220,9 +220,9 @@ boost::filesystem::path find_vst_host( * @return A socket endpoint path that corresponds to the format described * above. */ -boost::filesystem::path generate_group_endpoint( +ghc::filesystem::path generate_group_endpoint( const std::string& group_name, - const boost::filesystem::path& wine_prefix, + const ghc::filesystem::path& wine_prefix, const LibArchitecture architecture); /** @@ -233,6 +233,8 @@ boost::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 get_augmented_search_path(); @@ -240,7 +242,7 @@ 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. */ -boost::filesystem::path get_this_file_location(); +ghc::filesystem::path get_this_file_location(); /** * Load the configuration that belongs to a copy of or symlink to @@ -263,7 +265,7 @@ boost::filesystem::path get_this_file_location(); * * @see Configuration */ -Configuration load_config_for(const boost::filesystem::path& yabridge_path); +Configuration load_config_for(const ghc::filesystem::path& yabridge_path); /** * Send a desktop notification using `notify-send`. Used for diagnostics when a @@ -299,14 +301,14 @@ bool send_notification(const std::string& title, * @return The path to the *file* found, or `std::nullopt` if the file could not * be found. */ -template F = - bool(const boost::filesystem::path&)> -std::optional find_dominating_file( +template F = + bool(const ghc::filesystem::path&)> +std::optional find_dominating_file( const std::string& filename, - boost::filesystem::path starting_dir, - F&& predicate = boost::filesystem::exists) { + ghc::filesystem::path starting_dir, + F&& predicate = ghc::filesystem::exists) { while (starting_dir != "") { - const boost::filesystem::path candidate = starting_dir / filename; + const ghc::filesystem::path candidate = starting_dir / filename; if (predicate(candidate)) { return candidate; } diff --git a/src/wine-host/bridges/common.cpp b/src/wine-host/bridges/common.cpp index a9a57e15..7a183274 100644 --- a/src/wine-host/bridges/common.cpp +++ b/src/wine-host/bridges/common.cpp @@ -48,7 +48,7 @@ constexpr int extended_max_win32_messages = 8192; constexpr unsigned int juce_message_id = WM_USER + 123; HostBridge::HostBridge(MainContext& main_context, - boost::filesystem::path plugin_path, + ghc::filesystem::path plugin_path, pid_t parent_pid) : plugin_path_(plugin_path), main_context_(main_context), diff --git a/src/wine-host/bridges/common.h b/src/wine-host/bridges/common.h index d6b7b89b..e7be446a 100644 --- a/src/wine-host/bridges/common.h +++ b/src/wine-host/bridges/common.h @@ -18,7 +18,7 @@ #include "../boost-fix.h" -#include +#include #include "../../common/logging/common.h" #include "../utils.h" @@ -33,7 +33,7 @@ class HostBridge { protected: HostBridge(MainContext& main_context, - boost::filesystem::path plugin_path, + ghc::filesystem::path plugin_path, pid_t parent_pid); public: @@ -98,7 +98,7 @@ class HostBridge { /** * The path to the .dll being loaded in the Wine plugin host. */ - const boost::filesystem::path plugin_path_; + const ghc::filesystem::path plugin_path_; protected: /** diff --git a/src/wine-host/bridges/group.cpp b/src/wine-host/bridges/group.cpp index 25a9d519..8940dc5a 100644 --- a/src/wine-host/bridges/group.cpp +++ b/src/wine-host/bridges/group.cpp @@ -19,7 +19,6 @@ #include "../boost-fix.h" #include -#include #include #include "../../common/communication/common.h" @@ -30,7 +29,7 @@ // FIXME: `std::filesystem` is broken in wineg++, at least under Wine 5.8. Any // path operation will thrown an encoding related error -namespace fs = boost::filesystem; +namespace fs = ghc::filesystem; using namespace std::literals::chrono_literals; @@ -86,7 +85,7 @@ StdIoCapture::~StdIoCapture() noexcept { close(pipe_fd_[0]); } -GroupBridge::GroupBridge(boost::filesystem::path group_socket_path) +GroupBridge::GroupBridge(ghc::filesystem::path group_socket_path) : logger_(Logger::create_from_environment( create_logger_prefix(group_socket_path))), main_context_(), @@ -191,7 +190,7 @@ void GroupBridge::accept_requests() { // this process to crash during its initialization to prevent // waiting indefinitely on the sockets to be connected to. const auto request = read_object(socket); - write_object(socket, HostResponse{boost::this_process::get_id()}); + write_object(socket, HostResponse{.pid = getpid()}); // The plugin has to be initiated on the IO context's thread because // this has to be done on the same thread that's handling messages, diff --git a/src/wine-host/bridges/group.h b/src/wine-host/bridges/group.h index a3fb5bb7..ddeae468 100644 --- a/src/wine-host/bridges/group.h +++ b/src/wine-host/bridges/group.h @@ -123,7 +123,7 @@ class GroupBridge { * STDOUT and STDERR streams of the current process will be redirected to * a pipe so they can be properly written to a log file. */ - explicit GroupBridge(boost::filesystem::path group_socket_path); + explicit GroupBridge(ghc::filesystem::path group_socket_path); ~GroupBridge() noexcept; diff --git a/src/wine-host/meson.build b/src/wine-host/meson.build index d63d4db0..ea102d6b 100644 --- a/src/wine-host/meson.build +++ b/src/wine-host/meson.build @@ -11,9 +11,9 @@ if is_64bit_system configuration_dep, boost_dep, - boost_filesystem_64bit_dep, bitsery_dep, function2_dep, + ghc_filesystem_dep, rt_dep, tomlplusplus_dep, wine_ole32_dep, @@ -36,7 +36,7 @@ if with_bitbridge configuration_dep, boost_dep, - boost_filesystem_32bit_dep, + ghc_filesystem_dep, bitsery_dep, function2_dep, rt_dep, diff --git a/src/wine-host/xdnd-proxy.cpp b/src/wine-host/xdnd-proxy.cpp index 042a06fb..61d5d8f2 100644 --- a/src/wine-host/xdnd-proxy.cpp +++ b/src/wine-host/xdnd-proxy.cpp @@ -23,7 +23,7 @@ using namespace std::literals::chrono_literals; -namespace fs = boost::filesystem; +namespace fs = ghc::filesystem; /** * The window class name Wine uses for its `DoDragDrop()` tracker window. @@ -193,7 +193,7 @@ WineXdndProxy::Handle WineXdndProxy::get_handle() { } void WineXdndProxy::begin_xdnd(const boost::container::small_vector_base< - boost::filesystem::path>& file_paths, + ghc::filesystem::path>& file_paths, HWND tracker_window) { if (file_paths.empty()) { throw std::runtime_error("Cannot drag-and-drop without any files"); @@ -243,8 +243,8 @@ void WineXdndProxy::begin_xdnd(const boost::container::small_vector_base< [](size_t size, const auto& path) { // Account for the protocol, the trailing line feed, and URL // encoding - return size + - static_cast(static_cast(path.size()) * 1.2); + return size + static_cast( + static_cast(path.native().size()) * 1.2); })); for (const auto& path : file_paths) { dragged_files_uri_list_.append(file_protocol); @@ -849,10 +849,10 @@ void CALLBACK dnd_winevent_callback(HWINEVENTHOOK /*hWinEventHook*/, const char* unix_path = wine_get_unix_file_name(file_name.data()); if (unix_path) { - boost::system::error_code err; + std::error_code err; const fs::path cannonical_path = - boost::filesystem::canonical(unix_path, - err); + ghc::filesystem::canonical(unix_path, + err); if (err) { dragged_files.emplace_back(unix_path); } else { @@ -875,9 +875,9 @@ void CALLBACK dnd_winevent_callback(HWINEVENTHOOK /*hWinEventHook*/, const char* unix_path = wine_get_unix_file_name(storage.lpszFileName); if (unix_path) { - boost::system::error_code err; + std::error_code err; const fs::path cannonical_path = - boost::filesystem::canonical(unix_path, err); + ghc::filesystem::canonical(unix_path, err); if (err) { dragged_files.emplace_back(unix_path); } else { diff --git a/src/wine-host/xdnd-proxy.h b/src/wine-host/xdnd-proxy.h index 49b4d15c..f0593495 100644 --- a/src/wine-host/xdnd-proxy.h +++ b/src/wine-host/xdnd-proxy.h @@ -28,6 +28,7 @@ #include #include +#include #include "utils.h" @@ -149,7 +150,7 @@ class WineXdndProxy { * selection and setting up the event listeners. */ void begin_xdnd(const boost::container::small_vector_base< - boost::filesystem::path>& file_paths, + ghc::filesystem::path>& file_paths, HWND tracker_window); /** diff --git a/tools/patch-vst3-sdk.sh b/tools/patch-vst3-sdk.sh index 05ad3a6a..b21a3f34 100755 --- a/tools/patch-vst3-sdk.sh +++ b/tools/patch-vst3-sdk.sh @@ -68,10 +68,9 @@ replace_char16 "using Converter = std::wstring_convert$/#include /' "$sdk_directory/public.sdk/source/vst/hosting/module_win32.cpp" -sed -i 's/^namespace filesystem = std\(::experimental\)\?::filesystem;$/namespace filesystem = boost::filesystem;/' "$sdk_directory/public.sdk/source/vst/hosting/module_win32.cpp" -sed -i 's/\bfile_type::directory\b/file_type::directory_file/g' "$sdk_directory/public.sdk/source/vst/hosting/module_win32.cpp" +# We'll patch the Win32 module loading to use `ghc::filesystem` instead. +sed -i 's/^#include <\(experimental\/\)\?filesystem>$/#include /' "$sdk_directory/public.sdk/source/vst/hosting/module_win32.cpp" +sed -i 's/^namespace filesystem = std\(::experimental\)\?::filesystem;$/namespace filesystem = ghc::filesystem;/' "$sdk_directory/public.sdk/source/vst/hosting/module_win32.cpp" # Wine uses the narrow versions of everything by default, and in Unity builds # we need to explicitly use the UTF-16 version here.