From 7286faf3294087f41a24bc37281efa39cbe13a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 5 Aug 2023 21:18:52 +0200 Subject: [PATCH] *converter: make these buildable on platforms w/o dynamic plugins. Such as Emscripten or Android. The hypothetical use case is converting shader files directly on an Android device to debug things, or having a Node.js build of a scene/image converter for "portability". Static plugins can be linked to these if Magnum is built together with Magnum Plugins in a CMake superproject and the plugins are then linked via the MAGNUM_*CONVERTER_STATIC_PLUGINS CMake variable. The fontconverter and distanceconverter tools cause a CMake error on Emscripten as it's not currently possible to access the GPU through a command-line Node.js app. On Android they work though. --- package/archlinux/PKGBUILD-android-arm64 | 5 +++++ package/archlinux/PKGBUILD-emscripten-wasm | 5 +++++ .../archlinux/PKGBUILD-emscripten-wasm-webgl2 | 5 +++++ package/ci/android-x86-gles.sh | 5 +++++ package/ci/emscripten.sh | 5 +++++ src/Magnum/SceneTools/sceneconverter.cpp | 17 ++++++++++++++--- src/Magnum/ShaderTools/shaderconverter.cpp | 7 ++++++- src/Magnum/Text/CMakeLists.txt | 3 +++ src/Magnum/Text/fontconverter.cpp | 17 ++++++++++++++--- src/Magnum/TextureTools/CMakeLists.txt | 5 ++++- .../TextureTools/distancefieldconverter.cpp | 12 ++++++++++-- src/Magnum/Trade/imageconverter.cpp | 12 ++++++++++-- 12 files changed, 86 insertions(+), 12 deletions(-) diff --git a/package/archlinux/PKGBUILD-android-arm64 b/package/archlinux/PKGBUILD-android-arm64 index 912e749f0..89fabfc2b 100644 --- a/package/archlinux/PKGBUILD-android-arm64 +++ b/package/archlinux/PKGBUILD-android-arm64 @@ -50,6 +50,11 @@ build() { -DMAGNUM_WITH_ANDROIDAPPLICATION=ON \ -DMAGNUM_WITH_EGLCONTEXT=ON \ -DMAGNUM_WITH_WINDOWLESSEGLAPPLICATION=ON \ + -DMAGNUM_WITH_DISTANCEFIELDCONVERTER=ON \ + -DMAGNUM_WITH_FONTCONVERTER=ON \ + -DMAGNUM_WITH_IMAGECONVERTER=ON \ + -DMAGNUM_WITH_SCENECONVERTER=ON \ + -DMAGNUM_WITH_SHADERCONVERTER=ON \ -DMAGNUM_WITH_GL_INFO=ON \ -DMAGNUM_WITH_VK_INFO=ON \ -DMAGNUM_TARGET_GLES2=OFF \ diff --git a/package/archlinux/PKGBUILD-emscripten-wasm b/package/archlinux/PKGBUILD-emscripten-wasm index 80924061a..f75718bb4 100644 --- a/package/archlinux/PKGBUILD-emscripten-wasm +++ b/package/archlinux/PKGBUILD-emscripten-wasm @@ -52,6 +52,11 @@ build() { -DMAGNUM_WITH_TGAIMAGECONVERTER=ON \ -DMAGNUM_WITH_TGAIMPORTER=ON \ -DMAGNUM_WITH_WAVAUDIOIMPORTER=ON \ + -DMAGNUM_WITH_DISTANCEFIELDCONVERTER=OFF \ + -DMAGNUM_WITH_FONTCONVERTER=OFF \ + -DMAGNUM_WITH_IMAGECONVERTER=ON \ + -DMAGNUM_WITH_SCENECONVERTER=ON \ + -DMAGNUM_WITH_SHADERCONVERTER=ON \ -DMAGNUM_WITH_GL_INFO=ON \ -DMAGNUM_WITH_AL_INFO=ON \ -DMAGNUM_BUILD_TESTS=ON \ diff --git a/package/archlinux/PKGBUILD-emscripten-wasm-webgl2 b/package/archlinux/PKGBUILD-emscripten-wasm-webgl2 index cb0c7490b..42a55481d 100644 --- a/package/archlinux/PKGBUILD-emscripten-wasm-webgl2 +++ b/package/archlinux/PKGBUILD-emscripten-wasm-webgl2 @@ -53,6 +53,11 @@ build() { -DMAGNUM_WITH_TGAIMAGECONVERTER=ON \ -DMAGNUM_WITH_TGAIMPORTER=ON \ -DMAGNUM_WITH_WAVAUDIOIMPORTER=ON \ + -DMAGNUM_WITH_DISTANCEFIELDCONVERTER=OFF \ + -DMAGNUM_WITH_FONTCONVERTER=OFF \ + -DMAGNUM_WITH_IMAGECONVERTER=ON \ + -DMAGNUM_WITH_SCENECONVERTER=ON \ + -DMAGNUM_WITH_SHADERCONVERTER=ON \ -DMAGNUM_WITH_GL_INFO=ON \ -DMAGNUM_WITH_AL_INFO=ON \ -DMAGNUM_BUILD_TESTS=ON \ diff --git a/package/ci/android-x86-gles.sh b/package/ci/android-x86-gles.sh index 074d1e1f9..806bf42f9 100755 --- a/package/ci/android-x86-gles.sh +++ b/package/ci/android-x86-gles.sh @@ -72,6 +72,11 @@ cmake .. \ -DMAGNUM_WITH_TGAIMAGECONVERTER=ON \ -DMAGNUM_WITH_TGAIMPORTER=ON \ -DMAGNUM_WITH_WAVAUDIOIMPORTER=OFF \ + -DMAGNUM_WITH_DISTANCEFIELDCONVERTER=ON \ + -DMAGNUM_WITH_FONTCONVERTER=ON \ + -DMAGNUM_WITH_IMAGECONVERTER=ON \ + -DMAGNUM_WITH_SCENECONVERTER=ON \ + -DMAGNUM_WITH_SHADERCONVERTER=ON \ -DMAGNUM_WITH_GL_INFO=ON \ -DMAGNUM_BUILD_TESTS=ON \ -DMAGNUM_BUILD_GL_TESTS=ON \ diff --git a/package/ci/emscripten.sh b/package/ci/emscripten.sh index f0b01fd05..4c2eddd30 100755 --- a/package/ci/emscripten.sh +++ b/package/ci/emscripten.sh @@ -63,6 +63,11 @@ cmake .. \ -DMAGNUM_WITH_TGAIMAGECONVERTER=ON \ -DMAGNUM_WITH_TGAIMPORTER=ON \ -DMAGNUM_WITH_WAVAUDIOIMPORTER=ON \ + -DMAGNUM_WITH_DISTANCEFIELDCONVERTER=OFF \ + -DMAGNUM_WITH_FONTCONVERTER=OFF \ + -DMAGNUM_WITH_IMAGECONVERTER=ON \ + -DMAGNUM_WITH_SCENECONVERTER=ON \ + -DMAGNUM_WITH_SHADERCONVERTER=ON \ -DMAGNUM_WITH_GL_INFO=ON \ -DMAGNUM_WITH_AL_INFO=ON \ -DMAGNUM_BUILD_TESTS=ON \ diff --git a/src/Magnum/SceneTools/sceneconverter.cpp b/src/Magnum/SceneTools/sceneconverter.cpp index 1d6a56175..9b640888d 100644 --- a/src/Magnum/SceneTools/sceneconverter.cpp +++ b/src/Magnum/SceneTools/sceneconverter.cpp @@ -418,7 +418,9 @@ int main(int argc, char** argv) { .addArrayOption('C', "converter").setHelp("converter", "scene converter plugin(s)", "PLUGIN") .addArrayOption('P', "image-converter").setHelp("image-converter", "converter plugin(s) to apply to each image in the scene", "PLUGIN") .addArrayOption('M', "mesh-converter").setHelp("mesh-converter", "converter plugin(s) to apply to each mesh in the scene", "PLUGIN") + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT .addOption("plugin-dir").setHelp("plugin-dir", "override base plugin dir", "DIR") + #endif .addArrayOption("prefer").setHelp("prefer", "prefer particular plugins for given alias(es)", "alias:plugin1,plugin2,…") .addArrayOption("set").setHelp("set", "set global plugin(s) options", "plugin:key=val,key2=val2,…") #if defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) @@ -572,20 +574,29 @@ well, the IDs reference attributes of the first mesh.)") /* Importer manager */ PluginManager::Manager importerManager{ + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT args.value("plugin-dir").empty() ? Containers::String{} : - Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImporter::pluginSearchPaths().back()).second())}; + Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImporter::pluginSearchPaths().back()).second()) + #endif + }; /* Image converter manager for potential dependencies. Needs to be constructed before the scene converter manager for proper destruction order. */ PluginManager::Manager imageConverterManager{ + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT args.value("plugin-dir").empty() ? Containers::String{} : - Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImageConverter::pluginSearchPaths().back()).second())}; + Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImageConverter::pluginSearchPaths().back()).second()) + #endif + }; /* Scene converter manager, register the image converter manager with it */ PluginManager::Manager converterManager{ + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT args.value("plugin-dir").empty() ? Containers::String{} : - Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractSceneConverter::pluginSearchPaths().back()).second())}; + Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractSceneConverter::pluginSearchPaths().back()).second()) + #endif + }; converterManager.registerExternalManager(imageConverterManager); /* Set preferred plugins */ diff --git a/src/Magnum/ShaderTools/shaderconverter.cpp b/src/Magnum/ShaderTools/shaderconverter.cpp index a523bd10a..f18bc90ce 100644 --- a/src/Magnum/ShaderTools/shaderconverter.cpp +++ b/src/Magnum/ShaderTools/shaderconverter.cpp @@ -244,7 +244,9 @@ int main(int argc, char** argv) { .addBooleanOption("validate").setHelp("validate", "validate input") .addBooleanOption("link").setHelp("link", "link multiple input files together") .addArrayOption('C', "converter").setHelp("converter", "shader converter plugin(s)") + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT .addOption("plugin-dir").setHelp("plugin-dir", "override base plugin dir", "DIR") + #endif .addArrayOption('c', "converter-options").setHelp("converter-options", "configuration options to pass to the converter(s)", "key=val,key2=val2,…") .addBooleanOption("info").setHelp("info", "print SPIR-V module info and exit") .addBooleanOption('q', "quiet").setHelp("quiet", "quiet output from converter plugin(s)") @@ -364,8 +366,11 @@ see documentation of a particular converter for more information.)") /* Set up a converter manager */ PluginManager::Manager converterManager{ + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT args.value("plugin-dir").empty() ? Containers::String{} : - Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(ShaderTools::AbstractConverter::pluginSearchPaths().back()).second())}; + Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(ShaderTools::AbstractConverter::pluginSearchPaths().back()).second()) + #endif + }; /* Data passed from one converter to another in case there's more than one */ Containers::Array data; diff --git a/src/Magnum/Text/CMakeLists.txt b/src/Magnum/Text/CMakeLists.txt index 5fa021fb5..bc93f5321 100644 --- a/src/Magnum/Text/CMakeLists.txt +++ b/src/Magnum/Text/CMakeLists.txt @@ -112,6 +112,9 @@ if(MAGNUM_WITH_FONTCONVERTER) if(NOT MAGNUM_TARGET_GL) message(SEND_ERROR "magnum-fontconverter is available only if MAGNUM_TARGET_GL is enabled") endif() + if(CORRADE_TARGET_EMSCRIPTEN) + message(SEND_ERROR "The magnum-fontconverter utility isn't available on Emscripten due to lack of GPU access from Node.js. Set MAGNUM_WITH_FONTCONVERTER to OFF to skip building it.") + endif() find_package(Corrade REQUIRED Main) diff --git a/src/Magnum/Text/fontconverter.cpp b/src/Magnum/Text/fontconverter.cpp index 1a712fce0..f067a64ac 100644 --- a/src/Magnum/Text/fontconverter.cpp +++ b/src/Magnum/Text/fontconverter.cpp @@ -140,7 +140,9 @@ FontConverter::FontConverter(const Arguments& arguments): Platform::WindowlessAp .addArgument("output").setHelp("output", "output filename prefix") .addNamedArgument("font").setHelp("font", "font plugin") .addNamedArgument("converter").setHelp("converter", "font converter plugin") + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT .addOption("plugin-dir").setHelp("plugin-dir", "override base plugin dir", "DIR") + #endif .addOption("characters", "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789?!:;,. ").setHelp("characters", "characters to include in the output") @@ -158,21 +160,30 @@ FontConverter::FontConverter(const Arguments& arguments): Platform::WindowlessAp int FontConverter::exec() { /* Font converter dependencies */ PluginManager::Manager imageConverterManager{ + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT args.value("plugin-dir").empty() ? Containers::String{} : - Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImageConverter::pluginSearchPaths().back()).second())}; + Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImageConverter::pluginSearchPaths().back()).second()) + #endif + }; /* Load font */ PluginManager::Manager fontManager{ + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT args.value("plugin-dir").empty() ? Containers::String{} : - Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(AbstractFont::pluginSearchPaths().back()).second())}; + Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(AbstractFont::pluginSearchPaths().back()).second()) + #endif + }; Containers::Pointer font = fontManager.loadAndInstantiate(args.value("font")); if(!font) return 1; /* Register the image converter manager for potential dependencies (MagnumFontConverter needs TgaImageConverter, for example) */ PluginManager::Manager converterManager{ + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT args.value("plugin-dir").empty() ? Containers::String{} : - Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(AbstractFontConverter::pluginSearchPaths().back()).second())}; + Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(AbstractFontConverter::pluginSearchPaths().back()).second()) + #endif + }; converterManager.registerExternalManager(imageConverterManager); /* Load font converter */ diff --git a/src/Magnum/TextureTools/CMakeLists.txt b/src/Magnum/TextureTools/CMakeLists.txt index e076689de..69bd564a9 100644 --- a/src/Magnum/TextureTools/CMakeLists.txt +++ b/src/Magnum/TextureTools/CMakeLists.txt @@ -89,7 +89,10 @@ install(FILES ${MagnumTextureTools_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL if(MAGNUM_WITH_DISTANCEFIELDCONVERTER) if(NOT MAGNUM_TARGET_GL) - message(SEND_ERROR "magnum-distancefieldconverter is available only if MAGNUM_TARGET_GL is enabled") + message(SEND_ERROR "The magnum-distancefieldconverter utility is available only if MAGNUM_TARGET_GL is enabled") + endif() + if(CORRADE_TARGET_EMSCRIPTEN) + message(SEND_ERROR "The magnum-distancefieldconverter utility isn't available on Emscripten due to lack of GPU access from Node.js. Set MAGNUM_WITH_DISTANCEFIELDCONVERTER to OFF to skip building it.") endif() find_package(Corrade REQUIRED Main) diff --git a/src/Magnum/TextureTools/distancefieldconverter.cpp b/src/Magnum/TextureTools/distancefieldconverter.cpp index 6f68288de..59b2f7022 100644 --- a/src/Magnum/TextureTools/distancefieldconverter.cpp +++ b/src/Magnum/TextureTools/distancefieldconverter.cpp @@ -144,7 +144,9 @@ DistanceFieldConverter::DistanceFieldConverter(const Arguments& arguments): Plat .addArgument("output").setHelp("output", "output image") .addOption("importer", "AnyImageImporter").setHelp("importer", "image importer plugin") .addOption("converter", "AnyImageConverter").setHelp("converter", "image converter plugin") + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT .addOption("plugin-dir").setHelp("plugin-dir", "override base plugin dir", "DIR") + #endif .addNamedArgument("output-size").setHelp("output-size", "size of output image", "\"X Y\"") .addNamedArgument("radius").setHelp("radius", "distance field computation radius", "N") .addSkippedPrefix("magnum", "engine-specific options") @@ -157,15 +159,21 @@ DistanceFieldConverter::DistanceFieldConverter(const Arguments& arguments): Plat int DistanceFieldConverter::exec() { /* Load importer plugin */ PluginManager::Manager importerManager{ + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT args.value("plugin-dir").empty() ? Containers::String{} : - Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImporter::pluginSearchPaths().back()).second())}; + Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImporter::pluginSearchPaths().back()).second()) + #endif + }; Containers::Pointer importer = importerManager.loadAndInstantiate(args.value("importer")); if(!importer) return 1; /* Load converter plugin */ PluginManager::Manager converterManager{ + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT args.value("plugin-dir").empty() ? Containers::String{} : - Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImageConverter::pluginSearchPaths().back()).second())}; + Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImageConverter::pluginSearchPaths().back()).second()) + #endif + }; Containers::Pointer converter = converterManager.loadAndInstantiate(args.value("converter")); if(!converter) return 2; diff --git a/src/Magnum/Trade/imageconverter.cpp b/src/Magnum/Trade/imageconverter.cpp index e2d5dce54..ef99c31db 100644 --- a/src/Magnum/Trade/imageconverter.cpp +++ b/src/Magnum/Trade/imageconverter.cpp @@ -388,7 +388,9 @@ int main(int argc, char** argv) { .addArgument("output").setHelp("output", "output image; ignored if --info is present, disallowed for --in-place") .addOption('I', "importer", "AnyImageImporter").setHelp("importer", "image importer plugin", "PLUGIN") .addArrayOption('C', "converter").setHelp("converter", "image converter plugin(s)", "PLUGIN") + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT .addOption("plugin-dir").setHelp("plugin-dir", "override base plugin dir", "DIR") + #endif #if defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) .addBooleanOption("map").setHelp("map", "memory-map the input for zero-copy import (works only for standalone files)") #endif @@ -518,11 +520,17 @@ no -C / --converter is specified, AnyImageConverter is used.)") /* Importer and converter manager */ PluginManager::Manager importerManager{ + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT args.value("plugin-dir").empty() ? Containers::String{} : - Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImporter::pluginSearchPaths().back()).second())}; + Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImporter::pluginSearchPaths().back()).second()) + #endif + }; PluginManager::Manager converterManager{ + #ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT args.value("plugin-dir").empty() ? Containers::String{} : - Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImageConverter::pluginSearchPaths().back()).second())}; + Utility::Path::join(args.value("plugin-dir"), Utility::Path::split(Trade::AbstractImageConverter::pluginSearchPaths().back()).second()) + #endif + }; /* Print plugin info, if requested */ if(args.isSet("info-importer")) {