Skip to content

Commit 5152cb4

Browse files
bmehta001Copilot
andauthored
Reduce binary footprint and support embedding the SDK as a CMake subproject (#1499)
* 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> * 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> * 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 (\$<LINK_ONLY:...>). - 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> * 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 \$<LINK_ONLY:...> (hence it is exported for static builds); a shared mat absorbs it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * 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> * 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> * 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> * 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> * 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> * 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> * 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> * 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> * 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> * 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> * 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> * 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> * 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> * 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> * 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> * 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> * 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 <zlib.h> and produces libmat.so. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * 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> * 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> * Remove vcpkg release-bump production validation Remove the release-bump production-port validation added in 93dd36e. 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> * Revert "Remove vcpkg release-bump production validation" This reverts commit dd6007a. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent fa2734c commit 5152cb4

12 files changed

Lines changed: 552 additions & 70 deletions

File tree

‎.github/workflows/vcpkg-release-bump.yml‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,31 @@ jobs:
147147
mv "${MANIFEST}.tmp" "${MANIFEST}"
148148
./vcpkg format-manifest "${MANIFEST}"
149149
150+
- name: Validate updated production port
151+
if: ${{ steps.ver.outputs.skip != 'true' }}
152+
run: |
153+
set -euo pipefail
154+
cd vcpkg
155+
MANIFEST="ports/${PORT}/vcpkg.json"
156+
157+
# Exercise the real production path: MATSDK_VCPKG_SOURCE_DIR must be
158+
# unset so the port downloads the just-updated REF/SHA512 instead of
159+
# accidentally validating this workflow's working tree. This catches
160+
# manifest/portfile changes that require source changes not present in
161+
# the release tag.
162+
unset MATSDK_VCPKG_SOURCE_DIR
163+
164+
PORT_SPEC="${PORT}"
165+
if jq -e '(.features["minimal-sqlite"] != null) and (.features["curl-openssl"] != null)' "${MANIFEST}" >/dev/null; then
166+
# Use an opt-in feature set when available so release validation covers
167+
# feature wiring as well as the default graph. The default graph is
168+
# still covered by regular vcpkg CI and by consumers.
169+
PORT_SPEC="${PORT}[core,minimal-sqlite,curl-openssl]"
170+
fi
171+
172+
echo "Validating production port: ${PORT_SPEC}"
173+
./vcpkg install "${PORT_SPEC}" --triplet x64-linux --clean-after-build
174+
150175
- name: Detect change
151176
id: diff
152177
if: ${{ steps.ver.outputs.skip != 'true' }}

‎CMakeLists.txt‎

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ else()
1111
endif()
1212
message(STATUS "MATSDK_USE_VCPKG_DEPS: ${MATSDK_USE_VCPKG_DEPS}")
1313

14+
# Build a private, feature-stripped copy of the vendored SQLite amalgamation
15+
# instead of linking an external SQLite. The SDK uses SQLite only for its offline
16+
# event-storage cache, so the minimal build (see lib/CMakeLists.txt
17+
# MATSDK_SQLITE_MINIMAL_DEFS) omits every optional SQLite subsystem the SDK does
18+
# not use, shrinking the SQLite code ~10% and removing the external sqlite3
19+
# dependency. Off by default to preserve the existing external/system-SQLite
20+
# behavior; the Android NDK path always bundles SQLite regardless.
21+
option(MATSDK_MINIMAL_SQLITE "Build a feature-stripped vendored SQLite instead of an external one" OFF)
22+
message(STATUS "MATSDK_MINIMAL_SQLITE: ${MATSDK_MINIMAL_SQLITE}")
23+
1424
# Begin Uncomment for i386 build
1525
#set(CMAKE_SYSTEM_PROCESSOR i386)
1626
#set(CMAKE_C_FLAGS -m32)
@@ -327,8 +337,20 @@ message(STATUS "SDK version: ${SDK_VERSION_PREFIX}-${MATSDK_BUILD_VERSION}")
327337
option(BUILD_HEADERS "Build API headers" YES)
328338
option(BUILD_LIBRARY "Build library" YES)
329339
option(BUILD_TEST_TOOL "Build console test tool" YES)
330-
option(BUILD_UNIT_TESTS "Build unit tests" YES)
331-
option(BUILD_FUNC_TESTS "Build functional tests" YES)
340+
# Default the test suites ON only when this repository is the top-level project
341+
# (developer/CI build), and OFF when it is consumed via add_subdirectory()/
342+
# FetchContent, so downstream projects don't build the tests or require the
343+
# third_party/googletest submodule. PROJECT_IS_TOP_LEVEL exists on CMake >= 3.21;
344+
# fall back to comparing the source dirs on older CMake (floor is 3.15).
345+
if(DEFINED PROJECT_IS_TOP_LEVEL)
346+
set(MATSDK_TESTS_DEFAULT ${PROJECT_IS_TOP_LEVEL})
347+
elseif(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
348+
set(MATSDK_TESTS_DEFAULT ON)
349+
else()
350+
set(MATSDK_TESTS_DEFAULT OFF)
351+
endif()
352+
option(BUILD_UNIT_TESTS "Build unit tests" ${MATSDK_TESTS_DEFAULT})
353+
option(BUILD_FUNC_TESTS "Build functional tests" ${MATSDK_TESTS_DEFAULT})
332354
option(BUILD_JNI_WRAPPER "Build JNI wrapper" NO)
333355
option(BUILD_OBJC_WRAPPER "Build Obj-C wrapper" YES)
334356
option(BUILD_SWIFT_WRAPPER "Build Swift Wrappers" YES)
@@ -363,10 +385,25 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11"
363385
AND NOT BUILD_APPLE_HTTP)
364386
set(MATSDK_NEEDS_CURL ON)
365387
add_definitions(-DHAVE_MAT_CURL_HTTP_CLIENT)
366-
find_package(CURL REQUIRED)
367388
if(MATSDK_USE_VCPKG_DEPS)
389+
# The TLS backend (OpenSSL/mbedTLS) is selected by the vcpkg port's
390+
# curl-openssl (default) / curl-mbedtls features; the SDK just links libcurl.
391+
# Force CONFIG mode so the vcpkg-provided CURLConfig (which defines the
392+
# CURL::libcurl imported target) is used rather than the module FindCURL,
393+
# which on some CMake versions does not define that target.
394+
find_package(CURL CONFIG QUIET)
395+
if(NOT TARGET CURL::libcurl)
396+
message(FATAL_ERROR
397+
"libcurl was not found. The vcpkg port provides the curl HTTP client "
398+
"through the curl-openssl (default) or curl-mbedtls feature. Install "
399+
"cpp-client-telemetry with its default features, or, under the [core,...] "
400+
"form (which drops the default curl-openssl and system-sqlite features), "
401+
"re-select a curl backend and a SQLite backend together, e.g. "
402+
"[core,curl-openssl,system-sqlite] or [core,curl-mbedtls,minimal-sqlite].")
403+
endif()
368404
list(APPEND LIBS CURL::libcurl)
369405
else()
406+
find_package(CURL REQUIRED)
370407
# Prefer the imported target, which carries curl's include dirs and link
371408
# flags. Fall back to the find-module variables on CMake < 3.12, where
372409
# find_package(CURL) does not define CURL::libcurl.
@@ -383,13 +420,46 @@ endif()
383420
# Dependency resolution (vcpkg mode vs vendored)
384421
################################################################################################
385422
if(MATSDK_USE_VCPKG_DEPS)
386-
find_package(unofficial-sqlite3 CONFIG REQUIRED)
387-
find_package(ZLIB REQUIRED)
388-
find_package(nlohmann_json CONFIG REQUIRED)
389-
message(STATUS "Using vcpkg-provided sqlite3, zlib, nlohmann-json")
423+
if(APPLE)
424+
# macOS/iOS ship libsqlite3 and libz as system libraries (the SDK's SPM
425+
# distribution links them the same way), so the vcpkg sqlite3/zlib packages are
426+
# not pulled there -- find the system ones via CMake's standard find modules.
427+
find_package(SQLite3 REQUIRED)
428+
find_package(ZLIB REQUIRED)
429+
find_package(nlohmann_json CONFIG REQUIRED)
430+
set(MATSDK_APPLE_SYSTEM_DEPS ON)
431+
message(STATUS "Apple: using system SQLite3 + zlib; vcpkg-provided nlohmann-json")
432+
else()
433+
set(MATSDK_APPLE_SYSTEM_DEPS OFF)
434+
# SQLite is provided by the private minimal build when MATSDK_MINIMAL_SQLITE is
435+
# ON, so only require the external vcpkg sqlite3 package otherwise.
436+
if(NOT MATSDK_MINIMAL_SQLITE)
437+
find_package(unofficial-sqlite3 CONFIG QUIET)
438+
if(NOT unofficial-sqlite3_FOUND)
439+
message(FATAL_ERROR
440+
"SQLite was not found and the minimal SQLite is not enabled. The vcpkg "
441+
"port provides SQLite through one of two features: 'system-sqlite' "
442+
"(default, links the external sqlite3 package) or 'minimal-sqlite' "
443+
"(builds a private feature-stripped SQLite). Install "
444+
"cpp-client-telemetry with its default features, or with "
445+
"[core,system-sqlite] or [core,minimal-sqlite]. For a direct CMake build, pass "
446+
"-DMATSDK_MINIMAL_SQLITE=ON or ensure unofficial-sqlite3 is discoverable.")
447+
endif()
448+
endif()
449+
find_package(ZLIB REQUIRED)
450+
find_package(nlohmann_json CONFIG REQUIRED)
451+
if(MATSDK_MINIMAL_SQLITE)
452+
message(STATUS "Using vcpkg-provided zlib, nlohmann-json; private minimal SQLite")
453+
else()
454+
message(STATUS "Using vcpkg-provided sqlite3, zlib, nlohmann-json")
455+
endif()
456+
endif()
390457
else()
391-
# Include repo root to allow includes of vendored sqlite, zlib, and nlohmann
392-
include_directories(${CMAKE_SOURCE_DIR})
458+
# Include repo root to allow includes of vendored sqlite, zlib, and nlohmann.
459+
# Use CMAKE_CURRENT_SOURCE_DIR (this repo's root) rather than CMAKE_SOURCE_DIR
460+
# so the vendored headers still resolve when the SDK is consumed as a subproject
461+
# (add_subdirectory/FetchContent), where CMAKE_SOURCE_DIR is the consumer's root.
462+
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
393463
message(STATUS "Using vendored sqlite3, zlib, nlohmann-json")
394464
endif()
395465

‎cmake/MSTelemetryConfig.cmake.in‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@
22

33
include(CMakeFindDependencyMacro)
44

5-
# Re-find dependencies that consumers need
6-
find_dependency(unofficial-sqlite3 CONFIG)
5+
# Re-find dependencies that consumers need.
6+
# On Apple the SDK links the system libsqlite3 (SQLite::SQLite3); elsewhere it uses
7+
# the vcpkg sqlite3 package unless a private minimal SQLite is bundled.
8+
if(@MATSDK_APPLE_SYSTEM_DEPS@)
9+
find_dependency(SQLite3)
10+
elseif(NOT @MATSDK_BUNDLE_SQLITE@)
11+
find_dependency(unofficial-sqlite3 CONFIG)
12+
endif()
713
find_dependency(ZLIB)
814
find_dependency(nlohmann_json CONFIG)
915

@@ -14,7 +20,11 @@ find_dependency(nlohmann_json CONFIG)
1420
# because the macOS BUILD_APPLE_HTTP choice can't be inferred from
1521
# CMAKE_SYSTEM_NAME alone.
1622
if(@MATSDK_NEEDS_CURL@)
17-
find_dependency(CURL)
23+
# Force CONFIG mode so the vcpkg-provided CURLConfig (which defines the
24+
# CURL::libcurl imported target referenced by MSTelemetryTargets.cmake) is
25+
# used, rather than module-mode FindCURL, which on some CMake versions does
26+
# not define that target.
27+
find_dependency(CURL CONFIG)
1828
endif()
1929

2030
# Pthreads are needed on Linux and Android (POSIX threading)

‎docs/building-with-vcpkg.md‎

Lines changed: 124 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,24 @@ The vcpkg port automatically resolves the following dependencies:
145145

146146
| Dependency | vcpkg Package | CMake Target | Platforms |
147147
| -------------- | --------------- | --------------------------------- | ------------------ |
148-
| SQLite3 | `sqlite3` | `unofficial::sqlite3::sqlite3` | All |
149-
| zlib | `zlib` | `ZLIB::ZLIB` | All |
148+
| SQLite3 | `sqlite3` | `unofficial::sqlite3::sqlite3` | Non-Apple (default; see `minimal-sqlite`). **macOS/iOS link the system `libsqlite3`** (`SQLite::SQLite3`) |
149+
| zlib | `zlib` | `ZLIB::ZLIB` | Non-Apple. **macOS/iOS link the system `libz`** |
150150
| nlohmann JSON | `nlohmann-json` | `nlohmann_json::nlohmann_json` | All |
151-
| libcurl | `curl[openssl]` | `CURL::libcurl` | Non-Windows, non-Apple |
151+
| libcurl | `curl[openssl]` or `curl[mbedtls]` | `CURL::libcurl` | Non-Windows, non-Apple (required; TLS backend selectable: OpenSSL default or mbedTLS) |
152+
153+
On **macOS/iOS** the SDK links the OS-provided `libsqlite3` and `libz` (the same
154+
system libraries the SDK's Swift Package links), so the vcpkg `sqlite3` and `zlib`
155+
packages are not pulled there — those binaries carry no bundled SQLite/zlib.
156+
(`minimal-sqlite` therefore has no effect on Apple.)
157+
158+
The external `sqlite3` package is provided by the default `system-sqlite`
159+
feature. The `minimal-sqlite` feature replaces it with a private, feature-stripped
160+
SQLite built from the SDK's vendored amalgamation — see
161+
[Build a private minimal SQLite](#build-a-private-minimal-sqlite-minimal-sqlite-feature).
162+
163+
libcurl is provided by the default `curl-openssl` feature; `curl-mbedtls` swaps in
164+
the mbedTLS backend — see
165+
[Choose the HTTP client / TLS backend](#choose-the-http-client--tls-backend-largest-lever-on-linux).
152166

153167
Windows and macOS/iOS use platform-native HTTP clients (WinInet and
154168
NSURLSession respectively). Android vcpkg consumers use native libcurl because
@@ -230,6 +244,54 @@ the stripping happens at your link. Keep the SDK a static dependency linked
230244
*into* your binary: if you re-export its API across your own DLL boundary, the
231245
export table pins its symbols and defeats `/OPT:REF`.
232246

247+
### Choose the HTTP client / TLS backend (largest lever on Linux)
248+
249+
On Linux/Android the built-in HTTP client is libcurl, and curl's TLS backend
250+
dominates the SDK's footprint. (Windows uses WinInet and Apple uses NSURLSession,
251+
so this section does not apply there.) The port exposes the TLS backend as two
252+
mutually-exclusive features; pick the one that matches what your application
253+
already has:
254+
255+
| Feature | Transport | Approx. stripped size¹ | Use when |
256+
| ------- | --------- | ---------------------- | -------- |
257+
| `curl-openssl` (default) | libcurl + OpenSSL | ~10.6 MB | your app already links OpenSSL (share it) |
258+
| `curl-mbedtls` | libcurl + mbedTLS | ~4.4 MB | your app has no HTTP/TLS stack of its own |
259+
260+
¹ Rough sizes of a minimal Linux consumer **without** consumer-side dead-stripping
261+
(worst case); enabling `-Wl,--gc-sections` at your link reduces them. Your numbers
262+
depend on triplet, dead-stripping, and what else shares those libraries.
263+
264+
To select **mbedTLS**, two things are required in *your top-level* manifest:
265+
266+
```json
267+
{
268+
"dependencies": [
269+
{
270+
"name": "cpp-client-telemetry",
271+
"default-features": false,
272+
"features": [ "minimal-sqlite", "curl-mbedtls" ]
273+
},
274+
{ "name": "curl", "default-features": false, "features": [ "mbedtls" ] }
275+
]
276+
}
277+
```
278+
279+
1. `"default-features": false` (the `[core,...]` form) drops **all** of the SDK's
280+
default features -- both `curl-openssl` *and* `system-sqlite` -- so the SDK no
281+
longer *requests* OpenSSL. Because it also drops `system-sqlite`, you must
282+
re-select a SQLite backend (`minimal-sqlite` above, or `system-sqlite`);
283+
otherwise the SDK configure step fails with no SQLite feature selected.
284+
2. The explicit top-level `curl` entry is also needed because vcpkg honors curl's
285+
own `"default-features": false` **only for top-level dependencies** — curl's
286+
default `ssl` feature (which pulls OpenSSL on Linux) and `non-http` are
287+
installed transitively otherwise. With both, curl resolves to `curl[core,mbedtls]`
288+
and OpenSSL is not built; with only the feature, you get
289+
`curl[mbedtls,ssl,openssl,non-http]` (mbedTLS *and* OpenSSL). This recipe is
290+
verified with `vcpkg install --dry-run`.
291+
292+
The default install (no features specified) keeps `curl-openssl` and works out of
293+
the box.
294+
233295
### Drop unused SQLite features (json1)
234296

235297
The SDK uses SQLite only for offline event storage — plain tables and indexes,
@@ -256,6 +318,65 @@ If any package in your build (or your own code) needs SQLite's JSON functions,
256318
request `sqlite3[json1]` instead and the extension is restored for the whole
257319
graph.
258320

321+
### Build a private minimal SQLite (`minimal-sqlite` feature)
322+
323+
For a larger, self-contained reduction, the port can compile a private,
324+
feature-stripped SQLite directly from the SDK's vendored amalgamation instead of
325+
linking the external `sqlite3` package at all. The SDK uses SQLite only for its
326+
offline event-storage cache (plain tables and indexes, transactions, WAL,
327+
autovacuum/`VACUUM`, a few PRAGMAs, and one custom UTF-8 SQL function), so this
328+
build omits the unused SQLite subsystems — `SQLITE_OMIT_JSON` plus load-extension,
329+
shared-cache, deprecated APIs, authorization, EXPLAIN, introspection pragmas,
330+
deserialize, and more. The result is **~10% smaller SQLite code** (`.text`) and
331+
**~13% smaller** as a stripped object, and it drops the external `sqlite3`
332+
dependency from your graph entirely.
333+
334+
Enable it through the vcpkg feature:
335+
336+
```json
337+
{
338+
"dependencies": [
339+
{
340+
"name": "cpp-client-telemetry",
341+
"default-features": false,
342+
"features": [ "minimal-sqlite", "curl-openssl" ]
343+
}
344+
]
345+
}
346+
```
347+
348+
Use the `[core,minimal-sqlite]` form (here, `"default-features": false` is the
349+
`[core]` part) so the default `system-sqlite` feature — and its `sqlite3`
350+
dependency — is dropped. Because `[core]` drops **all** defaults, the example
351+
also re-selects `curl-openssl`: on Linux/Android the built-in curl client
352+
requires a TLS backend, so omitting it would fail to configure (swap in
353+
`curl-mbedtls` for the smaller mbedTLS backend). Requesting `minimal-sqlite`
354+
*without* `[core]` still pulls in the default `system-sqlite`; that is harmless
355+
(the external `sqlite3` is installed but unused) but does not save the dependency.
356+
357+
For a plain (non-vcpkg) CMake build, pass the option directly:
358+
359+
```bash
360+
cmake -DMATSDK_MINIMAL_SQLITE=ON ..
361+
```
362+
363+
The strip is **amalgamation-safe**: it changes no SQLite grammar/parser, so no
364+
code generation is required. All offline storage features the SDK relies on (WAL,
365+
autovacuum, `VACUUM`, PRAGMAs, the custom UTF-8 function, blobs, 64-bit integers,
366+
transactions) are retained, and the SDK's offline-storage unit tests pass
367+
unchanged against the minimal build.
368+
369+
> **Caveat — symbol visibility when linking statically.** The private SQLite keeps
370+
> SQLite's default `sqlite3_*` symbol names. For a **shared** `mat`
371+
> (`mat.dll` / `libmat.so` / `libmat.dylib`), those symbols are hidden by the
372+
> SDK's `-fvisibility=hidden`, so there is no conflict. For a **static** `mat`,
373+
> the minimal SQLite is installed and exported as a separate
374+
> `MSTelemetry::sqlite3_bundled` archive that links into your binary; if **any**
375+
> part of the final static link — your own code *or another dependency* — also
376+
> pulls in SQLite, the duplicate `sqlite3_*` symbols will collide at link time. In
377+
> that case, prefer the default `system-sqlite` feature so the whole graph shares a
378+
> single SQLite.
379+
259380
## How It Works: MATSDK_USE_VCPKG_DEPS
260381

261382
When the SDK detects it is being built via vcpkg (by checking for

0 commit comments

Comments
 (0)