From 5ba9ee4cbc4df56f95a8a5893edfb2b06cb8a6a5 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 6 Oct 2026 22:37:23 -0500 Subject: [PATCH 1/3] Preserve vcpkg dependencies in Apple static packages Match installed dependency discovery to the build so Apple consumers do not silently switch SQLite or zlib providers. Preserve non-vcpkg Apple behavior and shared-package dependency isolation. Files: cmake/MSTelemetryConfig.cmake.in, tests/vcpkg/package-dependency-tests.cmake, .github/workflows/test-vcpkg.yml, docs/maintainer-onboarding.md, docs/building-with-vcpkg.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 812576a3-8932-4848-bc8b-d17af18f65f2 --- .github/workflows/test-vcpkg.yml | 2 + cmake/MSTelemetryConfig.cmake.in | 2 +- docs/building-with-vcpkg.md | 19 +++++-- docs/maintainer-onboarding.md | 12 +++- tests/vcpkg/package-dependency-tests.cmake | 66 ++++++++++++++++++++++ 5 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 tests/vcpkg/package-dependency-tests.cmake diff --git a/.github/workflows/test-vcpkg.yml b/.github/workflows/test-vcpkg.yml index 48ff3d718..94c4f4a4e 100644 --- a/.github/workflows/test-vcpkg.yml +++ b/.github/workflows/test-vcpkg.yml @@ -35,6 +35,8 @@ jobs: run: python tests/vcpkg/test-release-port.py - name: Verify native feature mappings run: cmake -P tests/vcpkg/native-feature-tests.cmake + - name: Verify installed package dependency selection + run: cmake -P tests/vcpkg/package-dependency-tests.cmake windows: runs-on: windows-latest diff --git a/cmake/MSTelemetryConfig.cmake.in b/cmake/MSTelemetryConfig.cmake.in index 60a3579c2..d5f717528 100644 --- a/cmake/MSTelemetryConfig.cmake.in +++ b/cmake/MSTelemetryConfig.cmake.in @@ -5,7 +5,7 @@ include("${CMAKE_CURRENT_LIST_DIR}/MatsdkDependencyTargets.cmake") # Recreate dependencies only when a static package needs them at the final link. if(@MATSDK_CONFIG_STATIC_PACKAGE@) - if(@MATSDK_BUILD_PLATFORM_APPLE@) + if(@MATSDK_BUILD_PLATFORM_APPLE@ AND NOT @MATSDK_USING_VCPKG@) set(_matsdk_package_sqlite_args APPLE_SYSTEM APPLE_LIBRARY sqlite3) set(_matsdk_package_zlib_args APPLE_SYSTEM APPLE_LIBRARY z) else() diff --git a/docs/building-with-vcpkg.md b/docs/building-with-vcpkg.md index 53531cc03..c47b3408e 100644 --- a/docs/building-with-vcpkg.md +++ b/docs/building-with-vcpkg.md @@ -524,11 +524,17 @@ The [preparation helper](../.github/scripts/prepare-vcpkg-release.py) copies the **complete overlay port from the release tag**, not from the current development branch. It then replaces the archive `REF`, `SHA512`, and manifest version and removes any old `port-version`. This -carries feature declarations and their CMake wiring together, including -`minimal-sqlite` and the explicit Android curl backends. Run it from the released -SDK checkout against a separate vcpkg checkout outside the SDK source tree. +carries overlay feature declarations and their CMake wiring together, including +`minimal-sqlite` and the explicit Android curl backends. The result is a starting +point, not a registry-ready port: remove development source overrides and bundled +SQLite, put required external dependencies in core, and allow TLS features to +compose. Registry builds must use vcpkg SQLite/zlib on Apple as well as other +platforms, with installed package dependencies matching the build. Run it from +the released SDK checkout against a separate vcpkg checkout outside the SDK +source tree. Start with a clean vcpkg working tree: the helper replaces the destination port, -including existing patches. Before replacing it, the helper resolves the +including existing patches; retain or restore registry patches still required +by the released source. Before replacing it, the helper resolves the destination and requires both `.vcpkg-root` and `scripts/buildsystems/vcpkg.cmake` in the inferred vcpkg checkout. The helper requires Python 3.10 or newer and uses only the standard library. @@ -541,8 +547,9 @@ python .github/scripts/prepare-vcpkg-release.py --source-port tools/ports/cpp-cl Run `vcpkg format-manifest` on the resulting manifest and validate the downloaded release with `MATSDK_VCPKG_SOURCE_DIR` unset and without the SDK overlay before -submitting the registry PR. Cover the default graph and the advertised opt-in -features. Do not use the `tests/vcpkg` scripts for this release validation: they +submitting the registry PR. Cover core-only, default, and advertised opt-in +graphs, combined TLS features, and static/shared external consumers. +Do not use the `tests/vcpkg` scripts for this release validation: they intentionally build the local SDK checkout instead of the pinned archive. The helper does not build, commit, push, or open a PR. After validating the port, commit its changes, update the vcpkg version database, and submit the registry PR diff --git a/docs/maintainer-onboarding.md b/docs/maintainer-onboarding.md index 47e9111e0..b870ee411 100644 --- a/docs/maintainer-onboarding.md +++ b/docs/maintainer-onboarding.md @@ -368,11 +368,17 @@ The vcpkg port update is manual: current `microsoft/vcpkg` `master`. 2. From the released SDK checkout, use the [port preparation helper](building-with-vcpkg.md#promoting-features-on-release) - to copy the complete overlay port and set the new release version and source - archive SHA512. Include the manifest and feature wiring, not just the tag. + to copy the overlay port as a starting point and set the new release version + and source archive SHA512. Adapt the result for the registry: always use the + pinned archive, keep required dependencies in core, use external SQLite/zlib + on all supported platforms, and make TLS features composable. Development + source overrides and bundled `minimal-sqlite` belong only in the SDK overlay. + Include compatible feature wiring, not just the tag, and preserve any + registry-specific patches still needed by the released source. 3. Format the port manifest and build the production port from the published archive with `MATSDK_VCPKG_SOURCE_DIR` unset and without the SDK overlay. - Verify both the default graph and the release's advertised opt-in features. + Verify core-only, default, and advertised opt-in feature graphs, including + combined TLS features and external consumers of static and shared packages. Do not use the `tests/vcpkg` scripts for this step: they deliberately select local SDK source rather than the pinned release archive. 4. Commit the port changes. diff --git a/tests/vcpkg/package-dependency-tests.cmake b/tests/vcpkg/package-dependency-tests.cmake new file mode 100644 index 000000000..378a3b899 --- /dev/null +++ b/tests/vcpkg/package-dependency-tests.cmake @@ -0,0 +1,66 @@ +cmake_minimum_required(VERSION 3.19) + +get_filename_component(REPO_ROOT "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE) +if(NOT DEFINED OUTPUT_DIR) + set(OUTPUT_DIR "${REPO_ROOT}/out/package-dependency-tests") +endif() +file(MAKE_DIRECTORY "${OUTPUT_DIR}") +file(WRITE "${OUTPUT_DIR}/MSTelemetryTargets.cmake" "") +file(WRITE "${OUTPUT_DIR}/MatsdkDependencyTargets.cmake" [=[ +function(matsdk_add_package_system_dependency target canonical provider package) + cmake_parse_arguments(DEPENDENCY "APPLE_SYSTEM" "APPLE_LIBRARY;LEGACY_TARGET" "" ${ARGN}) + if(NOT provider STREQUAL "SYSTEM") + message(FATAL_ERROR "Unexpected provider for ${package}: ${provider}") + endif() + if((DEPENDENCY_APPLE_SYSTEM AND NOT EXPECTED_APPLE_SYSTEM) + OR (NOT DEPENDENCY_APPLE_SYSTEM AND EXPECTED_APPLE_SYSTEM)) + message(FATAL_ERROR "Incorrect Apple dependency selection for ${package}") + endif() + if(DEPENDENCY_APPLE_SYSTEM) + if(package STREQUAL "SQLite3") + set(expected_library sqlite3) + elseif(package STREQUAL "ZLIB") + set(expected_library z) + else() + message(FATAL_ERROR "Unexpected Apple dependency: ${package}") + endif() + if(NOT DEPENDENCY_APPLE_LIBRARY STREQUAL expected_library) + message(FATAL_ERROR "Incorrect Apple library for ${package}") + endif() + endif() + set_property(GLOBAL APPEND PROPERTY RESOLVED_DEPENDENCIES "${package}") +endfunction() +]=]) + +set(PACKAGE_INIT "macro(check_required_components name)\nendmacro()") +set(MATSDK_SQLITE_PROVIDER_RESOLVED SYSTEM) +set(MATSDK_ZLIB_PROVIDER_RESOLVED SYSTEM) +set(MATSDK_ANDROID_HTTP_CLIENT_RESOLVED NONE) +set(MATSDK_NEEDS_CURL OFF) +set(MATSDK_CURL_FETCHED OFF) +set(CMAKE_SYSTEM_NAME Darwin) + +foreach(MATSDK_BUILD_PLATFORM_APPLE ON OFF) + foreach(MATSDK_USING_VCPKG ON OFF) + foreach(MATSDK_CONFIG_STATIC_PACKAGE ON OFF) + set(EXPECTED_APPLE_SYSTEM OFF) + if(MATSDK_BUILD_PLATFORM_APPLE AND NOT MATSDK_USING_VCPKG) + set(EXPECTED_APPLE_SYSTEM ON) + endif() + set_property(GLOBAL PROPERTY RESOLVED_DEPENDENCIES "") + configure_file("${REPO_ROOT}/cmake/MSTelemetryConfig.cmake.in" + "${OUTPUT_DIR}/MSTelemetryConfig.cmake" @ONLY) + include("${OUTPUT_DIR}/MSTelemetryConfig.cmake") + get_property(dependencies GLOBAL PROPERTY RESOLVED_DEPENDENCIES) + if(MATSDK_CONFIG_STATIC_PACKAGE) + if(NOT dependencies STREQUAL "SQLite3;ZLIB") + message(FATAL_ERROR "Missing static package dependencies: ${dependencies}") + endif() + elseif(dependencies) + message(FATAL_ERROR "Shared packages must not rediscover private dependencies") + endif() + endforeach() + endforeach() +endforeach() + +message(STATUS "Package dependency selection passed for all eight configurations") From b0df2f1e56bc96754cb8919fc50c14fe05f95a40 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Wed, 7 Oct 2026 02:28:23 -0500 Subject: [PATCH 2/3] Isolate SDK SQLite and export actual providers to prevent release link conflicts Record dependency provenance before SDK discovery creates transitive targets, so static consumers reconstruct the same providers and shared consumers do not acquire private package requirements. Require caller-provided targets explicitly. Namespace bundled SQLite functions and data from the header and both amalgamations, including Windows APIs and debug globals. Keep the forced include private so minimal and full SDK SQLite coexist with application SQLite. Separate the registry promotion recipe from development-only overlay behavior: pin archives, keep required external dependencies in core, and allow TLS unions. Exercise provider metadata, missing-target errors, release promotion, and source/installed coexistence without weakening existing tests. Files changed: - .github\scripts\prepare-vcpkg-release.py - .github\workflows\test-embedding.yml - .github\workflows\test-vcpkg.yml - CMakeLists.txt - cmake\MSTelemetryConfig.cmake.in - cmake\MatsdkDependencyTargets.cmake - cmake\MatsdkSqliteNamespace.cmake - docs\building-with-vcpkg.md - docs\maintainer-onboarding.md - lib\CMakeLists.txt - tests\embedding\CMakeLists.txt - tests\package-coexistence\CMakeLists.txt - tests\package-coexistence\main.cpp - tests\package-dependencies\CMakeLists.txt - tests\vcpkg\CMakeLists.txt - tests\vcpkg\native-feature-tests.cmake - tests\vcpkg\package-dependency-tests.cmake - tests\vcpkg\test-release-port.py - tools\registry-ports\cpp-client-telemetry\portfile.cmake - tools\registry-ports\cpp-client-telemetry\vcpkg.json Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 812576a3-8932-4848-bc8b-d17af18f65f2 --- .github/scripts/prepare-vcpkg-release.py | 12 +- .github/workflows/test-embedding.yml | 43 +++++++ .github/workflows/test-vcpkg.yml | 2 + CMakeLists.txt | 33 +++++- cmake/MSTelemetryConfig.cmake.in | 30 ++--- cmake/MatsdkDependencyTargets.cmake | 41 +++++-- cmake/MatsdkSqliteNamespace.cmake | 33 ++++++ docs/building-with-vcpkg.md | 57 ++++++--- docs/maintainer-onboarding.md | 12 +- lib/CMakeLists.txt | 10 ++ tests/embedding/CMakeLists.txt | 33 ++++++ tests/package-coexistence/CMakeLists.txt | 49 ++++++++ tests/package-coexistence/main.cpp | 81 +++++++++++++ tests/package-dependencies/CMakeLists.txt | 101 ++++++++++++++++ tests/vcpkg/CMakeLists.txt | 12 ++ tests/vcpkg/native-feature-tests.cmake | 71 ++++++++++- tests/vcpkg/package-dependency-tests.cmake | 84 +++++-------- tests/vcpkg/test-release-port.py | 48 ++++++-- .../cpp-client-telemetry/portfile.cmake | 65 ++++++++++ .../cpp-client-telemetry/vcpkg.json | 111 ++++++++++++++++++ 20 files changed, 803 insertions(+), 125 deletions(-) create mode 100644 cmake/MatsdkSqliteNamespace.cmake create mode 100644 tests/package-coexistence/CMakeLists.txt create mode 100644 tests/package-coexistence/main.cpp create mode 100644 tests/package-dependencies/CMakeLists.txt create mode 100644 tools/registry-ports/cpp-client-telemetry/portfile.cmake create mode 100644 tools/registry-ports/cpp-client-telemetry/vcpkg.json diff --git a/.github/scripts/prepare-vcpkg-release.py b/.github/scripts/prepare-vcpkg-release.py index 529eda2b6..c6302a7b0 100644 --- a/.github/scripts/prepare-vcpkg-release.py +++ b/.github/scripts/prepare-vcpkg-release.py @@ -1,4 +1,4 @@ -"""Copy the release's complete overlay port into a vcpkg checkout.""" +"""Copy the release's registry recipe into a vcpkg checkout.""" import argparse import json @@ -34,14 +34,18 @@ def prepare_port(source_port, destination_port, version, sha512): manifest = json.loads((source_port / "vcpkg.json").read_text(encoding="utf-8")) if manifest["name"] != "cpp-client-telemetry": - raise ValueError("Release overlay is not the cpp-client-telemetry port") - for feature in ("minimal-sqlite", "android-curl-openssl"): + raise ValueError("Release recipe is not the cpp-client-telemetry port") + if "minimal-sqlite" in manifest.get("features", {}): + raise ValueError("Use the registry recipe, not the development overlay with minimal-sqlite") + for feature in ("android-curl-openssl", "android-curl-mbedtls", "no-logging"): if feature not in manifest.get("features", {}): - raise ValueError(f"Release overlay is missing the {feature} feature") + raise ValueError(f"Release recipe is missing the {feature} feature") manifest["version"] = version manifest.pop("port-version", None) portfile = (source_port / "portfile.cmake").read_text(encoding="utf-8") + if "MATSDK_VCPKG_SOURCE_DIR" in portfile: + raise ValueError("Registry recipes must not allow development source overrides") for field, value in (("REF", f"v{version}"), ("SHA512", sha512)): portfile, count = re.subn( rf"(?m)^([ \t]*{field}[ \t]+)[^\r\n]+", diff --git a/.github/workflows/test-embedding.yml b/.github/workflows/test-embedding.yml index 54980ed04..2a0795866 100644 --- a/.github/workflows/test-embedding.yml +++ b/.github/workflows/test-embedding.yml @@ -83,6 +83,16 @@ jobs: run: | cmake --build build-embedding --target embedding_test --parallel 4 ctest --test-dir build-embedding --output-on-failure + - name: Consume installed caller-provided package + if: matrix.preload-storage == 'ON' + run: | + cmake --install build-embedding --prefix "${RUNNER_TEMP}/matsdk" + cmake -G Ninja -S tests/vcpkg -B build-provided-consumer \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/matsdk" \ + -DMATSDK_TEST_PRELOAD_DEPENDENCIES=ON + cmake --build build-provided-consumer --parallel 4 + ctest --test-dir build-provided-consumer --output-on-failure windows: runs-on: windows-2022 @@ -100,6 +110,39 @@ jobs: cmake --build build-embedding --config Release --target embedding_test -- /m ctest --test-dir build-embedding -C Release --output-on-failure + sqlite-coexistence: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-2022, macos-latest] + shared: ["OFF", "ON"] + sqlite: [MINIMAL, VENDORED] + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - name: Install Linux HTTP dependencies + if: runner.os == 'Linux' + run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev + - name: Configure source consumer + run: > + cmake -S tests/package-coexistence -B build-coexistence + -DCMAKE_BUILD_TYPE=Release + -DBUILD_SHARED_LIBS=${{ matrix.shared }} + -DMATSDK_SQLITE_PROVIDER=${{ matrix.sqlite }} + -DMATSDK_ZLIB_PROVIDER=VENDORED + - name: Build, install, and test both consumers + shell: bash + run: | + cmake --build build-coexistence --config Release --parallel 4 + ctest --test-dir build-coexistence -C Release --output-on-failure + cmake --install build-coexistence --config Release --prefix "${RUNNER_TEMP}/matsdk" + cmake -S tests/package-coexistence -B build-installed-coexistence \ + -DCMAKE_BUILD_TYPE=Release \ + -DMATSDK_SQLITE_PROVIDER=${{ matrix.sqlite }} \ + -DMATSDK_INSTALLED_PREFIX="${RUNNER_TEMP}/matsdk" + cmake --build build-installed-coexistence --config Release --parallel 4 + ctest --test-dir build-installed-coexistence -C Release --output-on-failure + installed-package-linux: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/test-vcpkg.yml b/.github/workflows/test-vcpkg.yml index 94c4f4a4e..f7a82dd94 100644 --- a/.github/workflows/test-vcpkg.yml +++ b/.github/workflows/test-vcpkg.yml @@ -35,6 +35,8 @@ jobs: run: python tests/vcpkg/test-release-port.py - name: Verify native feature mappings run: cmake -P tests/vcpkg/native-feature-tests.cmake + - name: Verify registry core graphs and feature unions + run: cmake -DREGISTRY_MODE=ON -P tests/vcpkg/native-feature-tests.cmake - name: Verify installed package dependency selection run: cmake -P tests/vcpkg/package-dependency-tests.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index d47c0167a..81166adfe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,15 @@ cmake_minimum_required(VERSION 3.15...3.31) project(MSTelemetry LANGUAGES C CXX) -if(APPLE) - set(MATSDK_BUILD_PLATFORM_APPLE TRUE) -else() - set(MATSDK_BUILD_PLATFORM_APPLE FALSE) + +# Snapshot caller targets before curl discovery can import storage dependencies. +set(MATSDK_SQLITE_DEPENDENCY_KIND PACKAGE) +if(TARGET SQLite3::SQLite3 OR TARGET SQLite::SQLite3) + set(MATSDK_SQLITE_DEPENDENCY_KIND PROVIDED) +endif() +set(MATSDK_ZLIB_DEPENDENCY_KIND PACKAGE) +if(TARGET ZLIB::ZLIB) + set(MATSDK_ZLIB_DEPENDENCY_KIND PROVIDED) endif() ################################################################################################ @@ -180,6 +185,7 @@ endif() set(MATSDK_NEEDS_CURL OFF) set(MATSDK_CURL_FETCHED OFF) set(MATSDK_CURL_LINK_TARGET "") +set(MATSDK_CURL_DEPENDENCY_KIND NONE) if(PAL_IMPLEMENTATION STREQUAL "CPP11" AND NOT MATSDK_PLATFORM_IOS AND (NOT CMAKE_SYSTEM_NAME STREQUAL "Android" OR MATSDK_ANDROID_USES_CURL) @@ -189,11 +195,13 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11" HAVE_MAT_CURL_HTTP_CLIENT) if(TARGET CURL::libcurl) set(MATSDK_CURL_LINK_TARGET CURL::libcurl) + set(MATSDK_CURL_DEPENDENCY_KIND PROVIDED) elseif(MATSDK_CURL_PROVIDER_UPPER STREQUAL "FETCH") include(cmake/MatsdkFetchCurl.cmake) matsdk_fetch_curl(_matsdk_curl_target) set(MATSDK_CURL_LINK_TARGET "${_matsdk_curl_target}") set(MATSDK_CURL_FETCHED ON) + set(MATSDK_CURL_DEPENDENCY_KIND BUNDLED) else() find_package(CURL REQUIRED) if(NOT TARGET CURL::libcurl) @@ -201,19 +209,32 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11" "find_package(CURL) did not create the required CURL::libcurl target.") endif() set(MATSDK_CURL_LINK_TARGET CURL::libcurl) + set(MATSDK_CURL_DEPENDENCY_KIND PACKAGE) endif() endif() ################################################################################################ # Canonical dependency targets ################################################################################################ +set(MATSDK_SQLITE_PACKAGE_NAME SQLite3) +set(MATSDK_SQLITE_PACKAGE_TARGET SQLite::SQLite3) +if(MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "NONE") + set(MATSDK_SQLITE_DEPENDENCY_KIND NONE) +elseif(NOT MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "SYSTEM") + set(MATSDK_SQLITE_DEPENDENCY_KIND BUNDLED) +endif() +if(NOT MATSDK_ZLIB_PROVIDER_RESOLVED STREQUAL "SYSTEM") + set(MATSDK_ZLIB_DEPENDENCY_KIND BUNDLED) +endif() if(TARGET SQLite::SQLite3 AND NOT TARGET SQLite3::SQLite3) matsdk_add_interface_dependency(SQLite3::SQLite3 SQLite::SQLite3) endif() if(MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "SYSTEM" AND NOT TARGET SQLite3::SQLite3) if(APPLE AND NOT MATSDK_USING_VCPKG) matsdk_add_apple_system_library(SQLite3::SQLite3 sqlite3) + set(MATSDK_SQLITE_DEPENDENCY_KIND APPLE_SYSTEM) else() + set(MATSDK_SQLITE_DEPENDENCY_KIND PACKAGE) find_package(SQLite3 QUIET) if(TARGET SQLite::SQLite3 AND NOT TARGET SQLite3::SQLite3) matsdk_add_interface_dependency(SQLite3::SQLite3 SQLite::SQLite3) @@ -222,6 +243,8 @@ if(MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "SYSTEM" AND NOT TARGET SQLite3::SQL find_package(unofficial-sqlite3 CONFIG REQUIRED) matsdk_add_interface_dependency( SQLite3::SQLite3 unofficial::sqlite3::sqlite3) + set(MATSDK_SQLITE_PACKAGE_NAME unofficial-sqlite3) + set(MATSDK_SQLITE_PACKAGE_TARGET unofficial::sqlite3::sqlite3) endif() if(NOT TARGET SQLite3::SQLite3) message(FATAL_ERROR @@ -234,8 +257,10 @@ endif() if(MATSDK_ZLIB_PROVIDER_RESOLVED STREQUAL "SYSTEM" AND NOT TARGET ZLIB::ZLIB) if(APPLE AND NOT MATSDK_USING_VCPKG) matsdk_add_apple_system_library(ZLIB::ZLIB z) + set(MATSDK_ZLIB_DEPENDENCY_KIND APPLE_SYSTEM) else() find_package(ZLIB REQUIRED) + set(MATSDK_ZLIB_DEPENDENCY_KIND PACKAGE) endif() endif() diff --git a/cmake/MSTelemetryConfig.cmake.in b/cmake/MSTelemetryConfig.cmake.in index d5f717528..90ebfb796 100644 --- a/cmake/MSTelemetryConfig.cmake.in +++ b/cmake/MSTelemetryConfig.cmake.in @@ -5,26 +5,21 @@ include("${CMAKE_CURRENT_LIST_DIR}/MatsdkDependencyTargets.cmake") # Recreate dependencies only when a static package needs them at the final link. if(@MATSDK_CONFIG_STATIC_PACKAGE@) - if(@MATSDK_BUILD_PLATFORM_APPLE@ AND NOT @MATSDK_USING_VCPKG@) - set(_matsdk_package_sqlite_args APPLE_SYSTEM APPLE_LIBRARY sqlite3) - set(_matsdk_package_zlib_args APPLE_SYSTEM APPLE_LIBRARY z) - else() - set(_matsdk_package_sqlite_args) - set(_matsdk_package_zlib_args) - endif() matsdk_add_package_system_dependency( MSTelemetry::sqlite_dependency SQLite3::SQLite3 "@MATSDK_SQLITE_PROVIDER_RESOLVED@" - SQLite3 - LEGACY_TARGET SQLite::SQLite3 - ${_matsdk_package_sqlite_args}) + "@MATSDK_SQLITE_PACKAGE_NAME@" + KIND "@MATSDK_SQLITE_DEPENDENCY_KIND@" + LEGACY_TARGET "@MATSDK_SQLITE_PACKAGE_TARGET@" + APPLE_LIBRARY sqlite3) matsdk_add_package_system_dependency( MSTelemetry::zlib_dependency ZLIB::ZLIB "@MATSDK_ZLIB_PROVIDER_RESOLVED@" ZLIB - ${_matsdk_package_zlib_args}) + KIND "@MATSDK_ZLIB_DEPENDENCY_KIND@" + APPLE_LIBRARY z) endif() if("@MATSDK_ANDROID_HTTP_CLIENT_RESOLVED@" STREQUAL "") @@ -88,17 +83,14 @@ if(@MATSDK_CONFIG_STATIC_PACKAGE@ AND @MATSDK_NEEDS_CURL@) set_property(TARGET MSTelemetry::curl_archive PROPERTY INTERFACE_LINK_LIBRARIES "${_matsdk_curl_tls_targets}") else() - if(NOT TARGET CURL::libcurl) - find_dependency(CURL) - endif() + matsdk_add_package_system_dependency( + MSTelemetry::curl_dependency CURL::libcurl SYSTEM CURL + KIND "@MATSDK_CURL_DEPENDENCY_KIND@") endif() if(@MATSDK_CURL_FETCHED@) - set(_matsdk_curl_dependency_target MSTelemetry::curl_archive) - else() - set(_matsdk_curl_dependency_target CURL::libcurl) + matsdk_add_interface_dependency( + MSTelemetry::curl_dependency MSTelemetry::curl_archive) endif() - matsdk_add_interface_dependency( - MSTelemetry::curl_dependency "${_matsdk_curl_dependency_target}") endif() include("${CMAKE_CURRENT_LIST_DIR}/MSTelemetryTargets.cmake") diff --git a/cmake/MatsdkDependencyTargets.cmake b/cmake/MatsdkDependencyTargets.cmake index 47ddf21a4..385345a9b 100644 --- a/cmake/MatsdkDependencyTargets.cmake +++ b/cmake/MatsdkDependencyTargets.cmake @@ -20,20 +20,41 @@ function(matsdk_add_package_system_dependency dependency_target canonical_target endif() set(options APPLE_SYSTEM) - set(one_value_args APPLE_LIBRARY LEGACY_TARGET) + set(one_value_args APPLE_LIBRARY LEGACY_TARGET KIND) cmake_parse_arguments(MATSDK_PACKAGE_DEP "${options}" "${one_value_args}" "" ${ARGN}) - if(MATSDK_PACKAGE_DEP_APPLE_SYSTEM) - if(NOT DEFINED MATSDK_PACKAGE_DEP_APPLE_LIBRARY - OR MATSDK_PACKAGE_DEP_APPLE_LIBRARY STREQUAL "") + if(NOT MATSDK_PACKAGE_DEP_KIND) + set(MATSDK_PACKAGE_DEP_KIND PACKAGE) + if(MATSDK_PACKAGE_DEP_APPLE_SYSTEM) + set(MATSDK_PACKAGE_DEP_KIND APPLE_SYSTEM) + endif() + endif() + if(NOT MATSDK_PACKAGE_DEP_KIND MATCHES "^(PACKAGE|PROVIDED|APPLE_SYSTEM)$") + message(FATAL_ERROR "Invalid dependency kind: ${MATSDK_PACKAGE_DEP_KIND}") + endif() + if(NOT TARGET "${canonical_target}" + AND DEFINED MATSDK_PACKAGE_DEP_LEGACY_TARGET + AND TARGET "${MATSDK_PACKAGE_DEP_LEGACY_TARGET}") + matsdk_add_interface_dependency( + "${canonical_target}" "${MATSDK_PACKAGE_DEP_LEGACY_TARGET}") + endif() + if(NOT TARGET "${canonical_target}") + if(MATSDK_PACKAGE_DEP_KIND STREQUAL "APPLE_SYSTEM") + if(NOT DEFINED MATSDK_PACKAGE_DEP_APPLE_LIBRARY + OR MATSDK_PACKAGE_DEP_APPLE_LIBRARY STREQUAL "") + message(FATAL_ERROR + "APPLE_LIBRARY is required for Apple system dependencies.") + endif() + include("${_MATSDK_DEPENDENCY_TARGETS_DIR}/MatsdkAppleSystemDeps.cmake") + matsdk_add_apple_system_library( + "${canonical_target}" "${MATSDK_PACKAGE_DEP_APPLE_LIBRARY}") + elseif(MATSDK_PACKAGE_DEP_KIND STREQUAL "PACKAGE") + find_dependency(${package_name}) + else() message(FATAL_ERROR - "APPLE_LIBRARY is required for Apple system dependencies.") + "MSTelemetry was built with a caller-provided ${canonical_target}. " + "Define that target before find_package(MSTelemetry).") endif() - include("${_MATSDK_DEPENDENCY_TARGETS_DIR}/MatsdkAppleSystemDeps.cmake") - matsdk_add_apple_system_library( - "${canonical_target}" "${MATSDK_PACKAGE_DEP_APPLE_LIBRARY}") - elseif(NOT TARGET "${canonical_target}") - find_dependency(${package_name}) endif() if(NOT TARGET "${canonical_target}" AND DEFINED MATSDK_PACKAGE_DEP_LEGACY_TARGET diff --git a/cmake/MatsdkSqliteNamespace.cmake b/cmake/MatsdkSqliteNamespace.cmake new file mode 100644 index 000000000..fd25a5621 --- /dev/null +++ b/cmake/MatsdkSqliteNamespace.cmake @@ -0,0 +1,33 @@ +include_guard() + +function(matsdk_namespace_sqlite target header output) + set(symbols) + # The amalgamations also declare platform APIs and test globals absent from sqlite3.h. + foreach(source IN ITEMS "${header}" ${ARGN}) + file(STRINGS "${source}" declarations REGEX "^SQLITE_API ") + foreach(declaration IN LISTS declarations) + string(REGEX MATCH "sqlite3[A-Za-z0-9_]+[ \t]*[()\\[;=]" symbol "${declaration}") + if(NOT symbol) + message(FATAL_ERROR "Cannot namespace SQLite API declaration: ${declaration}") + endif() + string(REGEX REPLACE "[ \t]*[()\\[;=]$" "" symbol "${symbol}") + list(APPEND symbols "${symbol}") + endforeach() + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${source}") + endforeach() + if(NOT symbols) + message(FATAL_ERROR "No SQLite API declarations found in ${header}") + endif() + list(REMOVE_DUPLICATES symbols) + list(SORT symbols) + set(contents "#pragma once\n") + foreach(symbol IN LISTS symbols) + string(APPEND contents "#define ${symbol} matsdk_${symbol}\n") + endforeach() + file(GENERATE OUTPUT "${output}" CONTENT "${contents}") + if(MSVC) + target_compile_options(${target} INTERFACE "/FI${output}") + else() + target_compile_options(${target} INTERFACE "SHELL:-include \"${output}\"") + endif() +endfunction() diff --git a/docs/building-with-vcpkg.md b/docs/building-with-vcpkg.md index c47b3408e..6a8bf87fd 100644 --- a/docs/building-with-vcpkg.md +++ b/docs/building-with-vcpkg.md @@ -37,6 +37,18 @@ cd cpp_client_telemetry vcpkg install --overlay-ports=tools/ports cpp-client-telemetry ``` +The two recipes deliberately have different dependency policies: + +| Recipe | Source and dependency policy | +| --- | --- | +| `tools/ports` development overlay | Local checkout support and private `minimal-sqlite`; Linux TLS selection requires exactly one backend. | +| `tools/registry-ports` release recipe | Pinned archive only; external SQLite/zlib in core on every platform and Linux curl/OpenSSL in core. TLS feature unions are supported; `minimal-sqlite` is not a registry feature. | + +The feature examples below describe the development overlay unless explicitly +marked otherwise. In the release recipe, `[core]` still includes the required +external dependencies. `system-sqlite` and `curl-openssl` remain compatibility +features; they are not required to make a core-only install work. + ### Using in your CMake project After installing, add the SDK to your CMake project: @@ -501,16 +513,14 @@ 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. +Both `MINIMAL` and `VENDORED` SQLite use SDK-private `matsdk_sqlite3*` names +for functions and data, including platform-specific APIs. Static and shared SDKs +can therefore coexist with an application's full SQLite without duplicate +symbols or cross-instance interposition. The renaming header is private to +SDK-owned targets; consumers retain the normal SQLite API. Static packages +install the private archive as `MSTelemetry::sqlite3_bundled`. +Do not pass database handles, callbacks, or allocated buffers between the two +SQLite instances. Use `SYSTEM` when the whole graph should share one SQLite. ## How It Works @@ -521,15 +531,14 @@ registry port update. There is no release-triggered workflow that creates a vcpkg PR, and no repository token is needed for port preparation. The [preparation helper](../.github/scripts/prepare-vcpkg-release.py) copies the -**complete overlay port from the release tag**, not from the current development -branch. It then replaces the archive +**complete registry recipe from `tools/registry-ports` in the release tag**, +not the development overlay or current development branch. It replaces the archive `REF`, `SHA512`, and manifest version and removes any old `port-version`. This -carries overlay feature declarations and their CMake wiring together, including -`minimal-sqlite` and the explicit Android curl backends. The result is a starting -point, not a registry-ready port: remove development source overrides and bundled -SQLite, put required external dependencies in core, and allow TLS features to -compose. Registry builds must use vcpkg SQLite/zlib on Apple as well as other -platforms, with installed package dependencies matching the build. Run it from +carries registry feature declarations and their CMake wiring together, including +the explicit Android curl backends, opt-in logging/exception controls, and +composable TLS features. The helper rejects private minimal SQLite and local +source overrides. The recipe uses external SQLite/zlib on every platform, +including Apple, with required dependencies in core. Run it from the released SDK checkout against a separate vcpkg checkout outside the SDK source tree. Start with a clean vcpkg working tree: the helper replaces the destination port, @@ -542,7 +551,7 @@ Pass the four-component version **without** its `v` prefix and the SHA512 of the published GitHub source `.tar.gz` archive, not an xcframework, AAR, or ZIP: ```console -python .github/scripts/prepare-vcpkg-release.py --source-port tools/ports/cpp-client-telemetry --destination-port /ports/cpp-client-telemetry --version X.Y.Z.W --sha512 +python .github/scripts/prepare-vcpkg-release.py --source-port tools/registry-ports/cpp-client-telemetry --destination-port /ports/cpp-client-telemetry --version X.Y.Z.W --sha512 ``` Run `vcpkg format-manifest` on the resulting manifest and validate the downloaded @@ -563,6 +572,16 @@ SDK-specific dependency-mode switch is required. Android transport selection is separate: `MATSDK_ANDROID_HTTP_CLIENT=AUTO` resolves to the Java/JNI transport, while the explicit Android curl features select the native curl transport. +Installed packages record each dependency's actual provider rather than +inferring it from the consumer's platform. Static packages reconstruct discovered +packages, Apple system libraries, or bundled archives as appropriate; shared +packages do not rediscover private SQLite, zlib, or curl dependencies. If a source +embedding build supplied canonical dependency targets itself, its installed +static package requires the consuming project to define those same targets +(`SQLite3::SQLite3`, `ZLIB::ZLIB`, or `CURL::libcurl`, as applicable) before +`find_package(MSTelemetry)`. Missing caller-provided targets fail explicitly +instead of silently selecting a different dependency. + ## Migrating from the older overlay port Older revisions of this overlay port could build the SDK with the private diff --git a/docs/maintainer-onboarding.md b/docs/maintainer-onboarding.md index b870ee411..d9a986286 100644 --- a/docs/maintainer-onboarding.md +++ b/docs/maintainer-onboarding.md @@ -368,12 +368,12 @@ The vcpkg port update is manual: current `microsoft/vcpkg` `master`. 2. From the released SDK checkout, use the [port preparation helper](building-with-vcpkg.md#promoting-features-on-release) - to copy the overlay port as a starting point and set the new release version - and source archive SHA512. Adapt the result for the registry: always use the - pinned archive, keep required dependencies in core, use external SQLite/zlib - on all supported platforms, and make TLS features composable. Development - source overrides and bundled `minimal-sqlite` belong only in the SDK overlay. - Include compatible feature wiring, not just the tag, and preserve any + to copy `tools/registry-ports/cpp-client-telemetry` and set the new release + version and source archive SHA512. This separate registry recipe always uses + the pinned archive, keeps required external dependencies in core on all + supported platforms, and permits composable TLS features. Development source + overrides and bundled `minimal-sqlite` remain only in the SDK overlay. + Promote the complete recipe, not just the tag, and preserve any registry-specific patches still needed by the released source. 3. Format the port manifest and build the production port from the published archive with `MATSDK_VCPKG_SOURCE_DIR` unset and without the SDK overlay. diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index b77acdf41..d44de8ab6 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -532,7 +532,17 @@ set(MATSDK_SQLITE_MINIMAL_DEFS ) if(MATSDK_BUNDLE_SQLITE AND NOT TARGET sqlite3_bundled) + include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/MatsdkSqliteNamespace.cmake") + add_library(matsdk_sqlite_namespace INTERFACE) + matsdk_namespace_sqlite(matsdk_sqlite_namespace + "${CMAKE_CURRENT_SOURCE_DIR}/../sqlite/sqlite3.h" + "${CMAKE_CURRENT_BINARY_DIR}/matsdk-sqlite-symbols.h" + "${CMAKE_CURRENT_SOURCE_DIR}/../sqlite/sqlite3_retail.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../sqlite/sqlite3_debug.c") + target_link_libraries(matsdk_internal_config INTERFACE matsdk_sqlite_namespace) add_library(sqlite3_bundled STATIC "${CMAKE_CURRENT_SOURCE_DIR}/../sqlite/sqlite3.c") + target_link_libraries(sqlite3_bundled PRIVATE + "$") # 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. diff --git a/tests/embedding/CMakeLists.txt b/tests/embedding/CMakeLists.txt index 49b11b481..fb7a01ffa 100644 --- a/tests/embedding/CMakeLists.txt +++ b/tests/embedding/CMakeLists.txt @@ -71,6 +71,39 @@ else() add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../.." cpp_client_telemetry) endif() +get_filename_component(sdk_source "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE) +foreach(dependency SQLITE ZLIB CURL) + get_directory_property(kind DIRECTORY "${sdk_source}" + DEFINITION MATSDK_${dependency}_DEPENDENCY_KIND) + get_directory_property(provider DIRECTORY "${sdk_source}" + DEFINITION MATSDK_${dependency}_PROVIDER_RESOLVED) + if(dependency STREQUAL "CURL") + get_directory_property(needs_curl DIRECTORY "${sdk_source}" DEFINITION MATSDK_NEEDS_CURL) + if(NOT needs_curl) + set(expected NONE) + elseif(MATSDK_EMBEDDING_PRELOAD_CURL) + set(expected PROVIDED) + elseif(MATSDK_CURL_PROVIDER STREQUAL "FETCH") + set(expected BUNDLED) + else() + set(expected PACKAGE) + endif() + elseif(provider STREQUAL "NONE") + set(expected NONE) + elseif(NOT provider STREQUAL "SYSTEM") + set(expected BUNDLED) + elseif(MATSDK_EMBEDDING_PRELOAD_STORAGE_DEPS) + set(expected PROVIDED) + elseif(NOT APPLE) + set(expected PACKAGE) + else() + set(expected APPLE_SYSTEM) + endif() + if(NOT kind STREQUAL expected) + message(FATAL_ERROR "${dependency} recorded ${kind}, expected ${expected}") + endif() +endforeach() + add_executable(embedding_test "${CMAKE_CURRENT_LIST_DIR}/../vcpkg/main.cpp") target_link_libraries(embedding_test PRIVATE MSTelemetry::mat) if(MSVC) diff --git a/tests/package-coexistence/CMakeLists.txt b/tests/package-coexistence/CMakeLists.txt new file mode 100644 index 000000000..bd5dda1a8 --- /dev/null +++ b/tests/package-coexistence/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.19) +project(sqlite_coexistence_test LANGUAGES C CXX) + +get_filename_component(SDK_ROOT "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(MATSDK_SQLITE_PROVIDER MINIMAL CACHE STRING "") +set(MATSDK_ZLIB_PROVIDER VENDORED CACHE STRING "") +add_library(external_sqlite STATIC "${SDK_ROOT}/sqlite/sqlite3.c") +target_include_directories(external_sqlite PUBLIC "${SDK_ROOT}/sqlite") +if(NOT WIN32) + find_package(Threads REQUIRED) + target_link_libraries(external_sqlite PUBLIC Threads::Threads "${CMAKE_DL_LIBS}" m) +endif() + +if(MATSDK_INSTALLED_PREFIX) + find_package(MSTelemetry CONFIG REQUIRED PATHS "${MATSDK_INSTALLED_PREFIX}" + NO_DEFAULT_PATH) +else() + foreach(option HEADERS LIBRARY) + set(MATSDK_BUILD_${option} ON CACHE BOOL "" FORCE) + endforeach() + foreach(option UNIT_TESTS FUNC_TESTS TEST_TOOL PACKAGE JNI_WRAPPER OBJC_WRAPPER SWIFT_WRAPPER) + set(MATSDK_BUILD_${option} OFF CACHE BOOL "" FORCE) + endforeach() + add_subdirectory("${SDK_ROOT}" sdk) +endif() + +add_executable(sqlite_coexistence main.cpp) +target_link_libraries(sqlite_coexistence PRIVATE MSTelemetry::mat external_sqlite) +get_target_property(library_type MSTelemetry::mat TYPE) +if(library_type STREQUAL "STATIC_LIBRARY") + target_compile_definitions(sqlite_coexistence PRIVATE MATSDK_TEST_PRIVATE_SQLITE) +endif() +if(MATSDK_SQLITE_PROVIDER STREQUAL "MINIMAL") + target_compile_definitions(sqlite_coexistence PRIVATE MATSDK_TEST_MINIMAL_SQLITE) +endif() +if(WIN32 AND library_type STREQUAL "SHARED_LIBRARY") + add_custom_command(TARGET sqlite_coexistence POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_if_different + "$" "$") +endif() +if(MSVC) + target_compile_options(sqlite_coexistence PRIVATE /W4 /WX) +else() + target_compile_options(sqlite_coexistence PRIVATE -Wall -Wextra -Werror) +endif() +enable_testing() +add_test(NAME sqlite_coexistence COMMAND sqlite_coexistence) diff --git a/tests/package-coexistence/main.cpp b/tests/package-coexistence/main.cpp new file mode 100644 index 000000000..d75f01ca0 --- /dev/null +++ b/tests/package-coexistence/main.cpp @@ -0,0 +1,81 @@ +#include "LogManager.hpp" +#include "sqlite3.h" +#include + +#if defined(sqlite3_open) || defined(Z_PREFIX) || defined(MATSDK_DISABLE_EXCEPTIONS) +#error SDK-private compile policy leaked to a consumer +#endif + +LOGMANAGER_INSTANCE + +#ifdef MATSDK_TEST_PRIVATE_SQLITE +extern "C" +{ + int matsdk_sqlite3_open(const char*, sqlite3**); + int matsdk_sqlite3_close(sqlite3*); + int matsdk_sqlite3_exec(sqlite3*, const char*, int (*)(void*, int, char**, char**), void*, char**); + int matsdk_sqlite3_compileoption_used(const char*); +} +#endif + +int main() +{ + sqlite3* external = nullptr; + if (sqlite3_open(":memory:", &external) != SQLITE_OK) + { + std::fprintf(stderr, "External SQLite failed to open\n"); + return 1; + } + if (sqlite3_compileoption_used("OMIT_JSON") || + sqlite3_exec(external, "CREATE TABLE external_data(value); INSERT INTO external_data VALUES(42);", + nullptr, nullptr, nullptr) != SQLITE_OK) + { + std::fprintf(stderr, "External SQLite was replaced by the SDK's stripped copy\n"); + sqlite3_close(external); + return 1; + } +#ifdef MATSDK_TEST_PRIVATE_SQLITE + sqlite3* internal = nullptr; + if (matsdk_sqlite3_open(":memory:", &internal) != SQLITE_OK || + matsdk_sqlite3_exec(internal, "CREATE TABLE sdk_data(value); INSERT INTO sdk_data VALUES(7);", + nullptr, nullptr, nullptr) != SQLITE_OK) + { + std::fprintf(stderr, "SDK-private SQLite failed\n"); + if (internal) + { + matsdk_sqlite3_close(internal); + } + sqlite3_close(external); + return 1; + } +#ifdef MATSDK_TEST_MINIMAL_SQLITE + if (!matsdk_sqlite3_compileoption_used("OMIT_JSON")) + { + std::fprintf(stderr, "SDK-private SQLite was replaced by the external copy\n"); + matsdk_sqlite3_close(internal); + sqlite3_close(external); + return 1; + } +#endif + if (matsdk_sqlite3_close(internal) != SQLITE_OK) + { + std::fprintf(stderr, "SDK-private SQLite failed to close\n"); + sqlite3_close(external); + return 1; + } +#endif + MAT::ILogger* logger = MAT::LogManager::Initialize("sqlite-coexistence-test"); + if (!logger) + { + std::fprintf(stderr, "SDK initialization failed with external SQLite linked\n"); + sqlite3_close(external); + return 1; + } + MAT::LogManager::FlushAndTeardown(); + if (sqlite3_close(external) != SQLITE_OK) + { + std::fprintf(stderr, "External SQLite failed to close\n"); + return 1; + } + return 0; +} diff --git a/tests/package-dependencies/CMakeLists.txt b/tests/package-dependencies/CMakeLists.txt new file mode 100644 index 000000000..0b58e03da --- /dev/null +++ b/tests/package-dependencies/CMakeLists.txt @@ -0,0 +1,101 @@ +cmake_minimum_required(VERSION 3.19) +project(package_dependency_test LANGUAGES NONE) + +set(CMAKE_SYSTEM_NAME Darwin) +set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON) +set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_BINARY_DIR}/packages") +file(MAKE_DIRECTORY "${CMAKE_PREFIX_PATH}") +foreach(package_target IN ITEMS + "SQLite3|SQLite::SQLite3" "unofficial-sqlite3|unofficial::sqlite3::sqlite3" + "ZLIB|ZLIB::ZLIB" "CURL|CURL::libcurl") + string(REPLACE "|" ";" pair "${package_target}") + list(GET pair 0 package) + list(GET pair 1 target) + file(WRITE "${CMAKE_PREFIX_PATH}/${package}Config.cmake" + "add_library(${target} INTERFACE IMPORTED GLOBAL)\n" + "set_property(TARGET ${target} PROPERTY INTERFACE_LINK_LIBRARIES package-${package})\n") +endforeach() + +set(MATSDK_CONFIG_STATIC_PACKAGE ON) +if(SHARED) + set(MATSDK_CONFIG_STATIC_PACKAGE OFF) +endif() +set(MATSDK_SQLITE_PROVIDER_RESOLVED SYSTEM) +set(MATSDK_ZLIB_PROVIDER_RESOLVED SYSTEM) +set(MATSDK_SQLITE_DEPENDENCY_KIND "${SQLITE_KIND}") +set(MATSDK_ZLIB_DEPENDENCY_KIND "${ZLIB_KIND}") +set(MATSDK_SQLITE_PACKAGE_NAME SQLite3) +set(MATSDK_SQLITE_PACKAGE_TARGET SQLite::SQLite3) +if(UNOFFICIAL_SQLITE) + set(MATSDK_SQLITE_PACKAGE_NAME unofficial-sqlite3) + set(MATSDK_SQLITE_PACKAGE_TARGET unofficial::sqlite3::sqlite3) +endif() +if(SQLITE_KIND STREQUAL "BUNDLED") + set(MATSDK_SQLITE_PROVIDER_RESOLVED MINIMAL) +elseif(SQLITE_KIND STREQUAL "NONE") + set(MATSDK_SQLITE_PROVIDER_RESOLVED NONE) +endif() +if(ZLIB_KIND STREQUAL "BUNDLED") + set(MATSDK_ZLIB_PROVIDER_RESOLVED VENDORED) +endif() +if(NOT DEFINED CURL_KIND) + set(CURL_KIND PACKAGE) +endif() +if(NOT SHARED) + foreach(pair IN ITEMS "SQLite3::SQLite3|${SQLITE_KIND}" "ZLIB::ZLIB|${ZLIB_KIND}" + "CURL::libcurl|${CURL_KIND}") + string(REPLACE "|" ";" pair "${pair}") + list(GET pair 0 target) + list(GET pair 1 kind) + if(kind STREQUAL "PROVIDED" AND NOT target STREQUAL MISSING_TARGET) + if(target STREQUAL "SQLite3::SQLite3" AND LEGACY_SQLITE) + set(target SQLite::SQLite3) + endif() + add_library("${target}" INTERFACE IMPORTED GLOBAL) + set_property(TARGET "${target}" PROPERTY INTERFACE_LINK_LIBRARIES provided) + endif() + endforeach() +endif() +set(MATSDK_NEEDS_CURL ON) +set(MATSDK_CURL_FETCHED OFF) +set(MATSDK_CURL_DEPENDENCY_KIND "${CURL_KIND}") +set(MATSDK_ANDROID_HTTP_CLIENT_RESOLVED NONE) +set(PACKAGE_INIT "macro(check_required_components name)\nendmacro()") +file(COPY "${SDK_ROOT}/cmake/MatsdkDependencyTargets.cmake" + "${SDK_ROOT}/cmake/MatsdkAppleSystemDeps.cmake" + DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/MSTelemetryTargets.cmake" "") +configure_file("${SDK_ROOT}/cmake/MSTelemetryConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/MSTelemetryConfig.cmake" @ONLY) +include("${CMAKE_CURRENT_BINARY_DIR}/MSTelemetryConfig.cmake") + +foreach(pair IN ITEMS + "SQLite3::SQLite3|${SQLITE_KIND}|MSTelemetry::sqlite_dependency" + "ZLIB::ZLIB|${ZLIB_KIND}|MSTelemetry::zlib_dependency" + "CURL::libcurl|${CURL_KIND}|MSTelemetry::curl_dependency") + string(REPLACE "|" ";" pair "${pair}") + list(GET pair 0 target) + list(GET pair 1 kind) + list(GET pair 2 wrapper) + if(SHARED OR kind MATCHES "^(BUNDLED|NONE)$") + if(TARGET "${wrapper}") + message(FATAL_ERROR "Unexpected private dependency ${wrapper}") + endif() + else() + if(NOT TARGET "${wrapper}" OR NOT TARGET "${target}") + message(FATAL_ERROR "Missing ${kind} dependency ${target}") + endif() + get_target_property(links "${target}" INTERFACE_LINK_LIBRARIES) + if(kind STREQUAL "APPLE_SYSTEM") + if(NOT links MATCHES "^(sqlite3|z)$") + message(FATAL_ERROR "Apple dependency was replaced by ${links}") + endif() + elseif(kind STREQUAL "PROVIDED") + if(NOT links MATCHES "^(provided|SQLite::SQLite3)$") + message(FATAL_ERROR "Caller dependency was replaced by ${links}") + endif() + elseif(NOT links MATCHES "^(package-|SQLite::SQLite3|unofficial::sqlite3::sqlite3)") + message(FATAL_ERROR "Package dependency was replaced by ${links}") + endif() + endif() +endforeach() diff --git a/tests/vcpkg/CMakeLists.txt b/tests/vcpkg/CMakeLists.txt index b197a0920..a85ece89c 100644 --- a/tests/vcpkg/CMakeLists.txt +++ b/tests/vcpkg/CMakeLists.txt @@ -10,6 +10,18 @@ if(MSVC AND VCPKG_TARGET_TRIPLET MATCHES "-static$") set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") endif() +option(MATSDK_TEST_PRELOAD_DEPENDENCIES + "Supply canonical targets required by a caller-provided static SDK package" OFF) +if(MATSDK_TEST_PRELOAD_DEPENDENCIES) + find_package(CURL REQUIRED) + find_package(SQLite3 REQUIRED) + if(NOT TARGET SQLite3::SQLite3) + add_library(SQLite3::SQLite3 INTERFACE IMPORTED) + set_property(TARGET SQLite3::SQLite3 PROPERTY INTERFACE_LINK_LIBRARIES SQLite::SQLite3) + endif() + find_package(ZLIB REQUIRED) +endif() + find_package(MSTelemetry CONFIG REQUIRED) get_target_property(SDK_COMPILE_OPTIONS MSTelemetry::mat INTERFACE_COMPILE_OPTIONS) diff --git a/tests/vcpkg/native-feature-tests.cmake b/tests/vcpkg/native-feature-tests.cmake index 85892ac2c..9221103d5 100644 --- a/tests/vcpkg/native-feature-tests.cmake +++ b/tests/vcpkg/native-feature-tests.cmake @@ -1,7 +1,37 @@ cmake_minimum_required(VERSION 3.19) get_filename_component(REPO_ROOT "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE) -set(ENV{MATSDK_VCPKG_SOURCE_DIR} "${REPO_ROOT}") +if(REGISTRY_MODE) + set(ENV{MATSDK_VCPKG_SOURCE_DIR} "${REPO_ROOT}/does-not-exist") +else() + set(ENV{MATSDK_VCPKG_SOURCE_DIR} "${REPO_ROOT}") +endif() + +function(vcpkg_from_github) + cmake_parse_arguments(FETCH "" "OUT_SOURCE_PATH;REPO;REF;SHA512;HEAD_REF" "" ${ARGN}) + string(LENGTH "${FETCH_SHA512}" hash_length) + if(NOT FETCH_REPO STREQUAL "microsoft/cpp_client_telemetry" + OR NOT FETCH_REF MATCHES "^v[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$" + OR NOT FETCH_SHA512 MATCHES "^[0-9a-f]+$" OR NOT hash_length EQUAL 128) + message(FATAL_ERROR "Registry source must be a hash-verified release archive.") + endif() + set("${FETCH_OUT_SOURCE_PATH}" "${REPO_ROOT}" PARENT_SCOPE) + set(FETCHED ON PARENT_SCOPE) +endfunction() + +function(vcpkg_check_features) + cmake_parse_arguments(CHECK "" "OUT_FEATURE_OPTIONS" "FEATURES" ${ARGN}) + set(options) + while(CHECK_FEATURES) + list(POP_FRONT CHECK_FEATURES feature option) + set(value OFF) + if(feature IN_LIST FEATURES) + set(value ON) + endif() + list(APPEND options "-D${option}=${value}") + endwhile() + set("${CHECK_OUT_FEATURE_OPTIONS}" "${options}" PARENT_SCOPE) +endfunction() function(vcpkg_cmake_configure) cmake_parse_arguments(CONFIG "" "SOURCE_PATH" "OPTIONS" ${ARGN}) @@ -34,7 +64,11 @@ endfunction() function(check_feature_mapping platform linkage) set(FEATURES ${ARGN}) + set(VERSION 3.10.999.1) set(CURRENT_PORT_DIR "${REPO_ROOT}/tools/ports/cpp-client-telemetry") + if(REGISTRY_MODE) + set(CURRENT_PORT_DIR "${REPO_ROOT}/tools/registry-ports/cpp-client-telemetry") + endif() set(CURRENT_PACKAGES_DIR "${REPO_ROOT}/out/native-feature-tests") set(VCPKG_LIBRARY_LINKAGE "${linkage}") foreach(target LINUX WINDOWS OSX IOS ANDROID) @@ -68,10 +102,15 @@ function(check_feature_mapping platform linkage) endif() list(APPEND EXPECTED_OPTIONS "-DBUILD_SHARED_LIBS=${shared}") set(sqlite SYSTEM) - if("minimal-sqlite" IN_LIST FEATURES) + if(NOT REGISTRY_MODE AND "minimal-sqlite" IN_LIST FEATURES) set(sqlite MINIMAL) endif() list(APPEND EXPECTED_OPTIONS "-DMATSDK_SQLITE_PROVIDER=${sqlite}") + if(REGISTRY_MODE) + list(APPEND EXPECTED_OPTIONS + -DMATSDK_ZLIB_PROVIDER=SYSTEM -DMATSDK_CURL_PROVIDER=SYSTEM + -DBUILD_VERSION=3.10.999.1) + endif() set(apple_http OFF) if(platform STREQUAL "OSX" OR platform STREQUAL "IOS") set(apple_http ON) @@ -84,12 +123,40 @@ function(check_feature_mapping platform linkage) endif() list(APPEND EXPECTED_OPTIONS "-DMATSDK_ANDROID_HTTP_CLIENT=${android_http}") set(CONFIGURED OFF) + set(FETCHED OFF) include("${CURRENT_PORT_DIR}/portfile.cmake") if(NOT CONFIGURED) message(FATAL_ERROR "The feature mapping did not configure the SDK.") endif() + if(REGISTRY_MODE AND NOT FETCHED) + message(FATAL_ERROR "Registry port bypassed the pinned archive.") + endif() endfunction() +if(REGISTRY_MODE) + foreach(platform LINUX WINDOWS OSX IOS ANDROID) + foreach(linkage static dynamic) + foreach(features IN ITEMS "" device-id no-logging "no-exceptions;no-logging") + check_feature_mapping("${platform}" "${linkage}" ${features}) + endforeach() + if(platform STREQUAL "LINUX") + check_feature_mapping("${platform}" "${linkage}" + device-id curl-openssl curl-mbedtls system-sqlite) + elseif(platform STREQUAL "ANDROID") + foreach(transport android-curl-openssl android-curl-mbedtls + "android-curl-openssl;android-curl-mbedtls") + check_feature_mapping("${platform}" "${linkage}" + android-capi-http-client no-exceptions no-logging ${transport}) + endforeach() + elseif(platform STREQUAL "WINDOWS") + check_feature_mapping("${platform}" "${linkage}" device-id wininet) + endif() + endforeach() + endforeach() + message(STATUS "Registry feature mappings, core graphs, and TLS unions passed") + return() +endif() + if(DEFINED UNSUPPORTED_FEATURE) set(ENV{MATSDK_VCPKG_SOURCE_DIR} "${OLD_SOURCE}") if(UNSUPPORTED_FEATURE STREQUAL "minimal-sqlite") diff --git a/tests/vcpkg/package-dependency-tests.cmake b/tests/vcpkg/package-dependency-tests.cmake index 378a3b899..500e61a58 100644 --- a/tests/vcpkg/package-dependency-tests.cmake +++ b/tests/vcpkg/package-dependency-tests.cmake @@ -4,63 +4,43 @@ get_filename_component(REPO_ROOT "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE) if(NOT DEFINED OUTPUT_DIR) set(OUTPUT_DIR "${REPO_ROOT}/out/package-dependency-tests") endif() -file(MAKE_DIRECTORY "${OUTPUT_DIR}") -file(WRITE "${OUTPUT_DIR}/MSTelemetryTargets.cmake" "") -file(WRITE "${OUTPUT_DIR}/MatsdkDependencyTargets.cmake" [=[ -function(matsdk_add_package_system_dependency target canonical provider package) - cmake_parse_arguments(DEPENDENCY "APPLE_SYSTEM" "APPLE_LIBRARY;LEGACY_TARGET" "" ${ARGN}) - if(NOT provider STREQUAL "SYSTEM") - message(FATAL_ERROR "Unexpected provider for ${package}: ${provider}") - endif() - if((DEPENDENCY_APPLE_SYSTEM AND NOT EXPECTED_APPLE_SYSTEM) - OR (NOT DEPENDENCY_APPLE_SYSTEM AND EXPECTED_APPLE_SYSTEM)) - message(FATAL_ERROR "Incorrect Apple dependency selection for ${package}") - endif() - if(DEPENDENCY_APPLE_SYSTEM) - if(package STREQUAL "SQLite3") - set(expected_library sqlite3) - elseif(package STREQUAL "ZLIB") - set(expected_library z) - else() - message(FATAL_ERROR "Unexpected Apple dependency: ${package}") - endif() - if(NOT DEPENDENCY_APPLE_LIBRARY STREQUAL expected_library) - message(FATAL_ERROR "Incorrect Apple library for ${package}") + +function(check_dependency_config sqlite_kind zlib_kind shared) + string(MAKE_C_IDENTIFIER "${sqlite_kind}-${zlib_kind}-${shared}-${ARGN}" name) + execute_process( + COMMAND "${CMAKE_COMMAND}" + -S "${REPO_ROOT}/tests/package-dependencies" + -B "${OUTPUT_DIR}/${name}" + "-DSDK_ROOT=${REPO_ROOT}" + "-DSQLITE_KIND=${sqlite_kind}" + "-DZLIB_KIND=${zlib_kind}" + "-DSHARED=${shared}" ${ARGN} + RESULT_VARIABLE result OUTPUT_VARIABLE output ERROR_VARIABLE error) + if(EXPECTED_MISSING_TARGET) + if(result EQUAL 0 OR NOT error MATCHES "caller-provided ${EXPECTED_MISSING_TARGET}") + message(FATAL_ERROR "${name} did not reject the missing provided target:\n${output}\n${error}") endif() + elseif(NOT result EQUAL 0) + message(FATAL_ERROR "${name} failed:\n${output}\n${error}") endif() - set_property(GLOBAL APPEND PROPERTY RESOLVED_DEPENDENCIES "${package}") endfunction() -]=]) -set(PACKAGE_INIT "macro(check_required_components name)\nendmacro()") -set(MATSDK_SQLITE_PROVIDER_RESOLVED SYSTEM) -set(MATSDK_ZLIB_PROVIDER_RESOLVED SYSTEM) -set(MATSDK_ANDROID_HTTP_CLIENT_RESOLVED NONE) -set(MATSDK_NEEDS_CURL OFF) -set(MATSDK_CURL_FETCHED OFF) -set(CMAKE_SYSTEM_NAME Darwin) - -foreach(MATSDK_BUILD_PLATFORM_APPLE ON OFF) - foreach(MATSDK_USING_VCPKG ON OFF) - foreach(MATSDK_CONFIG_STATIC_PACKAGE ON OFF) - set(EXPECTED_APPLE_SYSTEM OFF) - if(MATSDK_BUILD_PLATFORM_APPLE AND NOT MATSDK_USING_VCPKG) - set(EXPECTED_APPLE_SYSTEM ON) - endif() - set_property(GLOBAL PROPERTY RESOLVED_DEPENDENCIES "") - configure_file("${REPO_ROOT}/cmake/MSTelemetryConfig.cmake.in" - "${OUTPUT_DIR}/MSTelemetryConfig.cmake" @ONLY) - include("${OUTPUT_DIR}/MSTelemetryConfig.cmake") - get_property(dependencies GLOBAL PROPERTY RESOLVED_DEPENDENCIES) - if(MATSDK_CONFIG_STATIC_PACKAGE) - if(NOT dependencies STREQUAL "SQLite3;ZLIB") - message(FATAL_ERROR "Missing static package dependencies: ${dependencies}") - endif() - elseif(dependencies) - message(FATAL_ERROR "Shared packages must not rediscover private dependencies") - endif() +foreach(sqlite_kind PACKAGE PROVIDED APPLE_SYSTEM BUNDLED NONE) + foreach(zlib_kind PACKAGE PROVIDED APPLE_SYSTEM BUNDLED) + foreach(shared ON OFF) + check_dependency_config("${sqlite_kind}" "${zlib_kind}" "${shared}") endforeach() endforeach() endforeach() +check_dependency_config(PACKAGE PACKAGE OFF -DUNOFFICIAL_SQLITE=ON) +check_dependency_config(PROVIDED PROVIDED OFF -DLEGACY_SQLITE=ON) +foreach(shared ON OFF) + check_dependency_config(PACKAGE PACKAGE "${shared}" -DCURL_KIND=PROVIDED) +endforeach() +foreach(target SQLite3::SQLite3 ZLIB::ZLIB CURL::libcurl) + set(EXPECTED_MISSING_TARGET "${target}") + check_dependency_config(PROVIDED PROVIDED OFF + -DCURL_KIND=PROVIDED "-DMISSING_TARGET=${target}") +endforeach() -message(STATUS "Package dependency selection passed for all eight configurations") +message(STATUS "All 44 package dependency configurations and 3 missing-target checks passed") diff --git a/tests/vcpkg/test-release-port.py b/tests/vcpkg/test-release-port.py index c75cceb34..b31f42fb0 100644 --- a/tests/vcpkg/test-release-port.py +++ b/tests/vcpkg/test-release-port.py @@ -1,4 +1,4 @@ -"""Regression tests for promoting the release overlay into the registry.""" +"""Regression tests for promoting the release registry recipe.""" import importlib.util import json @@ -21,7 +21,7 @@ def setUp(self): self.temporary = tempfile.TemporaryDirectory() self.addCleanup(self.temporary.cleanup) root = Path(self.temporary.name) - self.source = root / "release" / "tools" / "ports" / "cpp-client-telemetry" + self.source = root / "release" / "tools" / "registry-ports" / "cpp-client-telemetry" self.source.mkdir(parents=True) self.destination = root / "vcpkg" / "ports" / "cpp-client-telemetry" self.destination.mkdir(parents=True) @@ -35,14 +35,14 @@ def setUp(self): marker.touch() (self.destination / "obsolete.patch").write_text("old patch", encoding="utf-8") self.manifest = json.loads( - (REPO_ROOT / "tools" / "ports" / "cpp-client-telemetry" / "vcpkg.json").read_text( + (REPO_ROOT / "tools" / "registry-ports" / "cpp-client-telemetry" / "vcpkg.json").read_text( encoding="utf-8" ) ) self.manifest["port-version"] = 7 self.write_manifest() self.portfile = ( - REPO_ROOT / "tools" / "ports" / "cpp-client-telemetry" / "portfile.cmake" + REPO_ROOT / "tools" / "registry-ports" / "cpp-client-telemetry" / "portfile.cmake" ).read_text(encoding="utf-8") (self.source / "portfile.cmake").write_text(self.portfile, encoding="utf-8") @@ -62,16 +62,17 @@ def test_promotes_complete_release_port(self): portfile = (self.destination / "portfile.cmake").read_text(encoding="utf-8") self.assertIn("REF v3.10.999.1\n", portfile) self.assertIn(f"SHA512 {'a' * 128}\n", portfile) - self.assertIn("-DMATSDK_SQLITE_PROVIDER=${MATSDK_VCPKG_SQLITE_PROVIDER}", portfile) + self.assertIn("-DMATSDK_SQLITE_PROVIDER=SYSTEM", portfile) + self.assertIn("-DMATSDK_ZLIB_PROVIDER=SYSTEM", portfile) self.assertIn("-DMATSDK_ANDROID_HTTP_CLIENT=${MATSDK_ANDROID_HTTP_CLIENT}", portfile) - self.assertIn("${MATSDK_NATIVE_FEATURE_OPTIONS}", portfile) + self.assertIn("${FEATURE_OPTIONS}", portfile) for feature, option in ( ("no-exceptions", "MATSDK_DISABLE_EXCEPTIONS"), ("no-logging", "MATSDK_DISABLE_LOGGING"), ("android-capi-http-client", "MATSDK_ENABLE_CAPI_HTTP_CLIENT"), ): self.assertIn(feature, actual["features"]) - self.assertIn(f"{feature}|{option}", portfile) + self.assertIn(f"{feature} {option}", portfile) self.assertEqual((self.destination / "release.patch").read_text(), "new patch") self.assertFalse((self.destination / "obsolete.patch").exists()) self.assertEqual( @@ -81,7 +82,7 @@ def test_promotes_complete_release_port(self): self.assertEqual((self.destination / "portfile.cmake").read_text(), portfile) def test_rejects_release_missing_required_features_before_replacing_port(self): - for feature in ("minimal-sqlite", "android-curl-openssl"): + for feature in ("android-curl-openssl", "android-curl-mbedtls", "no-logging"): with self.subTest(feature=feature): definition = self.manifest["features"].pop(feature) self.write_manifest() @@ -90,6 +91,35 @@ def test_rejects_release_missing_required_features_before_replacing_port(self): self.assertTrue((self.destination / "obsolete.patch").exists()) self.manifest["features"][feature] = definition + def test_rejects_development_overlay_without_replacing_port(self): + self.manifest["features"]["minimal-sqlite"] = {"description": "Private SQLite"} + self.write_manifest() + with self.assertRaisesRegex(ValueError, "registry recipe"): + self.prepare() + self.assertTrue((self.destination / "obsolete.patch").exists()) + + def test_rejects_development_source_override_without_replacing_port(self): + (self.source / "portfile.cmake").write_text( + self.portfile + "\nset(SOURCE_PATH \"$ENV{MATSDK_VCPKG_SOURCE_DIR}\")\n", + encoding="utf-8", + ) + with self.assertRaisesRegex(ValueError, "source overrides"): + self.prepare() + self.assertTrue((self.destination / "obsolete.patch").exists()) + + def test_registry_core_contains_required_dependencies(self): + dependencies = { + item if isinstance(item, str) else item["name"]: item + for item in self.manifest["dependencies"] + } + for package in ("sqlite3", "zlib"): + self.assertIn(package, dependencies) + if isinstance(dependencies[package], dict): + self.assertNotIn("platform", dependencies[package]) + self.assertEqual(dependencies["curl"]["platform"], "linux") + self.assertIn("openssl", dependencies["curl"]["features"]) + self.assertNotIn("minimal-sqlite", self.manifest["features"]) + def test_rejects_missing_or_duplicate_archive_fields(self): for field in ("REF", "SHA512"): for replacement in ("", f" {field} duplicate\n {field} duplicate\n"): @@ -124,7 +154,7 @@ def test_describes_invalid_sha512_as_hexadecimal_characters(self): def test_rejects_overlapping_ports(self): with self.assertRaisesRegex(ValueError, "overlap"): - PREPARE.prepare_port(self.source, self.source, "3.10.999.1", "a" * 128) + PREPARE.prepare_port(self.destination, self.destination, "3.10.999.1", "a" * 128) self.assertTrue((self.source / "portfile.cmake").exists()) def test_rejects_lookalike_non_vcpkg_destination_without_deleting_files(self): diff --git a/tools/registry-ports/cpp-client-telemetry/portfile.cmake b/tools/registry-ports/cpp-client-telemetry/portfile.cmake new file mode 100644 index 000000000..4cae42336 --- /dev/null +++ b/tools/registry-ports/cpp-client-telemetry/portfile.cmake @@ -0,0 +1,65 @@ +# Release-promotion template: prepare-vcpkg-release.py replaces the version, +# REF, and SHA512 with the release containing these packaging fixes. +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO microsoft/cpp_client_telemetry + REF v3.10.279.1 + SHA512 fc31686bfbe50c3a7f2a287671354579c77de05adab74b350238e02441ede29fff8a5de0621742015547cc0571bb606683b343cd1b85b45fcaac85d31642f430 + HEAD_REF main +) + +vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS + FEATURES + device-id MATSDK_ENABLE_DEVICE_ID + no-exceptions MATSDK_DISABLE_EXCEPTIONS + no-logging MATSDK_DISABLE_LOGGING + android-capi-http-client MATSDK_ENABLE_CAPI_HTTP_CLIENT + wininet MATSDK_USE_WININET +) + +set(MATSDK_BUILD_APPLE_HTTP OFF) +if(VCPKG_TARGET_IS_OSX OR VCPKG_TARGET_IS_IOS) + set(MATSDK_BUILD_APPLE_HTTP ON) +endif() +set(MATSDK_ANDROID_HTTP_CLIENT AUTO) +if(VCPKG_TARGET_IS_ANDROID + AND ("android-curl-openssl" IN_LIST FEATURES OR "android-curl-mbedtls" IN_LIST FEATURES)) + set(MATSDK_ANDROID_HTTP_CLIENT CURL) +endif() +set(MATSDK_BUILD_SHARED_LIBS OFF) +if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic") + set(MATSDK_BUILD_SHARED_LIBS ON) +endif() +set(MATSDK_PLATFORM_OPTIONS) +if(VCPKG_TARGET_IS_IOS) + list(APPEND MATSDK_PLATFORM_OPTIONS -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0) +endif() + +vcpkg_cmake_configure( + SOURCE_PATH "${SOURCE_PATH}" + OPTIONS + ${FEATURE_OPTIONS} + ${MATSDK_PLATFORM_OPTIONS} + -DBUILD_SHARED_LIBS=${MATSDK_BUILD_SHARED_LIBS} + -DBUILD_VERSION=${VERSION} + -DMATSDK_BUILD_HEADERS=ON + -DMATSDK_BUILD_LIBRARY=ON + -DMATSDK_BUILD_TEST_TOOL=OFF + -DMATSDK_BUILD_UNIT_TESTS=OFF + -DMATSDK_BUILD_FUNC_TESTS=OFF + -DMATSDK_BUILD_PACKAGE=OFF + -DMATSDK_BUILD_JNI_WRAPPER=OFF + -DMATSDK_BUILD_OBJC_WRAPPER=OFF + -DMATSDK_BUILD_SWIFT_WRAPPER=OFF + -DMATSDK_BUILD_APPLE_HTTP=${MATSDK_BUILD_APPLE_HTTP} + -DMATSDK_ANDROID_HTTP_CLIENT=${MATSDK_ANDROID_HTTP_CLIENT} + -DMATSDK_SQLITE_PROVIDER=SYSTEM + -DMATSDK_ZLIB_PROVIDER=SYSTEM + -DMATSDK_CURL_PROVIDER=SYSTEM +) + +vcpkg_cmake_install() +vcpkg_cmake_config_fixup(PACKAGE_NAME MSTelemetry CONFIG_PATH lib/cmake/MSTelemetry) +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share") +vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE") diff --git a/tools/registry-ports/cpp-client-telemetry/vcpkg.json b/tools/registry-ports/cpp-client-telemetry/vcpkg.json new file mode 100644 index 000000000..2707c33ff --- /dev/null +++ b/tools/registry-ports/cpp-client-telemetry/vcpkg.json @@ -0,0 +1,111 @@ +{ + "name": "cpp-client-telemetry", + "version": "3.10.279.1", + "description": "Microsoft 1DS C/C++ Client Telemetry Library", + "homepage": "https://github.com/microsoft/cpp_client_telemetry", + "license": "Apache-2.0", + "supports": "((windows & !mingw) | linux | osx | ios | android) & !uwp", + "dependencies": [ + { + "name": "curl", + "default-features": false, + "features": [ + "openssl" + ], + "platform": "linux" + }, + "nlohmann-json", + { + "name": "sqlite3", + "default-features": false + }, + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + }, + "zlib" + ], + "default-features": [ + "device-id" + ], + "features": { + "android-capi-http-client": { + "description": "Allow Android C API consumers to provide custom HTTP send/cancel callbacks.", + "supports": "android" + }, + "android-curl-mbedtls": { + "description": "Enable Android native libcurl HTTP with mbedTLS. Can be combined with android-curl-openssl.", + "supports": "android", + "dependencies": [ + { + "name": "curl", + "default-features": false, + "features": [ + "mbedtls" + ], + "platform": "android" + } + ] + }, + "android-curl-openssl": { + "description": "Enable Android native libcurl HTTP with OpenSSL. Can be combined with android-curl-mbedtls.", + "supports": "android", + "dependencies": [ + { + "name": "curl", + "default-features": false, + "features": [ + "openssl" + ], + "platform": "android" + } + ] + }, + "curl-mbedtls": { + "description": "Add mbedTLS to the Linux libcurl HTTP client alongside its required OpenSSL backend.", + "dependencies": [ + { + "name": "curl", + "default-features": false, + "features": [ + "mbedtls" + ], + "platform": "linux" + } + ] + }, + "curl-openssl": { + "description": "Compatibility feature for Linux OpenSSL, which is always included in core.", + "dependencies": [ + { + "name": "curl", + "default-features": false, + "features": [ + "openssl" + ], + "platform": "linux" + } + ] + }, + "device-id": { + "description": "Collect a native device ID (default). Omit with default-features=false to provide your own DeviceInfo.Id." + }, + "no-exceptions": { + "description": "Disable exceptions in SDK-owned targets without changing consumer or dependency flags." + }, + "no-logging": { + "description": "Compile out internal diagnostics without disabling telemetry collection." + }, + "system-sqlite": { + "description": "Compatibility feature for external SQLite, which is always included in core." + }, + "wininet": { + "description": "Use Windows WinInet instead of the default WinHTTP transport.", + "supports": "windows & !mingw" + } + } +} From 4cdce4db27e1f3f021011b62653457dfa2cd2ad3 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Wed, 7 Oct 2026 14:46:40 -0500 Subject: [PATCH 3/3] Prepare 3.10.280.1 so packaging fixes reach a new SDK and SPM release Regenerate the public version for SDK 3.10.280.1 and SPM 3.10.280 without changing published tags or the generator policy. Files changed: lib\include\public\Version.hpp Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 812576a3-8932-4848-bc8b-d17af18f65f2 --- lib/include/public/Version.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/include/public/Version.hpp b/lib/include/public/Version.hpp index 3e9c6a7c3..57c7b5ae9 100644 --- a/lib/include/public/Version.hpp +++ b/lib/include/public/Version.hpp @@ -6,8 +6,8 @@ #define MAT_VERSION_HPP // WARNING: DO NOT MODIFY THIS FILE! // This file has been automatically generated, manual changes will be lost. -#define BUILD_VERSION_STR "3.10.279.1" -#define BUILD_VERSION 3,10,279,1 +#define BUILD_VERSION_STR "3.10.280.1" +#define BUILD_VERSION 3,10,280,1 #ifndef RESOURCE_COMPILER_INVOKED #include "ctmacros.hpp" @@ -18,7 +18,7 @@ namespace MAT_NS_BEGIN { uint64_t const Version = ((uint64_t)3 << 48) | ((uint64_t)10 << 32) | - ((uint64_t)279 << 16) | + ((uint64_t)280 << 16) | ((uint64_t)1); } MAT_NS_END