From 4e8493c6a42e6244fbad680c14d05af1da8f497e Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 25 Jun 2026 01:20:21 -0500 Subject: [PATCH 1/8] Add BUILD_CURL_HTTP_CLIENT option to build Linux without curl/TLS On the CPP11/curl path (non-Apple, non-Windows), the built-in libcurl HTTP client was always compiled and curl was a hard find_package(CURL REQUIRED) dependency -- pulling in curl and a TLS backend (OpenSSL/mbedTLS) even for hosts that already have their own HTTP stack. Add option(BUILD_CURL_HTTP_CLIENT ON). When OFF, the curl block is skipped (no find_package(CURL), no link, no -DHAVE_MAT_CURL_HTTP_CLIENT) and the build instead defines -DMATSDK_NO_DEFAULT_HTTP_CLIENT. mat/config.h then undefines HAVE_MAT_DEFAULT_HTTP_CLIENT centrally (regardless of the config preset), which the SDK already handles end-to-end: HttpClientFactory and HttpClient_Curl.cpp compile out, and LogManagerImpl's existing !HAVE_MAT_DEFAULT_HTTP_CLIENT branch requires the host to supply an IHttpClient via CFG_MODULE_HTTP_CLIENT. Default ON keeps existing behavior unchanged. Apple/Windows are unaffected (they use native HTTP stacks and never enter the curl block). Validated on WSL x64-linux: with OFF, libmat has no curl symbols and a consumer links with no -lcurl/-lTLS (1.43 MB stripped, vs 4.39 MB with curl+mbedTLS and 10.65 MB with curl+OpenSSL). Files changed: - CMakeLists.txt: BUILD_CURL_HTTP_CLIENT option + gating - lib/include/mat/config.h: central HAVE_MAT_DEFAULT_HTTP_CLIENT opt-out Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CMakeLists.txt | 39 +++++++++++++++++++++++++++------------ lib/include/mat/config.h | 10 ++++++++++ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 360bf7436..acb676355 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -355,27 +355,42 @@ endif() # HTTP stack section ################################################################################################ +# Built-in libcurl HTTP client. Disable to omit curl (and its TLS backend, e.g. +# OpenSSL/mbedTLS) from the build; the host must then supply an IHttpClient via +# CFG_MODULE_HTTP_CLIENT. Only meaningful on the CPP11/curl path (non-Apple, +# non-Windows); Apple/Windows use their native HTTP stacks regardless. +option(BUILD_CURL_HTTP_CLIENT "Build the built-in libcurl HTTP client" ON) + # Only use custom curl if compiling with CPP11 PAL set(MATSDK_NEEDS_CURL OFF) if(PAL_IMPLEMENTATION STREQUAL "CPP11" AND NOT BUILD_IOS AND (NOT CMAKE_SYSTEM_NAME STREQUAL "Android" OR MATSDK_USE_VCPKG_DEPS) AND NOT BUILD_APPLE_HTTP) - set(MATSDK_NEEDS_CURL ON) - add_definitions(-DHAVE_MAT_CURL_HTTP_CLIENT) - find_package(CURL REQUIRED) - if(MATSDK_USE_VCPKG_DEPS) - list(APPEND LIBS CURL::libcurl) - else() - # Prefer the imported target, which carries curl's include dirs and link - # flags. Fall back to the find-module variables on CMake < 3.12, where - # find_package(CURL) does not define CURL::libcurl. - if(TARGET CURL::libcurl) + if(BUILD_CURL_HTTP_CLIENT) + set(MATSDK_NEEDS_CURL ON) + add_definitions(-DHAVE_MAT_CURL_HTTP_CLIENT) + find_package(CURL REQUIRED) + if(MATSDK_USE_VCPKG_DEPS) list(APPEND LIBS CURL::libcurl) else() - include_directories(${CURL_INCLUDE_DIRS}) - list(APPEND LIBS "${CURL_LIBRARIES}") + # Prefer the imported target, which carries curl's include dirs and link + # flags. Fall back to the find-module variables on CMake < 3.12, where + # find_package(CURL) does not define CURL::libcurl. + if(TARGET CURL::libcurl) + list(APPEND LIBS CURL::libcurl) + else() + include_directories(${CURL_INCLUDE_DIRS}) + list(APPEND LIBS "${CURL_LIBRARIES}") + endif() endif() + else() + # No built-in HTTP client: omit the default client entirely so neither + # libcurl nor a TLS backend is linked. mat/config.h turns off + # HAVE_MAT_DEFAULT_HTTP_CLIENT in response, and LogManagerImpl then requires + # the host to provide an IHttpClient via CFG_MODULE_HTTP_CLIENT. + add_definitions(-DMATSDK_NO_DEFAULT_HTTP_CLIENT) + message(STATUS "BUILD_CURL_HTTP_CLIENT=OFF: omitting built-in HTTP client; host must supply IHttpClient via CFG_MODULE_HTTP_CLIENT") endif() endif() diff --git a/lib/include/mat/config.h b/lib/include/mat/config.h index 4baa54796..556a9c996 100644 --- a/lib/include/mat/config.h +++ b/lib/include/mat/config.h @@ -14,6 +14,16 @@ #include "config-default.h" #endif +/* Allow the build to omit the built-in default HTTP client. When the host + * supplies its own IHttpClient (via CFG_MODULE_HTTP_CLIENT) it can build with + * -DMATSDK_NO_DEFAULT_HTTP_CLIENT (set by CMake when BUILD_CURL_HTTP_CLIENT=OFF) + * to avoid compiling/linking any built-in client -- e.g. to drop libcurl and its + * TLS backend on Linux. This undefines the macro regardless of which config + * preset above defined it. */ +#if defined(MATSDK_NO_DEFAULT_HTTP_CLIENT) && defined(HAVE_MAT_DEFAULT_HTTP_CLIENT) +#undef HAVE_MAT_DEFAULT_HTTP_CLIENT +#endif + #if !defined(MATSDK_PAL_WIN32) && !defined(MATSDK_PAL_CPP11) #if defined(_WIN32) #define MATSDK_PAL_WIN32 From 167fc2bacb670cbb657bd3d6c53aaa76d7221ef6 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 25 Jun 2026 04:21:21 -0500 Subject: [PATCH 2/8] Add MATSDK_MINIMAL_SQLITE: private feature-stripped SQLite to cut footprint The SDK uses SQLite only for its offline event-storage cache (plain tables, transactions, WAL, autovacuum/VACUUM, a few PRAGMAs, and one custom UTF-8 function), so most SQLite subsystems are dead weight. Add an option to compile a private SQLite from the vendored amalgamation with a set of amalgamation-safe strip flags (single source of truth: MATSDK_SQLITE_MINIMAL_DEFS), removing the external sqlite3 dependency and shrinking SQLite ~10.2% (.text) / ~12.5% (object). - Root CMakeLists.txt: add option(MATSDK_MINIMAL_SQLITE) (default OFF). In vcpkg mode, skip find_package(unofficial-sqlite3) when bundling, and emit a clear FATAL_ERROR pointing at the system-sqlite/minimal-sqlite features when neither provides SQLite (e.g. a bare [core] install). - lib/CMakeLists.txt: define MATSDK_SQLITE_MINIMAL_DEFS, compute MATSDK_BUNDLE_SQLITE (minimal OR vendored-Android), and build a single sqlite3_bundled. The strip flags are applied ONLY when MATSDK_MINIMAL_SQLITE is ON, so the default Android legacy build keeps its existing unstripped bundled SQLite. Warnings are disabled on the vendored target (/w on MSVC, -w on GCC/Clang for the stripped build) so the SDK's -Werror/-WX does not fire on amalgamation code. A static mat propagates the PRIVATE sqlite3_bundled through its link interface, so export+install it. - MSTelemetryConfig.cmake.in: skip find_dependency(unofficial-sqlite3) when bundled. - vcpkg port: add a minimal-sqlite feature (-DMATSDK_MINIMAL_SQLITE=ON) and move sqlite3 into a default system-sqlite feature so [core,minimal-sqlite] drops it. - docs/building-with-vcpkg.md: document the feature, the size win, and the static-absorption symbol-visibility caveat. SQLITE_OMIT_AUTOINIT and SQLITE_DEFAULT_MEMSTATUS=0 are deliberately NOT stripped: the former because skipSqliteInitAndShutdown lets the host skip the SDK's explicit sqlite3_initialize() (which the host cannot do against a private SQLite), the latter because the SDK arms a soft heap limit via sqlite3_soft_heap_limit64() that is only enforced while memory statistics are enabled. Validated: vendored Linux Debug (77 offline-storage/SQLite unit tests pass on the debug amalgamation), vcpkg [core,minimal-sqlite] consumer (links MSTelemetry::sqlite3_bundled, runs 10/10, external sqlite3 dropped), default vcpkg path regression (system-sqlite intact), and MSVC compile/link of sqlite3_bundled+mat. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CMakeLists.txt | 28 +++- cmake/MSTelemetryConfig.cmake.in | 6 +- docs/building-with-vcpkg.md | 63 ++++++- lib/CMakeLists.txt | 156 +++++++++++++++--- .../ports/cpp-client-telemetry/portfile.cmake | 9 + tools/ports/cpp-client-telemetry/vcpkg.json | 23 ++- 6 files changed, 249 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index acb676355..8bd647993 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,16 @@ else() endif() message(STATUS "MATSDK_USE_VCPKG_DEPS: ${MATSDK_USE_VCPKG_DEPS}") +# Build a private, feature-stripped copy of the vendored SQLite amalgamation +# instead of linking an external SQLite. The SDK uses SQLite only for its offline +# event-storage cache, so the minimal build (see lib/CMakeLists.txt +# MATSDK_SQLITE_MINIMAL_DEFS) omits every optional SQLite subsystem the SDK does +# not use, shrinking the SQLite code ~10% and removing the external sqlite3 +# dependency. Off by default to preserve the existing external/system-SQLite +# behavior; the Android NDK path always bundles SQLite regardless. +option(MATSDK_MINIMAL_SQLITE "Build a feature-stripped vendored SQLite instead of an external one" OFF) +message(STATUS "MATSDK_MINIMAL_SQLITE: ${MATSDK_MINIMAL_SQLITE}") + # Begin Uncomment for i386 build #set(CMAKE_SYSTEM_PROCESSOR i386) #set(CMAKE_C_FLAGS -m32) @@ -398,10 +408,24 @@ endif() # Dependency resolution (vcpkg mode vs vendored) ################################################################################################ if(MATSDK_USE_VCPKG_DEPS) - find_package(unofficial-sqlite3 CONFIG REQUIRED) + # SQLite is provided by the private minimal build when MATSDK_MINIMAL_SQLITE is + # ON, so only require the external vcpkg sqlite3 package otherwise. + if(NOT MATSDK_MINIMAL_SQLITE) + find_package(unofficial-sqlite3 CONFIG QUIET) + if(NOT unofficial-sqlite3_FOUND) + message(FATAL_ERROR + "SQLite was not found and the minimal SQLite is not enabled. The vcpkg " + "port provides SQLite through one of two features: 'system-sqlite' " + "(default, links the external sqlite3 package) or 'minimal-sqlite' " + "(builds a private feature-stripped SQLite). Install " + "cpp-client-telemetry with its default features, or with " + "[core,minimal-sqlite]. For a direct CMake build, pass " + "-DMATSDK_MINIMAL_SQLITE=ON or ensure unofficial-sqlite3 is discoverable.") + endif() + endif() find_package(ZLIB REQUIRED) find_package(nlohmann_json CONFIG REQUIRED) - message(STATUS "Using vcpkg-provided sqlite3, zlib, nlohmann-json") + message(STATUS "Using vcpkg-provided zlib, nlohmann-json") else() # Include repo root to allow includes of vendored sqlite, zlib, and nlohmann include_directories(${CMAKE_SOURCE_DIR}) diff --git a/cmake/MSTelemetryConfig.cmake.in b/cmake/MSTelemetryConfig.cmake.in index 5cf00c560..f8c7a5d9a 100644 --- a/cmake/MSTelemetryConfig.cmake.in +++ b/cmake/MSTelemetryConfig.cmake.in @@ -3,7 +3,11 @@ include(CMakeFindDependencyMacro) # Re-find dependencies that consumers need -find_dependency(unofficial-sqlite3 CONFIG) +# SQLite is built into the SDK as a private minimal copy when MATSDK_MINIMAL_SQLITE +# is set, so the external sqlite3 package is only re-found when it is not bundled. +if(NOT @MATSDK_BUNDLE_SQLITE@) + find_dependency(unofficial-sqlite3 CONFIG) +endif() find_dependency(ZLIB) find_dependency(nlohmann_json CONFIG) diff --git a/docs/building-with-vcpkg.md b/docs/building-with-vcpkg.md index 7e5cff7d0..5c56373d6 100644 --- a/docs/building-with-vcpkg.md +++ b/docs/building-with-vcpkg.md @@ -145,11 +145,16 @@ The vcpkg port automatically resolves the following dependencies: | Dependency | vcpkg Package | CMake Target | Platforms | | -------------- | --------------- | --------------------------------- | ------------------ | -| SQLite3 | `sqlite3` | `unofficial::sqlite3::sqlite3` | All | +| SQLite3 | `sqlite3` | `unofficial::sqlite3::sqlite3` | All (default; see `minimal-sqlite`) | | zlib | `zlib` | `ZLIB::ZLIB` | All | | nlohmann JSON | `nlohmann-json` | `nlohmann_json::nlohmann_json` | All | | libcurl | `curl[openssl]` | `CURL::libcurl` | Non-Windows, non-Apple | +The external `sqlite3` package is provided by the default `system-sqlite` +feature. The `minimal-sqlite` feature replaces it with a private, feature-stripped +SQLite built from the SDK's vendored amalgamation — see +[Build a private minimal SQLite](#build-a-private-minimal-sqlite-minimal-sqlite-feature). + Windows and macOS/iOS use platform-native HTTP clients (WinInet and NSURLSession respectively). Android vcpkg consumers use native libcurl because the Java-backed `HttpClient_Android` singleton is initialized by the repo's @@ -256,6 +261,62 @@ If any package in your build (or your own code) needs SQLite's JSON functions, request `sqlite3[json1]` instead and the extension is restored for the whole graph. +### Build a private minimal SQLite (`minimal-sqlite` feature) + +For a larger, self-contained reduction, the port can compile a private, +feature-stripped SQLite directly from the SDK's vendored amalgamation instead of +linking the external `sqlite3` package at all. The SDK uses SQLite only for its +offline event-storage cache (plain tables and indexes, transactions, WAL, +autovacuum/`VACUUM`, a few PRAGMAs, and one custom UTF-8 SQL function), so this +build omits the unused SQLite subsystems — `SQLITE_OMIT_JSON` plus load-extension, +shared-cache, deprecated APIs, authorization, EXPLAIN, introspection pragmas, +deserialize, and more. The result is **~10% smaller SQLite code** (`.text`) and +**~13% smaller** as a stripped object, and it drops the external `sqlite3` +dependency from your graph entirely. + +Enable it through the vcpkg feature: + +```json +{ + "dependencies": [ + { + "name": "cpp-client-telemetry", + "default-features": false, + "features": [ "minimal-sqlite" ] + } + ] +} +``` + +Use the `[core,minimal-sqlite]` form (here, `"default-features": false` is the +`[core]` part) so the default `system-sqlite` feature — and its `sqlite3` +dependency — is dropped. Requesting `minimal-sqlite` *without* `[core]` still +pulls in the default `system-sqlite`; that is harmless (the external `sqlite3` is +installed but unused) but does not save the dependency. + +For a plain (non-vcpkg) CMake build, pass the option directly: + +```bash +cmake -DMATSDK_MINIMAL_SQLITE=ON .. +``` + +The strip is **amalgamation-safe**: it changes no SQLite grammar/parser, so no +code generation is required. All offline storage features the SDK relies on (WAL, +autovacuum, `VACUUM`, PRAGMAs, the custom UTF-8 function, blobs, 64-bit integers, +transactions) are retained, and the SDK's offline-storage unit tests pass +unchanged against the minimal build. + +> **Caveat — symbol visibility when linking statically.** The private SQLite keeps +> SQLite's default `sqlite3_*` symbol names. For a **shared** `mat` +> (`mat.dll` / `libmat.so` / `libmat.dylib`), those symbols are hidden by the +> SDK's `-fvisibility=hidden`, so there is no conflict. For a **static** `mat`, +> the minimal SQLite is installed and exported as a separate +> `MSTelemetry::sqlite3_bundled` archive that links into your binary; if **any** +> part of the final static link — your own code *or another dependency* — also +> pulls in SQLite, the duplicate `sqlite3_*` symbols will collide at link time. In +> that case, prefer the default `system-sqlite` feature so the whole graph shares a +> single SQLite. + ## How It Works: MATSDK_USE_VCPKG_DEPS When the SDK detects it is being built via vcpkg (by checking for diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 0d4161811..6a901b23c 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -390,6 +390,93 @@ endif() ################################################################################################ # Link dependencies ################################################################################################ +# --- Minimal SQLite ----------------------------------------------------------- +# The SDK uses SQLite only for its offline event-storage cache: plain tables, +# indexes, transactions, WAL, autovacuum/VACUUM, a handful of PRAGMAs, and one +# custom UTF-8 SQL function. None of SQLite's optional subsystems are needed, so +# when MATSDK_MINIMAL_SQLITE is set the bundled SQLite is compiled with these +# options to strip out everything the SDK does not use (~10% smaller SQLite code). +# They are all amalgamation-safe (no grammar/parser regeneration) and validated +# against the offline-storage unit tests. +# +# Two options are deliberately NOT stripped because the SDK depends on them: +# * SQLITE_OMIT_AUTOINIT: the skipSqliteInitAndShutdown runtime config lets the +# host own SQLite's lifecycle and skip the SDK's explicit sqlite3_initialize() +# (lib/offline/SQLiteWrapper.hpp). With a private bundled SQLite the host cannot +# initialize the SDK's copy, so auto-init must remain on. +# * SQLITE_DEFAULT_MEMSTATUS=0: the SDK arms a soft heap limit via +# sqlite3_soft_heap_limit64(cacheMemorySizeLimitInBytes) on every open, and that +# limit is only enforced while memory statistics are enabled. Disabling them +# would silently turn the configured memory cap into a no-op. +set(MATSDK_SQLITE_MINIMAL_DEFS + SQLITE_DQS=0 + SQLITE_THREADSAFE=1 + SQLITE_DEFAULT_WAL_SYNCHRONOUS=1 + SQLITE_DEFAULT_FOREIGN_KEYS=0 + SQLITE_LIKE_DOESNT_MATCH_BLOBS + SQLITE_MAX_EXPR_DEPTH=0 + SQLITE_MAX_MMAP_SIZE=0 + SQLITE_USE_ALLOCA + SQLITE_OMIT_DEPRECATED + SQLITE_OMIT_PROGRESS_CALLBACK + SQLITE_OMIT_SHARED_CACHE + SQLITE_OMIT_LOAD_EXTENSION + SQLITE_OMIT_DECLTYPE + SQLITE_OMIT_JSON + SQLITE_OMIT_TRACE + SQLITE_OMIT_COMPLETE + SQLITE_OMIT_GET_TABLE + SQLITE_OMIT_TCL_VARIABLE + SQLITE_OMIT_EXPLAIN + SQLITE_OMIT_AUTHORIZATION + SQLITE_OMIT_DESERIALIZE + SQLITE_OMIT_INTROSPECTION_PRAGMAS + SQLITE_UNTESTABLE +) + +# Bundle a vendored SQLite (built from sqlite/sqlite3.c) when MATSDK_MINIMAL_SQLITE +# is requested, or on the Android NDK legacy path (which has no system SQLite and +# has always built the vendored amalgamation). Otherwise an external/system SQLite +# is used. The feature-strip definitions above are applied ONLY when +# MATSDK_MINIMAL_SQLITE is ON, so the default Android legacy build keeps its +# existing (unstripped) bundled SQLite behavior. +set(MATSDK_BUNDLE_SQLITE OFF) +if(MATSDK_MINIMAL_SQLITE) + set(MATSDK_BUNDLE_SQLITE ON) +elseif(NOT MATSDK_USE_VCPKG_DEPS AND CMAKE_SYSTEM_NAME STREQUAL "Android") + set(MATSDK_BUNDLE_SQLITE ON) +endif() + +if(MATSDK_BUNDLE_SQLITE AND NOT TARGET sqlite3_bundled) + add_library(sqlite3_bundled STATIC "${CMAKE_CURRENT_SOURCE_DIR}/../sqlite/sqlite3.c") + # Consumers of MSTelemetry::mat never include sqlite3.h (it is an internal + # implementation detail), so the header path is only needed while building the + # SDK itself -- wrap it in BUILD_INTERFACE so install(EXPORT) stays valid. + target_include_directories(sqlite3_bundled PUBLIC + "$") + set_target_properties(sqlite3_bundled PROPERTIES POSITION_INDEPENDENT_CODE ON) + if(MATSDK_MINIMAL_SQLITE) + # Feature-stripped build: apply the minimal definitions. + target_compile_definitions(sqlite3_bundled PRIVATE ${MATSDK_SQLITE_MINIMAL_DEFS}) + endif() + if(MSVC) + # Silence the vendored amalgamation's warnings so they are not promoted to + # errors by the SDK's /WX, and drop /WX for this third-party translation unit. + target_compile_options(sqlite3_bundled PRIVATE /w) + elseif(MATSDK_MINIMAL_SQLITE) + # -w disables all warnings for this vendored translation unit so the SDK's + # -Werror does not fire on amalgamation code (the OMIT_* options leave some + # debug-build macros expanding to empty/unused statements). -fno-finite-math-only: + # the amalgamation relies on the INFINITY macro, which -ffast-math / + # -ffinite-math-only would break. + target_compile_options(sqlite3_bundled PRIVATE -w -fno-finite-math-only) + else() + # Unstripped vendored build (Android legacy): keep the existing narrower + # warning suppression. -fno-finite-math-only guards the INFINITY macro. + target_compile_options(sqlite3_bundled PRIVATE -fno-finite-math-only -Wno-unused-function) + endif() +endif() + # TODO: allow adding "${Tcmalloc_LIBRARIES}" to target_link_libraries for memory leak debugging # (USE_TCMALLOC / FindTcmalloc.cmake are configured for Debug builds in the root CMakeLists.txt, # but the library is not yet linked here). @@ -397,9 +484,15 @@ if(MATSDK_USE_VCPKG_DEPS) # vcpkg mode: all deps resolved via find_package() in root CMakeLists.txt # These are PUBLIC so static-library consumers get the transitive link set # through the exported MSTelemetry::mat target. + if(MATSDK_BUNDLE_SQLITE) + # Private minimal SQLite instead of the vcpkg sqlite3 package. PRIVATE so the + # SDK-internal copy is not re-exported to consumers. + target_link_libraries(mat PRIVATE sqlite3_bundled) + else() + target_link_libraries(mat PUBLIC unofficial::sqlite3::sqlite3) + endif() target_link_libraries(mat PUBLIC - unofficial::sqlite3::sqlite3 ZLIB::ZLIB nlohmann_json::nlohmann_json ${LIBS} @@ -407,15 +500,9 @@ if(MATSDK_USE_VCPKG_DEPS) else() # Legacy mode: use vendored or system-installed deps if(CMAKE_SYSTEM_NAME STREQUAL "Android") - # Android NDK has no system sqlite3 or zlib — build from bundled source. - add_library(sqlite3_bundled STATIC "${CMAKE_CURRENT_SOURCE_DIR}/../sqlite/sqlite3.c") - target_include_directories(sqlite3_bundled PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../sqlite") - set_target_properties(sqlite3_bundled PROPERTIES POSITION_INDEPENDENT_CODE ON) - # Guard bundled sqlite3 against toolchain or environment flags that imply finite-math-only (uses INFINITY macro). - # Also suppress warnings treated as errors in vendored code. - target_compile_options(sqlite3_bundled PRIVATE -fno-finite-math-only -Wno-unused-function) - - # Build zlib from bundled source. + # Build zlib from bundled source (Android NDK has no system zlib). SQLite is + # provided by sqlite3_bundled, created above (MATSDK_BUNDLE_SQLITE is ON for + # the Android NDK path). add_library(zlib_bundled STATIC "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/adler32.c" "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/compress.c" @@ -445,26 +532,34 @@ else() elseif(PAL_IMPLEMENTATION STREQUAL "WIN32") # Windows legacy: vendored sqlite/zlib headers are included via # include_directories in the PAL section above; link only ${LIBS} - # (e.g. CURL if needed — sqlite/zlib come from .vcxproj references). - target_link_libraries(mat PRIVATE ${LIBS}) - else() - # Linux/macOS legacy: link system-installed sqlite3 and zlib - if(EXISTS "/usr/local/lib/libsqlite3.a") - set(MATSDK_SQLITE3_LIB "/usr/local/lib/libsqlite3.a") - elseif(EXISTS "/usr/local/opt/sqlite/lib/libsqlite3.a") - set(MATSDK_SQLITE3_LIB "/usr/local/opt/sqlite/lib/libsqlite3.a") - elseif(EXISTS "/opt/homebrew/opt/sqlite/lib/libsqlite3.a") - set(MATSDK_SQLITE3_LIB "/opt/homebrew/opt/sqlite/lib/libsqlite3.a") + # (e.g. CURL if needed — sqlite/zlib come from .vcxproj references), plus the + # private minimal SQLite when MATSDK_MINIMAL_SQLITE is enabled. + if(MATSDK_BUNDLE_SQLITE) + target_link_libraries(mat PRIVATE sqlite3_bundled ${LIBS}) else() - # find_package(SQLite3) needs CMake >= 3.14, guaranteed by the project floor; - # SQLite::SQLite3 is an imported target carrying its own include dirs. - find_package(SQLite3 REQUIRED) - set(MATSDK_SQLITE3_LIB SQLite::SQLite3) + target_link_libraries(mat PRIVATE ${LIBS}) endif() - + else() + # Linux/macOS legacy: link system-installed (or private minimal) sqlite3 and system zlib find_package(ZLIB REQUIRED) target_include_directories(mat PRIVATE ${ZLIB_INCLUDE_DIRS}) - target_link_libraries(mat PRIVATE ${MATSDK_SQLITE3_LIB} ZLIB::ZLIB ${LIBS}) + if(MATSDK_BUNDLE_SQLITE) + target_link_libraries(mat PRIVATE sqlite3_bundled ZLIB::ZLIB ${LIBS}) + else() + if(EXISTS "/usr/local/lib/libsqlite3.a") + set(MATSDK_SQLITE3_LIB "/usr/local/lib/libsqlite3.a") + elseif(EXISTS "/usr/local/opt/sqlite/lib/libsqlite3.a") + set(MATSDK_SQLITE3_LIB "/usr/local/opt/sqlite/lib/libsqlite3.a") + elseif(EXISTS "/opt/homebrew/opt/sqlite/lib/libsqlite3.a") + set(MATSDK_SQLITE3_LIB "/opt/homebrew/opt/sqlite/lib/libsqlite3.a") + else() + # find_package(SQLite3) needs CMake >= 3.14, guaranteed by the project floor; + # SQLite::SQLite3 is an imported target carrying its own include dirs. + find_package(SQLite3 REQUIRED) + set(MATSDK_SQLITE3_LIB SQLite::SQLite3) + endif() + target_link_libraries(mat PRIVATE ${MATSDK_SQLITE3_LIB} ZLIB::ZLIB ${LIBS}) + endif() endif() endif() @@ -501,7 +596,14 @@ endif() # consumer that does find_package(MSTelemetry). Legacy (non-vcpkg) builds install # via install.sh or MSBuild output directories and don't need this. if(MATSDK_USE_VCPKG_DEPS) - install(TARGETS mat + # A static libmat propagates its PRIVATE static dependencies through its link + # interface, so the bundled SQLite must be part of the same export set and be + # installed alongside mat for downstream find_package() consumers to link. + set(MATSDK_INSTALL_TARGETS mat) + if(MATSDK_BUNDLE_SQLITE AND TARGET sqlite3_bundled) + list(APPEND MATSDK_INSTALL_TARGETS sqlite3_bundled) + endif() + install(TARGETS ${MATSDK_INSTALL_TARGETS} EXPORT MSTelemetryTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/tools/ports/cpp-client-telemetry/portfile.cmake b/tools/ports/cpp-client-telemetry/portfile.cmake index cfdab2368..20bc4e2b2 100644 --- a/tools/ports/cpp-client-telemetry/portfile.cmake +++ b/tools/ports/cpp-client-telemetry/portfile.cmake @@ -20,9 +20,18 @@ if(VCPKG_TARGET_IS_IOS) set(MATSDK_BUILD_IOS ON) endif() +# minimal-sqlite feature -> build a private feature-stripped SQLite instead of +# linking the external sqlite3 package. Maps to -DMATSDK_MINIMAL_SQLITE=ON/OFF. +vcpkg_check_features( + OUT_FEATURE_OPTIONS FEATURE_OPTIONS + FEATURES + minimal-sqlite MATSDK_MINIMAL_SQLITE +) + vcpkg_cmake_configure( SOURCE_PATH "${SOURCE_PATH}" OPTIONS + ${FEATURE_OPTIONS} -DMATSDK_USE_VCPKG_DEPS=ON -DBUILD_HEADERS=ON -DBUILD_LIBRARY=ON diff --git a/tools/ports/cpp-client-telemetry/vcpkg.json b/tools/ports/cpp-client-telemetry/vcpkg.json index 2ee6d9bc3..980356e54 100644 --- a/tools/ports/cpp-client-telemetry/vcpkg.json +++ b/tools/ports/cpp-client-telemetry/vcpkg.json @@ -15,10 +15,6 @@ "platform": "linux | android" }, "nlohmann-json", - { - "name": "sqlite3", - "default-features": false - }, { "name": "vcpkg-cmake", "host": true @@ -28,5 +24,22 @@ "host": true }, "zlib" - ] + ], + "default-features": [ + "system-sqlite" + ], + "features": { + "system-sqlite": { + "description": "Link the external vcpkg sqlite3 package for the offline storage cache (default).", + "dependencies": [ + { + "name": "sqlite3", + "default-features": false + } + ] + }, + "minimal-sqlite": { + "description": "Build a private, feature-stripped SQLite compiled from the SDK's vendored amalgamation instead of linking the external sqlite3 package. Smaller footprint; combine with [core,minimal-sqlite] to also drop the sqlite3 dependency." + } + } } From 0977e649cdc283222f3dbc36c3f85ccb1b624f88 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 25 Jun 2026 05:13:04 -0500 Subject: [PATCH 3/8] Address Copilot review: scope bundled-SQLite export to static mat - lib/CMakeLists.txt: only add sqlite3_bundled to the install/export set when mat is a STATIC_LIBRARY. A shared mat absorbs the private SQLite into libmat and does not propagate the PRIVATE dependency, so exporting the separate archive there was unnecessary and could let a consumer link a second SQLite copy. For a static mat the archive must stay exported because the static library propagates its PRIVATE dependency through its link interface (\$). - CMakeLists.txt: make the vcpkg dependency-mode status message reflect whether the external sqlite3 package or the private minimal SQLite is used. Verified with an isolated CMake export test: static mat exports m+sq (consumer linking only the namespaced lib resolves sq); shared mat exports only m and install(EXPORT) succeeds with sq excluded. Re-ran the vcpkg [core,minimal-sqlite] consumer (static x64-linux): 10/10. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CMakeLists.txt | 6 +++++- lib/CMakeLists.txt | 13 ++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8bd647993..6854ad2e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -425,7 +425,11 @@ if(MATSDK_USE_VCPKG_DEPS) endif() find_package(ZLIB REQUIRED) find_package(nlohmann_json CONFIG REQUIRED) - message(STATUS "Using vcpkg-provided zlib, nlohmann-json") + if(MATSDK_MINIMAL_SQLITE) + message(STATUS "Using vcpkg-provided zlib, nlohmann-json; private minimal SQLite") + else() + message(STATUS "Using vcpkg-provided sqlite3, zlib, nlohmann-json") + endif() else() # Include repo root to allow includes of vendored sqlite, zlib, and nlohmann include_directories(${CMAKE_SOURCE_DIR}) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 6a901b23c..e034735b7 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -597,11 +597,18 @@ endif() # via install.sh or MSBuild output directories and don't need this. if(MATSDK_USE_VCPKG_DEPS) # A static libmat propagates its PRIVATE static dependencies through its link - # interface, so the bundled SQLite must be part of the same export set and be - # installed alongside mat for downstream find_package() consumers to link. + # interface (as $), so the bundled SQLite must be part of the same + # export set and installed alongside mat for downstream find_package() consumers + # to link. A shared libmat absorbs sqlite3_bundled into the .so/.dylib/.dll and + # does not propagate the PRIVATE dep, so exporting the archive there is + # unnecessary (and risks a consumer linking a second SQLite copy) -- only export + # it for a static mat. set(MATSDK_INSTALL_TARGETS mat) if(MATSDK_BUNDLE_SQLITE AND TARGET sqlite3_bundled) - list(APPEND MATSDK_INSTALL_TARGETS sqlite3_bundled) + get_target_property(_mat_type mat TYPE) + if(_mat_type STREQUAL "STATIC_LIBRARY") + list(APPEND MATSDK_INSTALL_TARGETS sqlite3_bundled) + endif() endif() install(TARGETS ${MATSDK_INSTALL_TARGETS} EXPORT MSTelemetryTargets From 534be72aae811c273d5dfedc50585b008f72281c Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 25 Jun 2026 05:21:29 -0500 Subject: [PATCH 4/8] Clarify sqlite3_bundled PRIVATE-link comment (Copilot review) Correct the inline comment: a PRIVATE link of the bundled SQLite suppresses propagation of its include dirs / compile definitions, but a static mat still propagates the archive for linking via \$ (hence it is exported for static builds); a shared mat absorbs it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- lib/CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index e034735b7..a9cc8cc77 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -485,8 +485,11 @@ if(MATSDK_USE_VCPKG_DEPS) # These are PUBLIC so static-library consumers get the transitive link set # through the exported MSTelemetry::mat target. if(MATSDK_BUNDLE_SQLITE) - # Private minimal SQLite instead of the vcpkg sqlite3 package. PRIVATE so the - # SDK-internal copy is not re-exported to consumers. + # Private minimal SQLite instead of the vcpkg sqlite3 package. PRIVATE so its + # include dirs / compile definitions are not propagated as a public usage + # requirement. A static mat still propagates the archive itself for linking + # (via $), so it is added to the export set for static builds + # below; a shared mat absorbs it and propagates nothing. target_link_libraries(mat PRIVATE sqlite3_bundled) else() target_link_libraries(mat PUBLIC unofficial::sqlite3::sqlite3) From 2c88c16efda9362b7b4083f1eadcb4f65251c772 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 25 Jun 2026 11:50:41 -0500 Subject: [PATCH 5/8] vcpkg port: selectable TLS backend (curl-openssl/curl-mbedtls) + no-default-http-client feature Make the HTTP-client footprint a consumer choice instead of hardcoding curl[openssl]: - vcpkg.json: replace the base curl[openssl] dependency with three features -- curl-openssl (default; libcurl + OpenSSL), curl-mbedtls (libcurl + mbedTLS), and no-default-http-client (omit the built-in client). curl-openssl is a default feature so a plain install keeps current behavior; [core,no-default-http-client] drops curl entirely. - portfile.cmake: map the no-default-http-client feature to -DBUILD_CURL_HTTP_CLIENT=OFF via INVERTED_FEATURES. - CMakeLists.txt: when the built-in client is enabled in vcpkg mode but libcurl is not found, emit a clear FATAL_ERROR pointing at the curl-openssl/curl-mbedtls/ no-default-http-client features (instead of a bare find_package failure). - docs: document the size ladder (OpenSSL ~10.6MB / mbedTLS ~4.4MB / no-curl ~1.4MB) and the exact mbedTLS recipe -- crucially, the consumer must ALSO list curl with default-features:false at the top level, because vcpkg only honors curl's default-features:false for top-level dependencies (otherwise curl's ssl default pulls OpenSSL in transitively alongside mbedTLS). Validated on WSL with vcpkg: default resolves curl[openssl]+sqlite3; the documented mbedTLS recipe builds with mbedTLS only (no libssl/libcrypto, libcurl carries no OpenSSL symbols) and the consumer runs; [core,no-default-http-client] drops curl from the graph; [core,minimal-sqlite,no-default-http-client] drops curl and the external sqlite3. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CMakeLists.txt | 14 ++++- docs/building-with-vcpkg.md | 59 ++++++++++++++++++- .../ports/cpp-client-telemetry/portfile.cmake | 10 +++- tools/ports/cpp-client-telemetry/vcpkg.json | 40 ++++++++++--- 4 files changed, 110 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6854ad2e6..598a07f22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -380,10 +380,22 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11" if(BUILD_CURL_HTTP_CLIENT) set(MATSDK_NEEDS_CURL ON) add_definitions(-DHAVE_MAT_CURL_HTTP_CLIENT) - find_package(CURL REQUIRED) if(MATSDK_USE_VCPKG_DEPS) + # The TLS backend (OpenSSL/mbedTLS) is selected by the vcpkg port's + # curl-openssl (default) / curl-mbedtls features; the SDK just links libcurl. + find_package(CURL QUIET) + if(NOT CURL_FOUND) + message(FATAL_ERROR + "libcurl was not found but the built-in HTTP client is enabled. The " + "vcpkg port provides the curl HTTP client through the curl-openssl " + "(default) or curl-mbedtls feature, or you can omit it with the " + "no-default-http-client feature (host supplies its own IHttpClient). " + "Install cpp-client-telemetry with its default features, with " + "[core,curl-mbedtls], or with [core,no-default-http-client].") + endif() list(APPEND LIBS CURL::libcurl) else() + find_package(CURL REQUIRED) # Prefer the imported target, which carries curl's include dirs and link # flags. Fall back to the find-module variables on CMake < 3.12, where # find_package(CURL) does not define CURL::libcurl. diff --git a/docs/building-with-vcpkg.md b/docs/building-with-vcpkg.md index 5c56373d6..3e07c15da 100644 --- a/docs/building-with-vcpkg.md +++ b/docs/building-with-vcpkg.md @@ -148,13 +148,18 @@ The vcpkg port automatically resolves the following dependencies: | SQLite3 | `sqlite3` | `unofficial::sqlite3::sqlite3` | All (default; see `minimal-sqlite`) | | zlib | `zlib` | `ZLIB::ZLIB` | All | | nlohmann JSON | `nlohmann-json` | `nlohmann_json::nlohmann_json` | All | -| libcurl | `curl[openssl]` | `CURL::libcurl` | Non-Windows, non-Apple | +| libcurl | `curl[openssl]` or `curl[mbedtls]` | `CURL::libcurl` | Non-Windows, non-Apple (selectable; optional) | The external `sqlite3` package is provided by the default `system-sqlite` feature. The `minimal-sqlite` feature replaces it with a private, feature-stripped SQLite built from the SDK's vendored amalgamation — see [Build a private minimal SQLite](#build-a-private-minimal-sqlite-minimal-sqlite-feature). +libcurl is provided by the default `curl-openssl` feature; `curl-mbedtls` swaps in +the mbedTLS backend, and `no-default-http-client` drops the built-in client +entirely — see +[Choose the HTTP client / TLS backend](#choose-the-http-client--tls-backend-largest-lever-on-linux). + Windows and macOS/iOS use platform-native HTTP clients (WinInet and NSURLSession respectively). Android vcpkg consumers use native libcurl because the Java-backed `HttpClient_Android` singleton is initialized by the repo's @@ -235,6 +240,58 @@ the stripping happens at your link. Keep the SDK a static dependency linked *into* your binary: if you re-export its API across your own DLL boundary, the export table pins its symbols and defeats `/OPT:REF`. +### Choose the HTTP client / TLS backend (largest lever on Linux) + +On Linux/Android the built-in HTTP client is libcurl, and curl's TLS backend +dominates the SDK's footprint. (Windows uses WinInet and Apple uses NSURLSession, +so this section does not apply there.) The port exposes three mutually-exclusive +choices as features; pick the one that matches what your application already has: + +| Feature | Transport | Approx. stripped size¹ | Use when | +| ------- | --------- | ---------------------- | -------- | +| `curl-openssl` (default) | libcurl + OpenSSL | ~10.6 MB | your app already links OpenSSL (share it) | +| `curl-mbedtls` | libcurl + mbedTLS | ~4.4 MB | your app has no HTTP/TLS stack of its own | +| `no-default-http-client` | none (host-supplied) | ~1.4 MB | your app already has its own HTTP client | + +¹ Rough stripped sizes of a minimal Linux consumer measured for this SDK; your +numbers depend on triplet, dead-stripping, and what else shares those libraries. + +To select **mbedTLS**, two things are required in *your top-level* manifest: + +```json +{ + "dependencies": [ + { + "name": "cpp-client-telemetry", + "default-features": false, + "features": [ "minimal-sqlite", "curl-mbedtls" ] + }, + { "name": "curl", "default-features": false, "features": [ "mbedtls" ] } + ] +} +``` + +1. `[core,curl-mbedtls]` (the `"default-features": false` form) drops the SDK's + default `curl-openssl` feature, so the SDK no longer *requests* OpenSSL. +2. The explicit top-level `curl` entry is also needed because vcpkg honors curl's + own `"default-features": false` **only for top-level dependencies** — curl's + default `ssl` feature (which pulls OpenSSL on Linux) and `non-http` are + installed transitively otherwise. With both, curl resolves to `curl[core,mbedtls]` + and OpenSSL is not built; with only the feature, you get + `curl[mbedtls,ssl,openssl,non-http]` (mbedTLS *and* OpenSSL). This recipe is + verified with `vcpkg install --dry-run`. + +The default install (no features specified) keeps `curl-openssl` and works out of +the box. + +`no-default-http-client` omits the built-in client entirely (`-DBUILD_CURL_HTTP_CLIENT=OFF`, +no curl, no TLS). The SDK then **requires** the host to register its own +`IHttpClient` via `CFG_MODULE_HTTP_CLIENT`; without one, `LogManager::Initialize` +throws and no telemetry is uploaded. This is the smallest option but only makes +sense when your application already owns an HTTP/transport layer (it also lets +telemetry share a single, policy-vetted TLS path instead of a second one). For a +direct (non-vcpkg) CMake build, pass `-DBUILD_CURL_HTTP_CLIENT=OFF` instead. + ### Drop unused SQLite features (json1) The SDK uses SQLite only for offline event storage — plain tables and indexes, diff --git a/tools/ports/cpp-client-telemetry/portfile.cmake b/tools/ports/cpp-client-telemetry/portfile.cmake index 20bc4e2b2..3bdd2ca06 100644 --- a/tools/ports/cpp-client-telemetry/portfile.cmake +++ b/tools/ports/cpp-client-telemetry/portfile.cmake @@ -20,12 +20,18 @@ if(VCPKG_TARGET_IS_IOS) set(MATSDK_BUILD_IOS ON) endif() -# minimal-sqlite feature -> build a private feature-stripped SQLite instead of -# linking the external sqlite3 package. Maps to -DMATSDK_MINIMAL_SQLITE=ON/OFF. +# Feature -> CMake option mapping: +# * minimal-sqlite -> -DMATSDK_MINIMAL_SQLITE=ON (private feature-stripped SQLite). +# * no-default-http-client (INVERTED) -> -DBUILD_CURL_HTTP_CLIENT=OFF (omit the +# built-in libcurl client; host supplies its own IHttpClient). When the feature +# is absent the built-in curl client is built (ON), with its TLS backend chosen +# by the curl-openssl (default) / curl-mbedtls features in vcpkg.json. vcpkg_check_features( OUT_FEATURE_OPTIONS FEATURE_OPTIONS FEATURES minimal-sqlite MATSDK_MINIMAL_SQLITE + INVERTED_FEATURES + no-default-http-client BUILD_CURL_HTTP_CLIENT ) vcpkg_cmake_configure( diff --git a/tools/ports/cpp-client-telemetry/vcpkg.json b/tools/ports/cpp-client-telemetry/vcpkg.json index 980356e54..7a8336aea 100644 --- a/tools/ports/cpp-client-telemetry/vcpkg.json +++ b/tools/ports/cpp-client-telemetry/vcpkg.json @@ -6,14 +6,6 @@ "license": "Apache-2.0", "supports": "((windows & !mingw) | linux | osx | ios | android) & !uwp", "dependencies": [ - { - "name": "curl", - "default-features": false, - "features": [ - "openssl" - ], - "platform": "linux | android" - }, "nlohmann-json", { "name": "vcpkg-cmake", @@ -26,7 +18,8 @@ "zlib" ], "default-features": [ - "system-sqlite" + "system-sqlite", + "curl-openssl" ], "features": { "system-sqlite": { @@ -40,6 +33,35 @@ }, "minimal-sqlite": { "description": "Build a private, feature-stripped SQLite compiled from the SDK's vendored amalgamation instead of linking the external sqlite3 package. Smaller footprint; combine with [core,minimal-sqlite] to also drop the sqlite3 dependency." + }, + "curl-openssl": { + "description": "Built-in libcurl HTTP client with the OpenSSL TLS backend (default). Affects Linux/Android only; Windows uses WinInet and Apple uses NSURLSession regardless.", + "dependencies": [ + { + "name": "curl", + "default-features": false, + "features": [ + "openssl" + ], + "platform": "linux | android" + } + ] + }, + "curl-mbedtls": { + "description": "Built-in libcurl HTTP client with the mbedTLS backend instead of OpenSSL (smaller footprint). Affects Linux/Android only. Use [core,curl-mbedtls] to drop the default OpenSSL curl.", + "dependencies": [ + { + "name": "curl", + "default-features": false, + "features": [ + "mbedtls" + ], + "platform": "linux | android" + } + ] + }, + "no-default-http-client": { + "description": "Omit the built-in libcurl HTTP client entirely (no curl, no TLS backend). The host must supply its own IHttpClient via CFG_MODULE_HTTP_CLIENT. Use [core,no-default-http-client] to also drop curl from the dependency graph." } } } From c00ce552dc4989b6e264f0f2bb35f91122baaf56 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 25 Jun 2026 14:33:15 -0500 Subject: [PATCH 6/8] Harden HTTP-client features: CURL CONFIG mode + mutual-exclusivity guard (Copilot review) - CMakeLists.txt: in vcpkg mode use find_package(CURL CONFIG QUIET) and gate on TARGET CURL::libcurl. Forcing CONFIG selects the vcpkg-provided CURLConfig (which defines the imported target) rather than the module FindCURL, which on some CMake versions does not define CURL::libcurl and would fail at link. - portfile.cmake: fail fast when more than one of curl-openssl/curl-mbedtls/ no-default-http-client is selected. vcpkg cannot express mutual exclusivity, so a consumer requesting e.g. curl-mbedtls without [core] keeps the default curl-openssl and would union both TLS backends; the guard now errors with guidance to use the [core,...] form. Validated: the guard passes single selections and fires on curl-openssl+curl-mbedtls and curl-openssl+no-default-http-client; the default (curl-openssl) vcpkg consumer still configures via CURL CONFIG, links, and runs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CMakeLists.txt | 7 +++++-- .../ports/cpp-client-telemetry/portfile.cmake | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 598a07f22..60543137e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -383,8 +383,11 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11" if(MATSDK_USE_VCPKG_DEPS) # The TLS backend (OpenSSL/mbedTLS) is selected by the vcpkg port's # curl-openssl (default) / curl-mbedtls features; the SDK just links libcurl. - find_package(CURL QUIET) - if(NOT CURL_FOUND) + # Force CONFIG mode so the vcpkg-provided CURLConfig (which defines the + # CURL::libcurl imported target) is used rather than the module FindCURL, + # which on some CMake versions does not define that target. + find_package(CURL CONFIG QUIET) + if(NOT TARGET CURL::libcurl) message(FATAL_ERROR "libcurl was not found but the built-in HTTP client is enabled. The " "vcpkg port provides the curl HTTP client through the curl-openssl " diff --git a/tools/ports/cpp-client-telemetry/portfile.cmake b/tools/ports/cpp-client-telemetry/portfile.cmake index 3bdd2ca06..0e359f3e7 100644 --- a/tools/ports/cpp-client-telemetry/portfile.cmake +++ b/tools/ports/cpp-client-telemetry/portfile.cmake @@ -20,6 +20,27 @@ if(VCPKG_TARGET_IS_IOS) set(MATSDK_BUILD_IOS ON) endif() +# The three HTTP-client features are mutually exclusive: curl-openssl (default) and +# curl-mbedtls choose the TLS backend for the built-in client, and +# no-default-http-client omits the client. vcpkg cannot express mutual exclusivity, +# so fail fast if more than one is selected (e.g. requesting curl-mbedtls without +# [core] keeps the default curl-openssl, which would union both TLS backends). +set(_matsdk_http_features "") +foreach(_matsdk_http_feature curl-openssl curl-mbedtls no-default-http-client) + if(_matsdk_http_feature IN_LIST FEATURES) + list(APPEND _matsdk_http_features ${_matsdk_http_feature}) + endif() +endforeach() +list(LENGTH _matsdk_http_features _matsdk_http_feature_count) +if(_matsdk_http_feature_count GREATER 1) + message(FATAL_ERROR + "Select at most one HTTP-client feature, but got: ${_matsdk_http_features}. " + "curl-openssl (default), curl-mbedtls, and no-default-http-client are mutually " + "exclusive. To use a non-default one, drop the default with the [core,...] form, " + "e.g. cpp-client-telemetry[core,curl-mbedtls] or " + "cpp-client-telemetry[core,no-default-http-client].") +endif() + # Feature -> CMake option mapping: # * minimal-sqlite -> -DMATSDK_MINIMAL_SQLITE=ON (private feature-stripped SQLite). # * no-default-http-client (INVERTED) -> -DBUILD_CURL_HTTP_CLIENT=OFF (omit the From 7b3e35a707e24cbe5ec9fd21bb38a05482bd2458 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 25 Jun 2026 15:46:28 -0500 Subject: [PATCH 7/8] Remove the no-curl (no-default-http-client) option Drop the ability to build without the built-in libcurl HTTP client. That option only benefited consumers that already ship their own IHttpClient; the SDK's named consumers (and Apple/Windows, which use NSURLSession/WinInet) never needed it, and it added a fragile feature plus a config-flow opt-out. The TLS-backend selection (curl-openssl default / curl-mbedtls) and minimal-SQLite remain. - CMakeLists.txt: remove option(BUILD_CURL_HTTP_CLIENT) and the no-curl else branch; the curl HTTP client is always built on the CPP11/curl path again (keeping the find_package(CURL CONFIG) + TARGET CURL::libcurl hardening). - lib/include/mat/config.h: remove the MATSDK_NO_DEFAULT_HTTP_CLIENT -> HAVE_MAT_DEFAULT_HTTP_CLIENT opt-out. - vcpkg.json: remove the no-default-http-client feature. - portfile.cmake: remove the INVERTED_FEATURES mapping; the mutual-exclusivity guard now covers just curl-openssl vs curl-mbedtls. - docs: drop the no-curl row/section; note the size figures are worst-case (without consumer-side --gc-sections). Validated: vcpkg.json parses, CMake configures cleanly, and the mat target builds and links with the curl client compiled in. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CMakeLists.txt | 66 +++++++------------ docs/building-with-vcpkg.md | 22 ++----- lib/include/mat/config.h | 10 --- .../ports/cpp-client-telemetry/portfile.cmake | 28 +++----- tools/ports/cpp-client-telemetry/vcpkg.json | 3 - 5 files changed, 40 insertions(+), 89 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 60543137e..914f859aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -365,57 +365,39 @@ endif() # HTTP stack section ################################################################################################ -# Built-in libcurl HTTP client. Disable to omit curl (and its TLS backend, e.g. -# OpenSSL/mbedTLS) from the build; the host must then supply an IHttpClient via -# CFG_MODULE_HTTP_CLIENT. Only meaningful on the CPP11/curl path (non-Apple, -# non-Windows); Apple/Windows use their native HTTP stacks regardless. -option(BUILD_CURL_HTTP_CLIENT "Build the built-in libcurl HTTP client" ON) - # Only use custom curl if compiling with CPP11 PAL set(MATSDK_NEEDS_CURL OFF) if(PAL_IMPLEMENTATION STREQUAL "CPP11" AND NOT BUILD_IOS AND (NOT CMAKE_SYSTEM_NAME STREQUAL "Android" OR MATSDK_USE_VCPKG_DEPS) AND NOT BUILD_APPLE_HTTP) - if(BUILD_CURL_HTTP_CLIENT) - set(MATSDK_NEEDS_CURL ON) - add_definitions(-DHAVE_MAT_CURL_HTTP_CLIENT) - if(MATSDK_USE_VCPKG_DEPS) - # The TLS backend (OpenSSL/mbedTLS) is selected by the vcpkg port's - # curl-openssl (default) / curl-mbedtls features; the SDK just links libcurl. - # Force CONFIG mode so the vcpkg-provided CURLConfig (which defines the - # CURL::libcurl imported target) is used rather than the module FindCURL, - # which on some CMake versions does not define that target. - find_package(CURL CONFIG QUIET) - if(NOT TARGET CURL::libcurl) - message(FATAL_ERROR - "libcurl was not found but the built-in HTTP client is enabled. The " - "vcpkg port provides the curl HTTP client through the curl-openssl " - "(default) or curl-mbedtls feature, or you can omit it with the " - "no-default-http-client feature (host supplies its own IHttpClient). " - "Install cpp-client-telemetry with its default features, with " - "[core,curl-mbedtls], or with [core,no-default-http-client].") - endif() + set(MATSDK_NEEDS_CURL ON) + add_definitions(-DHAVE_MAT_CURL_HTTP_CLIENT) + if(MATSDK_USE_VCPKG_DEPS) + # The TLS backend (OpenSSL/mbedTLS) is selected by the vcpkg port's + # curl-openssl (default) / curl-mbedtls features; the SDK just links libcurl. + # Force CONFIG mode so the vcpkg-provided CURLConfig (which defines the + # CURL::libcurl imported target) is used rather than the module FindCURL, + # which on some CMake versions does not define that target. + find_package(CURL CONFIG QUIET) + if(NOT TARGET CURL::libcurl) + message(FATAL_ERROR + "libcurl was not found. The vcpkg port provides the curl HTTP client " + "through the curl-openssl (default) or curl-mbedtls feature. Install " + "cpp-client-telemetry with its default features or with [core,curl-mbedtls].") + endif() + list(APPEND LIBS CURL::libcurl) + else() + find_package(CURL REQUIRED) + # Prefer the imported target, which carries curl's include dirs and link + # flags. Fall back to the find-module variables on CMake < 3.12, where + # find_package(CURL) does not define CURL::libcurl. + if(TARGET CURL::libcurl) list(APPEND LIBS CURL::libcurl) else() - find_package(CURL REQUIRED) - # Prefer the imported target, which carries curl's include dirs and link - # flags. Fall back to the find-module variables on CMake < 3.12, where - # find_package(CURL) does not define CURL::libcurl. - if(TARGET CURL::libcurl) - list(APPEND LIBS CURL::libcurl) - else() - include_directories(${CURL_INCLUDE_DIRS}) - list(APPEND LIBS "${CURL_LIBRARIES}") - endif() + include_directories(${CURL_INCLUDE_DIRS}) + list(APPEND LIBS "${CURL_LIBRARIES}") endif() - else() - # No built-in HTTP client: omit the default client entirely so neither - # libcurl nor a TLS backend is linked. mat/config.h turns off - # HAVE_MAT_DEFAULT_HTTP_CLIENT in response, and LogManagerImpl then requires - # the host to provide an IHttpClient via CFG_MODULE_HTTP_CLIENT. - add_definitions(-DMATSDK_NO_DEFAULT_HTTP_CLIENT) - message(STATUS "BUILD_CURL_HTTP_CLIENT=OFF: omitting built-in HTTP client; host must supply IHttpClient via CFG_MODULE_HTTP_CLIENT") endif() endif() diff --git a/docs/building-with-vcpkg.md b/docs/building-with-vcpkg.md index 3e07c15da..1cba2f57b 100644 --- a/docs/building-with-vcpkg.md +++ b/docs/building-with-vcpkg.md @@ -156,8 +156,7 @@ SQLite built from the SDK's vendored amalgamation — see [Build a private minimal SQLite](#build-a-private-minimal-sqlite-minimal-sqlite-feature). libcurl is provided by the default `curl-openssl` feature; `curl-mbedtls` swaps in -the mbedTLS backend, and `no-default-http-client` drops the built-in client -entirely — see +the mbedTLS backend — see [Choose the HTTP client / TLS backend](#choose-the-http-client--tls-backend-largest-lever-on-linux). Windows and macOS/iOS use platform-native HTTP clients (WinInet and @@ -244,17 +243,18 @@ export table pins its symbols and defeats `/OPT:REF`. On Linux/Android the built-in HTTP client is libcurl, and curl's TLS backend dominates the SDK's footprint. (Windows uses WinInet and Apple uses NSURLSession, -so this section does not apply there.) The port exposes three mutually-exclusive -choices as features; pick the one that matches what your application already has: +so this section does not apply there.) The port exposes the TLS backend as two +mutually-exclusive features; pick the one that matches what your application +already has: | Feature | Transport | Approx. stripped size¹ | Use when | | ------- | --------- | ---------------------- | -------- | | `curl-openssl` (default) | libcurl + OpenSSL | ~10.6 MB | your app already links OpenSSL (share it) | | `curl-mbedtls` | libcurl + mbedTLS | ~4.4 MB | your app has no HTTP/TLS stack of its own | -| `no-default-http-client` | none (host-supplied) | ~1.4 MB | your app already has its own HTTP client | -¹ Rough stripped sizes of a minimal Linux consumer measured for this SDK; your -numbers depend on triplet, dead-stripping, and what else shares those libraries. +¹ Rough sizes of a minimal Linux consumer **without** consumer-side dead-stripping +(worst case); enabling `-Wl,--gc-sections` at your link reduces them. Your numbers +depend on triplet, dead-stripping, and what else shares those libraries. To select **mbedTLS**, two things are required in *your top-level* manifest: @@ -284,14 +284,6 @@ To select **mbedTLS**, two things are required in *your top-level* manifest: The default install (no features specified) keeps `curl-openssl` and works out of the box. -`no-default-http-client` omits the built-in client entirely (`-DBUILD_CURL_HTTP_CLIENT=OFF`, -no curl, no TLS). The SDK then **requires** the host to register its own -`IHttpClient` via `CFG_MODULE_HTTP_CLIENT`; without one, `LogManager::Initialize` -throws and no telemetry is uploaded. This is the smallest option but only makes -sense when your application already owns an HTTP/transport layer (it also lets -telemetry share a single, policy-vetted TLS path instead of a second one). For a -direct (non-vcpkg) CMake build, pass `-DBUILD_CURL_HTTP_CLIENT=OFF` instead. - ### Drop unused SQLite features (json1) The SDK uses SQLite only for offline event storage — plain tables and indexes, diff --git a/lib/include/mat/config.h b/lib/include/mat/config.h index 556a9c996..4baa54796 100644 --- a/lib/include/mat/config.h +++ b/lib/include/mat/config.h @@ -14,16 +14,6 @@ #include "config-default.h" #endif -/* Allow the build to omit the built-in default HTTP client. When the host - * supplies its own IHttpClient (via CFG_MODULE_HTTP_CLIENT) it can build with - * -DMATSDK_NO_DEFAULT_HTTP_CLIENT (set by CMake when BUILD_CURL_HTTP_CLIENT=OFF) - * to avoid compiling/linking any built-in client -- e.g. to drop libcurl and its - * TLS backend on Linux. This undefines the macro regardless of which config - * preset above defined it. */ -#if defined(MATSDK_NO_DEFAULT_HTTP_CLIENT) && defined(HAVE_MAT_DEFAULT_HTTP_CLIENT) -#undef HAVE_MAT_DEFAULT_HTTP_CLIENT -#endif - #if !defined(MATSDK_PAL_WIN32) && !defined(MATSDK_PAL_CPP11) #if defined(_WIN32) #define MATSDK_PAL_WIN32 diff --git a/tools/ports/cpp-client-telemetry/portfile.cmake b/tools/ports/cpp-client-telemetry/portfile.cmake index 0e359f3e7..320299930 100644 --- a/tools/ports/cpp-client-telemetry/portfile.cmake +++ b/tools/ports/cpp-client-telemetry/portfile.cmake @@ -20,13 +20,12 @@ if(VCPKG_TARGET_IS_IOS) set(MATSDK_BUILD_IOS ON) endif() -# The three HTTP-client features are mutually exclusive: curl-openssl (default) and -# curl-mbedtls choose the TLS backend for the built-in client, and -# no-default-http-client omits the client. vcpkg cannot express mutual exclusivity, -# so fail fast if more than one is selected (e.g. requesting curl-mbedtls without -# [core] keeps the default curl-openssl, which would union both TLS backends). +# curl-openssl (default) and curl-mbedtls choose the TLS backend for the built-in +# HTTP client and are mutually exclusive. vcpkg cannot express mutual exclusivity, +# so fail fast if both are selected (e.g. requesting curl-mbedtls without [core] +# keeps the default curl-openssl, which would union both TLS backends). set(_matsdk_http_features "") -foreach(_matsdk_http_feature curl-openssl curl-mbedtls no-default-http-client) +foreach(_matsdk_http_feature curl-openssl curl-mbedtls) if(_matsdk_http_feature IN_LIST FEATURES) list(APPEND _matsdk_http_features ${_matsdk_http_feature}) endif() @@ -34,25 +33,16 @@ endforeach() list(LENGTH _matsdk_http_features _matsdk_http_feature_count) if(_matsdk_http_feature_count GREATER 1) message(FATAL_ERROR - "Select at most one HTTP-client feature, but got: ${_matsdk_http_features}. " - "curl-openssl (default), curl-mbedtls, and no-default-http-client are mutually " - "exclusive. To use a non-default one, drop the default with the [core,...] form, " - "e.g. cpp-client-telemetry[core,curl-mbedtls] or " - "cpp-client-telemetry[core,no-default-http-client].") + "curl-openssl (default) and curl-mbedtls are mutually exclusive but both were " + "selected. To use mbedTLS, drop the default with the [core,...] form, e.g. " + "cpp-client-telemetry[core,curl-mbedtls].") endif() -# Feature -> CMake option mapping: -# * minimal-sqlite -> -DMATSDK_MINIMAL_SQLITE=ON (private feature-stripped SQLite). -# * no-default-http-client (INVERTED) -> -DBUILD_CURL_HTTP_CLIENT=OFF (omit the -# built-in libcurl client; host supplies its own IHttpClient). When the feature -# is absent the built-in curl client is built (ON), with its TLS backend chosen -# by the curl-openssl (default) / curl-mbedtls features in vcpkg.json. +# minimal-sqlite -> -DMATSDK_MINIMAL_SQLITE=ON (private feature-stripped SQLite). vcpkg_check_features( OUT_FEATURE_OPTIONS FEATURE_OPTIONS FEATURES minimal-sqlite MATSDK_MINIMAL_SQLITE - INVERTED_FEATURES - no-default-http-client BUILD_CURL_HTTP_CLIENT ) vcpkg_cmake_configure( diff --git a/tools/ports/cpp-client-telemetry/vcpkg.json b/tools/ports/cpp-client-telemetry/vcpkg.json index 7a8336aea..4097d7cff 100644 --- a/tools/ports/cpp-client-telemetry/vcpkg.json +++ b/tools/ports/cpp-client-telemetry/vcpkg.json @@ -59,9 +59,6 @@ "platform": "linux | android" } ] - }, - "no-default-http-client": { - "description": "Omit the built-in libcurl HTTP client entirely (no curl, no TLS backend). The host must supply its own IHttpClient via CFG_MODULE_HTTP_CLIENT. Use [core,no-default-http-client] to also drop curl from the dependency graph." } } } From c83b7c6d5ceb0c2959af1ba79a75b62f84aabaab Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 25 Jun 2026 16:32:19 -0500 Subject: [PATCH 8/8] vcpkg: use Apple's system libsqlite3/libz on macOS/iOS instead of vcpkg packages macOS/iOS ship libsqlite3 and libz as system libraries, so pulling and statically linking the vcpkg sqlite3 + zlib packages added ~1 MB of redundant code to Apple binaries. Link the system libraries instead -- consistent with the SDK's own Swift Package (which links .linkedLibrary("sqlite3"/"z")) and with how analogous telemetry SDKs (e.g. sentry-native) gate these deps off Apple platforms. - vcpkg.json: gate the zlib dependency and the system-sqlite feature's sqlite3 dependency to "!osx & !ios" so they are not installed on Apple. - CMakeLists.txt: on APPLE in vcpkg mode, find_package(SQLite3)/find_package(ZLIB) (CMake's modules resolve to the OS libraries) and set MATSDK_APPLE_SYSTEM_DEPS. - lib/CMakeLists.txt: link SQLite::SQLite3 + ZLIB::ZLIB on Apple; never bundle a private SQLite on Apple (MATSDK_MINIMAL_SQLITE is a no-op there since the system lib is already smaller). - MSTelemetryConfig.cmake.in: re-find system SQLite3 on Apple, the vcpkg unofficial-sqlite3 elsewhere. - docs: note the Apple system-lib behavior. Validated: non-Apple paths unchanged -- Linux vendored mat builds, and the Linux vcpkg consumer's generated config resolves unofficial-sqlite3 (if(OFF)) and runs. The Apple build itself needs validation on macOS/iOS CI (no Mac available here); the risk is whether find_package(SQLite3) resolves the system lib under the vcpkg Apple triplets' find-root settings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CMakeLists.txt | 52 +++++++++++++-------- cmake/MSTelemetryConfig.cmake.in | 10 ++-- docs/building-with-vcpkg.md | 9 +++- lib/CMakeLists.txt | 45 ++++++++++++------ tools/ports/cpp-client-telemetry/vcpkg.json | 10 ++-- 5 files changed, 82 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 914f859aa..45f9c3bb0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -405,27 +405,39 @@ endif() # Dependency resolution (vcpkg mode vs vendored) ################################################################################################ if(MATSDK_USE_VCPKG_DEPS) - # SQLite is provided by the private minimal build when MATSDK_MINIMAL_SQLITE is - # ON, so only require the external vcpkg sqlite3 package otherwise. - if(NOT MATSDK_MINIMAL_SQLITE) - find_package(unofficial-sqlite3 CONFIG QUIET) - if(NOT unofficial-sqlite3_FOUND) - message(FATAL_ERROR - "SQLite was not found and the minimal SQLite is not enabled. The vcpkg " - "port provides SQLite through one of two features: 'system-sqlite' " - "(default, links the external sqlite3 package) or 'minimal-sqlite' " - "(builds a private feature-stripped SQLite). Install " - "cpp-client-telemetry with its default features, or with " - "[core,minimal-sqlite]. For a direct CMake build, pass " - "-DMATSDK_MINIMAL_SQLITE=ON or ensure unofficial-sqlite3 is discoverable.") - endif() - endif() - find_package(ZLIB REQUIRED) - find_package(nlohmann_json CONFIG REQUIRED) - if(MATSDK_MINIMAL_SQLITE) - message(STATUS "Using vcpkg-provided zlib, nlohmann-json; private minimal SQLite") + if(APPLE) + # macOS/iOS ship libsqlite3 and libz as system libraries (the SDK's SPM + # distribution links them the same way), so the vcpkg sqlite3/zlib packages are + # not pulled there -- find the system ones via CMake's standard find modules. + find_package(SQLite3 REQUIRED) + find_package(ZLIB REQUIRED) + find_package(nlohmann_json CONFIG REQUIRED) + set(MATSDK_APPLE_SYSTEM_DEPS ON) + message(STATUS "Apple: using system SQLite3 + zlib; vcpkg-provided nlohmann-json") else() - message(STATUS "Using vcpkg-provided sqlite3, zlib, nlohmann-json") + set(MATSDK_APPLE_SYSTEM_DEPS OFF) + # SQLite is provided by the private minimal build when MATSDK_MINIMAL_SQLITE is + # ON, so only require the external vcpkg sqlite3 package otherwise. + if(NOT MATSDK_MINIMAL_SQLITE) + find_package(unofficial-sqlite3 CONFIG QUIET) + if(NOT unofficial-sqlite3_FOUND) + message(FATAL_ERROR + "SQLite was not found and the minimal SQLite is not enabled. The vcpkg " + "port provides SQLite through one of two features: 'system-sqlite' " + "(default, links the external sqlite3 package) or 'minimal-sqlite' " + "(builds a private feature-stripped SQLite). Install " + "cpp-client-telemetry with its default features, or with " + "[core,minimal-sqlite]. For a direct CMake build, pass " + "-DMATSDK_MINIMAL_SQLITE=ON or ensure unofficial-sqlite3 is discoverable.") + endif() + endif() + find_package(ZLIB REQUIRED) + find_package(nlohmann_json CONFIG REQUIRED) + if(MATSDK_MINIMAL_SQLITE) + message(STATUS "Using vcpkg-provided zlib, nlohmann-json; private minimal SQLite") + else() + message(STATUS "Using vcpkg-provided sqlite3, zlib, nlohmann-json") + endif() endif() else() # Include repo root to allow includes of vendored sqlite, zlib, and nlohmann diff --git a/cmake/MSTelemetryConfig.cmake.in b/cmake/MSTelemetryConfig.cmake.in index f8c7a5d9a..9946c3ccc 100644 --- a/cmake/MSTelemetryConfig.cmake.in +++ b/cmake/MSTelemetryConfig.cmake.in @@ -2,10 +2,12 @@ include(CMakeFindDependencyMacro) -# Re-find dependencies that consumers need -# SQLite is built into the SDK as a private minimal copy when MATSDK_MINIMAL_SQLITE -# is set, so the external sqlite3 package is only re-found when it is not bundled. -if(NOT @MATSDK_BUNDLE_SQLITE@) +# Re-find dependencies that consumers need. +# On Apple the SDK links the system libsqlite3 (SQLite::SQLite3); elsewhere it uses +# the vcpkg sqlite3 package unless a private minimal SQLite is bundled. +if(@MATSDK_APPLE_SYSTEM_DEPS@) + find_dependency(SQLite3) +elseif(NOT @MATSDK_BUNDLE_SQLITE@) find_dependency(unofficial-sqlite3 CONFIG) endif() find_dependency(ZLIB) diff --git a/docs/building-with-vcpkg.md b/docs/building-with-vcpkg.md index 1cba2f57b..afa22e2cb 100644 --- a/docs/building-with-vcpkg.md +++ b/docs/building-with-vcpkg.md @@ -145,11 +145,16 @@ The vcpkg port automatically resolves the following dependencies: | Dependency | vcpkg Package | CMake Target | Platforms | | -------------- | --------------- | --------------------------------- | ------------------ | -| SQLite3 | `sqlite3` | `unofficial::sqlite3::sqlite3` | All (default; see `minimal-sqlite`) | -| zlib | `zlib` | `ZLIB::ZLIB` | All | +| SQLite3 | `sqlite3` | `unofficial::sqlite3::sqlite3` | Non-Apple (default; see `minimal-sqlite`). **macOS/iOS link the system `libsqlite3`** (`SQLite::SQLite3`) | +| zlib | `zlib` | `ZLIB::ZLIB` | Non-Apple. **macOS/iOS link the system `libz`** | | nlohmann JSON | `nlohmann-json` | `nlohmann_json::nlohmann_json` | All | | libcurl | `curl[openssl]` or `curl[mbedtls]` | `CURL::libcurl` | Non-Windows, non-Apple (selectable; optional) | +On **macOS/iOS** the SDK links the OS-provided `libsqlite3` and `libz` (the same +system libraries the SDK's Swift Package links), so the vcpkg `sqlite3` and `zlib` +packages are not pulled there — those binaries carry no bundled SQLite/zlib. +(`minimal-sqlite` therefore has no effect on Apple.) + The external `sqlite3` package is provided by the default `system-sqlite` feature. The `minimal-sqlite` feature replaces it with a private, feature-stripped SQLite built from the SDK's vendored amalgamation — see diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index a9cc8cc77..2850359bd 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -441,7 +441,9 @@ set(MATSDK_SQLITE_MINIMAL_DEFS # MATSDK_MINIMAL_SQLITE is ON, so the default Android legacy build keeps its # existing (unstripped) bundled SQLite behavior. set(MATSDK_BUNDLE_SQLITE OFF) -if(MATSDK_MINIMAL_SQLITE) +if(MATSDK_MINIMAL_SQLITE AND NOT APPLE) + # On Apple the SDK links the system libsqlite3 (smaller than any bundled copy), + # so MATSDK_MINIMAL_SQLITE has no effect there. set(MATSDK_BUNDLE_SQLITE ON) elseif(NOT MATSDK_USE_VCPKG_DEPS AND CMAKE_SYSTEM_NAME STREQUAL "Android") set(MATSDK_BUNDLE_SQLITE ON) @@ -484,22 +486,35 @@ if(MATSDK_USE_VCPKG_DEPS) # vcpkg mode: all deps resolved via find_package() in root CMakeLists.txt # These are PUBLIC so static-library consumers get the transitive link set # through the exported MSTelemetry::mat target. - if(MATSDK_BUNDLE_SQLITE) - # Private minimal SQLite instead of the vcpkg sqlite3 package. PRIVATE so its - # include dirs / compile definitions are not propagated as a public usage - # requirement. A static mat still propagates the archive itself for linking - # (via $), so it is added to the export set for static builds - # below; a shared mat absorbs it and propagates nothing. - target_link_libraries(mat PRIVATE sqlite3_bundled) + if(APPLE) + # macOS/iOS link the system libsqlite3 + libz (SQLite::SQLite3 / ZLIB::ZLIB + # resolve to the OS libraries via CMake's find modules), so the vcpkg + # sqlite3/zlib packages are neither pulled nor linked here. + target_link_libraries(mat + PUBLIC + SQLite::SQLite3 + ZLIB::ZLIB + nlohmann_json::nlohmann_json + ${LIBS} + ) else() - target_link_libraries(mat PUBLIC unofficial::sqlite3::sqlite3) + if(MATSDK_BUNDLE_SQLITE) + # Private minimal SQLite instead of the vcpkg sqlite3 package. PRIVATE so its + # include dirs / compile definitions are not propagated as a public usage + # requirement. A static mat still propagates the archive itself for linking + # (via $), so it is added to the export set for static builds + # below; a shared mat absorbs it and propagates nothing. + target_link_libraries(mat PRIVATE sqlite3_bundled) + else() + target_link_libraries(mat PUBLIC unofficial::sqlite3::sqlite3) + endif() + target_link_libraries(mat + PUBLIC + ZLIB::ZLIB + nlohmann_json::nlohmann_json + ${LIBS} + ) endif() - target_link_libraries(mat - PUBLIC - ZLIB::ZLIB - nlohmann_json::nlohmann_json - ${LIBS} - ) else() # Legacy mode: use vendored or system-installed deps if(CMAKE_SYSTEM_NAME STREQUAL "Android") diff --git a/tools/ports/cpp-client-telemetry/vcpkg.json b/tools/ports/cpp-client-telemetry/vcpkg.json index 4097d7cff..480a1ccbb 100644 --- a/tools/ports/cpp-client-telemetry/vcpkg.json +++ b/tools/ports/cpp-client-telemetry/vcpkg.json @@ -15,7 +15,10 @@ "name": "vcpkg-cmake-config", "host": true }, - "zlib" + { + "name": "zlib", + "platform": "!osx & !ios" + } ], "default-features": [ "system-sqlite", @@ -23,11 +26,12 @@ ], "features": { "system-sqlite": { - "description": "Link the external vcpkg sqlite3 package for the offline storage cache (default).", + "description": "Link the external vcpkg sqlite3 package for the offline storage cache (default). On macOS/iOS the SDK links the system libsqlite3 instead, so this dependency is not pulled there.", "dependencies": [ { "name": "sqlite3", - "default-features": false + "default-features": false, + "platform": "!osx & !ios" } ] },