Skip to content

Commit

Permalink
Add the chainloader side of yabridge_version
Browse files Browse the repository at this point in the history
This can be used by hosts to determine which version of yabridge is in
use.
  • Loading branch information
robbert-vdh committed Dec 10, 2023
1 parent 2b602c9 commit d39d3a6
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 15 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- The yabridge libraries now export a `yabridge_version` function that hosts can
query to get the yabridge version in use. This will return the yabridge
version that would be loaded when using the plugin, also when called on the
chainloading libraries.

### Changed

- Parsing failures for `yabridge.toml` files will no longer cause plugins to
Expand Down
35 changes: 30 additions & 5 deletions src/chainloader/clap-chainloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ void (*yabridge_module_free)(ClapPluginBridge* instance) = nullptr;
const void* (*yabridge_module_get_factory)(ClapPluginBridge* instance,
const char* factory_id) = nullptr;

// This bridges the `yabridge_version()` call from the plugin library. This
// function was added later, so through weird version mixing it may be missing
// on the yabridge library.
char* (*remote_yabridge_version)() = nullptr;

/**
* The bridge instance for this chainloader. This is initialized when
* `clap_entry.init` first gets called.
Expand Down Expand Up @@ -89,21 +94,27 @@ bool initialize_library() {
return false;
}

#define LOAD_FUNCTION(name) \
#define MAYBE_LOAD_FUNCTION(name) \
do { \
(name) = \
reinterpret_cast<decltype(name)>(dlsym(library_handle, #name)); \
if (!(name)) { \
log_failing_dlsym(yabridge_clap_plugin_name, #name); \
return false; \
} \
} while (false)
#define LOAD_FUNCTION(name) \
do { \
MAYBE_LOAD_FUNCTION(name); \
if (!(name)) { \
log_failing_dlsym(yabridge_clap_plugin_name, #name); \
return false; \
} \
} while (false)

LOAD_FUNCTION(yabridge_module_init);
LOAD_FUNCTION(yabridge_module_free);
LOAD_FUNCTION(yabridge_module_get_factory);
MAYBE_LOAD_FUNCTION(remote_yabridge_version);

#undef LOAD_FUNCTION
#undef MAYBE_LOAD_FUNCTION

return true;
}
Expand Down Expand Up @@ -163,3 +174,17 @@ CLAP_EXPORT const clap_plugin_entry_t clap_entry = {
};

#pragma GCC diagnostic pop

/**
* This returns the actual yabridge library's version through
* `yabridge_version()`. Reporting the version associated with this chainloader
* wouldn't be very useful, and that would also cause the chainloader to be
* rebuilt on every git commit in development.
*/
extern "C" YABRIDGE_EXPORT char* yabridge_version() {
if (!initialize_library() || !remote_yabridge_version) {
return nullptr;
}

return remote_yabridge_version();
}
35 changes: 30 additions & 5 deletions src/chainloader/vst2-chainloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ using AEffect = void;
AEffect* (*yabridge_plugin_init)(audioMasterCallback host_callback,
const char* plugin_path) = nullptr;

// This bridges the `yabridge_version()` call from the plugin library. This
// function was added later, so through weird version mixing it may be missing
// on the yabridge library.
char* (*remote_yabridge_version)() = nullptr;

/**
* The first time one of the exported functions from this library gets called,
* we'll need to load the corresponding `libyabridge-*.so` file and fetch the
Expand All @@ -72,19 +77,25 @@ bool initialize_library() {
return false;
}

#define LOAD_FUNCTION(name) \
#define MAYBE_LOAD_FUNCTION(name) \
do { \
(name) = \
reinterpret_cast<decltype(name)>(dlsym(library_handle, #name)); \
if (!(name)) { \
log_failing_dlsym(yabridge_vst2_plugin_name, #name); \
return false; \
} \
} while (false)
#define LOAD_FUNCTION(name) \
do { \
MAYBE_LOAD_FUNCTION(name); \
if (!(name)) { \
log_failing_dlsym(yabridge_vst2_plugin_name, #name); \
return false; \
} \
} while (false)

LOAD_FUNCTION(yabridge_plugin_init);
MAYBE_LOAD_FUNCTION(remote_yabridge_version);

#undef LOAD_FUNCTION
#undef MAYBE_LOAD_FUNCTION

return true;
}
Expand All @@ -109,3 +120,17 @@ extern "C" YABRIDGE_EXPORT AEffect* deprecated_main(
YABRIDGE_EXPORT AEffect* deprecated_main(audioMasterCallback audioMaster) {
return VSTPluginMain(audioMaster);
}

/**
* This returns the actual yabridge library's version through
* `yabridge_version()`. Reporting the version associated with this chainloader
* wouldn't be very useful, and that would also cause the chainloader to be
* rebuilt on every git commit in development.
*/
extern "C" YABRIDGE_EXPORT char* yabridge_version() {
if (!initialize_library() || !remote_yabridge_version) {
return nullptr;
}

return remote_yabridge_version();
}
35 changes: 30 additions & 5 deletions src/chainloader/vst3-chainloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ void (*yabridge_module_free)(Vst3PluginBridge* instance) = nullptr;
PluginFactory* (*yabridge_module_get_plugin_factory)(
Vst3PluginBridge* instance) = nullptr;

// This bridges the `yabridge_version()` call from the plugin library. This
// function was added later, so through weird version mixing it may be missing
// on the yabridge library.
char* (*remote_yabridge_version)() = nullptr;

/**
* The bridge instance for this chainloader. This is initialized when
* `ModuleEntry()` first gets called.
Expand Down Expand Up @@ -89,21 +94,27 @@ bool initialize_library() {
return false;
}

#define LOAD_FUNCTION(name) \
#define MAYBE_LOAD_FUNCTION(name) \
do { \
(name) = \
reinterpret_cast<decltype(name)>(dlsym(library_handle, #name)); \
if (!(name)) { \
log_failing_dlsym(yabridge_vst3_plugin_name, #name); \
return false; \
} \
} while (false)
#define LOAD_FUNCTION(name) \
do { \
MAYBE_LOAD_FUNCTION(name); \
if (!(name)) { \
log_failing_dlsym(yabridge_vst3_plugin_name, #name); \
return false; \
} \
} while (false)

LOAD_FUNCTION(yabridge_module_init);
LOAD_FUNCTION(yabridge_module_free);
LOAD_FUNCTION(yabridge_module_get_plugin_factory);
MAYBE_LOAD_FUNCTION(remote_yabridge_version);

#undef LOAD_FUNCTION
#undef MAYBE_LOAD_FUNCTION

return true;
}
Expand Down Expand Up @@ -146,3 +157,17 @@ extern "C" YABRIDGE_EXPORT PluginFactory* GetPluginFactory() {

return yabridge_module_get_plugin_factory(bridge.get());
}

/**
* This returns the actual yabridge library's version through
* `yabridge_version()`. Reporting the version associated with this chainloader
* wouldn't be very useful, and that would also cause the chainloader to be
* rebuilt on every git commit in development.
*/
extern "C" YABRIDGE_EXPORT char* yabridge_version() {
if (!initialize_library() || !remote_yabridge_version) {
return nullptr;
}

return remote_yabridge_version();
}

0 comments on commit d39d3a6

Please sign in to comment.