diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d51b968..fd31fb5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ Versioning](https://semver.org/spec/v2.0.0.html). rather than the loaded `.so` file. - Increased the maximum number of audio channels from 32 to 256. - Clarified the error that appears when we're unable to load the `.dll`. +- Yabridge will now print the used version of Wine during startup. This can be + useful for diagnosing startup problems. ### Fixed diff --git a/src/plugin/plugin-bridge.cpp b/src/plugin/plugin-bridge.cpp index ae171911..740f34f5 100644 --- a/src/plugin/plugin-bridge.cpp +++ b/src/plugin/plugin-bridge.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -134,6 +135,16 @@ fs::path generate_endpoint_name(); */ fs::path get_this_file_location(); +/** + * Return the installed Wine version. This is obtained by from `wine --version` + * and then stripping the `wine-` prefix. This respects the `WINELOADER` + * environment variable used in the scripts generated by winegcc. + * + * This will *not* throw when Wine can not be found, but will instead return + * ''. This way the user will still get some useful log files. + */ +std::string get_wine_version(); + /** * Locate the Wine prefix and set the `WINEPREFIX` environment variable if * found. This way it's also possible to run .dll files outside of a Wine prefix @@ -170,6 +181,7 @@ PluginBridge::PluginBridge(audioMasterCallback host_callback) host_callback_function(host_callback), logger(Logger::create_from_environment( create_logger_prefix(socket_endpoint.path()))), + wine_version(get_wine_version()), wine_stdout(io_context), wine_stderr(io_context), #ifndef USE_WINEDBG @@ -202,11 +214,12 @@ PluginBridge::PluginBridge(audioMasterCallback host_callback) { logger.log("Initializing yabridge version " + std::string(yabridge_git_version)); - logger.log("host: '" + vst_host_path.string() + "'"); - logger.log("plugin: '" + vst_plugin_path.string() + "'"); - logger.log("socket: '" + socket_endpoint.path() + "'"); - logger.log("wineprefix: '" + + logger.log("host: '" + vst_host_path.string() + "'"); + logger.log("plugin: '" + vst_plugin_path.string() + "'"); + logger.log("socket: '" + socket_endpoint.path() + "'"); + logger.log("wine prefix: '" + find_wineprefix().value_or("").string() + "'"); + logger.log("wine version: '" + wine_version + "'"); // Include a list of enabled compile-tiem features, mostly to make debug // logs more useful @@ -802,8 +815,41 @@ fs::path get_this_file_location() { return "/" / boost::dll::this_line_location(); } +std::string get_wine_version() { + // The '*.exe' scripts generated by winegcc allow you to override the binary + // used to run Wine, so will will respect this as well + std::string wine_command = "wine"; + + bp::native_environment env = boost::this_process::environment(); + if (!env["WINELOADER"].empty()) { + wine_command = env.get("WINELOADER"); + } + + bp::ipstream output; + try { + const fs::path wine_path = bp::search_path(wine_command); + bp::system(wine_path, "--version", bp::std_out = output); + } catch (const std::system_error&) { + return ""; + } + + // `wine --version` might contain additional output in certain custom Wine + // builds, so we only want to look at the first line + std::string version_string; + std::getline(output, version_string); + + // Strip the `wine-` prefix from the output, could potentially be absent in + // custom Wine builds + const std::string version_prefix("wine-"); + if (version_string.find(version_prefix) == 0) { + version_string = version_string.substr(version_prefix.size()); + } + + return version_string; +} + bp::environment set_wineprefix() { - auto env = boost::this_process::environment(); + bp::native_environment env = boost::this_process::environment(); // Allow the wine prefix to be overridden manually if (!env["WINEPREFIX"].empty()) {