frontend, libobs: Plugin manager 1.5 - #13594
Conversation
This provides the counterpart to the existing "target_disable" function, which also allows the functionality to be factored out of existing helper code that might run this implicitly. Co-authored-by: PatTheMav <PatTheMav@users.noreply.github.com>
Core modules are main OBS Studio functionality implemented as runtime modules, but are conceptually considered mandatory and the application is incomplete without them. This change also introduces a configure-time dependency of core modules on "libobs" (already a generation-time dependency) and produces a library target with the names of all core modules available at build system generation. Co-authored-by: PatTheMav <PatTheMav@users.noreply.github.com>
Moves first-party runtime modules into the "core" directory rather than the "obs-plugins" directory to better differentiate them from legacy plugins as well as existing 3rd-party plugins. This change also requires the existing plugin directory to be explicitly added as a possible module search path by application logic, as libobs's internal logic will not add this path anymore and thus third-party plugins would not be discovered anymore. Co-authored-by: PatTheMav <PatTheMav@users.noreply.github.com>
Adds a separate code path just for loading core modules based on the list of modules created at build system generation. Paths to load core modules from is platform-specific, but not changeable for users and is thus not changeable by a caller. Instead path discovery is implemented for each platform separately, generating the necessary module loading package directly before handing it over to the existing module load callback function. Co-authored-by: PatTheMav <PatTheMav@users.noreply.github.com>
With this change module loading in the application is managed by the plugin manager and allows the application to explicitly load core modules independantly from 3rd party (plugin) modules. The implementation is split into separate files for different platforms to allow for cleaner code handling the different possible locations and path schemes used, including all possible legacy locations and plugin bundle formats. This change introduces new locations and directory formats for plugins: * WINDOWS: Portable plugins need to be placed in a directory called "plugins" adjacent to the "bin" directory of an OBS Studio installation. * WINDOWS: Plugins need to be packaged into their own directory "bundles", with the associated DLL in the root of the bundle and the associated "data" directory next to it. * WINDOWS: The "obs-plugins" directory adjacent to the "bin" directory is deprecated and considered a legacy location for all plugins. * MACOS: No changes in locations or formats. * LINUX: Plugins distributed via system package managers now need to use the "obs-modules/plugins" directory in the system library directory for binaries, and the "obs/obs-modules/plugins" directory in the system data directory for resources. * Linux: The "obs-plugins" directories in the system library and system data directories are deprecated. * Linux: Plugins distributed outside of system packages need to use the same directory format as plugins for Windows (see above). * Linux: A "portable" plugin location like on Windows is not supported. * All Platforms: A single environment variable "OBS_PLUGINS_PATH" can now be used to provide a highest-priority location from which to load plugins. This directory needs to contain plugin bundles per the new format. * All Platforms: A custom legacy plugin locations can still be provided via the "OBS_LEGACY_PLUGINS_PATH" and "OBS_LEGACY_PLUGINS_DATA_PATH" environment variables. These are only compatible with plugins using the legacy format and are considered deprecated. Co-authored-by: PatTheMav <PatTheMav@users.noreply.github.com>
PatTheMav
left a comment
There was a problem hiding this comment.
In addition to my comment about virtual camera module unregistering, what changes are necessary in the entire updater infrastructure to facilitate this move?
macOS is entirely unaffected, for Linux this would need to be deferred to packaging systems and how they might handle this, for Windows this is entirely up to the 1st-party updater program.
I'd like to think that for users this process should be entirely hidden, with all known existing files being removed in their old locations and all new files placed in their new locations. Existing unknown files (e.g. third-party plugins) and related directories (i.e. their data directory) should be untouched.
Is the Windows updater capable of handling a "move" of existing?
Ping @Warchamp7.
| if exist "%~dp0\data\obs-plugins\win-dshow\obs-virtualcam-module32.dll" ( | ||
| regsvr32.exe /u /s "%~dp0\data\obs-plugins\win-dshow\obs-virtualcam-module32.dll" | ||
| if exist "%~dp0\data\core\win-dshow\obs-virtualcam-module32.dll" ( | ||
| regsvr32.exe /u /s "%~dp0\data\core\win-dshow\obs-virtualcam-module32.dll" |
There was a problem hiding this comment.
How can we/do we want to handle an existing virtual camera installation?
I'm not too familiar with registration of dshow modules, but if there is an existing registration and the DLL location changes under the hood (maybe because the updater is smart enough to do so), then Windows might retain a dshow filter registration that's invalid?
In any case the code should make it possible for a user to remove an existing registration even if the DLL moved.
There was a problem hiding this comment.
Re: Moving an existing on Windows. In terms of core modules, I'd think we'd go with deleting the existing instead of moving, as the installer should be putting the latest versions of core modules in core, and the old versions would remain in obs-plugins, and data. It should be possible for the installer to remove/cleanup old files.
Currently no, it does not. It's been discussed before but I believe not currently implemented @derrod. |
| // * User Path: <Environment Variable> | ||
| // * Binary: <Environment Variable>/<Plugin>/<Plugin>.so | ||
| // * Data: <Environment Variable>/<Plugin>/data |
There was a problem hiding this comment.
We are at UI level, so we can split Flatpak, PPA and unofficial packages behavior apart.
For Flatpak, <Environment Variable> should not exist at all going forward.
| State flatpakPluginState = State::Failure; | ||
|
|
||
| { | ||
| std::string binaryPath{kLegacyFlatpakPath}; | ||
| std::string dataPath{kLegacyFlatpakPath}; | ||
| binaryPath.append(Constants::kPlatformLibraryPath); | ||
| binaryPath.append("obs-plugins/"); | ||
| dataPath.append(Constants::kPlatformDataPath); | ||
| dataPath.append("obs/obs-plugins/%module%"); | ||
|
|
||
| ModuleLoadInfo info = {.path_info = | ||
| { | ||
| .binary = binaryPath.c_str(), | ||
| .data = dataPath.c_str(), | ||
| }, | ||
| .type = MODULE_TYPE_LEGACY_PLUGIN, | ||
| .name = nullptr}; | ||
|
|
||
| flatpakPluginState = pluginLoadHelper(info, failedModules_); | ||
| } |
There was a problem hiding this comment.
Why this path is not guarded to not run under a non-Flatpak env ?
tytan652
left a comment
There was a problem hiding this comment.
Some documentation typo/fixups.
|
|
||
| // Flatpak 3rd-Party Plugin Locations | ||
| // | ||
| // * Flatppak Path: /app/plugins |
There was a problem hiding this comment.
| // * Flatppak Path: /app/plugins | |
| // * Flatpak Extension Point Path: /app/plugins |
| // * Binary: /app/plugins/<System Library Path>/obs-modules/plugins/<Plugin>.so | ||
| // * Data: /app/plugins/<System Data Path>/share/obs/obs-modules/plugins/<Plugin> | ||
| // | ||
| // * XDG Data Home Path: /home/<User>/.local/share |
There was a problem hiding this comment.
| // * XDG Data Home Path: /home/<User>/.local/share | |
| // * XDG Data Home Path: |
This path is technically invalid in our Flatpak context (the set value is a Flatpak internal behavior).
| // * Binary: <XDG Data Home Path>/obs-studio/plugins/<Plugin>/<Plugin>.so | ||
| // * Data: <XDG Data Home Path>/obs-studio/plugins/<Plugin>/data | ||
| // | ||
| // * XDG Config Home Path: /home/<User>/.config |
There was a problem hiding this comment.
| // * XDG Config Home Path: /home/<User>/.config | |
| // * XDG Config Home Path: |
This path is technically invalid in our Flatpak context (the set value is a Flatpak internal behavior).
| option(ENABLE_FLATPAK "Enable Flatpak-specific implementations." OFF) | ||
| mark_as_advanced(ENABLE_FLATPAK) |
There was a problem hiding this comment.
I'm not 100% sold on using ENABLE_ for naming that option but it's not a major issue.
There was a problem hiding this comment.
FWIW I'm fine with giving it a different name, it's just what I came up with to present how/where that variable comes into play in the build setup.
| "branch": "test", | ||
| "separate-locales": false, | ||
| "build-options": { | ||
| "no-debuginfo": true | ||
| }, |
There was a problem hiding this comment.
Are those changes supposed to be made to the actual Flatpak manifest? This looks like a temporary test setup to me..
There was a problem hiding this comment.
Besides two specific line change (merge-dirs and in config-opts), nothing else you end up being commited in this file.
| inline constexpr std::string_view kXDGConfigHomeVariable{"XDG_CONFIG_HOME"}; | ||
| inline constexpr std::string_view kXDGDataHomeVariable{"XDG_DATA_HOME"}; |
There was a problem hiding this comment.
These should not be implemented in the generic header, as they are platform concerns. Those should instead live in the Linux and Flatpak headers.
| constexpr std::string_view kFlatpakPath{"/app/plugins/"}; | ||
| constexpr std::string_view kLegacyFlatpakPath{"/app/plugins/"}; |
There was a problem hiding this comment.
I don't think we need two separate constants for this, as the differentiation between "legacy" and "not legacy" on Flatpak is not in the prefix, but the internal path structure after that (which is covered by the constants above).
| "ENABLE_WEBRTC": false | ||
| "ENABLE_WEBRTC": false, | ||
| "ENABLE_FLATPAK": false |
There was a problem hiding this comment.
The value should be default-initialised to FALSE inside CMake (otherwise the variable is unintialized for other platforms - see also my recent PR with CMake updates that also addresses uninitialised variable errors).
Conceptually nothing outside of the Flatpak manifest should "know", be concerned, or in any other way interact with this configuration value.
Description
This PR is a significant change in how modules and plugins are loaded by OBS. It makes several changes:
target_enablefunctions which is an explicit counterpart to the existingtarget_disablefunction.libobssuch that the libobs initialization code has a list of modules to explicitly load.coredirectory rather than the existingobs-pluginsdirectory to differentiate them from third party plugins.libobsis given platform-specific functionality from loading core modules from their new location. Additionally, the list generated in 3. is used to explicitly load the core modules compiled with the OBS app, exclude any other modules placed in thecoredirectory, and to give an error message and shut OBS down if all required core modules are not found.Motivation and Context
This PR finishes up the restructuring of plugins and plugin loading that was requested as a part of the plugin manager project. The work in this PR defines a much clearer delineation for module loading between libobs and the frontend, and also draws a clear line between core modules and third party plugins. Finally, this re-structuring will streamline the future (planned) installation/uninstall features of the Plugin Manager.
How Has This Been Tested?
The code in this PR has been tested on all three platforms. For all platforms new plugin locations were tested to ensure plugins loaded properly, as well as legacy plugins locations and formats. All legacy plugins are properly flagged. Additionally, broken plugins were tested to ensure they are flagged as failed. Finally, duplicate plugins were tested, and the proper plugin is loaded, and subsequent are blocked.
For core module loading, proper loading of all core modules was tested. Additionally, tests were done to ensure third party modules placed in
coreare not loaded. Finally, missing or unloadable core plugins were tested.Types of changes
Checklist: