Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 57 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -355,38 +365,71 @@ 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()

################################################################################################
# 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")
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})
Expand Down
6 changes: 5 additions & 1 deletion cmake/MSTelemetryConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
63 changes: 62 additions & 1 deletion docs/building-with-vcpkg.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading
Loading