From 4e8493c6a42e6244fbad680c14d05af1da8f497e Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 25 Jun 2026 01:20:21 -0500 Subject: [PATCH 01/25] 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 02/25] 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 03/25] 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 04/25] 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 05/25] 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 06/25] 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 07/25] 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 08/25] 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" } ] }, From 3621a325b7ab69c721627d98616535133adc0c03 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 25 Jun 2026 20:31:29 -0500 Subject: [PATCH 09/25] Clarify mbedTLS guidance: [core,...] drops system-sqlite too The curl-openssl/curl-mbedtls guidance in the port's fatal-error messages and docs recommended cpp-client-telemetry[core,curl-mbedtls], but the [core,...] form (default-features:false) drops ALL default features -- including system-sqlite -- not just curl-openssl. That example yields a config-time failure with no SQLite backend selected. Update both FATAL_ERROR messages (portfile.cmake mutual-exclusivity guard, CMakeLists.txt libcurl-not-found) and the docs prose to show a complete, working feature set ([core,curl-mbedtls,system-sqlite]) and to note that [core,...] also drops system-sqlite, so a SQLite backend must be re-selected. Files: tools/ports/cpp-client-telemetry/portfile.cmake, CMakeLists.txt, docs/building-with-vcpkg.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CMakeLists.txt | 4 +++- docs/building-with-vcpkg.md | 7 +++++-- tools/ports/cpp-client-telemetry/portfile.cmake | 7 +++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45f9c3bb0..3fcb875d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -384,7 +384,9 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11" 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].") + "cpp-client-telemetry with its default features, or, for mbedTLS, with " + "[core,curl-mbedtls,system-sqlite] -- the [core,...] form also drops the " + "default system-sqlite feature, so re-select system-sqlite or minimal-sqlite.") endif() list(APPEND LIBS CURL::libcurl) else() diff --git a/docs/building-with-vcpkg.md b/docs/building-with-vcpkg.md index afa22e2cb..34e7da127 100644 --- a/docs/building-with-vcpkg.md +++ b/docs/building-with-vcpkg.md @@ -276,8 +276,11 @@ To select **mbedTLS**, two things are required in *your top-level* manifest: } ``` -1. `[core,curl-mbedtls]` (the `"default-features": false` form) drops the SDK's - default `curl-openssl` feature, so the SDK no longer *requests* OpenSSL. +1. `"default-features": false` (the `[core,...]` form) drops **all** of the SDK's + default features -- both `curl-openssl` *and* `system-sqlite` -- so the SDK no + longer *requests* OpenSSL. Because it also drops `system-sqlite`, you must + re-select a SQLite backend (`minimal-sqlite` above, or `system-sqlite`); + otherwise the SDK configure step fails with no SQLite feature selected. 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 diff --git a/tools/ports/cpp-client-telemetry/portfile.cmake b/tools/ports/cpp-client-telemetry/portfile.cmake index 320299930..2c7981fee 100644 --- a/tools/ports/cpp-client-telemetry/portfile.cmake +++ b/tools/ports/cpp-client-telemetry/portfile.cmake @@ -34,8 +34,11 @@ list(LENGTH _matsdk_http_features _matsdk_http_feature_count) if(_matsdk_http_feature_count GREATER 1) message(FATAL_ERROR "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].") + "selected. To use mbedTLS, drop the defaults with the [core,...] form and " + "re-select a SQLite backend (the [core,...] form also drops the default " + "system-sqlite feature), e.g. " + "cpp-client-telemetry[core,curl-mbedtls,system-sqlite] " + "(or minimal-sqlite in place of system-sqlite).") endif() # minimal-sqlite -> -DMATSDK_MINIMAL_SQLITE=ON (private feature-stripped SQLite). From 884cbb05cca47196242e78f4ce1f2875c911052b Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 25 Jun 2026 20:37:25 -0500 Subject: [PATCH 10/25] Fix misleading curl 'optional' label and mbedTLS feature description Two doc/manifest accuracy fixes from Copilot review: - The dependency table labeled libcurl 'optional' for non-Windows/non-Apple, but since the no-curl option was removed, Linux/Android vcpkg builds always require curl (only the TLS backend is selectable). Relabel as required. - The curl-mbedtls feature description recommended [core,curl-mbedtls], which drops all defaults (incl. system-sqlite); note that a SQLite backend must be re-selected to avoid a configure-time failure. Files: docs/building-with-vcpkg.md, tools/ports/cpp-client-telemetry/vcpkg.json Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/building-with-vcpkg.md | 2 +- tools/ports/cpp-client-telemetry/vcpkg.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/building-with-vcpkg.md b/docs/building-with-vcpkg.md index 34e7da127..968e8503e 100644 --- a/docs/building-with-vcpkg.md +++ b/docs/building-with-vcpkg.md @@ -148,7 +148,7 @@ The vcpkg port automatically resolves the following dependencies: | 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) | +| libcurl | `curl[openssl]` or `curl[mbedtls]` | `CURL::libcurl` | Non-Windows, non-Apple (required; TLS backend selectable: OpenSSL default or mbedTLS) | 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` diff --git a/tools/ports/cpp-client-telemetry/vcpkg.json b/tools/ports/cpp-client-telemetry/vcpkg.json index 480a1ccbb..ba5234ef7 100644 --- a/tools/ports/cpp-client-telemetry/vcpkg.json +++ b/tools/ports/cpp-client-telemetry/vcpkg.json @@ -52,7 +52,7 @@ ] }, "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.", + "description": "Built-in libcurl HTTP client with the mbedTLS backend instead of OpenSSL (smaller footprint). Affects Linux/Android only. Use [core,curl-mbedtls,system-sqlite] to drop the default OpenSSL curl; the [core,...] form drops all defaults (including system-sqlite), so also re-select system-sqlite or minimal-sqlite.", "dependencies": [ { "name": "curl", From f6ae4c4557688dc5d534c06cdb2469168a75eb36 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 25 Jun 2026 20:54:25 -0500 Subject: [PATCH 11/25] Harden [core,...] guidance and fix exported CURL find_dependency mode Five fixes from the Copilot review on the curl/SQLite feature interactions (all stem from vcpkg's [core,...] form dropping ALL default features, not just one): - portfile.cmake: fail fast on Linux/Android when no curl TLS backend is selected (verified: a real vcpkg install of [core,minimal-sqlite] now stops at the portfile with a complete [core,curl-openssl,system-sqlite] example, instead of a later, opaque libcurl-not-found error). - CMakeLists.txt libcurl message: show how to re-select a curl backend (not only mbedTLS) under [core,...], alongside a SQLite backend. - CMakeLists.txt SQLite message: include the valid [core,system-sqlite] path, not only [core,minimal-sqlite]. - MSTelemetryConfig.cmake.in: find_dependency(CURL CONFIG) so the exported package config uses the vcpkg CURLConfig that defines CURL::libcurl (the target MSTelemetryTargets references), matching the unofficial-sqlite3/ nlohmann_json CONFIG siblings and the root CMakeLists CURL CONFIG lookup. - docs: minimal-sqlite manifest example re-selects curl-openssl so the Linux/Android manifest actually configures. Files: CMakeLists.txt, cmake/MSTelemetryConfig.cmake.in, docs/building-with-vcpkg.md, tools/ports/cpp-client-telemetry/portfile.cmake Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CMakeLists.txt | 9 +++++---- cmake/MSTelemetryConfig.cmake.in | 6 +++++- docs/building-with-vcpkg.md | 11 +++++++---- tools/ports/cpp-client-telemetry/portfile.cmake | 12 ++++++++++++ 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fcb875d7..0221dcbe6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -384,9 +384,10 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11" 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, for mbedTLS, with " - "[core,curl-mbedtls,system-sqlite] -- the [core,...] form also drops the " - "default system-sqlite feature, so re-select system-sqlite or minimal-sqlite.") + "cpp-client-telemetry with its default features, or, under the [core,...] " + "form (which drops the default curl-openssl and system-sqlite features), " + "re-select a curl backend and a SQLite backend together, e.g. " + "[core,curl-openssl,system-sqlite] or [core,curl-mbedtls,minimal-sqlite].") endif() list(APPEND LIBS CURL::libcurl) else() @@ -429,7 +430,7 @@ if(MATSDK_USE_VCPKG_DEPS) "(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 " + "[core,system-sqlite] or [core,minimal-sqlite]. For a direct CMake build, pass " "-DMATSDK_MINIMAL_SQLITE=ON or ensure unofficial-sqlite3 is discoverable.") endif() endif() diff --git a/cmake/MSTelemetryConfig.cmake.in b/cmake/MSTelemetryConfig.cmake.in index 9946c3ccc..af3838d65 100644 --- a/cmake/MSTelemetryConfig.cmake.in +++ b/cmake/MSTelemetryConfig.cmake.in @@ -20,7 +20,11 @@ find_dependency(nlohmann_json CONFIG) # because the macOS BUILD_APPLE_HTTP choice can't be inferred from # CMAKE_SYSTEM_NAME alone. if(@MATSDK_NEEDS_CURL@) - find_dependency(CURL) + # Force CONFIG mode so the vcpkg-provided CURLConfig (which defines the + # CURL::libcurl imported target referenced by MSTelemetryTargets.cmake) is + # used, rather than module-mode FindCURL, which on some CMake versions does + # not define that target. + find_dependency(CURL CONFIG) endif() # Pthreads are needed on Linux and Android (POSIX threading) diff --git a/docs/building-with-vcpkg.md b/docs/building-with-vcpkg.md index 968e8503e..315fa8662 100644 --- a/docs/building-with-vcpkg.md +++ b/docs/building-with-vcpkg.md @@ -339,7 +339,7 @@ Enable it through the vcpkg feature: { "name": "cpp-client-telemetry", "default-features": false, - "features": [ "minimal-sqlite" ] + "features": [ "minimal-sqlite", "curl-openssl" ] } ] } @@ -347,9 +347,12 @@ Enable it through the vcpkg feature: 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. +dependency — is dropped. Because `[core]` drops **all** defaults, the example +also re-selects `curl-openssl`: on Linux/Android the built-in curl client +requires a TLS backend, so omitting it would fail to configure (swap in +`curl-mbedtls` for the smaller mbedTLS backend). 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: diff --git a/tools/ports/cpp-client-telemetry/portfile.cmake b/tools/ports/cpp-client-telemetry/portfile.cmake index 2c7981fee..3136708d5 100644 --- a/tools/ports/cpp-client-telemetry/portfile.cmake +++ b/tools/ports/cpp-client-telemetry/portfile.cmake @@ -41,6 +41,18 @@ if(_matsdk_http_feature_count GREATER 1) "(or minimal-sqlite in place of system-sqlite).") endif() +# On Linux/Android the built-in curl HTTP client requires exactly one TLS backend. +# The [core,...] form drops the default curl-openssl, so fail fast (with a complete +# example) rather than letting the SDK CMake fail later on a missing libcurl. +if((VCPKG_TARGET_IS_LINUX OR VCPKG_TARGET_IS_ANDROID) AND _matsdk_http_feature_count EQUAL 0) + message(FATAL_ERROR + "On Linux/Android the built-in curl HTTP client requires exactly one TLS " + "backend feature, but none was selected. The [core,...] form drops the " + "default curl-openssl feature, so re-add a curl backend together with a " + "SQLite backend, e.g. cpp-client-telemetry[core,curl-openssl,system-sqlite] " + "(or curl-mbedtls / minimal-sqlite in place of those).") +endif() + # minimal-sqlite -> -DMATSDK_MINIMAL_SQLITE=ON (private feature-stripped SQLite). vcpkg_check_features( OUT_FEATURE_OPTIONS FEATURE_OPTIONS From 14aa079c394ccbb1918997752902d7f998c87880 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Thu, 25 Jun 2026 21:02:49 -0500 Subject: [PATCH 12/25] Scope curl TLS-backend guards to Linux/Android only The mutual-exclusivity check (curl-openssl vs curl-mbedtls) previously ran on all platforms. Since curl-openssl is a default feature and the curl dependency is platform-filtered to linux|android, a cross-platform manifest that enables curl-mbedtls without [core] would falsely fail the port on Windows/macOS/iOS -- where curl is not used (WinInet / Apple HTTP) and neither feature pulls curl. Wrap both the mutual-exclusivity (count>1) and no-curl (count==0) checks in a single VCPKG_TARGET_IS_LINUX/ANDROID block so they only fire where the curl backend selection is actually meaningful. Verified on x64-linux: [core,minimal- sqlite] still fails with the no-curl message, and [curl-mbedtls] (no core) still fails with the mutual-exclusivity message. Files: tools/ports/cpp-client-telemetry/portfile.cmake Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../ports/cpp-client-telemetry/portfile.cmake | 49 ++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/tools/ports/cpp-client-telemetry/portfile.cmake b/tools/ports/cpp-client-telemetry/portfile.cmake index 3136708d5..3d32ee75c 100644 --- a/tools/ports/cpp-client-telemetry/portfile.cmake +++ b/tools/ports/cpp-client-telemetry/portfile.cmake @@ -21,9 +21,12 @@ if(VCPKG_TARGET_IS_IOS) endif() # 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). +# HTTP client and are mutually exclusive. They only matter on Linux/Android: the +# curl dependency is platform-filtered to those triplets, so on Windows/macOS/iOS +# both features may be present (curl-openssl is a default) yet pull no curl, and +# the SDK uses WinInet / Apple HTTP there. vcpkg cannot express mutual exclusivity +# or "exactly one of", so validate it here -- but only where curl is actually used, +# to avoid failing legitimate cross-platform manifests on Windows/Apple. set(_matsdk_http_features "") foreach(_matsdk_http_feature curl-openssl curl-mbedtls) if(_matsdk_http_feature IN_LIST FEATURES) @@ -31,26 +34,26 @@ foreach(_matsdk_http_feature curl-openssl curl-mbedtls) endif() endforeach() list(LENGTH _matsdk_http_features _matsdk_http_feature_count) -if(_matsdk_http_feature_count GREATER 1) - message(FATAL_ERROR - "curl-openssl (default) and curl-mbedtls are mutually exclusive but both were " - "selected. To use mbedTLS, drop the defaults with the [core,...] form and " - "re-select a SQLite backend (the [core,...] form also drops the default " - "system-sqlite feature), e.g. " - "cpp-client-telemetry[core,curl-mbedtls,system-sqlite] " - "(or minimal-sqlite in place of system-sqlite).") -endif() - -# On Linux/Android the built-in curl HTTP client requires exactly one TLS backend. -# The [core,...] form drops the default curl-openssl, so fail fast (with a complete -# example) rather than letting the SDK CMake fail later on a missing libcurl. -if((VCPKG_TARGET_IS_LINUX OR VCPKG_TARGET_IS_ANDROID) AND _matsdk_http_feature_count EQUAL 0) - message(FATAL_ERROR - "On Linux/Android the built-in curl HTTP client requires exactly one TLS " - "backend feature, but none was selected. The [core,...] form drops the " - "default curl-openssl feature, so re-add a curl backend together with a " - "SQLite backend, e.g. cpp-client-telemetry[core,curl-openssl,system-sqlite] " - "(or curl-mbedtls / minimal-sqlite in place of those).") +if(VCPKG_TARGET_IS_LINUX OR VCPKG_TARGET_IS_ANDROID) + if(_matsdk_http_feature_count GREATER 1) + message(FATAL_ERROR + "curl-openssl (default) and curl-mbedtls are mutually exclusive but both were " + "selected. To use mbedTLS, drop the defaults with the [core,...] form and " + "re-select a SQLite backend (the [core,...] form also drops the default " + "system-sqlite feature), e.g. " + "cpp-client-telemetry[core,curl-mbedtls,system-sqlite] " + "(or minimal-sqlite in place of system-sqlite).") + elseif(_matsdk_http_feature_count EQUAL 0) + # The built-in curl HTTP client requires exactly one TLS backend. The [core,...] + # form drops the default curl-openssl, so fail fast (with a complete example) + # rather than letting the SDK CMake fail later on a missing libcurl. + message(FATAL_ERROR + "On Linux/Android the built-in curl HTTP client requires exactly one TLS " + "backend feature, but none was selected. The [core,...] form drops the " + "default curl-openssl feature, so re-add a curl backend together with a " + "SQLite backend, e.g. cpp-client-telemetry[core,curl-openssl,system-sqlite] " + "(or curl-mbedtls / minimal-sqlite in place of those).") + endif() endif() # minimal-sqlite -> -DMATSDK_MINIMAL_SQLITE=ON (private feature-stripped SQLite). From 509ed08ca32e3b6ae088c0d7f0a5b2a55e104e8e Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Mon, 29 Jun 2026 22:14:00 -0500 Subject: [PATCH 13/25] vcpkg port tests: build the working tree, not a pinned release The port tests built the SDK from the portfile's pinned vcpkg_from_github REF (v3.10.161.1), so they never exercised the PR's own source -- and the macOS/iOS jobs failed because this PR's manifest drops the Apple sqlite3/zlib packages while the old pinned source still calls find_package(unofficial-sqlite3) unconditionally (the Apple system-libs branch only exists in the PR source). Add an opt-in MATSDK_VCPKG_SOURCE_DIR hook to portfile.cmake: when set, the port builds that local source; when unset (production installs), the pinned release is downloaded as before, so the published port behavior is unchanged. The five tests/vcpkg/* scripts set it to the repo root so the port tests validate the actual source + manifest together. Verified on Linux (x64-linux): the port now builds the working-tree SDK and the consumer passes 10/10; the macOS/iOS jobs will exercise the Apple system-libs branch (find_package(SQLite3)/ZLIB) instead of the dropped vcpkg packages. Files: tools/ports/cpp-client-telemetry/portfile.cmake, tests/vcpkg/test-vcpkg-{linux,macos,ios,android}.sh, tests/vcpkg/test-vcpkg-windows.ps1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/vcpkg/test-vcpkg-android.sh | 4 ++++ tests/vcpkg/test-vcpkg-ios.sh | 4 ++++ tests/vcpkg/test-vcpkg-linux.sh | 4 ++++ tests/vcpkg/test-vcpkg-macos.sh | 4 ++++ tests/vcpkg/test-vcpkg-windows.ps1 | 4 ++++ .../ports/cpp-client-telemetry/portfile.cmake | 24 +++++++++++++------ 6 files changed, 37 insertions(+), 7 deletions(-) diff --git a/tests/vcpkg/test-vcpkg-android.sh b/tests/vcpkg/test-vcpkg-android.sh index c43c73967..f49a24195 100755 --- a/tests/vcpkg/test-vcpkg-android.sh +++ b/tests/vcpkg/test-vcpkg-android.sh @@ -10,6 +10,10 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" OVERLAY_PORTS="${REPO_ROOT}/tools/ports" +# Build the working tree under review (not a pinned release) so this test +# validates the actual SDK source together with the port manifest/portfile. +export MATSDK_VCPKG_SOURCE_DIR="${REPO_ROOT}" + # Android ABI/API (defaults match the repo's Android minSdk) ANDROID_ABI="${1:-arm64-v8a}" ANDROID_API="${2:-23}" diff --git a/tests/vcpkg/test-vcpkg-ios.sh b/tests/vcpkg/test-vcpkg-ios.sh index f564e4615..c1097c3bd 100755 --- a/tests/vcpkg/test-vcpkg-ios.sh +++ b/tests/vcpkg/test-vcpkg-ios.sh @@ -10,6 +10,10 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" OVERLAY_PORTS="${REPO_ROOT}/tools/ports" + +# Build the working tree under review (not a pinned release) so this test +# validates the actual SDK source together with the port manifest/portfile. +export MATSDK_VCPKG_SOURCE_DIR="${REPO_ROOT}" USE_SIMULATOR=false for arg in "$@"; do diff --git a/tests/vcpkg/test-vcpkg-linux.sh b/tests/vcpkg/test-vcpkg-linux.sh index 3482abe53..d98757db8 100755 --- a/tests/vcpkg/test-vcpkg-linux.sh +++ b/tests/vcpkg/test-vcpkg-linux.sh @@ -9,6 +9,10 @@ REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" BUILD_DIR="${SCRIPT_DIR}/build-linux" OVERLAY_PORTS="${REPO_ROOT}/tools/ports" +# Build the working tree under review (not a pinned release) so this test +# validates the actual SDK source together with the port manifest/portfile. +export MATSDK_VCPKG_SOURCE_DIR="${REPO_ROOT}" + echo "=== MSTelemetry vcpkg port test (Linux) ===" echo "Repository root: ${REPO_ROOT}" diff --git a/tests/vcpkg/test-vcpkg-macos.sh b/tests/vcpkg/test-vcpkg-macos.sh index d864928c8..9a7d1bfd3 100755 --- a/tests/vcpkg/test-vcpkg-macos.sh +++ b/tests/vcpkg/test-vcpkg-macos.sh @@ -9,6 +9,10 @@ REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" BUILD_DIR="${SCRIPT_DIR}/build-macos" OVERLAY_PORTS="${REPO_ROOT}/tools/ports" +# Build the working tree under review (not a pinned release) so this test +# validates the actual SDK source together with the port manifest/portfile. +export MATSDK_VCPKG_SOURCE_DIR="${REPO_ROOT}" + echo "=== MSTelemetry vcpkg port test (macOS) ===" echo "Repository root: ${REPO_ROOT}" diff --git a/tests/vcpkg/test-vcpkg-windows.ps1 b/tests/vcpkg/test-vcpkg-windows.ps1 index 0536f2b8f..2b62452db 100644 --- a/tests/vcpkg/test-vcpkg-windows.ps1 +++ b/tests/vcpkg/test-vcpkg-windows.ps1 @@ -14,6 +14,10 @@ $RepoRoot = (Resolve-Path (Join-Path $ScriptDir "..\..")).Path $BuildDir = Join-Path $ScriptDir "build-windows" $OverlayPorts = Join-Path $RepoRoot "tools\ports" +# Build the working tree under review (not a pinned release) so this test +# validates the actual SDK source together with the port manifest/portfile. +$env:MATSDK_VCPKG_SOURCE_DIR = $RepoRoot + Write-Host "=== MSTelemetry vcpkg port test (Windows) ===" -ForegroundColor Cyan # Resolve vcpkg root: parameter > VCPKG_ROOT env var > error diff --git a/tools/ports/cpp-client-telemetry/portfile.cmake b/tools/ports/cpp-client-telemetry/portfile.cmake index 3d32ee75c..ee41997a4 100644 --- a/tools/ports/cpp-client-telemetry/portfile.cmake +++ b/tools/ports/cpp-client-telemetry/portfile.cmake @@ -1,10 +1,20 @@ -vcpkg_from_github( - OUT_SOURCE_PATH SOURCE_PATH - REPO microsoft/cpp_client_telemetry - REF v3.10.161.1 - SHA512 4664b34ddce601d6a95669df4a59d11a6cc67de1f23de132192f791a275edc6a10b8498d340e6cf7d120d9e7a22c494d7517b24fc0954bf9e236e84a8800589a - HEAD_REF main -) +# In-repo port validation (tests/vcpkg/*) sets MATSDK_VCPKG_SOURCE_DIR so the port +# builds the working tree under review instead of a pinned release -- this is what +# lets the port tests actually exercise the SDK source + manifest together. When +# the variable is unset (production installs), the pinned release is downloaded as +# usual, so the published port behavior is unchanged. +if(DEFINED ENV{MATSDK_VCPKG_SOURCE_DIR}) + set(SOURCE_PATH "$ENV{MATSDK_VCPKG_SOURCE_DIR}") + message(STATUS "cpp-client-telemetry: building local source $ENV{MATSDK_VCPKG_SOURCE_DIR} (MATSDK_VCPKG_SOURCE_DIR is set)") +else() + vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO microsoft/cpp_client_telemetry + REF v3.10.161.1 + SHA512 4664b34ddce601d6a95669df4a59d11a6cc67de1f23de132192f791a275edc6a10b8498d340e6cf7d120d9e7a22c494d7517b24fc0954bf9e236e84a8800589a + HEAD_REF main + ) +endif() # Determine if Apple HTTP should be used (no curl needed). # Note: BUILD_APPLE_HTTP must remain ON for macOS/iOS because the vcpkg.json From 00c562189048b0606d3dffccf856deb738e9b243 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 30 Jun 2026 12:29:10 -0500 Subject: [PATCH 14/25] Fix Windows vcpkg test to actually build the working tree On Windows, vcpkg runs portfiles in a sanitized environment and strips custom variables unless allow-listed via VCPKG_KEEP_ENV_VARS. Without it the portfile never saw MATSDK_VCPKG_SOURCE_DIR and silently fell back to the pinned release (v3.10.161.1), so the Windows port test validated the old release instead of the PR source while still reporting PASS. Allow-list the variable so the test builds the working tree, matching the Linux/macOS scripts (POSIX vcpkg passes the variable through, so they need no change). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/vcpkg/test-vcpkg-windows.ps1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/vcpkg/test-vcpkg-windows.ps1 b/tests/vcpkg/test-vcpkg-windows.ps1 index 2b62452db..29de9c631 100644 --- a/tests/vcpkg/test-vcpkg-windows.ps1 +++ b/tests/vcpkg/test-vcpkg-windows.ps1 @@ -17,6 +17,12 @@ $OverlayPorts = Join-Path $RepoRoot "tools\ports" # Build the working tree under review (not a pinned release) so this test # validates the actual SDK source together with the port manifest/portfile. $env:MATSDK_VCPKG_SOURCE_DIR = $RepoRoot +# On Windows, vcpkg runs portfiles in a sanitized environment and strips custom +# variables unless they are allow-listed here. Without this, the portfile does +# not see MATSDK_VCPKG_SOURCE_DIR and silently builds the pinned release instead +# of the working tree (POSIX vcpkg passes the variable through, so the Linux/ +# macOS scripts do not need this). +$env:VCPKG_KEEP_ENV_VARS = "MATSDK_VCPKG_SOURCE_DIR" Write-Host "=== MSTelemetry vcpkg port test (Windows) ===" -ForegroundColor Cyan From 299414180fa525c4df4a6e352409bd463c96d4e4 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 7 Jul 2026 13:37:20 -0500 Subject: [PATCH 15/25] Gate test suites on top-level project (default OFF for consumers) BUILD_UNIT_TESTS/BUILD_FUNC_TESTS defaulted to ON unconditionally, so a downstream project consuming this repo via add_subdirectory()/FetchContent built the whole test suite and required the third_party/googletest submodule. Default them ON only when this repo is the top-level project (PROJECT_IS_TOP_LEVEL on CMake >= 3.21, source-dir comparison on older CMake) and OFF when consumed as a subproject. Direct/CI builds are unchanged (top-level => ON) since build scripts rely on the default; verified BUILD_UNIT_TESTS/BUILD_FUNC_TESTS=ON for a top-level configure and OFF via add_subdirectory. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CMakeLists.txt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0221dcbe6..7a60cc5a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -337,8 +337,20 @@ message(STATUS "SDK version: ${SDK_VERSION_PREFIX}-${MATSDK_BUILD_VERSION}") option(BUILD_HEADERS "Build API headers" YES) option(BUILD_LIBRARY "Build library" YES) option(BUILD_TEST_TOOL "Build console test tool" YES) -option(BUILD_UNIT_TESTS "Build unit tests" YES) -option(BUILD_FUNC_TESTS "Build functional tests" YES) +# Default the test suites ON only when this repository is the top-level project +# (developer/CI build), and OFF when it is consumed via add_subdirectory()/ +# FetchContent, so downstream projects don't build the tests or require the +# third_party/googletest submodule. PROJECT_IS_TOP_LEVEL exists on CMake >= 3.21; +# fall back to comparing the source dirs on older CMake (floor is 3.15). +if(DEFINED PROJECT_IS_TOP_LEVEL) + set(MATSDK_TESTS_DEFAULT ${PROJECT_IS_TOP_LEVEL}) +elseif(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(MATSDK_TESTS_DEFAULT ON) +else() + set(MATSDK_TESTS_DEFAULT OFF) +endif() +option(BUILD_UNIT_TESTS "Build unit tests" ${MATSDK_TESTS_DEFAULT}) +option(BUILD_FUNC_TESTS "Build functional tests" ${MATSDK_TESTS_DEFAULT}) option(BUILD_JNI_WRAPPER "Build JNI wrapper" NO) option(BUILD_OBJC_WRAPPER "Build Obj-C wrapper" YES) option(BUILD_SWIFT_WRAPPER "Build Swift Wrappers" YES) From 2995f9e9510ee840d45ff5876b911157dc41b2d0 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 7 Jul 2026 13:47:07 -0500 Subject: [PATCH 16/25] Address Copilot review: validate source dir, append VCPKG_KEEP_ENV_VARS - portfile.cmake: validate MATSDK_VCPKG_SOURCE_DIR points at a real checkout (CMakeLists.txt present) and fail early with a clear message instead of a confusing downstream CMake error. - test-vcpkg-windows.ps1: append MATSDK_VCPKG_SOURCE_DIR to VCPKG_KEEP_ENV_VARS instead of overwriting it, preserving any entries the caller/CI already set. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/vcpkg/test-vcpkg-windows.ps1 | 6 +++++- tools/ports/cpp-client-telemetry/portfile.cmake | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/vcpkg/test-vcpkg-windows.ps1 b/tests/vcpkg/test-vcpkg-windows.ps1 index 29de9c631..b1390425a 100644 --- a/tests/vcpkg/test-vcpkg-windows.ps1 +++ b/tests/vcpkg/test-vcpkg-windows.ps1 @@ -22,7 +22,11 @@ $env:MATSDK_VCPKG_SOURCE_DIR = $RepoRoot # not see MATSDK_VCPKG_SOURCE_DIR and silently builds the pinned release instead # of the working tree (POSIX vcpkg passes the variable through, so the Linux/ # macOS scripts do not need this). -$env:VCPKG_KEEP_ENV_VARS = "MATSDK_VCPKG_SOURCE_DIR" +if ($env:VCPKG_KEEP_ENV_VARS) { + $env:VCPKG_KEEP_ENV_VARS = "$($env:VCPKG_KEEP_ENV_VARS);MATSDK_VCPKG_SOURCE_DIR" +} else { + $env:VCPKG_KEEP_ENV_VARS = "MATSDK_VCPKG_SOURCE_DIR" +} Write-Host "=== MSTelemetry vcpkg port test (Windows) ===" -ForegroundColor Cyan diff --git a/tools/ports/cpp-client-telemetry/portfile.cmake b/tools/ports/cpp-client-telemetry/portfile.cmake index ee41997a4..70d2b4e73 100644 --- a/tools/ports/cpp-client-telemetry/portfile.cmake +++ b/tools/ports/cpp-client-telemetry/portfile.cmake @@ -5,6 +5,11 @@ # usual, so the published port behavior is unchanged. if(DEFINED ENV{MATSDK_VCPKG_SOURCE_DIR}) set(SOURCE_PATH "$ENV{MATSDK_VCPKG_SOURCE_DIR}") + if(NOT EXISTS "${SOURCE_PATH}/CMakeLists.txt") + message(FATAL_ERROR + "MATSDK_VCPKG_SOURCE_DIR is set to '${SOURCE_PATH}', but no CMakeLists.txt " + "was found there. It must point to a cpp_client_telemetry source checkout.") + endif() message(STATUS "cpp-client-telemetry: building local source $ENV{MATSDK_VCPKG_SOURCE_DIR} (MATSDK_VCPKG_SOURCE_DIR is set)") else() vcpkg_from_github( From 5d127d72731229d41fd4145c6af768b8874ae215 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 7 Jul 2026 17:28:20 -0500 Subject: [PATCH 17/25] Support consuming SDK as a CMake subproject in legacy mode Applies the two changes the ONNX Runtime consumer patch carried so they can be dropped from the downstream patch set. Change 1 (CMakeLists.txt): use CMAKE_CURRENT_SOURCE_DIR instead of CMAKE_SOURCE_DIR for the vendored sqlite/zlib/nlohmann include path, so the headers still resolve when the SDK is added via add_subdirectory/FetchContent (where CMAKE_SOURCE_DIR points at the consumer's root, not this repo). Change 2 (lib/CMakeLists.txt): extend the Android bundled-deps legacy path to also cover iOS. A cross-compile cannot reliably find a system libsqlite3, and the vendored zlib renames its exports to act_z_* (zlib/names.h) so a system libz cannot satisfy those symbols. iOS now builds the vendored sqlite amalgamation + bundled zlib, matching Android. Only affects legacy mode (MATSDK_USE_VCPKG_DEPS=OFF); the vcpkg Apple path still links system libs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CMakeLists.txt | 7 +++++-- lib/CMakeLists.txt | 22 ++++++++++++++-------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a60cc5a8..8b2321e3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -455,8 +455,11 @@ if(MATSDK_USE_VCPKG_DEPS) endif() endif() else() - # Include repo root to allow includes of vendored sqlite, zlib, and nlohmann - include_directories(${CMAKE_SOURCE_DIR}) + # Include repo root to allow includes of vendored sqlite, zlib, and nlohmann. + # Use CMAKE_CURRENT_SOURCE_DIR (this repo's root) rather than CMAKE_SOURCE_DIR + # so the vendored headers still resolve when the SDK is consumed as a subproject + # (add_subdirectory/FetchContent), where CMAKE_SOURCE_DIR is the consumer's root. + include_directories(${CMAKE_CURRENT_SOURCE_DIR}) message(STATUS "Using vendored sqlite3, zlib, nlohmann-json") endif() diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 2850359bd..5414a5dab 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -445,7 +445,10 @@ 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") +elseif(NOT MATSDK_USE_VCPKG_DEPS AND (CMAKE_SYSTEM_NAME STREQUAL "Android" OR CMAKE_SYSTEM_NAME STREQUAL "iOS")) + # Android NDK has no system SQLite; iOS shares this path because a cross-compile + # cannot reliably discover a system libsqlite3 via find_package. Both build the + # vendored amalgamation instead. set(MATSDK_BUNDLE_SQLITE ON) endif() @@ -517,10 +520,13 @@ if(MATSDK_USE_VCPKG_DEPS) endif() else() # Legacy mode: use vendored or system-installed deps - if(CMAKE_SYSTEM_NAME STREQUAL "Android") - # 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). + if(CMAKE_SYSTEM_NAME STREQUAL "Android" OR CMAKE_SYSTEM_NAME STREQUAL "iOS") + # Build zlib from bundled source. Android NDK has no system zlib. iOS shares + # this path: the vendored zlib headers rename their exports to act_z_* (via + # zlib/names.h), so a system libz cannot satisfy those symbols, and a + # cross-compile cannot reliably discover system zlib/sqlite3 via find_package. + # SQLite is provided by sqlite3_bundled, created above (MATSDK_BUNDLE_SQLITE is + # ON for these platforms in legacy mode). add_library(zlib_bundled STATIC "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/adler32.c" "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/compress.c" @@ -541,9 +547,9 @@ else() target_include_directories(zlib_bundled PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../zlib") set_target_properties(zlib_bundled PROPERTIES POSITION_INDEPENDENT_CODE ON) # Bundled zlib compiles the pristine sources without zlib's configure step, - # so tell it is available (Android is POSIX). This gives gz*.c the - # real POSIX declarations for read/write/lseek/close instead of relying on - # implicit (int-returning) declarations. + # so tell it is available (Android and iOS are POSIX). This gives + # gz*.c the real POSIX declarations for read/write/lseek/close instead of + # relying on implicit (int-returning) declarations. target_compile_definitions(zlib_bundled PRIVATE Z_HAVE_UNISTD_H) target_link_libraries(mat PRIVATE sqlite3_bundled zlib_bundled ${LIBS}) From e8a25ad0968b8bc9bbc065ce0a35dbc5b5f7e862 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 7 Jul 2026 17:35:45 -0500 Subject: [PATCH 18/25] Explicitly disable warning-as-error for the vendored SQLite TU on MSVC Address Copilot review comment on lib/CMakeLists.txt:470. The comment claimed the build drops /WX for the vendored SQLite translation unit, but the code only added /w. /w disables all warnings, but MSVC can still promote a non-suppressible warning to an error under an inherited /WX. Add /WX- so the code literally matches the comment's stated intent and cannot be broken by such a warning. Verified cl.exe accepts /w /WX- together. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- lib/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 5414a5dab..998cdea17 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -465,9 +465,10 @@ if(MATSDK_BUNDLE_SQLITE AND NOT TARGET sqlite3_bundled) 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) + # Silence the vendored amalgamation's warnings (/w) and turn off + # warning-as-error (/WX-) for this third-party translation unit, so the SDK's + # /WX does not promote any amalgamation warning that survives /w to an error. + target_compile_options(sqlite3_bundled PRIVATE /w /WX-) 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 From 5a238e8bff6eaabfb059c56d19bdfbf58af896c9 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 7 Jul 2026 17:43:20 -0500 Subject: [PATCH 19/25] Clarify MATSDK_MINIMAL_SQLITE-on-Apple comment for the iOS legacy path Address Copilot review comment on lib/CMakeLists.txt:446. Adding iOS to the legacy bundled-SQLite path means MATSDK_MINIMAL_SQLITE is no longer a strict no-op on all Apple builds: iOS in legacy mode (MATSDK_USE_VCPKG_DEPS=OFF) bundles the amalgamation and applies the strip definitions to it, matching Android legacy. Clarify the comment so it no longer reads as a blanket 'no effect on Apple' statement. No behavior change. 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 998cdea17..11bf1cce6 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -442,8 +442,11 @@ set(MATSDK_SQLITE_MINIMAL_DEFS # existing (unstripped) bundled SQLite behavior. set(MATSDK_BUNDLE_SQLITE OFF) 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. + # MATSDK_MINIMAL_SQLITE does not by itself force bundling on Apple: macOS (vcpkg + # or native legacy) and iOS-vcpkg link the smaller system libsqlite3, so the + # feature is a no-op there. iOS *legacy* (MATSDK_USE_VCPKG_DEPS=OFF) is the + # exception -- it bundles the amalgamation via the branch below, and when + # MATSDK_MINIMAL_SQLITE is ON its strip definitions are applied to that copy. set(MATSDK_BUNDLE_SQLITE ON) elseif(NOT MATSDK_USE_VCPKG_DEPS AND (CMAKE_SYSTEM_NAME STREQUAL "Android" OR CMAKE_SYSTEM_NAME STREQUAL "iOS")) # Android NDK has no system SQLite; iOS shares this path because a cross-compile From c11447591cee1f889039a7eee43e8b11043422b0 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 7 Jul 2026 19:54:15 -0500 Subject: [PATCH 20/25] Link system sqlite3 + zlib on Apple legacy builds (match repo convention) Take further inspiration from the ONNX Runtime consumer patch, verified against what the repo already does on Apple. The SDK's own iOS Xcode projects link libsqlite3.tbd + libz.tbd from the SDKROOT, Package.swift links .linkedLibrary("sqlite3")/("z"), and #1499 already links the system libsqlite3/libz on the vcpkg Apple path. Bundling is an Android-only convention (the NDK ships no system zlib). So the earlier change that made iOS legacy bundle sqlite+zlib was the inconsistent one; this aligns iOS with the rest of the repo. - Apple legacy (macOS + iOS) now links system `sqlite3 z` by portable names in a single elseif(APPLE) branch. macOS moves off find_package(ZLIB) + hardcoded Homebrew .a paths (non-relocatable) onto the same portable link names, so exported static packages stay relocatable. iOS no longer bundles. - iOS dropped from the MATSDK_BUNDLE_SQLITE gating and the bundled-zlib branch, which are now Android-only. - Exclude iOS from include_directories(/usr/local/include): that host (macOS) path must not be injected into an iOS cross-compile's search path where it can shadow the iOS SDK's own headers. - Linux legacy simplified to find_package(SQLite3) (the Homebrew .a fallbacks were macOS-only and are now handled by the Apple branch). Verified: Linux top-level and add_subdirectory legacy builds both produce libmat.so. The Apple legacy path is exercised by the macOS-latest CI leg (build-posix-latest, legacy mode); iOS cannot be built on this host. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- lib/CMakeLists.txt | 64 +++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 11bf1cce6..7b834b14a 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -6,8 +6,10 @@ cmake_policy(SET CMP0063 NEW) # to downstream consumers via find_package() (see target_include_directories below). include_directories( . ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include/public ${CMAKE_CURRENT_SOURCE_DIR}/include/mat ${CMAKE_CURRENT_SOURCE_DIR}/pal ${CMAKE_CURRENT_SOURCE_DIR}/utils ${CMAKE_CURRENT_SOURCE_DIR}/modules/exp ${CMAKE_CURRENT_SOURCE_DIR}/modules/dataviewer ${CMAKE_CURRENT_SOURCE_DIR}/modules/privacyguard ${CMAKE_CURRENT_SOURCE_DIR}/modules/liveeventinspector ${CMAKE_CURRENT_SOURCE_DIR}/modules/cds ${CMAKE_CURRENT_SOURCE_DIR}/modules/signals ${CMAKE_CURRENT_SOURCE_DIR}/modules/sanitizer ) -# Legacy builds may need system-installed deps from /usr/local/include -if(NOT MATSDK_USE_VCPKG_DEPS) +# Legacy builds may need system-installed deps from /usr/local/include. Excluded on +# iOS: /usr/local/include is a host (macOS) path, and injecting it into an iOS +# cross-compile's search path can shadow the iOS SDK's own headers. +if(NOT MATSDK_USE_VCPKG_DEPS AND NOT CMAKE_SYSTEM_NAME STREQUAL "iOS") include_directories(/usr/local/include) endif() @@ -442,16 +444,11 @@ set(MATSDK_SQLITE_MINIMAL_DEFS # existing (unstripped) bundled SQLite behavior. set(MATSDK_BUNDLE_SQLITE OFF) if(MATSDK_MINIMAL_SQLITE AND NOT APPLE) - # MATSDK_MINIMAL_SQLITE does not by itself force bundling on Apple: macOS (vcpkg - # or native legacy) and iOS-vcpkg link the smaller system libsqlite3, so the - # feature is a no-op there. iOS *legacy* (MATSDK_USE_VCPKG_DEPS=OFF) is the - # exception -- it bundles the amalgamation via the branch below, and when - # MATSDK_MINIMAL_SQLITE is ON its strip definitions are applied to that copy. + # On Apple the SDK links the system libsqlite3/libz (see the Apple branch below), + # 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" OR CMAKE_SYSTEM_NAME STREQUAL "iOS")) - # Android NDK has no system SQLite; iOS shares this path because a cross-compile - # cannot reliably discover a system libsqlite3 via find_package. Both build the - # vendored amalgamation instead. +elseif(NOT MATSDK_USE_VCPKG_DEPS AND CMAKE_SYSTEM_NAME STREQUAL "Android") + # Android NDK ships no system SQLite, so the vendored amalgamation is always bundled. set(MATSDK_BUNDLE_SQLITE ON) endif() @@ -524,13 +521,11 @@ if(MATSDK_USE_VCPKG_DEPS) endif() else() # Legacy mode: use vendored or system-installed deps - if(CMAKE_SYSTEM_NAME STREQUAL "Android" OR CMAKE_SYSTEM_NAME STREQUAL "iOS") - # Build zlib from bundled source. Android NDK has no system zlib. iOS shares - # this path: the vendored zlib headers rename their exports to act_z_* (via - # zlib/names.h), so a system libz cannot satisfy those symbols, and a - # cross-compile cannot reliably discover system zlib/sqlite3 via find_package. - # SQLite is provided by sqlite3_bundled, created above (MATSDK_BUNDLE_SQLITE is - # ON for these platforms in legacy mode). + if(CMAKE_SYSTEM_NAME STREQUAL "Android") + # Build zlib from bundled source: the Android NDK ships no system zlib, and the + # vendored zlib renames its exports to act_z_* (via zlib/names.h). 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" @@ -551,9 +546,9 @@ else() target_include_directories(zlib_bundled PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../zlib") set_target_properties(zlib_bundled PROPERTIES POSITION_INDEPENDENT_CODE ON) # Bundled zlib compiles the pristine sources without zlib's configure step, - # so tell it is available (Android and iOS are POSIX). This gives - # gz*.c the real POSIX declarations for read/write/lseek/close instead of - # relying on implicit (int-returning) declarations. + # so tell it is available (Android is POSIX). This gives gz*.c the + # real POSIX declarations for read/write/lseek/close instead of relying on + # implicit (int-returning) declarations. target_compile_definitions(zlib_bundled PRIVATE Z_HAVE_UNISTD_H) target_link_libraries(mat PRIVATE sqlite3_bundled zlib_bundled ${LIBS}) @@ -567,26 +562,25 @@ else() else() target_link_libraries(mat PRIVATE ${LIBS}) endif() + elseif(APPLE) + # macOS and iOS both ship system libsqlite3 and libz. Link them by portable + # names -- matching the SDK's own iOS Xcode projects (libsqlite3.tbd + libz.tbd + # from the SDKROOT), Package.swift (.linkedLibrary sqlite3/z), and the vcpkg + # Apple path -- so nothing is bundled and exported static packages stay + # relocatable. On Apple, #include / resolve from the SDK + # sysroot, so no explicit include dir or find_package is needed. + target_link_libraries(mat PRIVATE sqlite3 z ${LIBS}) else() - # Linux/macOS legacy: link system-installed (or private minimal) sqlite3 and system zlib + # Linux legacy: system zlib + system (or private minimal) sqlite3. find_package(ZLIB REQUIRED) target_include_directories(mat PRIVATE ${ZLIB_INCLUDE_DIRS}) 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}) + # 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) + target_link_libraries(mat PRIVATE SQLite::SQLite3 ZLIB::ZLIB ${LIBS}) endif() endif() endif() From 2b52d061e307ab72424e07213b13a39830a75deb Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Wed, 8 Jul 2026 17:23:03 -0500 Subject: [PATCH 21/25] Drop redundant ZLIB include dir on the Linux legacy path target_include_directories(mat PRIVATE ${ZLIB_INCLUDE_DIRS}) was redundant: mat already links ZLIB::ZLIB (and SQLite::SQLite3), imported targets that propagate their own include directories. Verified: Linux legacy mat build still resolves and produces libmat.so. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- lib/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 7b834b14a..8ec22f54b 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -571,9 +571,9 @@ else() # sysroot, so no explicit include dir or find_package is needed. target_link_libraries(mat PRIVATE sqlite3 z ${LIBS}) else() - # Linux legacy: system zlib + system (or private minimal) sqlite3. + # Linux legacy: system zlib + system (or private minimal) sqlite3. ZLIB::ZLIB + # and SQLite::SQLite3 are imported targets that carry their own include dirs. find_package(ZLIB REQUIRED) - target_include_directories(mat PRIVATE ${ZLIB_INCLUDE_DIRS}) if(MATSDK_BUNDLE_SQLITE) target_link_libraries(mat PRIVATE sqlite3_bundled ZLIB::ZLIB ${LIBS}) else() From 07db5df3fe824408eb953b1248d47e09b107778f Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Fri, 10 Jul 2026 10:11:06 -0500 Subject: [PATCH 22/25] vcpkg port: bump pinned REF to v3.10.173.1 to match the SDK version The port pinned v3.10.161.1 while the SDK source on this branch is at v3.10.173.1 (Version.hpp), leaving production installs two releases behind. Bump the portfile REF + SHA512 and the vcpkg.json version to v3.10.173.1; the SHA512 is computed from the release source tarball. Note: the port's minimal-sqlite and Apple system-sqlite features depend on CMake changes introduced by this PR that are not yet in any release tag. The in-repo port tests exercise them against local source via MATSDK_VCPKG_SOURCE_DIR, and the pinned REF must be advanced again to the release that includes these changes once it is cut. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tools/ports/cpp-client-telemetry/portfile.cmake | 4 ++-- tools/ports/cpp-client-telemetry/vcpkg.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/ports/cpp-client-telemetry/portfile.cmake b/tools/ports/cpp-client-telemetry/portfile.cmake index 70d2b4e73..c9ce3168c 100644 --- a/tools/ports/cpp-client-telemetry/portfile.cmake +++ b/tools/ports/cpp-client-telemetry/portfile.cmake @@ -15,8 +15,8 @@ else() vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO microsoft/cpp_client_telemetry - REF v3.10.161.1 - SHA512 4664b34ddce601d6a95669df4a59d11a6cc67de1f23de132192f791a275edc6a10b8498d340e6cf7d120d9e7a22c494d7517b24fc0954bf9e236e84a8800589a + REF v3.10.173.1 + SHA512 e55bc35274236f57757660073c4dccccab3462342c8566212f1df4bf8824295a2bb3d3d79a11f3950e7c9252641827e9dd3d7c28c421dea3bdaee277e4f2ce32 HEAD_REF main ) endif() diff --git a/tools/ports/cpp-client-telemetry/vcpkg.json b/tools/ports/cpp-client-telemetry/vcpkg.json index ba5234ef7..e8a9eb5a5 100644 --- a/tools/ports/cpp-client-telemetry/vcpkg.json +++ b/tools/ports/cpp-client-telemetry/vcpkg.json @@ -1,6 +1,6 @@ { "name": "cpp-client-telemetry", - "version": "3.10.161.1", + "version": "3.10.173.1", "description": "Microsoft 1DS C/C++ Client Telemetry Library", "homepage": "https://github.com/microsoft/cpp_client_telemetry", "license": "Apache-2.0", From 93dd36e92388b4afadc2ac5ab9e6e24ece1b6e4d Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Sun, 12 Jul 2026 11:56:23 -0500 Subject: [PATCH 23/25] Validate vcpkg release bump production port path After updating the vcpkg port REF/SHA512/version for a new SDK release, exercise the real production port path with MATSDK_VCPKG_SOURCE_DIR unset. This catches mismatches where the port manifest assumes source changes that are not present in the release tag the port downloads. When the new footprint features are present, validate the opt-in minimal-sqlite + curl-openssl feature set so release automation covers both release pinning and feature wiring before opening the vcpkg PR. Validation: - Parsed .github/workflows/vcpkg-release-bump.yml with PyYAML. - Verified the feature-selection expression resolves to cpp-client-telemetry[core,minimal-sqlite,curl-openssl] for the current port. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/vcpkg-release-bump.yml | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.github/workflows/vcpkg-release-bump.yml b/.github/workflows/vcpkg-release-bump.yml index d09706242..77ed47444 100644 --- a/.github/workflows/vcpkg-release-bump.yml +++ b/.github/workflows/vcpkg-release-bump.yml @@ -147,6 +147,31 @@ jobs: mv "${MANIFEST}.tmp" "${MANIFEST}" ./vcpkg format-manifest "${MANIFEST}" + - name: Validate updated production port + if: ${{ steps.ver.outputs.skip != 'true' }} + run: | + set -euo pipefail + cd vcpkg + MANIFEST="ports/${PORT}/vcpkg.json" + + # Exercise the real production path: MATSDK_VCPKG_SOURCE_DIR must be + # unset so the port downloads the just-updated REF/SHA512 instead of + # accidentally validating this workflow's working tree. This catches + # manifest/portfile changes that require source changes not present in + # the release tag. + unset MATSDK_VCPKG_SOURCE_DIR + + PORT_SPEC="${PORT}" + if jq -e '(.features["minimal-sqlite"] != null) and (.features["curl-openssl"] != null)' "${MANIFEST}" >/dev/null; then + # Use an opt-in feature set when available so release validation covers + # feature wiring as well as the default graph. The default graph is + # still covered by regular vcpkg CI and by consumers. + PORT_SPEC="${PORT}[core,minimal-sqlite,curl-openssl]" + fi + + echo "Validating production port: ${PORT_SPEC}" + ./vcpkg install "${PORT_SPEC}" --triplet x64-linux --clean-after-build + - name: Detect change id: diff if: ${{ steps.ver.outputs.skip != 'true' }} From dd6007a693363b457d1ab12c576db606086891aa Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Sun, 12 Jul 2026 12:06:25 -0500 Subject: [PATCH 24/25] Remove vcpkg release-bump production validation Remove the release-bump production-port validation added in 93dd36e9. The vcpkg port update will instead rely on the explicit release sequencing: merge the SDK source changes, cut a new SDK tag, then bump the vcpkg REF, SHA512, and version to that tag. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/vcpkg-release-bump.yml | 25 ------------------------ 1 file changed, 25 deletions(-) diff --git a/.github/workflows/vcpkg-release-bump.yml b/.github/workflows/vcpkg-release-bump.yml index 77ed47444..d09706242 100644 --- a/.github/workflows/vcpkg-release-bump.yml +++ b/.github/workflows/vcpkg-release-bump.yml @@ -147,31 +147,6 @@ jobs: mv "${MANIFEST}.tmp" "${MANIFEST}" ./vcpkg format-manifest "${MANIFEST}" - - name: Validate updated production port - if: ${{ steps.ver.outputs.skip != 'true' }} - run: | - set -euo pipefail - cd vcpkg - MANIFEST="ports/${PORT}/vcpkg.json" - - # Exercise the real production path: MATSDK_VCPKG_SOURCE_DIR must be - # unset so the port downloads the just-updated REF/SHA512 instead of - # accidentally validating this workflow's working tree. This catches - # manifest/portfile changes that require source changes not present in - # the release tag. - unset MATSDK_VCPKG_SOURCE_DIR - - PORT_SPEC="${PORT}" - if jq -e '(.features["minimal-sqlite"] != null) and (.features["curl-openssl"] != null)' "${MANIFEST}" >/dev/null; then - # Use an opt-in feature set when available so release validation covers - # feature wiring as well as the default graph. The default graph is - # still covered by regular vcpkg CI and by consumers. - PORT_SPEC="${PORT}[core,minimal-sqlite,curl-openssl]" - fi - - echo "Validating production port: ${PORT_SPEC}" - ./vcpkg install "${PORT_SPEC}" --triplet x64-linux --clean-after-build - - name: Detect change id: diff if: ${{ steps.ver.outputs.skip != 'true' }} From e9392631eeaca9963b06bbac8c0b127cc5d50fd3 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Sun, 12 Jul 2026 19:32:45 -0500 Subject: [PATCH 25/25] Revert "Remove vcpkg release-bump production validation" This reverts commit dd6007a693363b457d1ab12c576db606086891aa. --- .github/workflows/vcpkg-release-bump.yml | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.github/workflows/vcpkg-release-bump.yml b/.github/workflows/vcpkg-release-bump.yml index d09706242..77ed47444 100644 --- a/.github/workflows/vcpkg-release-bump.yml +++ b/.github/workflows/vcpkg-release-bump.yml @@ -147,6 +147,31 @@ jobs: mv "${MANIFEST}.tmp" "${MANIFEST}" ./vcpkg format-manifest "${MANIFEST}" + - name: Validate updated production port + if: ${{ steps.ver.outputs.skip != 'true' }} + run: | + set -euo pipefail + cd vcpkg + MANIFEST="ports/${PORT}/vcpkg.json" + + # Exercise the real production path: MATSDK_VCPKG_SOURCE_DIR must be + # unset so the port downloads the just-updated REF/SHA512 instead of + # accidentally validating this workflow's working tree. This catches + # manifest/portfile changes that require source changes not present in + # the release tag. + unset MATSDK_VCPKG_SOURCE_DIR + + PORT_SPEC="${PORT}" + if jq -e '(.features["minimal-sqlite"] != null) and (.features["curl-openssl"] != null)' "${MANIFEST}" >/dev/null; then + # Use an opt-in feature set when available so release validation covers + # feature wiring as well as the default graph. The default graph is + # still covered by regular vcpkg CI and by consumers. + PORT_SPEC="${PORT}[core,minimal-sqlite,curl-openssl]" + fi + + echo "Validating production port: ${PORT_SPEC}" + ./vcpkg install "${PORT_SPEC}" --triplet x64-linux --clean-after-build + - name: Detect change id: diff if: ${{ steps.ver.outputs.skip != 'true' }}