From 985103e7d4df652aa5467c6cb628f80c625b55df Mon Sep 17 00:00:00 2001 From: Aaron Colwell <300262+acolwell@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:28:08 -0800 Subject: [PATCH] Verify plugins are loadable in Windows installer builds and fix missing dependencies (#946) * Add logic to verify that OFX plugins load. * Add missing libheif dependencies. --- .github/workflows/build_installer.yml | 32 +++++++++++++ .github/workflows/verify_plugin_loads.cpp | 58 +++++++++++++++++++++++ tools/jenkins/genDllVersions.sh | 2 + 3 files changed, 92 insertions(+) create mode 100644 .github/workflows/verify_plugin_loads.cpp diff --git a/.github/workflows/build_installer.yml b/.github/workflows/build_installer.yml index 088635c53..9b9ddee8d 100644 --- a/.github/workflows/build_installer.yml +++ b/.github/workflows/build_installer.yml @@ -59,6 +59,22 @@ jobs: echo "INSTALLER_NAME=${INSTALLER_NAME}" >> $GITHUB_OUTPUT echo "INSTALLER_DIR=$(cygpath -m ${INSTALLER_DIR})" >> $GITHUB_OUTPUT + - name: Build verify_plugin_loads binary + run: | + g++ -DWINDOWS -o verify_plugin_loads .github/workflows/verify_plugin_loads.cpp libs/OpenFX/HostSupport/src/ofxhBinary.cpp libs/OpenFX/HostSupport/src/ofxhUtilities.cpp -I libs/OpenFX/HostSupport/include/ -I libs/OpenFX/include/ + + - name: Uninstall Natron dependencies + run: | + pacman -Rs --noconfirm mingw-w64-x86_64-natron-build-deps-qt5 + + - name: Verify plugin loading + run: | + INSTALLER_DIR=$(cygpath -u '${{ steps.build.outputs.INSTALLER_DIR }}')/${{ steps.build.outputs.INSTALLER_NAME }} + for x in $(find ${INSTALLER_DIR}/Plugins -name *.ofx); do + echo "Testing $(basename ${x}) ..." + PATH=${INSTALLER_DIR}/bin ./verify_plugin_loads.exe "${x}" + done + - name: Upload artifacts uses: actions/upload-artifact@v4.3.1 with: @@ -125,6 +141,22 @@ jobs: echo "SYMBOLS_NAME=${SYMBOLS_NAME}" >> $GITHUB_OUTPUT echo "SYMBOLS_DIR=$(cygpath -m ${SYMBOLS_DIR})" >> $GITHUB_OUTPUT + - name: Build verify_plugin_loads binary + run: | + g++ -DWINDOWS -o verify_plugin_loads .github/workflows/verify_plugin_loads.cpp libs/OpenFX/HostSupport/src/ofxhBinary.cpp libs/OpenFX/HostSupport/src/ofxhUtilities.cpp -I libs/OpenFX/HostSupport/include/ -I libs/OpenFX/include/ + + - name: Uninstall Natron dependencies + run: | + pacman -Rs --noconfirm mingw-w64-x86_64-natron-build-deps-qt5 + + - name: Verify plugin loading + run: | + INSTALLER_DIR=$(cygpath -u '${{ steps.build.outputs.INSTALLER_DIR }}')/${{ steps.build.outputs.INSTALLER_NAME }} + for x in $(find ${INSTALLER_DIR}/Plugins -name *.ofx); do + echo "Testing $(basename ${x}) ..." + PATH=${INSTALLER_DIR}/bin ./verify_plugin_loads.exe "${x}" + done + - name: Upload installer uses: actions/upload-artifact@v4.3.1 with: diff --git a/.github/workflows/verify_plugin_loads.cpp b/.github/workflows/verify_plugin_loads.cpp new file mode 100644 index 000000000..6bc1dbd60 --- /dev/null +++ b/.github/workflows/verify_plugin_loads.cpp @@ -0,0 +1,58 @@ + +#include "ofxhBinary.h" +#include "ofxhPluginCache.h" + +int +main(int argc, const char* argv[]) +{ + if (argc < 2) { + std::cerr << "Usage: " << argv[0] << " \n"; + return 1; + } + + const char* const binaryPath = argv[1]; + + // TODO: Change code to _dlHandle = dlopen(_binaryPath.c_str(), RTLD_NOW|RTLD_LOCAL); + OFX::Binary bin(binaryPath); + + if (bin.isInvalid()) { + std::cerr << "error: '" << binaryPath << "' is invalid.\n"; + return 1; + } + + bin.load(); + + if (!bin.isLoaded()) { + std::cerr << "error: '" << binaryPath << "' failed to load.\n"; + return 1; + } + + auto* getNumberOfPlugins = (OFX::Host::OfxGetNumberOfPluginsFunc)bin.findSymbol("OfxGetNumberOfPlugins"); + auto* getPluginFunc = (OFX::Host::OfxGetPluginFunc)bin.findSymbol("OfxGetPlugin"); + + if (getNumberOfPlugins == nullptr || getPluginFunc == nullptr) { + std::cerr << "error: '" << binaryPath << "' missing required symbols.\n"; + return 1; + } + + const int numPlugins = getNumberOfPlugins(); + + std::cout << "numPlugins: " << numPlugins << "\n"; + + if (numPlugins <= 0) { + std::cerr << "error: unexpected number of plugins.\n"; + return 1; + } + + for (int i = 0; i < numPlugins; ++i) { + auto* plugin = getPluginFunc(i); + if (plugin == nullptr) { + std::cerr << "Failed to get plugin " << i << "\n"; + return 1; + } + + std::cout << "plugin[" << i << "] : " << plugin->pluginIdentifier << " v" << plugin->pluginVersionMajor << "." << plugin->pluginVersionMinor << "\n"; + } + + return 0; +} \ No newline at end of file diff --git a/tools/jenkins/genDllVersions.sh b/tools/jenkins/genDllVersions.sh index 1e5a42814..6503dda63 100755 --- a/tools/jenkins/genDllVersions.sh +++ b/tools/jenkins/genDllVersions.sh @@ -254,6 +254,8 @@ catDll libdatrie- catDll libsnappy #catDll libpugixml catDll libheif +catDll libkvazaar- +catDll libcryptopp catDll rav1e catDll libde265- catDll libx265