From e6a79b6bb28c17c675e1a220683c0b9e3c465140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=B8nner=C3=B8d=20Madsen?= Date: Wed, 28 Oct 2026 11:05:16 +0100 Subject: [PATCH] fix(juce): fail the build on Linux when JUCE is built without curl On Linux, juce::WebInputStream makes HTTPS requests through libcurl. With JUCE_USE_CURL=0 it falls back to a plain-socket client that only accepts http:// URLs, so the module built fine but could never reach the Moonbase API and the product could never activate. The module now stops with an #error in that configuration, naming the fix: leave JUCE_USE_CURL on and pass NEEDS_CURL TRUE to juce_add_plugin() or juce_add_gui_app(). Other platforms use the OS's own HTTP stack and ignore the flag. The docs no longer recommend JUCE_USE_CURL=0 and gain a "Linux needs libcurl" section. The repository's own module targets (JUCE tests, UI snapshots, the sample app, the module-only consumer smoke) switch to NEEDS_CURL TRUE, and the JUCE workflow installs libcurl on Linux. Tested on Linux (JUCE 8.0.4): the JUCE suite passes 165/165 with curl on, and compiling the module with JUCE_USE_CURL=0 stops on the new #error alone. On macOS the suite passes and the module-only consumer smoke still builds with the CURL and OpenSSL lookups disabled. --- .github/workflows/juce.yml | 6 +++-- docs/juce-module.md | 25 ++++++++++++++----- examples/juce-native/CMakeLists.txt | 4 +-- modules/moonbase_licensing/README.md | 9 ++++--- .../juce/juce_http_transport.h | 7 +++--- .../moonbase_licensing/moonbase_licensing.cpp | 9 +++++++ tests/juce/CMakeLists.txt | 4 +-- tests/juce_consumer_smoke/CMakeLists.txt | 6 ++--- tests/visual/CMakeLists.txt | 4 +-- 9 files changed, 51 insertions(+), 23 deletions(-) diff --git a/.github/workflows/juce.yml b/.github/workflows/juce.yml index 9e06c23..b84f230 100644 --- a/.github/workflows/juce.yml +++ b/.github/workflows/juce.yml @@ -9,7 +9,9 @@ name: JUCE module # native backend, i.e. a real cross-backend RS256 round-trip on each OS. The # suite needs nothing from the core SDK target, so the build configures with # -DMOONBASE_JUCE_MODULE_ONLY=ON, which also skips its CURL lookup. OpenSSL is -# still installed because the suite signs its test tokens with it. +# still installed because the suite signs its test tokens with it, and libcurl +# on Linux because JUCE makes HTTPS requests through it there: the module fails +# the build when JUCE_USE_CURL is off on Linux. # # JUCE 9 runs on every OS too. It is the current major line, and it changes # platform code as well as the API (its Linux build needs libxi-dev, for one). @@ -58,7 +60,7 @@ jobs: run: | sudo apt-get update sudo apt-get install -y \ - libssl-dev \ + libssl-dev libcurl4-openssl-dev \ libx11-dev libxext-dev libxinerama-dev libxrandr-dev libxcursor-dev \ libxcomposite-dev libxrender-dev libxi-dev libfreetype6-dev libfontconfig1-dev \ libasound2-dev libglu1-mesa-dev mesa-common-dev xvfb diff --git a/docs/juce-module.md b/docs/juce-module.md index 4bc006b..d7b406a 100644 --- a/docs/juce-module.md +++ b/docs/juce-module.md @@ -22,13 +22,15 @@ This one is too — it has **no third-party dependencies**: | Concern | How | | --- | --- | -| HTTP | `juce::WebInputStream` (`juce_http_transport`) — no CURL | +| HTTP | `juce::WebInputStream` (`juce_http_transport`), so no HTTP library of its own | | JSON | bundled `nlohmann/json` single header (in the module's `vendor/`) | | RS256 JWT verification | OS-native: **Security.framework** (macOS/iOS), **CNG/bcrypt** (Windows), system **libcrypto** (Linux) | -So a downstream project adds the module and builds — nothing to `brew` / `vcpkg` / -`apt` install. *(The only platform caveat: on Linux the module links the -always-present system `libcrypto`. macOS and Windows need nothing beyond the OS.)* +So a downstream project adds the module and builds, with nothing to `brew` or +`vcpkg` install. *(Linux is the one platform with caveats: the module links the +always-present system `libcrypto`, and JUCE needs libcurl there for HTTPS, as the +[Linux note](#linux-needs-libcurl) below explains. macOS and Windows need nothing +beyond the OS.)* The module sets `MOONBASE_CRYPTO_NATIVE` and `MOONBASE_DISABLE_CURL_TRANSPORT` itself; the core SDK keeps its OpenSSL + CURL defaults for non-JUCE consumers, so @@ -44,7 +46,6 @@ Add this repository as a git submodule, then point your build at the module fold juce_add_module(external/moonbase-cpp/modules/moonbase_licensing) target_link_libraries(MyPlugin PRIVATE moonbase_licensing) -target_compile_definitions(MyPlugin PRIVATE JUCE_USE_CURL=0) ``` **CMake, through FetchContent** @@ -65,7 +66,6 @@ set(MOONBASE_JUCE_MODULE_ONLY ON) FetchContent_MakeAvailable(moonbase_cpp) # after JUCE target_link_libraries(MyPlugin PRIVATE moonbase_licensing) -target_compile_definitions(MyPlugin PRIVATE JUCE_USE_CURL=0) ``` **Projucer** — *Modules → Add a module from a specified folder…* → select @@ -84,6 +84,19 @@ be ambiguous with JUCE's, Carbon's `Point` and GDI's `Rectangle()`, so neither i reachable under its own name once you include the module header. Define `MOONBASE_DISABLE_SYSTEM_NAME_SHIM` if you need them. +### Linux needs libcurl + +On Linux, `juce::WebInputStream` makes HTTPS requests through libcurl. Without it +JUCE can only reach `http://` URLs, so the module could never reach the Moonbase +API. Leave `JUCE_USE_CURL` on (JUCE's default), install libcurl's development +package (`libcurl4-openssl-dev` on Debian and Ubuntu), and pass `NEEDS_CURL TRUE` +to `juce_add_plugin()` or `juce_add_gui_app()` so JUCE links it. In the Projucer, +leave `JUCE_USE_CURL` enabled in `juce_core`'s module settings. + +With `JUCE_USE_CURL=0` the module fails to compile on Linux, rather than build a +product that can never activate. Other platforms use the OS's own HTTP stack and +ignore the flag. + ## Configure + show it ```cpp diff --git a/examples/juce-native/CMakeLists.txt b/examples/juce-native/CMakeLists.txt index 72df2f0..6ce4995 100644 --- a/examples/juce-native/CMakeLists.txt +++ b/examples/juce-native/CMakeLists.txt @@ -9,7 +9,8 @@ juce_add_gui_app(MoonbaseActivationNative PRODUCT_NAME "Moonbase Activation" COMPANY_NAME "Moonbase" BUNDLE_ID "sh.moonbase.activation.native" - VERSION "0.0.1") + VERSION "0.0.1" + NEEDS_CURL TRUE) target_sources(MoonbaseActivationNative PRIVATE Main.cpp) @@ -17,7 +18,6 @@ target_compile_features(MoonbaseActivationNative PRIVATE cxx_std_17) target_compile_definitions(MoonbaseActivationNative PRIVATE JUCE_WEB_BROWSER=0 - JUCE_USE_CURL=0 JUCE_APPLICATION_NAME_STRING="$" JUCE_APPLICATION_VERSION_STRING="$") diff --git a/modules/moonbase_licensing/README.md b/modules/moonbase_licensing/README.md index 7b27a74..bd95ada 100644 --- a/modules/moonbase_licensing/README.md +++ b/modules/moonbase_licensing/README.md @@ -50,10 +50,10 @@ Add the module, fill in three fields, show one component. the plugin opens, stays reachable from an "Update available" badge on the license screen, and "Skip this update" is remembered until a newer version ships. Opt out with `config.enableUpdatePrompt = false`. -- **Zero third-party dependencies.** HTTP over `juce::WebInputStream` (no CURL), JSON +- **Zero third-party dependencies.** HTTP over `juce::WebInputStream`, JSON via a bundled `nlohmann/json`, and RS256 verification via OS-native crypto: Security.framework (macOS/iOS), CNG/bcrypt (Windows), system libcrypto (Linux). - Nothing to `brew`/`vcpkg`/`apt` install. + Nothing to `brew`/`vcpkg` install. On Linux, JUCE itself needs libcurl for HTTPS. - **Batteries included.** Persists the license to a per-user file, fails loud on misconfiguration, exposes a diagnostics sink for field debugging, and can attach JUCE system/host telemetry to requests. Brandable end to end. @@ -86,9 +86,12 @@ Add this repository (as a git submodule, say) and point your build at the module juce_add_module(path/to/moonbase-cpp/modules/moonbase_licensing) target_link_libraries(MyPlugin PRIVATE moonbase_licensing) -target_compile_definitions(MyPlugin PRIVATE JUCE_USE_CURL=0) # keep the zero-dep HTTP path ``` +On Linux, leave `JUCE_USE_CURL` on and pass `NEEDS_CURL TRUE` to `juce_add_plugin()`: +JUCE makes HTTPS requests through libcurl there, and the module fails to compile +without it. See [the JUCE module guide](../../docs/juce-module.md#linux-needs-libcurl). + Prefer `FetchContent` to a submodule? Set `MOONBASE_JUCE_MODULE_ONLY` and the repository adds just this module, with no OpenSSL or CURL lookups. See [the JUCE module guide](../../docs/juce-module.md#add-it-to-your-project). diff --git a/modules/moonbase_licensing/juce/juce_http_transport.h b/modules/moonbase_licensing/juce/juce_http_transport.h index f92d600..4e247c2 100644 --- a/modules/moonbase_licensing/juce/juce_http_transport.h +++ b/modules/moonbase_licensing/juce/juce_http_transport.h @@ -1,9 +1,10 @@ #pragma once // HTTP transport for the Moonbase SDK built on juce::WebInputStream, so the -// module needs no CURL. Build JUCE with JUCE_USE_CURL=0 to keep CURL out -// entirely (the transport uses the platform stack: WinHTTP / NSURLSession / -// libcurl-free POSIX backends). +// module brings no HTTP library of its own. WebInputStream uses the platform +// stack (WinINet / NSURLSession / HttpURLConnection on Android), except on Linux, +// where JUCE makes HTTPS requests through libcurl: moonbase_licensing.cpp fails +// the build when JUCE_USE_CURL is off there. #include #include diff --git a/modules/moonbase_licensing/moonbase_licensing.cpp b/modules/moonbase_licensing/moonbase_licensing.cpp index db27ddd..5850171 100644 --- a/modules/moonbase_licensing/moonbase_licensing.cpp +++ b/modules/moonbase_licensing/moonbase_licensing.cpp @@ -16,6 +16,15 @@ #include "moonbase_licensing.h" +// On Linux, juce::WebInputStream makes HTTPS requests through libcurl. With +// JUCE_USE_CURL=0 it falls back to a plain-socket client that only speaks +// http://, so every call to the Moonbase API would fail at runtime and the +// product could never activate. Stop the build instead. Other platforms use the +// OS's own HTTP stack and ignore JUCE_USE_CURL. +#if (JUCE_LINUX || JUCE_BSD) && ! JUCE_USE_CURL + #error "moonbase_licensing needs JUCE_USE_CURL on Linux: without libcurl, JUCE cannot make HTTPS requests to the Moonbase API. Remove JUCE_USE_CURL=0 and, with CMake, pass NEEDS_CURL TRUE to juce_add_plugin() or juce_add_gui_app()." +#endif + //============================================================================== #include "juce/ActivationController.cpp" #include "juce/ui/ActivationLookAndFeel.cpp" diff --git a/tests/juce/CMakeLists.txt b/tests/juce/CMakeLists.txt index d99b61f..99601c7 100644 --- a/tests/juce/CMakeLists.txt +++ b/tests/juce/CMakeLists.txt @@ -20,7 +20,8 @@ if(NOT TARGET doctest::doctest) endif() juce_add_console_app(MoonbaseJuceTests - PRODUCT_NAME "Moonbase JUCE Tests") + PRODUCT_NAME "Moonbase JUCE Tests" + NEEDS_CURL TRUE) target_sources(MoonbaseJuceTests PRIVATE controller_tests.cpp @@ -32,7 +33,6 @@ target_compile_features(MoonbaseJuceTests PRIVATE cxx_std_17) target_compile_definitions(MoonbaseJuceTests PRIVATE JUCE_WEB_BROWSER=0 - JUCE_USE_CURL=0 JUCE_STANDALONE_APPLICATION=1 JUCE_MODAL_LOOPS_PERMITTED=1 # exposes MessageManager::runDispatchLoopUntil for pumping JUCE_APPLICATION_NAME_STRING="Moonbase JUCE Tests" diff --git a/tests/juce_consumer_smoke/CMakeLists.txt b/tests/juce_consumer_smoke/CMakeLists.txt index ed6cad4..1cc2168 100644 --- a/tests/juce_consumer_smoke/CMakeLists.txt +++ b/tests/juce_consumer_smoke/CMakeLists.txt @@ -29,15 +29,15 @@ add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../.. moonbase_cpp) juce_add_console_app(MoonbaseJuceConsumerSmoke PRODUCT_NAME "Moonbase JUCE Consumer Smoke" - VERSION "1.0.0") + VERSION "1.0.0" + NEEDS_CURL TRUE) target_sources(MoonbaseJuceConsumerSmoke PRIVATE main.cpp) target_compile_features(MoonbaseJuceConsumerSmoke PRIVATE cxx_std_17) target_compile_definitions(MoonbaseJuceConsumerSmoke PRIVATE - JUCE_WEB_BROWSER=0 - JUCE_USE_CURL=0) + JUCE_WEB_BROWSER=0) target_link_libraries(MoonbaseJuceConsumerSmoke PRIVATE moonbase_licensing diff --git a/tests/visual/CMakeLists.txt b/tests/visual/CMakeLists.txt index 280c942..5567e1d 100644 --- a/tests/visual/CMakeLists.txt +++ b/tests/visual/CMakeLists.txt @@ -5,7 +5,8 @@ # .//tests/visual/MoonbaseUiSnapshots ui-snapshots juce_add_console_app(MoonbaseUiSnapshots - PRODUCT_NAME "Moonbase UI Snapshots") + PRODUCT_NAME "Moonbase UI Snapshots" + NEEDS_CURL TRUE) target_sources(MoonbaseUiSnapshots PRIVATE snapshot_main.cpp) @@ -13,7 +14,6 @@ target_compile_features(MoonbaseUiSnapshots PRIVATE cxx_std_17) target_compile_definitions(MoonbaseUiSnapshots PRIVATE JUCE_WEB_BROWSER=0 - JUCE_USE_CURL=0 JUCE_STANDALONE_APPLICATION=1 JUCE_APPLICATION_NAME_STRING="Moonbase UI Snapshots" JUCE_APPLICATION_VERSION_STRING="1.0.0")