From dda585e68c0d1fb1af1445ce421fe43900db8050 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 28 Jul 2026 03:16:32 -0500 Subject: [PATCH 1/9] Add non-vcpkg CMake embedding target Expose the same MSTelemetry::mat target name for build-tree add_subdirectory/FetchContent consumers so downstream projects can link one target regardless of vcpkg/install vs source embedding. Files changed: - lib/CMakeLists.txt: add MSTelemetry::mat build-tree alias. - CMakeLists.txt, lib/CMakeLists.txt: add optional MATSDK_CURL_TARGET, MATSDK_SQLITE_TARGET, and MATSDK_ZLIB_TARGET overrides for non-vcpkg superbuilds, with a WIN32 zlib guard for the existing act_z_* header path. - docs/embedding-with-cmake.md: document source embedding and dependency target overrides. - tests/embedding/CMakeLists.txt: add add_subdirectory smoke project linking MSTelemetry::mat. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b12c5862-01e3-45e4-bf91-6389c20cae41 --- CMakeLists.txt | 43 ++++++++++++++++++++++----- docs/embedding-with-cmake.md | 53 ++++++++++++++++++++++++++++++++++ lib/CMakeLists.txt | 41 ++++++++++++++++++-------- tests/embedding/CMakeLists.txt | 18 ++++++++++++ 4 files changed, 135 insertions(+), 20 deletions(-) create mode 100644 docs/embedding-with-cmake.md create mode 100644 tests/embedding/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b2321e3c..3ed4d5fa9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -361,6 +361,29 @@ option(BUILD_LIVEEVENTINSPECTOR "Build Live Event Inspector" YES) option(BUILD_SIGNALS "Build Signals" YES) option(BUILD_SANITIZER "Build Sanitizer" YES) option(LINK_STATIC_DEPENDS "Link dependencies for static build" YES) +set(MATSDK_CURL_TARGET "" CACHE STRING + "Optional existing CMake target to use for libcurl in non-vcpkg builds, instead of find_package(CURL)") +set(MATSDK_SQLITE_TARGET "" CACHE STRING + "Optional existing CMake target to use for SQLite in non-vcpkg builds, instead of find_package(SQLite3)") +set(MATSDK_ZLIB_TARGET "" CACHE STRING + "Optional existing CMake target to use for zlib in non-vcpkg builds, instead of find_package(ZLIB)") +foreach(_matsdk_dependency_target_var MATSDK_CURL_TARGET MATSDK_SQLITE_TARGET MATSDK_ZLIB_TARGET) + if(${_matsdk_dependency_target_var} AND NOT TARGET "${${_matsdk_dependency_target_var}}") + message(FATAL_ERROR + "${_matsdk_dependency_target_var} was set to '${${_matsdk_dependency_target_var}}', " + "but no such CMake target exists. Define the target before adding " + "cpp_client_telemetry, or leave ${_matsdk_dependency_target_var} empty to " + "use the SDK's default dependency discovery.") + endif() +endforeach() +if(MATSDK_ZLIB_TARGET AND PAL_IMPLEMENTATION STREQUAL "WIN32" AND NOT MATSDK_USE_VCPKG_DEPS) + message(FATAL_ERROR + "MATSDK_ZLIB_TARGET is not supported for non-vcpkg WIN32 builds because " + "the legacy WIN32 include path uses the SDK's vendored zlib headers, which " + "rename zlib symbols to act_z_*. Use vcpkg mode, omit MATSDK_ZLIB_TARGET " + "and rely on the legacy .vcxproj dependency, or add a dedicated bundled-zlib " + "CMake path first.") +endif() # Enable Azure Monitor / Application Insights end-point support option(BUILD_AZMON "Build for Azure Monitor" YES) @@ -403,15 +426,19 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11" endif() list(APPEND LIBS CURL::libcurl) else() - find_package(CURL REQUIRED) - # Prefer the imported target, which carries curl's include dirs and link - # flags. Fall back to the find-module variables on CMake < 3.12, where - # find_package(CURL) does not define CURL::libcurl. - if(TARGET CURL::libcurl) - list(APPEND LIBS CURL::libcurl) + if(MATSDK_CURL_TARGET) + list(APPEND LIBS "${MATSDK_CURL_TARGET}") else() - include_directories(${CURL_INCLUDE_DIRS}) - list(APPEND LIBS "${CURL_LIBRARIES}") + find_package(CURL REQUIRED) + # Prefer the imported target, which carries curl's include dirs and link + # flags. Fall back to the find-module variables on CMake < 3.12, where + # find_package(CURL) does not define CURL::libcurl. + if(TARGET CURL::libcurl) + list(APPEND LIBS CURL::libcurl) + else() + include_directories(${CURL_INCLUDE_DIRS}) + list(APPEND LIBS "${CURL_LIBRARIES}") + endif() endif() endif() endif() diff --git a/docs/embedding-with-cmake.md b/docs/embedding-with-cmake.md new file mode 100644 index 000000000..f68d124e6 --- /dev/null +++ b/docs/embedding-with-cmake.md @@ -0,0 +1,53 @@ +# Embedding 1DS with CMake + +Consumers that build the SDK from source with `add_subdirectory()` or +`FetchContent` can link the same target name used by installed/vcpkg builds: + +```cmake +set(BUILD_TEST_TOOL OFF CACHE BOOL "" FORCE) +set(BUILD_UNIT_TESTS OFF CACHE BOOL "" FORCE) +set(BUILD_FUNC_TESTS OFF CACHE BOOL "" FORCE) +set(BUILD_PACKAGE OFF CACHE BOOL "" FORCE) + +add_subdirectory(cpp_client_telemetry) +target_link_libraries(your_target PRIVATE MSTelemetry::mat) +``` + +For a static SDK build, CMake carries the SDK's link dependencies through the +`MSTelemetry::mat` target, so the consuming target should not need to name the +SDK's internal dependencies directly. + +## Non-vcpkg dependency selection + +When the CPP11 PAL uses the curl HTTP transport outside vcpkg, the SDK normally +calls `find_package(CURL)` and links `CURL::libcurl` when that imported target is +available. Non-vcpkg Linux builds similarly use `find_package()` for zlib and +SQLite unless the minimal bundled SQLite option is enabled. + +To make a superbuild choose the dependency implementation (for example, libcurl +built with OpenSSL vs. mbedTLS) without changing the leaf consumer target, define +the desired dependency targets before adding the SDK and point the matching +`MATSDK_*_TARGET` cache variables at them: + +```cmake +# Created by your superbuild, package manager, or imported-target wrappers. +add_library(my_curl_target STATIC IMPORTED GLOBAL) # OpenSSL or mbedTLS curl +add_library(my_zlib_target STATIC IMPORTED GLOBAL) +add_library(my_sqlite_target STATIC IMPORTED GLOBAL) + +set(MATSDK_CURL_TARGET my_curl_target CACHE STRING "" FORCE) +set(MATSDK_ZLIB_TARGET my_zlib_target CACHE STRING "" FORCE) +set(MATSDK_SQLITE_TARGET my_sqlite_target CACHE STRING "" FORCE) +add_subdirectory(cpp_client_telemetry) + +target_link_libraries(your_target PRIVATE MSTelemetry::mat) +``` + +If a `MATSDK_*_TARGET` value is empty, the SDK falls back to its existing +dependency discovery for that library. + +`MATSDK_ZLIB_TARGET` is intentionally rejected for non-vcpkg WIN32 builds today: +that legacy path includes the SDK's vendored zlib headers, which rename zlib +symbols to `act_z_*`. Use vcpkg mode, the existing Visual Studio project +dependency path, or add a dedicated bundled-zlib CMake path before supplying a +custom WIN32 zlib target. diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 97428a101..c4f6a54db 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -325,6 +325,9 @@ else() message(STATUS "Building static SDK library") add_library(mat STATIC ${SRCS}) endif() +if(NOT TARGET MSTelemetry::mat) + add_library(MSTelemetry::mat ALIAS mat) +endif() # Public-API export decoration (MATSDK_LIBABI in lib/include/public/ctmacros.hpp). # The SDK has no .def file, so __declspec(dllexport)/(dllimport) on Windows and @@ -565,14 +568,18 @@ else() target_link_libraries(mat PRIVATE sqlite3_bundled zlib_bundled ${LIBS}) elseif(PAL_IMPLEMENTATION STREQUAL "WIN32") # Windows legacy: vendored sqlite/zlib headers are included via - # include_directories in the PAL section above; link only ${LIBS} - # (e.g. CURL if needed — sqlite/zlib come from .vcxproj references), plus the - # private minimal SQLite when MATSDK_MINIMAL_SQLITE is enabled. + # include_directories in the PAL section above; link only explicit CMake deps + # (e.g. CURL if needed, or a parent-provided SQLite target). Parent-provided + # zlib is rejected in the root CMakeLists because the vendored zlib headers + # rename zlib symbols to act_z_* on this path. If no MATSDK_*_TARGET is + # supplied, legacy .vcxproj builds provide sqlite/zlib. + set(_matsdk_win32_deps ${LIBS}) if(MATSDK_BUNDLE_SQLITE) - target_link_libraries(mat PRIVATE sqlite3_bundled ${LIBS}) - else() - target_link_libraries(mat PRIVATE ${LIBS}) + list(APPEND _matsdk_win32_deps sqlite3_bundled) + elseif(MATSDK_SQLITE_TARGET) + list(APPEND _matsdk_win32_deps "${MATSDK_SQLITE_TARGET}") endif() + target_link_libraries(mat PRIVATE ${_matsdk_win32_deps}) elseif(APPLE) # macOS and iOS both ship system libsqlite3 and libz. Link them by portable # names -- matching the SDK's own iOS Xcode projects (libsqlite3.tbd + libz.tbd @@ -584,14 +591,24 @@ else() else() # Linux legacy: system zlib + system (or private minimal) sqlite3. ZLIB::ZLIB # and SQLite::SQLite3 are imported targets that carry their own include dirs. - find_package(ZLIB REQUIRED) + if(MATSDK_ZLIB_TARGET) + set(_matsdk_zlib_target "${MATSDK_ZLIB_TARGET}") + else() + find_package(ZLIB REQUIRED) + set(_matsdk_zlib_target ZLIB::ZLIB) + endif() if(MATSDK_BUNDLE_SQLITE) - target_link_libraries(mat PRIVATE sqlite3_bundled ZLIB::ZLIB ${LIBS}) + target_link_libraries(mat PRIVATE sqlite3_bundled ${_matsdk_zlib_target} ${LIBS}) else() - # find_package(SQLite3) needs CMake >= 3.14, guaranteed by the project floor; - # SQLite::SQLite3 is an imported target carrying its own include dirs. - find_package(SQLite3 REQUIRED) - target_link_libraries(mat PRIVATE SQLite::SQLite3 ZLIB::ZLIB ${LIBS}) + if(MATSDK_SQLITE_TARGET) + set(_matsdk_sqlite_target "${MATSDK_SQLITE_TARGET}") + else() + # find_package(SQLite3) needs CMake >= 3.14, guaranteed by the project floor; + # SQLite::SQLite3 is an imported target carrying its own include dirs. + find_package(SQLite3 REQUIRED) + set(_matsdk_sqlite_target SQLite::SQLite3) + endif() + target_link_libraries(mat PRIVATE ${_matsdk_sqlite_target} ${_matsdk_zlib_target} ${LIBS}) endif() endif() endif() diff --git a/tests/embedding/CMakeLists.txt b/tests/embedding/CMakeLists.txt new file mode 100644 index 000000000..58b9123e2 --- /dev/null +++ b/tests/embedding/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.15...3.31) +project(cpp-client-telemetry_embedding_test LANGUAGES C CXX) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(BUILD_HEADERS ON CACHE BOOL "" FORCE) +set(BUILD_LIBRARY ON CACHE BOOL "" FORCE) +set(BUILD_TEST_TOOL OFF CACHE BOOL "" FORCE) +set(BUILD_UNIT_TESTS OFF CACHE BOOL "" FORCE) +set(BUILD_FUNC_TESTS OFF CACHE BOOL "" FORCE) +set(BUILD_PACKAGE OFF CACHE BOOL "" FORCE) + +add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../.." cpp_client_telemetry) + +add_executable(embedding_test "${CMAKE_CURRENT_LIST_DIR}/../vcpkg/main.cpp") +target_link_libraries(embedding_test PRIVATE MSTelemetry::mat) From ad301a270e7fd9e8f1183a4c22760985f00f8aa9 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 28 Jul 2026 04:43:06 -0500 Subject: [PATCH 2/9] Add fetched static curl for non-vcpkg embedding Allow source-embedding consumers to set MATSDK_CURL_PROVIDER=FETCH so 1DS downloads and builds a pinned static curl dependency on Linux, matching the ORT GenAI model. Details: - Add MATSDK_CURL_PROVIDER and MATSDK_CURL_TLS_BACKEND options, defaulting to package discovery and mbedTLS for fetched curl. - Add pinned curl and mbedTLS URL/SHA cache variables. - Add cmake/MatsdkFetchCurl.cmake to build HTTP(S)-only static curl with mbedTLS or OpenSSL. - Document fetched curl and dependency-target override usage for non-vcpkg embedding. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b12c5862-01e3-45e4-bf91-6389c20cae41 --- CMakeLists.txt | 26 +++++++ cmake/MatsdkFetchCurl.cmake | 129 +++++++++++++++++++++++++++++++++++ docs/embedding-with-cmake.md | 19 +++++- 3 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 cmake/MatsdkFetchCurl.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ed4d5fa9..77ab655fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -363,10 +363,32 @@ option(BUILD_SANITIZER "Build Sanitizer" YES) option(LINK_STATIC_DEPENDS "Link dependencies for static build" YES) set(MATSDK_CURL_TARGET "" CACHE STRING "Optional existing CMake target to use for libcurl in non-vcpkg builds, instead of find_package(CURL)") +set(MATSDK_CURL_PROVIDER "PACKAGE" CACHE STRING + "How non-vcpkg builds resolve libcurl: PACKAGE (find_package) or FETCH (FetchContent static curl)") +set_property(CACHE MATSDK_CURL_PROVIDER PROPERTY STRINGS PACKAGE FETCH) +set(MATSDK_CURL_TLS_BACKEND "MBEDTLS" CACHE STRING + "TLS backend for MATSDK_CURL_PROVIDER=FETCH: MBEDTLS or OPENSSL") +set_property(CACHE MATSDK_CURL_TLS_BACKEND PROPERTY STRINGS MBEDTLS OPENSSL) +set(MATSDK_CURL_URL "https://github.com/curl/curl/releases/download/curl-8_21_0/curl-8.21.0.tar.xz" CACHE STRING + "URL for MATSDK_CURL_PROVIDER=FETCH") +set(MATSDK_CURL_SHA1 "c3b4712175609f1e1662e716efd4fd48901e863d" CACHE STRING + "SHA1 for MATSDK_CURL_URL") +set(MATSDK_MBEDTLS_URL "https://github.com/Mbed-TLS/mbedtls/releases/download/mbedtls-3.6.7/mbedtls-3.6.7.tar.bz2" CACHE STRING + "URL for the mbedTLS dependency used by MATSDK_CURL_PROVIDER=FETCH and MATSDK_CURL_TLS_BACKEND=MBEDTLS") +set(MATSDK_MBEDTLS_SHA1 "e892e98cff90cf7e0736c525bf357626a2513c4c" CACHE STRING + "SHA1 for MATSDK_MBEDTLS_URL") set(MATSDK_SQLITE_TARGET "" CACHE STRING "Optional existing CMake target to use for SQLite in non-vcpkg builds, instead of find_package(SQLite3)") set(MATSDK_ZLIB_TARGET "" CACHE STRING "Optional existing CMake target to use for zlib in non-vcpkg builds, instead of find_package(ZLIB)") +string(TOUPPER "${MATSDK_CURL_PROVIDER}" MATSDK_CURL_PROVIDER_UPPER) +if(NOT MATSDK_CURL_PROVIDER_UPPER STREQUAL "PACKAGE" AND NOT MATSDK_CURL_PROVIDER_UPPER STREQUAL "FETCH") + message(FATAL_ERROR "MATSDK_CURL_PROVIDER must be PACKAGE or FETCH; got '${MATSDK_CURL_PROVIDER}'.") +endif() +string(TOUPPER "${MATSDK_CURL_TLS_BACKEND}" MATSDK_CURL_TLS_BACKEND_UPPER) +if(NOT MATSDK_CURL_TLS_BACKEND_UPPER STREQUAL "MBEDTLS" AND NOT MATSDK_CURL_TLS_BACKEND_UPPER STREQUAL "OPENSSL") + message(FATAL_ERROR "MATSDK_CURL_TLS_BACKEND must be MBEDTLS or OPENSSL; got '${MATSDK_CURL_TLS_BACKEND}'.") +endif() foreach(_matsdk_dependency_target_var MATSDK_CURL_TARGET MATSDK_SQLITE_TARGET MATSDK_ZLIB_TARGET) if(${_matsdk_dependency_target_var} AND NOT TARGET "${${_matsdk_dependency_target_var}}") message(FATAL_ERROR @@ -428,6 +450,10 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11" else() if(MATSDK_CURL_TARGET) list(APPEND LIBS "${MATSDK_CURL_TARGET}") + elseif(MATSDK_CURL_PROVIDER_UPPER STREQUAL "FETCH") + include(cmake/MatsdkFetchCurl.cmake) + matsdk_fetch_curl(_matsdk_curl_target) + list(APPEND LIBS "${_matsdk_curl_target}") else() find_package(CURL REQUIRED) # Prefer the imported target, which carries curl's include dirs and link diff --git a/cmake/MatsdkFetchCurl.cmake b/cmake/MatsdkFetchCurl.cmake new file mode 100644 index 000000000..c0bae1207 --- /dev/null +++ b/cmake/MatsdkFetchCurl.cmake @@ -0,0 +1,129 @@ +include(FetchContent) + +function(matsdk_fetch_curl out_target) + if(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") + message(FATAL_ERROR + "MATSDK_CURL_PROVIDER=FETCH is currently supported only on Linux. " + "Use MATSDK_CURL_PROVIDER=PACKAGE or provide MATSDK_CURL_TARGET for this platform.") + endif() + if(TARGET CURL::libcurl) + message(FATAL_ERROR + "MATSDK_CURL_PROVIDER=FETCH requires owning the CURL::libcurl target, " + "but a target with that name already exists. Use MATSDK_CURL_PROVIDER=PACKAGE " + "or provide MATSDK_CURL_TARGET instead.") + endif() + + set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) + set(CMAKE_POLICY_DEFAULT_CMP0126 NEW) + + foreach(option IN ITEMS + BUILD_SHARED_LIBS + BUILD_TESTING + ENABLE_PROGRAMS + ENABLE_TESTING + GEN_FILES + UNSAFE_BUILD + INSTALL_MBEDTLS_HEADERS + MBEDTLS_FATAL_WARNINGS + USE_SHARED_MBEDTLS_LIBRARY + LINK_WITH_PTHREAD + BUILD_CURL_EXE + BUILD_EXAMPLES + BUILD_LIBCURL_DOCS + BUILD_MISC_DOCS + ENABLE_CURL_MANUAL + CURL_ENABLE_EXPORT_TARGET + CURL_USE_OPENSSL + CURL_USE_PKGCONFIG + CURL_USE_CMAKECONFIG + CURL_ZLIB + CURL_BROTLI + CURL_ZSTD + USE_LIBIDN2 + CURL_USE_LIBPSL + CURL_USE_LIBSSH2 + CURL_USE_LIBSSH + CURL_USE_GSSAPI + CURL_USE_GSASL + USE_NGHTTP2 + USE_NGTCP2 + USE_QUICHE + ENABLE_ARES + ENABLE_UNIX_SOCKETS) + set(${option} OFF) + endforeach() + + foreach(option IN ITEMS + BUILD_STATIC_LIBS + DISABLE_PACKAGE_CONFIG_AND_INSTALL + CURL_DISABLE_INSTALL + HTTP_ONLY + CURL_DISABLE_ALTSVC + CURL_DISABLE_HSTS + CURL_DISABLE_COOKIES + CURL_DISABLE_NETRC + CURL_DISABLE_MIME + CURL_DISABLE_DOH + CURL_DISABLE_AWS + CURL_DISABLE_BEARER_AUTH + CURL_DISABLE_DIGEST_AUTH + CURL_DISABLE_KERBEROS_AUTH + CURL_DISABLE_NEGOTIATE_AUTH) + set(${option} ON) + endforeach() + + set(CURL_CA_BUNDLE none) + set(CURL_CA_PATH none) + + if(MATSDK_CURL_TLS_BACKEND_UPPER STREQUAL "MBEDTLS") + set(USE_STATIC_MBEDTLS_LIBRARY ON) + set(CURL_USE_MBEDTLS ON) + set(HAVE_MBEDTLS_DES_CRYPT_ECB ON) + set(MBEDTLS_CONFIG_FILE "") + set(MBEDTLS_USER_CONFIG_FILE "") + + FetchContent_Declare( + matsdk_mbedtls + URL ${MATSDK_MBEDTLS_URL} + URL_HASH SHA1=${MATSDK_MBEDTLS_SHA1}) + FetchContent_MakeAvailable(matsdk_mbedtls) + + foreach(target mbedtls mbedx509 mbedcrypto) + if(NOT TARGET ${target}) + message(FATAL_ERROR "Embedded mbedTLS dependency target not found: ${target}") + endif() + set_target_properties(${target} PROPERTIES + POSITION_INDEPENDENT_CODE ON + C_VISIBILITY_PRESET hidden) + target_compile_options(${target} PRIVATE + $<$:-ffunction-sections;-fdata-sections>) + endforeach() + + set(MBEDTLS_INCLUDE_DIR "${matsdk_mbedtls_SOURCE_DIR}/include") + set(MBEDTLS_LIBRARY MbedTLS::mbedtls) + set(MBEDX509_LIBRARY MbedTLS::mbedx509) + set(MBEDCRYPTO_LIBRARY MbedTLS::mbedcrypto) + set(MBEDTLS_USE_STATIC_LIBS ON) + elseif(MATSDK_CURL_TLS_BACKEND_UPPER STREQUAL "OPENSSL") + set(CURL_USE_OPENSSL ON) + find_package(OpenSSL REQUIRED) + endif() + + FetchContent_Declare( + matsdk_curl + URL ${MATSDK_CURL_URL} + URL_HASH SHA1=${MATSDK_CURL_SHA1}) + FetchContent_MakeAvailable(matsdk_curl) + + if(NOT TARGET CURL::libcurl OR NOT TARGET libcurl_static) + message(FATAL_ERROR "The embedded static CURL::libcurl target was not created.") + endif() + + set_target_properties(libcurl_static PROPERTIES + POSITION_INDEPENDENT_CODE ON + C_VISIBILITY_PRESET hidden) + target_compile_options(libcurl_static PRIVATE + $<$:-ffunction-sections;-fdata-sections>) + + set(${out_target} CURL::libcurl PARENT_SCOPE) +endfunction() diff --git a/docs/embedding-with-cmake.md b/docs/embedding-with-cmake.md index f68d124e6..a28d8f18b 100644 --- a/docs/embedding-with-cmake.md +++ b/docs/embedding-with-cmake.md @@ -21,8 +21,23 @@ SDK's internal dependencies directly. When the CPP11 PAL uses the curl HTTP transport outside vcpkg, the SDK normally calls `find_package(CURL)` and links `CURL::libcurl` when that imported target is -available. Non-vcpkg Linux builds similarly use `find_package()` for zlib and -SQLite unless the minimal bundled SQLite option is enabled. +available. On Linux, set `MATSDK_CURL_PROVIDER=FETCH` to let the SDK download and +build a pinned static curl dependency instead: + +```cmake +set(MATSDK_CURL_PROVIDER FETCH CACHE STRING "" FORCE) +set(MATSDK_CURL_TLS_BACKEND MBEDTLS CACHE STRING "" FORCE) # or OPENSSL +add_subdirectory(cpp_client_telemetry) + +target_link_libraries(your_target PRIVATE MSTelemetry::mat) +``` + +The default fetched backend is mbedTLS and is fully self-contained. Selecting +`OPENSSL` builds curl from source but still requires the parent build environment +to provide OpenSSL through `find_package(OpenSSL)`. + +Non-vcpkg Linux builds similarly use `find_package()` for zlib and SQLite unless +the minimal bundled SQLite option is enabled. To make a superbuild choose the dependency implementation (for example, libcurl built with OpenSSL vs. mbedTLS) without changing the leaf consumer target, define From e9864140cc5c5cdbb2eb4bdb2ccf738c5d960fd4 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 28 Jul 2026 05:01:09 -0500 Subject: [PATCH 3/9] Address Copilot review for fetched curl embedding Use SHA256 URL_HASH pins for fetched curl and mbedTLS instead of SHA1, matching FetchContent's stronger integrity checks. Do not override CURL_CA_BUNDLE/CURL_CA_PATH to none; allow fetched curl to use normal CA discovery so default TLS verification can succeed without every consumer supplying CAINFO. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b12c5862-01e3-45e4-bf91-6389c20cae41 --- CMakeLists.txt | 8 ++++---- cmake/MatsdkFetchCurl.cmake | 7 ++----- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 77ab655fa..e7296e6e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -371,12 +371,12 @@ set(MATSDK_CURL_TLS_BACKEND "MBEDTLS" CACHE STRING set_property(CACHE MATSDK_CURL_TLS_BACKEND PROPERTY STRINGS MBEDTLS OPENSSL) set(MATSDK_CURL_URL "https://github.com/curl/curl/releases/download/curl-8_21_0/curl-8.21.0.tar.xz" CACHE STRING "URL for MATSDK_CURL_PROVIDER=FETCH") -set(MATSDK_CURL_SHA1 "c3b4712175609f1e1662e716efd4fd48901e863d" CACHE STRING - "SHA1 for MATSDK_CURL_URL") +set(MATSDK_CURL_SHA256 "aa1b66a70eace83dc624508745646c08ae561de512ab403adffb93ac87fc72e6" CACHE STRING + "SHA256 for MATSDK_CURL_URL") set(MATSDK_MBEDTLS_URL "https://github.com/Mbed-TLS/mbedtls/releases/download/mbedtls-3.6.7/mbedtls-3.6.7.tar.bz2" CACHE STRING "URL for the mbedTLS dependency used by MATSDK_CURL_PROVIDER=FETCH and MATSDK_CURL_TLS_BACKEND=MBEDTLS") -set(MATSDK_MBEDTLS_SHA1 "e892e98cff90cf7e0736c525bf357626a2513c4c" CACHE STRING - "SHA1 for MATSDK_MBEDTLS_URL") +set(MATSDK_MBEDTLS_SHA256 "a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6" CACHE STRING + "SHA256 for MATSDK_MBEDTLS_URL") set(MATSDK_SQLITE_TARGET "" CACHE STRING "Optional existing CMake target to use for SQLite in non-vcpkg builds, instead of find_package(SQLite3)") set(MATSDK_ZLIB_TARGET "" CACHE STRING diff --git a/cmake/MatsdkFetchCurl.cmake b/cmake/MatsdkFetchCurl.cmake index c0bae1207..e37dd1a4f 100644 --- a/cmake/MatsdkFetchCurl.cmake +++ b/cmake/MatsdkFetchCurl.cmake @@ -72,9 +72,6 @@ function(matsdk_fetch_curl out_target) set(${option} ON) endforeach() - set(CURL_CA_BUNDLE none) - set(CURL_CA_PATH none) - if(MATSDK_CURL_TLS_BACKEND_UPPER STREQUAL "MBEDTLS") set(USE_STATIC_MBEDTLS_LIBRARY ON) set(CURL_USE_MBEDTLS ON) @@ -85,7 +82,7 @@ function(matsdk_fetch_curl out_target) FetchContent_Declare( matsdk_mbedtls URL ${MATSDK_MBEDTLS_URL} - URL_HASH SHA1=${MATSDK_MBEDTLS_SHA1}) + URL_HASH SHA256=${MATSDK_MBEDTLS_SHA256}) FetchContent_MakeAvailable(matsdk_mbedtls) foreach(target mbedtls mbedx509 mbedcrypto) @@ -112,7 +109,7 @@ function(matsdk_fetch_curl out_target) FetchContent_Declare( matsdk_curl URL ${MATSDK_CURL_URL} - URL_HASH SHA1=${MATSDK_CURL_SHA1}) + URL_HASH SHA256=${MATSDK_CURL_SHA256}) FetchContent_MakeAvailable(matsdk_curl) if(NOT TARGET CURL::libcurl OR NOT TARGET libcurl_static) From 9df5b11444e8403e32bec98a3886a4f5e25551de Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 28 Jul 2026 14:15:05 -0500 Subject: [PATCH 4/9] Harden curl capability handling in embedded builds Select HTTP/2 only when the linked curl runtime advertises support and otherwise request HTTP/1.1, so minimal fetched curl builds do not force an unavailable protocol. Check curl option/getinfo failures, preserve constructor configuration errors, and use the correct response-code/socket types before sending. Also fix the conventional calloc argument ordering in EventProperties while bundling small correctness work with the larger embedding PR. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b12c5862-01e3-45e4-bf91-6389c20cae41 --- lib/http/HttpClient_Curl.hpp | 201 +++++++++++++++++------- lib/system/EventProperties.cpp | 3 +- tests/unittests/HttpClientCurlTests.cpp | 9 ++ 3 files changed, 157 insertions(+), 56 deletions(-) diff --git a/lib/http/HttpClient_Curl.hpp b/lib/http/HttpClient_Curl.hpp index b1bb5344c..446bcd8a3 100644 --- a/lib/http/HttpClient_Curl.hpp +++ b/lib/http/HttpClient_Curl.hpp @@ -71,6 +71,13 @@ class HttpClient_Curl : public IHttpClient { class CurlHttpOperation { public: + static long GetPreferredHttpVersion() + { + const curl_version_info_data* versionInfo = curl_version_info(CURLVERSION_NOW); + return (versionInfo != nullptr && (versionInfo->features & CURL_VERSION_HTTP2) != 0) + ? CURL_HTTP_VERSION_2_0 + : CURL_HTTP_VERSION_1_1; + } void DispatchEvent(HttpStateEvent type) { @@ -134,21 +141,35 @@ class CurlHttpOperation { #if 0 // Be verbose - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + if (!SetOption(CURLOPT_VERBOSE, 1L)) #else - curl_easy_setopt(curl, CURLOPT_VERBOSE, 0); + if (!SetOption(CURLOPT_VERBOSE, 0L)) #endif + { + DispatchEvent(OnCreateFailed); + return; + } // Specify target URL - curl_easy_setopt(curl, CURLOPT_URL, m_url.c_str()); + if (!SetOption(CURLOPT_URL, m_url.c_str()) + || !SetOption(CURLOPT_SSL_VERIFYPEER, sslVerify ? 1L : 0L) + || !SetOption(CURLOPT_SSL_VERIFYHOST, sslVerify ? 2L : 0L)) + { + DispatchEvent(OnCreateFailed); + return; + } - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, sslVerify ? 1L : 0L); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, sslVerify ? 2L : 0L); - if (!m_sslCaInfo.empty()) { - curl_easy_setopt(curl, CURLOPT_CAINFO, m_sslCaInfo.c_str()); + if (!m_sslCaInfo.empty() && !SetOption(CURLOPT_CAINFO, m_sslCaInfo.c_str())) + { + DispatchEvent(OnCreateFailed); + return; + } + + if (!SetOption(CURLOPT_HTTP_VERSION, GetPreferredHttpVersion())) + { + DispatchEvent(OnCreateFailed); + return; } - // HTTP/2 please, fallback to HTTP/1.1 if not supported - curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); // Headers are copied into m_headersChunk during construction and the // curl_slist is kept alive until destruction, so the original map does @@ -156,15 +177,24 @@ class CurlHttpOperation { for (const auto& kv : requestHeaders) { std::string header = kv.first + ": " + kv.second; - m_headersChunk = curl_slist_append(m_headersChunk, header.c_str()); + curl_slist* appended = curl_slist_append(m_headersChunk, header.c_str()); + if (appended == nullptr) + { + res = CURLE_OUT_OF_MEMORY; + DispatchEvent(OnCreateFailed); + return; + } + m_headersChunk = appended; } - if(m_headersChunk != nullptr) + if(m_headersChunk != nullptr && !SetOption(CURLOPT_HTTPHEADER, m_headersChunk)) { - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, m_headersChunk); + DispatchEvent(OnCreateFailed); + return; } TRACE("method=%s, url=%s\n", this->m_method.c_str(), this->m_url.c_str()); + m_isConfigured = true; DispatchEvent(OnCreated); } @@ -181,7 +211,10 @@ class CurlHttpOperation { } DispatchEvent(OnDestroy); res = CURLE_OK; - curl_easy_cleanup(curl); + if (curl != nullptr) + { + curl_easy_cleanup(curl); + } curl_slist_free_all(m_headersChunk); ReleaseResponse(); } @@ -198,9 +231,12 @@ class CurlHttpOperation { const void *request = requestBody.empty() ? nullptr : requestBody.data(); const size_t reqSize = requestBody.size(); - if(!curl) + if(!curl || !m_isConfigured) { - res = CURLE_FAILED_INIT; + if (res == CURLE_OK) + { + res = CURLE_FAILED_INIT; + } DispatchEvent(OnSendFailed); goto cleanup; } @@ -209,32 +245,42 @@ class CurlHttpOperation { // curl_easy_setopt(curl, CURLOPT_LOCALPORT, dcf_port); // Perform initial connect, handling the timeout if needed - curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L); - DispatchEvent(OnConnecting); - res = curl_easy_perform(curl); - if(CURLE_OK != res) + if (!SetOption(CURLOPT_CONNECT_ONLY, 1L)) { - DispatchEvent(OnConnectFailed); // couldn't connect - stage 1 - TRACE("Error #1: %s\n", curl_easy_strerror(res)); + DispatchEvent(OnConnectFailed); goto cleanup; } + DispatchEvent(OnConnecting); + { + const CURLcode curlResult = curl_easy_perform(curl); + res = static_cast(curlResult); + if(CURLE_OK != curlResult) + { + DispatchEvent(OnConnectFailed); // couldn't connect - stage 1 + TRACE("Error #1: %s\n", curl_easy_strerror(curlResult)); + goto cleanup; + } + } - /* Extract the socket from the curl handle - we'll need it for waiting. - * Note that this API takes a pointer to a 'long' while we use - * curl_socket_t for sockets otherwise. - */ - + { + CURLcode infoResult; #if LIBCURL_VERSION_NUM >= 0x072D00 // Version 7.45.00 - res = curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sockextr); + infoResult = curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sockextr); #else - res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockextr); + long lastSocket = -1; + infoResult = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &lastSocket); + if (infoResult == CURLE_OK) + { + sockextr = static_cast(lastSocket); + } #endif - - if(CURLE_OK != res) - { - DispatchEvent(OnConnectFailed); // couldn't connect - stage 2 - TRACE("Error #2: %s\n", curl_easy_strerror(res)); - goto cleanup; + if(CURLE_OK != infoResult) + { + res = static_cast(infoResult); + DispatchEvent(OnConnectFailed); // couldn't connect - stage 2 + TRACE("Error #2: %s\n", curl_easy_strerror(infoResult)); + goto cleanup; + } } /* wait for the socket to become ready for sending */ @@ -248,27 +294,42 @@ class CurlHttpOperation { } // once connection is there - switch back to easy perform for HTTP post - curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 0); + if (!SetOption(CURLOPT_CONNECT_ONLY, 0L)) + { + DispatchEvent(OnSendFailed); + goto cleanup; + } // send all data to our callback function if (rawResponse) { - curl_easy_setopt(curl, CURLOPT_HEADER, true); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (void *)&WriteMemoryCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response); - } else { - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (void *)&WriteVectorCallback); - curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void *)&respHeaders); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&respBody); + if (!SetOption(CURLOPT_HEADER, 1L) + || !SetOption(CURLOPT_WRITEFUNCTION, (void *)&WriteMemoryCallback) + || !SetOption(CURLOPT_WRITEDATA, (void *)&response)) + { + DispatchEvent(OnSendFailed); + goto cleanup; + } + } + else if (!SetOption(CURLOPT_WRITEFUNCTION, (void *)&WriteVectorCallback) + || !SetOption(CURLOPT_HEADERDATA, (void *)&respHeaders) + || !SetOption(CURLOPT_WRITEDATA, (void *)&respBody)) + { + DispatchEvent(OnSendFailed); + goto cleanup; } // TODO: only two methods supported for now - POST and GET if (m_method.compare("POST") == 0) { // POST - curl_easy_setopt(curl, CURLOPT_POST, true); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, static_cast(request)); - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, reqSize); + if (!SetOption(CURLOPT_POST, 1L) + || !SetOption(CURLOPT_POSTFIELDS, static_cast(request)) + || !SetOption(CURLOPT_POSTFIELDSIZE_LARGE, static_cast(reqSize))) + { + DispatchEvent(OnSendFailed); + goto cleanup; + } } else if (m_method.compare("GET") == 0) { @@ -280,16 +341,23 @@ class CurlHttpOperation { goto cleanup; } - curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 30L); - curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 4096); - DispatchEvent(OnSending); - res = curl_easy_perform(curl); - if(CURLE_OK != res) + if (!SetOption(CURLOPT_LOW_SPEED_TIME, 30L) + || !SetOption(CURLOPT_LOW_SPEED_LIMIT, 4096L)) { DispatchEvent(OnSendFailed); - TRACE("Error: %s\n", curl_easy_strerror(res)); goto cleanup; } + DispatchEvent(OnSending); + { + const CURLcode curlResult = curl_easy_perform(curl); + res = static_cast(curlResult); + if(CURLE_OK != curlResult) + { + DispatchEvent(OnSendFailed); + TRACE("Error: %s\n", curl_easy_strerror(curlResult)); + goto cleanup; + } + } /* Code snippet to parse raw HTTP response. This might come in handy * if we ever consider to handle the raw upload instead of curl_easy_perform @@ -303,7 +371,17 @@ class CurlHttpOperation { */ /* libcurl is nice enough to parse the response code itself: */ - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res); + { + long responseCode = 0; + const CURLcode infoResult = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode); + if (infoResult != CURLE_OK) + { + res = static_cast(infoResult); + DispatchEvent(OnSendFailed); + goto cleanup; + } + res = responseCode; + } // We got some response from server. Dump the contents. TRACE("HTTP response code %d\n", res); DispatchEvent(OnResponse); @@ -436,7 +514,7 @@ class CurlHttpOperation { const size_t httpConnTimeout; // Timeout for connect. Default: 5s CURL *curl; // Local curl instance - CURLcode res = CURLE_OK; // Curl result OR HTTP status code if successful + long res = CURLE_OK; // Curl result OR HTTP status code if successful IHttpResponseCallback* m_callback = nullptr; @@ -444,6 +522,7 @@ class CurlHttpOperation { std::string m_method; std::string m_url; std::string m_sslCaInfo; + bool m_isConfigured = false; // The SDK upload path keeps the owning IHttpRequest alive through the // callback context until Send() completes; copying this body would duplicate // every upload payload. Unlike CURLOPT_CAINFO, the body pointer is set and @@ -458,7 +537,7 @@ class CurlHttpOperation { // Socket parameters curl_socket_t sockfd = 0; - long sockextr = 0; + curl_socket_t sockextr = CURL_SOCKET_BAD; curl_off_t nread = 0; size_t sendlen = 0; // # bytes sent by client @@ -466,6 +545,20 @@ class CurlHttpOperation { std::future result; + template + bool SetOption(CURLoption option, TValue value) + { + const CURLcode optionResult = curl_easy_setopt(curl, option, value); + if (optionResult != CURLE_OK) + { + res = static_cast(optionResult); + TRACE("curl_easy_setopt(%d) failed: %s\n", + static_cast(option), curl_easy_strerror(optionResult)); + return false; + } + return true; + } + /** * Helper routine to wait for data on socket * diff --git a/lib/system/EventProperties.cpp b/lib/system/EventProperties.cpp index 2ade77741..71d5f4c5b 100644 --- a/lib/system/EventProperties.cpp +++ b/lib/system/EventProperties.cpp @@ -474,7 +474,7 @@ namespace MAT_NS_BEGIN { evt_prop* EventProperties::pack() { size_t size = m_storage->properties.size() + m_storage->propertiesPartB.size() + 1; - evt_prop * result = static_cast(calloc(sizeof(evt_prop), size)); + evt_prop * result = static_cast(calloc(size, sizeof(evt_prop))); if (result==nullptr) { LOG_ERROR("Unable to allocate memory to pack EventProperties"); @@ -620,4 +620,3 @@ namespace MAT_NS_BEGIN { } MAT_NS_END - diff --git a/tests/unittests/HttpClientCurlTests.cpp b/tests/unittests/HttpClientCurlTests.cpp index c9894b90d..f57788670 100644 --- a/tests/unittests/HttpClientCurlTests.cpp +++ b/tests/unittests/HttpClientCurlTests.cpp @@ -56,6 +56,15 @@ TEST_F(HttpClientCurlTests, CurlHttpOperation_ConstructsWithCaInfo) ASSERT_NE(op.GetHandle(), nullptr); } +TEST(HttpClientCurlOperationTests, SelectsHttp2OnlyWhenRuntimeSupportsIt) +{ + const curl_version_info_data* versionInfo = curl_version_info(CURLVERSION_NOW); + const long expected = (versionInfo != nullptr && (versionInfo->features & CURL_VERSION_HTTP2) != 0) + ? CURL_HTTP_VERSION_2_0 + : CURL_HTTP_VERSION_1_1; + EXPECT_EQ(CurlHttpOperation::GetPreferredHttpVersion(), expected); +} + // --- ILogConfiguration integration --- TEST(HttpClientCurlConfigTests, LogConfiguration_SslVerify_DefaultIsTrue) From ca5a967badb2a8bc8858ff4ef16a7fe7e5e858d8 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 28 Jul 2026 18:26:59 -0500 Subject: [PATCH 5/9] Modernize CMake embedding and portability Bundle the remaining embedding work into PR #1511 so downstream projects can consume one stable target without source rewrites or platform-specific dependency glue. Key changes: - use standard CMAKE_OSX_* architecture/sysroot/deployment settings with legacy input compatibility; - add canonical MATSDK_* build options and explicit STATIC/SHARED library selection; - make warnings, Werror, ARC, visibility, and dead-strip policy target-local; - add explicit SYSTEM/MINIMAL/VENDORED SQLite and zlib providers with self-contained static installs; - preserve static/dynamic and pinned-source vcpkg compatibility; - add FetchContent consumer CI for Linux, Windows, macOS universal/arm64, iOS device/simulator, and Android under warnings-as-errors; - update build scripts/docs and route legacy installation through cmake --install. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b12c5862-01e3-45e4-bf91-6389c20cae41 --- .github/workflows/test-embedding.yml | 144 ++++++ CMakeLists.txt | 429 +++++------------- README.md | 1 + build-ios.sh | 6 +- build.sh | 15 +- cmake/MSTelemetryConfig.cmake.in | 18 +- cmake/MatsdkFetchCurl.cmake | 6 + cmake/MatsdkOptions.cmake | 167 +++++++ docs/building-with-vcpkg.md | 4 +- docs/cpp-start-ios.md | 20 + docs/cpp-start-macosx.md | 18 +- docs/embedding-with-cmake.md | 44 +- docs/sharing-a-single-sdk-runtime.md | 2 +- install.sh | 14 +- lib/CMakeLists.txt | 344 +++++++------- .../posix/DeviceInformationImpl_Android.cpp | 5 +- .../posix/NetworkInformationImpl_Android.cpp | 7 +- .../posix/SystemInformationImpl_Android.cpp | 5 +- tests/CMakeLists.txt | 4 +- tests/embedding/CMakeLists.txt | 32 +- tests/functests/CMakeLists.txt | 38 +- tests/unittests/CMakeLists.txt | 38 +- .../ports/cpp-client-telemetry/portfile.cmake | 27 +- 23 files changed, 802 insertions(+), 586 deletions(-) create mode 100644 .github/workflows/test-embedding.yml create mode 100644 cmake/MatsdkOptions.cmake diff --git a/.github/workflows/test-embedding.yml b/.github/workflows/test-embedding.yml new file mode 100644 index 000000000..f1049da92 --- /dev/null +++ b/.github/workflows/test-embedding.yml @@ -0,0 +1,144 @@ +name: Source embedding matrix + +on: + push: + branches: + - main + - master + - dev + pull_request: + branches: + - main + - master + - dev + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + linux: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - dependencies: system + library-type: STATIC + fetchcontent: OFF + - dependencies: system + library-type: SHARED + fetchcontent: ON + - dependencies: self-contained + library-type: STATIC + fetchcontent: ON + steps: + - uses: actions/checkout@v4 + - name: Install system dependencies + if: matrix.dependencies == 'system' + run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev libsqlite3-dev ninja-build zlib1g-dev + - name: Configure + shell: bash + run: | + options=( + -G Ninja + -S tests/embedding + -B build-embedding + -DCMAKE_BUILD_TYPE=Release + -DMATSDK_EMBEDDING_USE_FETCHCONTENT=${{ matrix.fetchcontent }} + -DMATSDK_LIBRARY_TYPE=${{ matrix.library-type }} + ) + if [[ "${{ matrix.dependencies }}" == "self-contained" ]]; then + options+=( + -DMATSDK_CURL_PROVIDER=FETCH + -DMATSDK_CURL_TLS_BACKEND=MBEDTLS + -DMATSDK_SQLITE_PROVIDER=MINIMAL + -DMATSDK_ZLIB_PROVIDER=VENDORED + ) + else + options+=( + -DMATSDK_SQLITE_PROVIDER=SYSTEM + -DMATSDK_ZLIB_PROVIDER=SYSTEM + ) + fi + cmake "${options[@]}" + - name: Build and run + run: | + cmake --build build-embedding --target embedding_test --parallel 4 + ./build-embedding/embedding_test + + windows: + runs-on: windows-2022 + steps: + - uses: actions/checkout@v4 + - name: Configure + run: > + cmake -S tests/embedding -B build-embedding -A x64 + -DMATSDK_EMBEDDING_USE_FETCHCONTENT=ON + -DMATSDK_SQLITE_PROVIDER=VENDORED + -DMATSDK_ZLIB_PROVIDER=VENDORED + - name: Build and run + shell: pwsh + run: | + cmake --build build-embedding --config Release --target embedding_test -- /m + & .\build-embedding\Release\embedding_test.exe + + macos: + runs-on: macos-latest + strategy: + matrix: + architectures: [arm64, "arm64;x86_64"] + steps: + - uses: actions/checkout@v4 + - name: Configure + run: > + cmake -G Ninja -S tests/embedding -B build-embedding + -DCMAKE_BUILD_TYPE=Release + "-DCMAKE_OSX_ARCHITECTURES=${{ matrix.architectures }}" + -DMATSDK_EMBEDDING_USE_FETCHCONTENT=ON + -DMATSDK_SQLITE_PROVIDER=SYSTEM + -DMATSDK_ZLIB_PROVIDER=SYSTEM + - name: Build + run: cmake --build build-embedding --target embedding_test --parallel 4 + + ios: + runs-on: macos-latest + strategy: + matrix: + sdk: [iphoneos, iphonesimulator] + steps: + - uses: actions/checkout@v4 + - name: Configure + run: > + cmake -G Xcode -S tests/embedding -B build-embedding + -DCMAKE_SYSTEM_NAME=iOS + -DCMAKE_OSX_SYSROOT=${{ matrix.sdk }} + -DCMAKE_OSX_ARCHITECTURES=arm64 + -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 + -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=NO + -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=NO + -DMATSDK_BUILD_IOS=ON + -DMATSDK_EMBEDDING_USE_FETCHCONTENT=ON + -DMATSDK_SQLITE_PROVIDER=SYSTEM + -DMATSDK_ZLIB_PROVIDER=SYSTEM + - name: Build + run: cmake --build build-embedding --config Release --target embedding_test --parallel 4 + + android: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Configure + run: > + cmake -G Ninja -S tests/embedding -B build-embedding + -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_LATEST_HOME}/build/cmake/android.toolchain.cmake + -DANDROID_ABI=arm64-v8a + -DANDROID_PLATFORM=23 + -DCMAKE_BUILD_TYPE=Release + -DMATSDK_EMBEDDING_USE_FETCHCONTENT=ON + -DMATSDK_SQLITE_PROVIDER=VENDORED + -DMATSDK_ZLIB_PROVIDER=VENDORED + - name: Build + run: cmake --build build-embedding --target embedding_test --parallel 4 diff --git a/CMakeLists.txt b/CMakeLists.txt index e7296e6e2..fa5950633 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,32 @@ cmake_minimum_required(VERSION 3.15...3.31) + +# Backward-compatible translation for legacy Apple build scripts. Standard +# CMAKE_OSX_* variables are the canonical interface and must be initialized +# before project() so CMake's compiler/platform detection sees them. +if(NOT DEFINED CMAKE_OSX_ARCHITECTURES) + if(DEFINED IOS_ARCH AND NOT IOS_ARCH STREQUAL "") + set(CMAKE_OSX_ARCHITECTURES "${IOS_ARCH}" CACHE STRING + "Apple target architectures" FORCE) + elseif(DEFINED MAC_ARCH AND NOT MAC_ARCH STREQUAL "") + if(MAC_ARCH STREQUAL "universal") + set(_matsdk_legacy_apple_architectures "arm64;x86_64") + else() + set(_matsdk_legacy_apple_architectures "${MAC_ARCH}") + endif() + set(CMAKE_OSX_ARCHITECTURES "${_matsdk_legacy_apple_architectures}" CACHE STRING + "Apple target architectures" FORCE) + endif() +endif() +if(NOT DEFINED CMAKE_OSX_SYSROOT AND DEFINED IOS_PLAT AND NOT IOS_PLAT STREQUAL "") + set(CMAKE_OSX_SYSROOT "${IOS_PLAT}" CACHE STRING "Apple SDK sysroot" FORCE) +endif() +if(NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET + AND DEFINED IOS_DEPLOYMENT_TARGET + AND NOT IOS_DEPLOYMENT_TARGET STREQUAL "") + set(CMAKE_OSX_DEPLOYMENT_TARGET "${IOS_DEPLOYMENT_TARGET}" CACHE STRING + "Apple deployment target" FORCE) +endif() + project(MSTelemetry LANGUAGES C CXX) ################################################################################################ @@ -11,15 +39,12 @@ 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}") +set(MATSDK_SQLITE_TARGET "" CACHE STRING + "Optional existing CMake target to use for SQLite in non-vcpkg builds, instead of find_package(SQLite3)") +set(MATSDK_ZLIB_TARGET "" CACHE STRING + "Optional existing CMake target to use for zlib in non-vcpkg builds, instead of find_package(ZLIB)") + +include(cmake/MatsdkOptions.cmake) # Begin Uncomment for i386 build #set(CMAKE_SYSTEM_PROCESSOR i386) @@ -34,104 +59,20 @@ if (NOT TARGET_ARCH) set(TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR}) endif() -# Enable ARC for obj-c on Apple -# Initialize platform options before conditional blocks (needed for config templates) -if(NOT DEFINED BUILD_IOS) - set(BUILD_IOS OFF) -endif() -if(NOT APPLE AND NOT DEFINED BUILD_APPLE_HTTP) - set(BUILD_APPLE_HTTP OFF) -endif() - if(APPLE) - message(STATUS "BUILD_IOS: ${BUILD_IOS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fobjc-arc") - - # iOS build options - option(BUILD_IOS "Build for iOS" NO) - option(FORCE_RESET_OSX_DEPLOYMENT_TARGET "Clear the OSX Deployment Target Set" YES) - if (DEFINED FORCE_RESET_DEPLOYMENT_TARGET) - set(FORCE_RESET_OSX_DEPLOYMENT_TARGET ${FORCE_RESET_DEPLOYMENT_TARGET}) - endif() - - # When building via vcpkg, the toolchain file handles architecture, sysroot, - # deployment target, and platform flags. Skip manual flag configuration. - if(NOT MATSDK_USE_VCPKG_DEPS) - if(BUILD_IOS) - set(TARGET_ARCH "APPLE") - set(IOS True) - set(APPLE True) - - if(FORCE_RESET_OSX_DEPLOYMENT_TARGET) - set(CMAKE_OSX_DEPLOYMENT_TARGET "" CACHE STRING "Force unset of the deployment target for iOS" FORCE) - if (${IOS_PLAT} STREQUAL "iphonesimulator") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mios-simulator-version-min=${IOS_DEPLOYMENT_TARGET}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mios-simulator-version-min=${IOS_DEPLOYMENT_TARGET}") - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -miphoneos-version-min=${IOS_DEPLOYMENT_TARGET}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -miphoneos-version-min=${IOS_DEPLOYMENT_TARGET}") - endif() - endif() - - if((${IOS_PLAT} STREQUAL "iphoneos") OR (${IOS_PLAT} STREQUAL "iphonesimulator") OR (${IOS_PLAT} STREQUAL "xros") OR (${IOS_PLAT} STREQUAL "xrsimulator")) - set(IOS_PLATFORM "${IOS_PLAT}") - else() - message(FATAL_ERROR "Unrecognized iOS platform '${IOS_PLAT}'") - endif() - - if(${IOS_ARCH} STREQUAL "x86_64") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch x86_64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch x86_64") - set(CMAKE_SYSTEM_PROCESSOR x86_64) - elseif(${IOS_ARCH} STREQUAL "arm64") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch arm64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch arm64") - set(CMAKE_SYSTEM_PROCESSOR arm64) - elseif(${IOS_ARCH} STREQUAL "arm64e") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch arm64e") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch arm64e") - set(CMAKE_SYSTEM_PROCESSOR arm64e) - else() - message(FATAL_ERROR "Unrecognized iOS architecture '${IOS_ARCH}'") - endif() - - execute_process(COMMAND xcodebuild -version -sdk ${IOS_PLATFORM} ONLY_ACTIVE_ARCH=NO Path - OUTPUT_VARIABLE CMAKE_OSX_SYSROOT - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - message(STATUS "CMAKE_OSX_SYSROOT ${CMAKE_OSX_SYSROOT}") - message(STATUS "ARCHITECTURE: ${CMAKE_SYSTEM_PROCESSOR}") - message(STATUS "PLATFORM: ${IOS_PLATFORM}") - else() - if("${MAC_ARCH}" STREQUAL "x86_64") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch x86_64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch x86_64") - set(CMAKE_SYSTEM_PROCESSOR x86_64) - set(TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR}) - set(CMAKE_OSX_ARCHITECTURES ${MAC_ARCH}) - set(APPLE True) - elseif("${MAC_ARCH}" STREQUAL "arm64") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch arm64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch arm64") - set(CMAKE_SYSTEM_PROCESSOR arm64) - set(TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR}) - set(CMAKE_OSX_ARCHITECTURES ${MAC_ARCH}) - set(APPLE True) - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch x86_64 -arch arm64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch x86_64 -arch arm64") - endif() - message(STATUS "MAC_ARCH: ${MAC_ARCH}") - endif() - else() - # vcpkg mode: just set internal flags from what the toolchain provides - if(BUILD_IOS OR CMAKE_SYSTEM_NAME STREQUAL "iOS") - set(BUILD_IOS ON) - set(TARGET_ARCH "APPLE") - set(IOS True) - endif() - message(STATUS "vcpkg toolchain managing architecture and platform flags") + if(MATSDK_BUILD_IOS + OR CMAKE_SYSTEM_NAME STREQUAL "iOS" + OR CMAKE_SYSTEM_NAME STREQUAL "visionOS") + set(MATSDK_BUILD_IOS ON) + set(TARGET_ARCH "APPLE") + set(IOS TRUE) + elseif(CMAKE_OSX_ARCHITECTURES) + set(TARGET_ARCH "${CMAKE_OSX_ARCHITECTURES}") endif() + message(STATUS "MATSDK_BUILD_IOS: ${MATSDK_BUILD_IOS}") + message(STATUS "CMAKE_OSX_ARCHITECTURES: ${CMAKE_OSX_ARCHITECTURES}") + message(STATUS "CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT}") + message(STATUS "CMAKE_OSX_DEPLOYMENT_TARGET: ${CMAKE_OSX_DEPLOYMENT_TARGET}") endif() message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}") @@ -144,126 +85,41 @@ message(STATUS "CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}") include(tools/ParseOsRelease.cmake) -# When building via vcpkg, let the toolchain manage compiler flags. -# Only apply project-specific flags for non-vcpkg (legacy) builds. -if(NOT MATSDK_USE_VCPKG_DEPS) - -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - set(WARN_FLAGS "/W4 /WX") -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - # -Wno-unknown-warning-option is Clang-only, omitted here - set(WARN_FLAGS "-Wall -Werror -Wextra -Wno-unused-parameter -Wno-unused-but-set-variable") -else() - # Clang / AppleClang - set(WARN_FLAGS "-Wall -Werror -Wextra -Wno-unused-parameter -Wno-unknown-warning-option -Wno-unused-but-set-variable") -endif() - -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - # Using GCC with -s and -Wl linker flags. -ffunction-sections/-fdata-sections - # are set once for all dep modes by the global block further below. - set(REL_FLAGS "-s -Wl,--gc-sections -Os ${WARN_FLAGS} -fmerge-all-constants") -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - set(REL_FLAGS "${WARN_FLAGS}") -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") - set(REL_FLAGS "-Os ${WARN_FLAGS} -fmerge-all-constants") -else() - # Using clang - strip unsupported GCC options (-ffunction-sections is set by - # the global block further below). - set(REL_FLAGS "-Os ${WARN_FLAGS} -fmerge-all-constants") -endif() - -## Uncomment this to reduce the volume of note warnings on RPi4 w/gcc-8 Ref. https://gcc.gnu.org/ml/gcc/2017-05/msg00073.html -#if (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l") -# set(WARN_FLAGS "${WARN_FLAGS} -Wno-psabi" -#endif() - -# Use libtcmalloc for Debug builds memory leaks detection -set(DBG_FLAGS "-ggdb -gdwarf-2 -O0 ${WARN_FLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free") - -if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - #TODO: -fno-rtti - message(STATUS "Building Release ...") - set(CMAKE_C_FLAGS "$ENV{CFLAGS} ${CMAKE_C_FLAGS} -std=c11 ${REL_FLAGS}") - set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} ${CMAKE_CXX_FLAGS} -std=c++11 ${REL_FLAGS}") -else() - set(USE_TCMALLOC 1) - message(STATUS "Building Debug ...") - include(tools/FindTcmalloc.cmake) - set(CMAKE_C_FLAGS "$ENV{CFLAGS} ${CMAKE_C_FLAGS} -std=c11 ${DBG_FLAGS}") - set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} ${CMAKE_CXX_FLAGS} -std=c++11 ${DBG_FLAGS}") -endif() - -#Remove /Zi for Win32 debug compiler issue -if(MSVC) - string( TOLOWER "${CMAKE_VS_PLATFORM_NAME}" PLATFORM_NAME_LOWER ) - if (PLATFORM_NAME_LOWER STREQUAL "win32") - string(REGEX REPLACE "/Z[iI7]" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") - string(REGEX REPLACE "/Z[iI7]" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") - endif() -endif() - -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - # using Clang -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - # using GCC - # Prefer to generate position-independent code - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") - # using Intel C++ -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - # using Visual Studio C++ -endif() - -endif() # NOT MATSDK_USE_VCPKG_DEPS (compiler flags) - -# --- Dead-strip enablement (applies in BOTH vendored and vcpkg modes) --------- -# Deliberate exception to the "let the toolchain manage compiler flags" note -# above (the NOT MATSDK_USE_VCPKG_DEPS block): these flags are NOT optimization -# or dependency choices the vcpkg toolchain owns -- they only split functions and -# data into separate COMDATs/sections so a *consumer's* linker can drop -# unreferenced SDK code (MSVC /OPT:REF + /OPT:ICF, GNU/Clang --gc-sections, Apple -# ld -dead_strip). The toolchain does not set them, and the vcpkg-packaged -# library (and every MSVC build, which never gets /Gy from the block above) would -# otherwise link whole .obj files instead of individual functions. Applying them -# here in both modes closes that gap and matches the MSBuild Release projects, -# which already enable FunctionLevelLinking + OptimizeReferences + COMDATFolding. +# SDK-owned compiler policy. This interface target is linked PRIVATE by SDK +# targets, so add_subdirectory()/FetchContent consumers and vendored dependency +# targets never inherit the SDK's warning-as-error or optimization policy. +add_library(matsdk_build_options INTERFACE) if(MSVC) - # /Gy (function-level linking) is supported by both cl.exe and clang-cl. - add_compile_options(/Gy) - # /Gw (whole-program global data) is cl.exe-only; the ClangCL toolset (for - # which MSVC is also true) does not support it. - if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - add_compile_options(/Gw) - endif() -elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") - # On Mach-O, clang emits .subsections_via_symbols, so ld64's -dead_strip - # already removes unreferenced code at per-symbol (function) granularity - # without -ffunction-sections; we add it only for cross-toolchain - # consistency. -fdata-sections is omitted because it historically conflicted - # with bitcode on AppleClang. - add_compile_options(-ffunction-sections) + target_compile_options(matsdk_build_options INTERFACE + /W4 + $<$:/WX> + /Gy + $<$:/Gw>) else() - # GCC / Clang (Linux, Android, MinGW) - add_compile_options(-ffunction-sections -fdata-sections) -endif() - -# Hidden symbol visibility (non-Windows): export only the MATSDK_LIBABI-decorated -# public API (classes + the C API), hiding SDK internals and the bundled -# sqlite3/zlib. This shrinks the dynamic symbol table (faster dynamic -# linking/loading, smaller binaries) and enables more inlining + dead-code -# elimination -- the non-Windows analog of what /Gy plus the consumer's /OPT:REF -# achieve on MSVC. All Windows toolchains (MSVC, MinGW, ClangCL) restrict exports -# via __declspec(dllexport) on MATSDK_LIBABI (lib/include/public/ctmacros.hpp), -# so this is gated on NOT WIN32 (not NOT MSVC, which would also catch MinGW/ -# Clang-GNU Windows builds and apply ELF-style visibility that does not belong on -# a PE/COFF target). -if(NOT WIN32) - # -fvisibility=hidden applies to C and C++; -fvisibility-inlines-hidden is a - # C++-only option, so scope it to CXX. (Applying it to C sources -- e.g. the - # bundled sqlite3/zlib on the legacy Android path -- makes Clang emit an - # "unused argument" warning that becomes an error under the project's -Werror.) - add_compile_options(-fvisibility=hidden $<$:-fvisibility-inlines-hidden>) + target_compile_options(matsdk_build_options INTERFACE + -Wall + -Wextra + -Wno-unused-parameter + -Wno-unused-but-set-variable + $<$:-Werror> + $<$:-Wno-unknown-warning-option> + $<$:-Wno-unknown-warning-option> + $<$:-ggdb> + $<$:-gdwarf-2> + $<$:-O0> + $<$:-fno-builtin-malloc> + $<$:-fno-builtin-calloc> + $<$:-fno-builtin-realloc> + $<$:-fno-builtin-free> + $<$>:-Os> + $<$>:-fmerge-all-constants> + -ffunction-sections + $<$>:-fdata-sections>) + if(NOT WIN32) + target_compile_options(matsdk_build_options INTERFACE + -fvisibility=hidden + $<$:-fvisibility-inlines-hidden>) + endif() endif() include(tools/Utils.cmake) @@ -300,10 +156,6 @@ if(USE_ONEDS_SECURE_MEM_FUNCTIONS) add_definitions(-DUSE_ONEDS_SECURE_MEM_FUNCTIONS) endif() -if(PAL_IMPLEMENTATION STREQUAL "WIN32" AND NOT MATSDK_USE_VCPKG_DEPS) - add_definitions(-DZLIB_WINAPI) -endif() - add_definitions(-DNOMINMAX) ################################################################################################ @@ -332,35 +184,8 @@ endif() message(STATUS "SDK version: ${SDK_VERSION_PREFIX}-${MATSDK_BUILD_VERSION}") ################################################################################################ -# User options (must be before HTTP stack section for BUILD_APPLE_HTTP) +# Embedding/dependency options ################################################################################################ -option(BUILD_HEADERS "Build API headers" YES) -option(BUILD_LIBRARY "Build library" YES) -option(BUILD_TEST_TOOL "Build console test tool" YES) -# Default the test suites ON only when this repository is the top-level project -# (developer/CI build), and OFF when it is consumed via add_subdirectory()/ -# FetchContent, so downstream projects don't build the tests or require the -# third_party/googletest submodule. PROJECT_IS_TOP_LEVEL exists on CMake >= 3.21; -# fall back to comparing the source dirs on older CMake (floor is 3.15). -if(DEFINED PROJECT_IS_TOP_LEVEL) - set(MATSDK_TESTS_DEFAULT ${PROJECT_IS_TOP_LEVEL}) -elseif(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - set(MATSDK_TESTS_DEFAULT ON) -else() - set(MATSDK_TESTS_DEFAULT OFF) -endif() -option(BUILD_UNIT_TESTS "Build unit tests" ${MATSDK_TESTS_DEFAULT}) -option(BUILD_FUNC_TESTS "Build functional tests" ${MATSDK_TESTS_DEFAULT}) -option(BUILD_JNI_WRAPPER "Build JNI wrapper" NO) -option(BUILD_OBJC_WRAPPER "Build Obj-C wrapper" YES) -option(BUILD_SWIFT_WRAPPER "Build Swift Wrappers" YES) -option(BUILD_PACKAGE "Build package" YES) -option(BUILD_PRIVACYGUARD "Build Privacy Guard" YES) -option(BUILD_CDS "Build CDS - Common Diagnostic Stack" YES) -option(BUILD_LIVEEVENTINSPECTOR "Build Live Event Inspector" YES) -option(BUILD_SIGNALS "Build Signals" YES) -option(BUILD_SANITIZER "Build Sanitizer" YES) -option(LINK_STATIC_DEPENDS "Link dependencies for static build" YES) set(MATSDK_CURL_TARGET "" CACHE STRING "Optional existing CMake target to use for libcurl in non-vcpkg builds, instead of find_package(CURL)") set(MATSDK_CURL_PROVIDER "PACKAGE" CACHE STRING @@ -377,10 +202,6 @@ set(MATSDK_MBEDTLS_URL "https://github.com/Mbed-TLS/mbedtls/releases/download/mb "URL for the mbedTLS dependency used by MATSDK_CURL_PROVIDER=FETCH and MATSDK_CURL_TLS_BACKEND=MBEDTLS") set(MATSDK_MBEDTLS_SHA256 "a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6" CACHE STRING "SHA256 for MATSDK_MBEDTLS_URL") -set(MATSDK_SQLITE_TARGET "" CACHE STRING - "Optional existing CMake target to use for SQLite in non-vcpkg builds, instead of find_package(SQLite3)") -set(MATSDK_ZLIB_TARGET "" CACHE STRING - "Optional existing CMake target to use for zlib in non-vcpkg builds, instead of find_package(ZLIB)") string(TOUPPER "${MATSDK_CURL_PROVIDER}" MATSDK_CURL_PROVIDER_UPPER) if(NOT MATSDK_CURL_PROVIDER_UPPER STREQUAL "PACKAGE" AND NOT MATSDK_CURL_PROVIDER_UPPER STREQUAL "FETCH") message(FATAL_ERROR "MATSDK_CURL_PROVIDER must be PACKAGE or FETCH; got '${MATSDK_CURL_PROVIDER}'.") @@ -389,6 +210,15 @@ string(TOUPPER "${MATSDK_CURL_TLS_BACKEND}" MATSDK_CURL_TLS_BACKEND_UPPER) if(NOT MATSDK_CURL_TLS_BACKEND_UPPER STREQUAL "MBEDTLS" AND NOT MATSDK_CURL_TLS_BACKEND_UPPER STREQUAL "OPENSSL") message(FATAL_ERROR "MATSDK_CURL_TLS_BACKEND must be MBEDTLS or OPENSSL; got '${MATSDK_CURL_TLS_BACKEND}'.") endif() +if(MATSDK_USE_VCPKG_DEPS AND MATSDK_CURL_PROVIDER_UPPER STREQUAL "FETCH") + message(FATAL_ERROR + "MATSDK_CURL_PROVIDER=FETCH is a non-vcpkg dependency mode. " + "Use the vcpkg curl-openssl/curl-mbedtls feature instead.") +endif() +if(MATSDK_CURL_TARGET AND MATSDK_CURL_PROVIDER_UPPER STREQUAL "FETCH") + message(FATAL_ERROR + "MATSDK_CURL_TARGET and MATSDK_CURL_PROVIDER=FETCH are mutually exclusive.") +endif() foreach(_matsdk_dependency_target_var MATSDK_CURL_TARGET MATSDK_SQLITE_TARGET MATSDK_ZLIB_TARGET) if(${_matsdk_dependency_target_var} AND NOT TARGET "${${_matsdk_dependency_target_var}}") message(FATAL_ERROR @@ -398,23 +228,7 @@ foreach(_matsdk_dependency_target_var MATSDK_CURL_TARGET MATSDK_SQLITE_TARGET MA "use the SDK's default dependency discovery.") endif() endforeach() -if(MATSDK_ZLIB_TARGET AND PAL_IMPLEMENTATION STREQUAL "WIN32" AND NOT MATSDK_USE_VCPKG_DEPS) - message(FATAL_ERROR - "MATSDK_ZLIB_TARGET is not supported for non-vcpkg WIN32 builds because " - "the legacy WIN32 include path uses the SDK's vendored zlib headers, which " - "rename zlib symbols to act_z_*. Use vcpkg mode, omit MATSDK_ZLIB_TARGET " - "and rely on the legacy .vcxproj dependency, or add a dedicated bundled-zlib " - "CMake path first.") -endif() - -# Enable Azure Monitor / Application Insights end-point support -option(BUILD_AZMON "Build for Azure Monitor" YES) - -if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - option(BUILD_APPLE_HTTP "Build Apple HTTP client" YES) -endif() - -if(BUILD_APPLE_HTTP) +if(MATSDK_BUILD_APPLE_HTTP) add_definitions(-DAPPLE_HTTP=1) endif() @@ -425,9 +239,9 @@ endif() # 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 MATSDK_BUILD_IOS AND (NOT CMAKE_SYSTEM_NAME STREQUAL "Android" OR MATSDK_USE_VCPKG_DEPS) - AND NOT BUILD_APPLE_HTTP) + AND NOT MATSDK_BUILD_APPLE_HTTP) set(MATSDK_NEEDS_CURL ON) add_definitions(-DHAVE_MAT_CURL_HTTP_CLIENT) if(MATSDK_USE_VCPKG_DEPS) @@ -473,50 +287,35 @@ endif() # Dependency resolution (vcpkg mode vs vendored) ################################################################################################ if(MATSDK_USE_VCPKG_DEPS) - if(APPLE) - # macOS/iOS ship libsqlite3 and libz as system libraries (the SDK's SPM - # distribution links them the same way), so the vcpkg sqlite3/zlib packages are - # not pulled there -- find the system ones via CMake's standard find modules. - find_package(SQLite3 REQUIRED) - find_package(ZLIB REQUIRED) - find_package(nlohmann_json CONFIG REQUIRED) - set(MATSDK_APPLE_SYSTEM_DEPS ON) - message(STATUS "Apple: using system SQLite3 + zlib; vcpkg-provided nlohmann-json") - else() - set(MATSDK_APPLE_SYSTEM_DEPS OFF) - # SQLite is provided by the private minimal build when MATSDK_MINIMAL_SQLITE is - # ON, so only require the external vcpkg sqlite3 package otherwise. - if(NOT MATSDK_MINIMAL_SQLITE) + if(MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "SYSTEM" AND NOT MATSDK_SQLITE_TARGET) + if(APPLE) + find_package(SQLite3 REQUIRED) + else() 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,system-sqlite] or [core,minimal-sqlite]. For a direct CMake build, pass " - "-DMATSDK_MINIMAL_SQLITE=ON or ensure unofficial-sqlite3 is discoverable.") + "MATSDK_SQLITE_PROVIDER=SYSTEM requires the vcpkg sqlite3 package. " + "Install the system-sqlite feature, choose " + "MATSDK_SQLITE_PROVIDER=MINIMAL/VENDORED, or provide MATSDK_SQLITE_TARGET.") endif() endif() + endif() + if(MATSDK_ZLIB_PROVIDER_RESOLVED STREQUAL "SYSTEM" AND NOT MATSDK_ZLIB_TARGET) find_package(ZLIB REQUIRED) - find_package(nlohmann_json CONFIG REQUIRED) - if(MATSDK_MINIMAL_SQLITE) - message(STATUS "Using vcpkg-provided zlib, nlohmann-json; private minimal SQLite") - else() - message(STATUS "Using vcpkg-provided sqlite3, zlib, nlohmann-json") - endif() endif() + find_package(nlohmann_json CONFIG REQUIRED) + message(STATUS + "Using vcpkg dependency mode with SQLite=${MATSDK_SQLITE_PROVIDER_RESOLVED}, " + "zlib=${MATSDK_ZLIB_PROVIDER_RESOLVED}") else() - # Include repo root to allow includes of vendored sqlite, zlib, and nlohmann. - # Use CMAKE_CURRENT_SOURCE_DIR (this repo's root) rather than CMAKE_SOURCE_DIR - # so the vendored headers still resolve when the SDK is consumed as a subproject - # (add_subdirectory/FetchContent), where CMAKE_SOURCE_DIR is the consumer's root. + # nlohmann JSON remains header-only and vendored for source embedding. include_directories(${CMAKE_CURRENT_SOURCE_DIR}) - message(STATUS "Using vendored sqlite3, zlib, nlohmann-json") + message(STATUS + "Using source dependency mode with SQLite=${MATSDK_SQLITE_PROVIDER_RESOLVED}, " + "zlib=${MATSDK_ZLIB_PROVIDER_RESOLVED}, vendored nlohmann-json") endif() -if(BUILD_UNIT_TESTS OR BUILD_FUNC_TESTS) +if(MATSDK_BUILD_UNIT_TESTS OR MATSDK_BUILD_FUNC_TESTS) message(STATUS "Adding gtest") add_library(gtest STATIC IMPORTED GLOBAL) message(STATUS "Adding gmock") @@ -533,16 +332,16 @@ include_directories(lib/pal) # enable_testing() # add_subdirectory(bondlite/tests) #endif() -if(BUILD_HEADERS) +if(MATSDK_BUILD_HEADERS) add_subdirectory(lib/include) endif() include_directories(lib/include) -if(BUILD_LIBRARY) +if(MATSDK_BUILD_LIBRARY) add_subdirectory(lib) endif() -if(BUILD_UNIT_TESTS OR BUILD_FUNC_TESTS) +if(MATSDK_BUILD_UNIT_TESTS OR MATSDK_BUILD_FUNC_TESTS) message(STATUS "Building tests") enable_testing() add_subdirectory(tests) @@ -552,7 +351,7 @@ endif() # Packaging ################################################################################################ -if (BUILD_PACKAGE) +if(MATSDK_BUILD_PACKAGE) if ("${CMAKE_PACKAGE_TYPE}" STREQUAL "deb") include(tools/MakeDeb.cmake) endif() diff --git a/README.md b/README.md index 3ddcbb580..a5deb9557 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ Platform specific build instructions: * [Linux](docs/cpp-start-linux.md). [WSL](https://docs.microsoft.com/en-us/windows/wsl/install-win10) or [Docker](https://www.docker.com/products/docker-desktop) can be used to build for various Linux distros. Please refer to [build-docker.cmd](build-docker.cmd) script and [the list of supported containers](docker/). Docker build script accepts the container name as first argument. * [iOS/iPadOS](docs/cpp-start-ios.md) * [Android](docs/cpp-start-android.md) +* [CMake source embedding / FetchContent](docs/embedding-with-cmake.md) Other resources to learn how to setup the build system: diff --git a/build-ios.sh b/build-ios.sh index d316fe2fa..9eb362af3 100755 --- a/build-ios.sh +++ b/build-ios.sh @@ -49,7 +49,6 @@ fi echo "IOS_ARCH = $IOS_ARCH, IOS_PLAT = $IOS_PLAT, BUILD_TYPE = $BUILD_TYPE" -FORCE_RESET_DEPLOYMENT_TARGET=NO DEPLOYMENT_TARGET="" if [ "$IOS_PLAT" == "iphoneos" ] || [ "$IOS_PLAT" == "iphonesimulator" ]; then @@ -57,19 +56,16 @@ if [ "$IOS_PLAT" == "iphoneos" ] || [ "$IOS_PLAT" == "iphonesimulator" ]; then DEPLOYMENT_TARGET="$IOS_DEPLOYMENT_TARGET" if [ -z "$DEPLOYMENT_TARGET" ]; then DEPLOYMENT_TARGET="12.0" - FORCE_RESET_DEPLOYMENT_TARGET=YES fi elif [ "$IOS_PLAT" == "xros" ] || [ "$IOS_PLAT" == "xrsimulator" ]; then SYS_NAME="visionOS" DEPLOYMENT_TARGET="$XROS_DEPLOYMENT_TARGET" if [ -z "$DEPLOYMENT_TARGET" ]; then DEPLOYMENT_TARGET="1.0" - FORCE_RESET_DEPLOYMENT_TARGET=YES fi fi echo "deployment target = $DEPLOYMENT_TARGET" -echo "force reset deployment target = $FORCE_RESET_DEPLOYMENT_TARGET" # Install build tools and recent sqlite3 FILE=".buildtools" @@ -92,7 +88,7 @@ cd out CMAKE_PACKAGE_TYPE=tgz -cmake_cmd="cmake -DCMAKE_OSX_SYSROOT=$IOS_PLAT -DCMAKE_SYSTEM_NAME=$SYS_NAME -DCMAKE_IOS_ARCH_ABI=$IOS_ARCH -DCMAKE_OSX_DEPLOYMENT_TARGET=$DEPLOYMENT_TARGET -DBUILD_IOS=YES -DIOS_ARCH=$IOS_ARCH -DIOS_PLAT=$IOS_PLAT -DIOS_DEPLOYMENT_TARGET=$DEPLOYMENT_TARGET -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_PACKAGE_TYPE=$CMAKE_PACKAGE_TYPE -DFORCE_RESET_DEPLOYMENT_TARGET=$FORCE_RESET_DEPLOYMENT_TARGET $CMAKE_OPTS .." +cmake_cmd="cmake -DCMAKE_OSX_SYSROOT=$IOS_PLAT -DCMAKE_SYSTEM_NAME=$SYS_NAME -DCMAKE_OSX_ARCHITECTURES=$IOS_ARCH -DCMAKE_OSX_DEPLOYMENT_TARGET=$DEPLOYMENT_TARGET -DMATSDK_BUILD_IOS=ON -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_PACKAGE_TYPE=$CMAKE_PACKAGE_TYPE $CMAKE_OPTS .." echo "${cmake_cmd}" eval $cmake_cmd diff --git a/build.sh b/build.sh index 52a5081b2..cf8f91ac3 100755 --- a/build.sh +++ b/build.sh @@ -98,7 +98,7 @@ fi # Evaluate switches LINK_TYPE= -CMAKE_OPTS="${CMAKE_OPTS:--DBUILD_SHARED_LIBS=OFF}" +CMAKE_OPTS="${CMAKE_OPTS:--DMATSDK_LIBRARY_TYPE=STATIC}" while getopts "h?vl:D:" opt; do case "$opt" in h|\?) usage @@ -133,7 +133,7 @@ fi echo "CMAKE_OPTS from caller: $CMAKE_OPTS" if [ "$LINK_TYPE" == "shared" ]; then - CMAKE_OPTS="${CMAKE_OPTS} -DBUILD_SHARED_LIBS=ON" + CMAKE_OPTS="${CMAKE_OPTS} -DMATSDK_LIBRARY_TYPE=SHARED" fi # Set target MacOS minver @@ -185,8 +185,15 @@ fi # Fail on error set -e -# TODO: should this be improved to verify if the platform is Apple? Right now we unconditionally pass -DMAC_ARCH even if building for Windows or Linux. -cmake_cmd="cmake -DMAC_ARCH=$MAC_ARCH -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_PACKAGE_TYPE=$CMAKE_PACKAGE_TYPE -DCMAKE_CXX_FLAGS="${CUSTOM_CMAKE_CXX_FLAG}" $CMAKE_OPTS .." +APPLE_CMAKE_OPTS="" +if [[ "$OS_NAME" == *Darwin* ]]; then + if [[ "$MAC_ARCH" == "universal" ]]; then + APPLE_CMAKE_OPTS='-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"' + else + APPLE_CMAKE_OPTS="-DCMAKE_OSX_ARCHITECTURES=$MAC_ARCH" + fi +fi +cmake_cmd="cmake $APPLE_CMAKE_OPTS -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_PACKAGE_TYPE=$CMAKE_PACKAGE_TYPE -DCMAKE_CXX_FLAGS="${CUSTOM_CMAKE_CXX_FLAG}" $CMAKE_OPTS .." echo $cmake_cmd eval $cmake_cmd diff --git a/cmake/MSTelemetryConfig.cmake.in b/cmake/MSTelemetryConfig.cmake.in index af3838d65..f51f4cb89 100644 --- a/cmake/MSTelemetryConfig.cmake.in +++ b/cmake/MSTelemetryConfig.cmake.in @@ -2,15 +2,17 @@ include(CMakeFindDependencyMacro) -# Re-find dependencies that consumers need. -# On Apple the SDK links the system libsqlite3 (SQLite::SQLite3); elsewhere it uses -# the vcpkg sqlite3 package unless a private minimal SQLite is bundled. -if(@MATSDK_APPLE_SYSTEM_DEPS@) - find_dependency(SQLite3) -elseif(NOT @MATSDK_BUNDLE_SQLITE@) - find_dependency(unofficial-sqlite3 CONFIG) +# Re-find only dependencies that were external to the SDK package. +if(NOT @MATSDK_BUNDLE_SQLITE@) + if(@APPLE@) + find_dependency(SQLite3) + else() + find_dependency(unofficial-sqlite3 CONFIG) + endif() +endif() +if(NOT @MATSDK_BUNDLE_ZLIB@) + find_dependency(ZLIB) endif() -find_dependency(ZLIB) find_dependency(nlohmann_json CONFIG) # Curl is re-found only when the SDK was built with the curl HTTP client diff --git a/cmake/MatsdkFetchCurl.cmake b/cmake/MatsdkFetchCurl.cmake index e37dd1a4f..baa5ceb76 100644 --- a/cmake/MatsdkFetchCurl.cmake +++ b/cmake/MatsdkFetchCurl.cmake @@ -122,5 +122,11 @@ function(matsdk_fetch_curl out_target) target_compile_options(libcurl_static PRIVATE $<$:-ffunction-sections;-fdata-sections>) + set(_matsdk_fetched_curl_targets libcurl_static) + if(MATSDK_CURL_TLS_BACKEND_UPPER STREQUAL "MBEDTLS") + list(APPEND _matsdk_fetched_curl_targets mbedtls mbedx509 mbedcrypto) + endif() + set(MATSDK_FETCHED_CURL_TARGETS + "${_matsdk_fetched_curl_targets}" PARENT_SCOPE) set(${out_target} CURL::libcurl PARENT_SCOPE) endfunction() diff --git a/cmake/MatsdkOptions.cmake b/cmake/MatsdkOptions.cmake new file mode 100644 index 000000000..111aa94b3 --- /dev/null +++ b/cmake/MatsdkOptions.cmake @@ -0,0 +1,167 @@ +function(matsdk_bool_option canonical legacy description default_value) + set(initial_value "${default_value}") + set(canonical_predefined OFF) + if(DEFINED ${canonical}) + set(canonical_predefined ON) + endif() + set(legacy_defined OFF) + if(NOT "${legacy}" STREQUAL "") + if(DEFINED ${legacy}) + set(legacy_defined ON) + if(NOT canonical_predefined) + set(initial_value "${${legacy}}") + endif() + endif() + endif() + option(${canonical} "${description}" "${initial_value}") + if(canonical_predefined AND legacy_defined + AND NOT "${${legacy}}" STREQUAL "${${canonical}}") + message(DEPRECATION + "${legacy} is deprecated and conflicts with ${canonical}; " + "${canonical}=${${canonical}} takes precedence.") + endif() +endfunction() + +if(DEFINED PROJECT_IS_TOP_LEVEL) + set(MATSDK_PROJECT_IS_TOP_LEVEL "${PROJECT_IS_TOP_LEVEL}") +elseif(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(MATSDK_PROJECT_IS_TOP_LEVEL ON) +else() + set(MATSDK_PROJECT_IS_TOP_LEVEL OFF) +endif() + +matsdk_bool_option(MATSDK_BUILD_HEADERS BUILD_HEADERS + "Build API headers" ON) +matsdk_bool_option(MATSDK_BUILD_LIBRARY BUILD_LIBRARY + "Build the SDK library" ON) +matsdk_bool_option(MATSDK_BUILD_TEST_TOOL BUILD_TEST_TOOL + "Build the console test tool" "${MATSDK_PROJECT_IS_TOP_LEVEL}") +matsdk_bool_option(MATSDK_BUILD_UNIT_TESTS BUILD_UNIT_TESTS + "Build unit tests" "${MATSDK_PROJECT_IS_TOP_LEVEL}") +matsdk_bool_option(MATSDK_BUILD_FUNC_TESTS BUILD_FUNC_TESTS + "Build functional tests" "${MATSDK_PROJECT_IS_TOP_LEVEL}") +matsdk_bool_option(MATSDK_BUILD_JNI_WRAPPER BUILD_JNI_WRAPPER + "Build the JNI wrapper" OFF) +matsdk_bool_option(MATSDK_BUILD_OBJC_WRAPPER BUILD_OBJC_WRAPPER + "Build the Objective-C wrapper" ON) +matsdk_bool_option(MATSDK_BUILD_SWIFT_WRAPPER BUILD_SWIFT_WRAPPER + "Build Swift wrappers" ON) +matsdk_bool_option(MATSDK_BUILD_PACKAGE BUILD_PACKAGE + "Build an SDK package" "${MATSDK_PROJECT_IS_TOP_LEVEL}") +matsdk_bool_option(MATSDK_BUILD_PRIVACYGUARD BUILD_PRIVACYGUARD + "Build Privacy Guard" ON) +matsdk_bool_option(MATSDK_BUILD_CDS BUILD_CDS + "Build Common Diagnostic Stack" ON) +matsdk_bool_option(MATSDK_BUILD_LIVEEVENTINSPECTOR BUILD_LIVEEVENTINSPECTOR + "Build Live Event Inspector" ON) +matsdk_bool_option(MATSDK_BUILD_SIGNALS BUILD_SIGNALS + "Build Signals" ON) +matsdk_bool_option(MATSDK_BUILD_SANITIZER BUILD_SANITIZER + "Build Sanitizer" ON) +matsdk_bool_option(MATSDK_BUILD_AZMON BUILD_AZMON + "Build Azure Monitor / Application Insights support" ON) +matsdk_bool_option(MATSDK_BUILD_APPLE_HTTP BUILD_APPLE_HTTP + "Build the Apple-native HTTP client" "${APPLE}") + +set(_matsdk_ios_default OFF) +if(CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "visionOS") + set(_matsdk_ios_default ON) +endif() +matsdk_bool_option(MATSDK_BUILD_IOS BUILD_IOS + "Build for iOS or visionOS" "${_matsdk_ios_default}") + +matsdk_bool_option(MATSDK_WARNINGS_AS_ERRORS "" + "Treat warnings in SDK-owned targets as errors" "${MATSDK_PROJECT_IS_TOP_LEVEL}") +matsdk_bool_option(MATSDK_LINK_STATIC_DEPENDS LINK_STATIC_DEPENDS + "Link dependencies statically where supported" ON) + +set(_matsdk_library_type_default STATIC) +if(NOT DEFINED MATSDK_LIBRARY_TYPE AND DEFINED BUILD_SHARED_LIBS AND BUILD_SHARED_LIBS) + set(_matsdk_library_type_default SHARED) +endif() +set(MATSDK_LIBRARY_TYPE "${_matsdk_library_type_default}" CACHE STRING + "SDK library type: STATIC or SHARED") +set_property(CACHE MATSDK_LIBRARY_TYPE PROPERTY STRINGS STATIC SHARED) +string(TOUPPER "${MATSDK_LIBRARY_TYPE}" MATSDK_LIBRARY_TYPE) +if(NOT MATSDK_LIBRARY_TYPE STREQUAL "STATIC" AND NOT MATSDK_LIBRARY_TYPE STREQUAL "SHARED") + message(FATAL_ERROR + "MATSDK_LIBRARY_TYPE must be STATIC or SHARED; got '${MATSDK_LIBRARY_TYPE}'.") +endif() + +set(MATSDK_SQLITE_PROVIDER "AUTO" CACHE STRING + "SQLite dependency provider: AUTO, SYSTEM, MINIMAL, or VENDORED") +set_property(CACHE MATSDK_SQLITE_PROVIDER PROPERTY STRINGS AUTO SYSTEM MINIMAL VENDORED) +set(MATSDK_ZLIB_PROVIDER "AUTO" CACHE STRING + "zlib dependency provider: AUTO, SYSTEM, or VENDORED") +set_property(CACHE MATSDK_ZLIB_PROVIDER PROPERTY STRINGS AUTO SYSTEM VENDORED) +option(MATSDK_MINIMAL_SQLITE + "Deprecated compatibility switch for MATSDK_SQLITE_PROVIDER=MINIMAL" OFF) +option(MATSDK_BUNDLE_VENDORED_DEPS + "Build the SDK's vendored SQLite and symbol-prefixed zlib" OFF) + +string(TOUPPER "${MATSDK_SQLITE_PROVIDER}" MATSDK_SQLITE_PROVIDER_RESOLVED) +string(TOUPPER "${MATSDK_ZLIB_PROVIDER}" MATSDK_ZLIB_PROVIDER_RESOLVED) + +if(MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "AUTO") + if(MATSDK_SQLITE_TARGET) + set(MATSDK_SQLITE_PROVIDER_RESOLVED SYSTEM) + elseif(MATSDK_MINIMAL_SQLITE) + set(MATSDK_SQLITE_PROVIDER_RESOLVED MINIMAL) + elseif(MATSDK_BUNDLE_VENDORED_DEPS + OR (NOT MATSDK_USE_VCPKG_DEPS + AND (WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Android"))) + set(MATSDK_SQLITE_PROVIDER_RESOLVED VENDORED) + else() + set(MATSDK_SQLITE_PROVIDER_RESOLVED SYSTEM) + endif() +elseif(MATSDK_MINIMAL_SQLITE + AND NOT MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "MINIMAL") + message(FATAL_ERROR + "MATSDK_MINIMAL_SQLITE=ON conflicts with " + "MATSDK_SQLITE_PROVIDER=${MATSDK_SQLITE_PROVIDER}.") +endif() + +if(MATSDK_ZLIB_PROVIDER_RESOLVED STREQUAL "AUTO") + if(MATSDK_ZLIB_TARGET) + set(MATSDK_ZLIB_PROVIDER_RESOLVED SYSTEM) + elseif(MATSDK_BUNDLE_VENDORED_DEPS + OR (NOT MATSDK_USE_VCPKG_DEPS + AND (WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Android"))) + set(MATSDK_ZLIB_PROVIDER_RESOLVED VENDORED) + else() + set(MATSDK_ZLIB_PROVIDER_RESOLVED SYSTEM) + endif() +endif() + +if(NOT MATSDK_SQLITE_PROVIDER_RESOLVED MATCHES "^(SYSTEM|MINIMAL|VENDORED)$") + message(FATAL_ERROR + "MATSDK_SQLITE_PROVIDER must be AUTO, SYSTEM, MINIMAL, or VENDORED; " + "got '${MATSDK_SQLITE_PROVIDER}'.") +endif() +if(NOT MATSDK_ZLIB_PROVIDER_RESOLVED MATCHES "^(SYSTEM|VENDORED)$") + message(FATAL_ERROR + "MATSDK_ZLIB_PROVIDER must be AUTO, SYSTEM, or VENDORED; " + "got '${MATSDK_ZLIB_PROVIDER}'.") +endif() +if(MATSDK_SQLITE_TARGET AND NOT MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "SYSTEM") + message(FATAL_ERROR + "MATSDK_SQLITE_TARGET requires MATSDK_SQLITE_PROVIDER=AUTO or SYSTEM.") +endif() +if(MATSDK_ZLIB_TARGET AND NOT MATSDK_ZLIB_PROVIDER_RESOLVED STREQUAL "SYSTEM") + message(FATAL_ERROR + "MATSDK_ZLIB_TARGET requires MATSDK_ZLIB_PROVIDER=AUTO or SYSTEM.") +endif() + +set(MATSDK_BUNDLE_SQLITE OFF) +if(MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "MINIMAL" + OR MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "VENDORED") + set(MATSDK_BUNDLE_SQLITE ON) +endif() +set(MATSDK_BUNDLE_ZLIB OFF) +if(MATSDK_ZLIB_PROVIDER_RESOLVED STREQUAL "VENDORED") + set(MATSDK_BUNDLE_ZLIB ON) +endif() + +message(STATUS "MATSDK_LIBRARY_TYPE: ${MATSDK_LIBRARY_TYPE}") +message(STATUS "MATSDK_SQLITE_PROVIDER: ${MATSDK_SQLITE_PROVIDER} -> ${MATSDK_SQLITE_PROVIDER_RESOLVED}") +message(STATUS "MATSDK_ZLIB_PROVIDER: ${MATSDK_ZLIB_PROVIDER} -> ${MATSDK_ZLIB_PROVIDER_RESOLVED}") diff --git a/docs/building-with-vcpkg.md b/docs/building-with-vcpkg.md index 315fa8662..b40ebb144 100644 --- a/docs/building-with-vcpkg.md +++ b/docs/building-with-vcpkg.md @@ -211,7 +211,7 @@ will automatically use the optimized zlib-ng build. This section applies when the SDK is linked **statically** into your binary (the default for the `*-static` vcpkg triplets) — most footprint control then lives on *your* side of the link. If you instead consume a **dynamic** `mat` -(e.g. the default `x64-windows` triplet, or `BUILD_SHARED_LIBS=ON`), the runtime +(e.g. the default `x64-windows` triplet, or `MATSDK_LIBRARY_TYPE=SHARED`), the runtime ships as its own `mat.dll` / `libmat.so` / `libmat.dylib`; the SDK's own `-fvisibility=hidden` and `/Gy /Gw` already trim its exported symbol table, and the consumer-side linker options below are specific to the static-link case. @@ -357,7 +357,7 @@ requires a TLS backend, so omitting it would fail to configure (swap in For a plain (non-vcpkg) CMake build, pass the option directly: ```bash -cmake -DMATSDK_MINIMAL_SQLITE=ON .. +cmake -DMATSDK_SQLITE_PROVIDER=MINIMAL .. ``` The strip is **amalgamation-safe**: it changes no SQLite grammar/parser, so no diff --git a/docs/cpp-start-ios.md b/docs/cpp-start-ios.md index ad80866e0..d00f2aa2a 100644 --- a/docs/cpp-start-ios.md +++ b/docs/cpp-start-ios.md @@ -37,6 +37,26 @@ If Xcode reports that the requested simulator runtime is missing, install it from Xcode > Settings > Components or run `xcodebuild -downloadPlatform iOS -architectureVariant arm64`. +For direct CMake integration, use the standard Apple variables rather than +SDK-specific architecture flags: + +```sh +cmake -S . -B out \ + -DCMAKE_SYSTEM_NAME=iOS \ + -DCMAKE_OSX_SYSROOT=iphonesimulator \ + -DCMAKE_OSX_ARCHITECTURES=arm64 \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 \ + -DCMAKE_BUILD_TYPE=Release \ + -DMATSDK_BUILD_IOS=ON \ + -DMATSDK_BUILD_UNIT_TESTS=OFF \ + -DMATSDK_BUILD_FUNC_TESTS=OFF \ + -DMATSDK_BUILD_OBJC_WRAPPER=OFF \ + -DMATSDK_BUILD_SWIFT_WRAPPER=OFF +``` + +Use `iphoneos` for a device build. Legacy `IOS_ARCH`/`IOS_PLAT` inputs remain +accepted temporarily, but new integrations should use `CMAKE_OSX_*`. + ## 3. Integrate the SDK into your C++ project SDK package contains headers and library installed at the following locations diff --git a/docs/cpp-start-macosx.md b/docs/cpp-start-macosx.md index ec9ef9f71..b0312507b 100644 --- a/docs/cpp-start-macosx.md +++ b/docs/cpp-start-macosx.md @@ -35,22 +35,18 @@ If you do not have those credentials, generate them and use the username and pas ### 2. Run the file build.sh to build the SDK, this will build the SDK along with Unit and Functional Tests -To disable building the tests go to the **CMakeLists.txt** file in the root of the SDK directory and change +To disable tests without editing SDK sources, pass the namespaced CMake options: -```console -option(BUILD_UNIT_TESTS "Build unit tests" YES) -option(BUILD_FUNC_TESTS "Build functional tests" YES) -``` - -to - -```console -option(BUILD_UNIT_TESTS "Build unit tests" NO) -option(BUILD_FUNC_TESTS "Build functional tests" NO) +```sh +CMAKE_OPTS="-DMATSDK_BUILD_UNIT_TESTS=OFF -DMATSDK_BUILD_FUNC_TESTS=OFF" ./build.sh ``` _**Note:** In order to build from scratch all dependencies along with the SDK you need to run: `./build.sh clean`_ +For direct CMake builds, use `CMAKE_OSX_ARCHITECTURES` (`arm64`, `x86_64`, or +`arm64;x86_64`) and `CMAKE_OSX_DEPLOYMENT_TARGET`. The SDK no longer injects +global `-arch` or deployment-target flags. + ### 3. The SDK will be installed under `usr/local/lib/libmat.a` ## **Instrument your code to send a telemetry event** diff --git a/docs/embedding-with-cmake.md b/docs/embedding-with-cmake.md index a28d8f18b..ca524f8fb 100644 --- a/docs/embedding-with-cmake.md +++ b/docs/embedding-with-cmake.md @@ -4,10 +4,11 @@ Consumers that build the SDK from source with `add_subdirectory()` or `FetchContent` can link the same target name used by installed/vcpkg builds: ```cmake -set(BUILD_TEST_TOOL OFF CACHE BOOL "" FORCE) -set(BUILD_UNIT_TESTS OFF CACHE BOOL "" FORCE) -set(BUILD_FUNC_TESTS OFF CACHE BOOL "" FORCE) -set(BUILD_PACKAGE OFF CACHE BOOL "" FORCE) +set(MATSDK_LIBRARY_TYPE STATIC CACHE STRING "" FORCE) +set(MATSDK_BUILD_TEST_TOOL OFF CACHE BOOL "" FORCE) +set(MATSDK_BUILD_UNIT_TESTS OFF CACHE BOOL "" FORCE) +set(MATSDK_BUILD_FUNC_TESTS OFF CACHE BOOL "" FORCE) +set(MATSDK_BUILD_PACKAGE OFF CACHE BOOL "" FORCE) add_subdirectory(cpp_client_telemetry) target_link_libraries(your_target PRIVATE MSTelemetry::mat) @@ -17,6 +18,31 @@ For a static SDK build, CMake carries the SDK's link dependencies through the `MSTelemetry::mat` target, so the consuming target should not need to name the SDK's internal dependencies directly. +`MATSDK_LIBRARY_TYPE` explicitly selects `STATIC` or `SHARED` without changing +the parent project's global `BUILD_SHARED_LIBS` value. Legacy `BUILD_*` inputs +remain accepted for compatibility, but new integrations should use the +namespaced `MATSDK_*` options. + +`MATSDK_WARNINGS_AS_ERRORS` defaults to `ON` for standalone SDK builds and +`OFF` when the SDK is embedded. Its warning policy is private to SDK-owned +targets and never propagates to the parent consumer or vendored dependencies. +Set it explicitly to `ON` in consumer CI to test new toolchains strictly. + +## SQLite and zlib providers + +Source builds can select dependency modes without patching 1DS sources: + +```cmake +set(MATSDK_SQLITE_PROVIDER MINIMAL CACHE STRING "" FORCE) # SYSTEM, MINIMAL, VENDORED +set(MATSDK_ZLIB_PROVIDER VENDORED CACHE STRING "" FORCE) # SYSTEM or VENDORED +``` + +`MINIMAL` builds the feature-stripped SQLite amalgamation. `VENDORED` builds the +unstripped vendored dependency. `SYSTEM` uses `find_package()` unless a matching +`MATSDK_SQLITE_TARGET` or `MATSDK_ZLIB_TARGET` is supplied. `AUTO` preserves +platform defaults: system dependencies on desktop/Apple source builds and +vendored dependencies on Windows/Android source builds. + ## Non-vcpkg dependency selection When the CPP11 PAL uses the curl HTTP transport outside vcpkg, the SDK normally @@ -37,7 +63,7 @@ The default fetched backend is mbedTLS and is fully self-contained. Selecting to provide OpenSSL through `find_package(OpenSSL)`. Non-vcpkg Linux builds similarly use `find_package()` for zlib and SQLite unless -the minimal bundled SQLite option is enabled. +an explicit vendored/minimal provider is selected. To make a superbuild choose the dependency implementation (for example, libcurl built with OpenSSL vs. mbedTLS) without changing the leaf consumer target, define @@ -61,8 +87,6 @@ target_link_libraries(your_target PRIVATE MSTelemetry::mat) If a `MATSDK_*_TARGET` value is empty, the SDK falls back to its existing dependency discovery for that library. -`MATSDK_ZLIB_TARGET` is intentionally rejected for non-vcpkg WIN32 builds today: -that legacy path includes the SDK's vendored zlib headers, which rename zlib -symbols to `act_z_*`. Use vcpkg mode, the existing Visual Studio project -dependency path, or add a dedicated bundled-zlib CMake path before supplying a -custom WIN32 zlib target. +For a fully self-contained source build, use `MATSDK_SQLITE_PROVIDER=MINIMAL` +and `MATSDK_ZLIB_PROVIDER=VENDORED`; the vendored targets are PIC, hidden, and +compiled without inheriting the SDK's warnings-as-errors policy. diff --git a/docs/sharing-a-single-sdk-runtime.md b/docs/sharing-a-single-sdk-runtime.md index 10e69746d..b3515c220 100644 --- a/docs/sharing-a-single-sdk-runtime.md +++ b/docs/sharing-a-single-sdk-runtime.md @@ -86,7 +86,7 @@ else() endif() ``` -The port honors `VCPKG_LIBRARY_LINKAGE` / `BUILD_SHARED_LIBS` and emits the +The port honors `VCPKG_LIBRARY_LINKAGE` / `MATSDK_LIBRARY_TYPE` and emits the shared `mat` plus its import lib and the `MSTelemetry` CMake config package. ### Pin one version across all modules diff --git a/install.sh b/install.sh index 4dcddc197..c8b1df24f 100755 --- a/install.sh +++ b/install.sh @@ -1,7 +1,11 @@ #!/bin/sh -MATSDK_INSTALL_DIR=$1 +set -e + +MATSDK_INSTALL_DIR=${1:-/usr/local} +if [ ! -f out/cmake_install.cmake ]; then + echo "ERROR: out/cmake_install.cmake not found; configure and build the SDK first." >&2 + exit 1 +fi + echo "Install SDK to $MATSDK_INSTALL_DIR" -mkdir -p $MATSDK_INSTALL_DIR/lib -cp out/lib/libmat.* $MATSDK_INSTALL_DIR/lib -mkdir -p $MATSDK_INSTALL_DIR/include/mat -cp lib/include/public/* $MATSDK_INSTALL_DIR/include/mat +cmake --install out --prefix "$MATSDK_INSTALL_DIR" diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index c4f6a54db..b040def5c 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -6,10 +6,9 @@ cmake_policy(SET CMP0063 NEW) # to downstream consumers via find_package() (see target_include_directories below). include_directories( . ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include/public ${CMAKE_CURRENT_SOURCE_DIR}/include/mat ${CMAKE_CURRENT_SOURCE_DIR}/pal ${CMAKE_CURRENT_SOURCE_DIR}/utils ${CMAKE_CURRENT_SOURCE_DIR}/modules/exp ${CMAKE_CURRENT_SOURCE_DIR}/modules/dataviewer ${CMAKE_CURRENT_SOURCE_DIR}/modules/privacyguard ${CMAKE_CURRENT_SOURCE_DIR}/modules/liveeventinspector ${CMAKE_CURRENT_SOURCE_DIR}/modules/cds ${CMAKE_CURRENT_SOURCE_DIR}/modules/signals ${CMAKE_CURRENT_SOURCE_DIR}/modules/sanitizer ) -# Legacy builds may need system-installed deps from /usr/local/include. Excluded on -# iOS: /usr/local/include is a host (macOS) path, and injecting it into an iOS -# cross-compile's search path can shadow the iOS SDK's own headers. -if(NOT MATSDK_USE_VCPKG_DEPS AND NOT CMAKE_SYSTEM_NAME STREQUAL "iOS") +# Legacy native builds may need system-installed deps from /usr/local/include. +# Never inject this host path into iOS, Android, or other cross-compiles. +if(NOT MATSDK_USE_VCPKG_DEPS AND NOT CMAKE_CROSSCOMPILING) include_directories(/usr/local/include) endif() @@ -66,7 +65,7 @@ set(SRCS decorators/BaseDecorator.cpp ) # Support for Azure Monitor / Application Insights -if(BUILD_AZMON) +if(MATSDK_BUILD_AZMON) include(modules/azmon/CMakeLists.txt OPTIONAL) endif() @@ -91,7 +90,7 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/dataviewer/") ) endif() -if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/privacyguard/" AND BUILD_PRIVACYGUARD) +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/privacyguard/" AND MATSDK_BUILD_PRIVACYGUARD) list(APPEND SRCS modules/privacyguard/PrivacyGuard.cpp modules/privacyguard/RegisteredFileTypes.cpp @@ -99,14 +98,14 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/privacyguard/" AND BUILD_PRIVACYG ) endif() -if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/liveeventinspector/" AND BUILD_LIVEEVENTINSPECTOR) +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/liveeventinspector/" AND MATSDK_BUILD_LIVEEVENTINSPECTOR) list(APPEND SRCS modules/liveeventinspector/LiveEventInspector.cpp modules/liveeventinspector/LiveEventInspector.hpp ) endif() -if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/cds/" AND BUILD_CDS) +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/cds/" AND MATSDK_BUILD_CDS) add_definitions(-DHAVE_MAT_CDS) list(APPEND SRCS modules/cds/CdsFactory.hpp @@ -114,14 +113,14 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/cds/" AND BUILD_CDS) ) endif() -if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/signals/" AND BUILD_SIGNALS) +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/signals/" AND MATSDK_BUILD_SIGNALS) list(APPEND SRCS modules/signals/Signals.cpp modules/signals/SignalsEncoder.cpp ) endif() -if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/sanitizer/" AND BUILD_SANITIZER) +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/sanitizer/" AND MATSDK_BUILD_SANITIZER) list(APPEND SRCS modules/sanitizer/detectors/EmailAddressDetector.cpp modules/sanitizer/detectors/JwtDetector.cpp @@ -153,7 +152,7 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11") list(APPEND SRCS pal/posix/sysinfo_utils_apple.cpp ) - if(BUILD_IOS) + if(MATSDK_BUILD_IOS) list(APPEND SRCS pal/posix/sysinfo_utils_ios.mm ) @@ -178,7 +177,7 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11") endif() if(APPLE) - if(BUILD_APPLE_HTTP OR BUILD_IOS) + if(MATSDK_BUILD_APPLE_HTTP OR MATSDK_BUILD_IOS) list(APPEND SRCS http/HttpClient_Apple.mm ) @@ -216,7 +215,7 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11") ) endif() endif() - if(APPLE AND BUILD_OBJC_WRAPPER) + if(APPLE AND MATSDK_BUILD_OBJC_WRAPPER) message(STATUS "Include ObjC Wrappers") set(OBJC_WRAPPER_SRCS ../wrappers/obj-c/ODWLogger.mm @@ -233,13 +232,13 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11") ../wrappers/obj-c/ODWDiagnosticDataViewer.mm ) endif() - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/privacyguard/" AND BUILD_PRIVACYGUARD) + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/privacyguard/" AND MATSDK_BUILD_PRIVACYGUARD) set(MATSDK_OBJC_PRIVACYGUARD_AVAILABLE ON) list(APPEND OBJC_WRAPPER_SRCS ../wrappers/obj-c/ODWPrivacyGuard.mm ) endif() - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/sanitizer/" AND BUILD_SANITIZER) + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/modules/sanitizer/" AND MATSDK_BUILD_SANITIZER) set(MATSDK_OBJC_SANITIZER_AVAILABLE ON) list(APPEND OBJC_WRAPPER_SRCS ../wrappers/obj-c/ODWSanitizer.mm @@ -248,7 +247,7 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11") list(APPEND SRCS ${OBJC_WRAPPER_SRCS}) endif() - if(APPLE AND BUILD_SWIFT_WRAPPER) + if(APPLE AND MATSDK_BUILD_SWIFT_WRAPPER) message(STATUS "Building Swift Wrappers") # Run swift build for the Swift Wrappers Package string(TOLOWER ${CMAKE_BUILD_TYPE} LOWER_BUILD_TYPE) @@ -271,9 +270,6 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11") elseif(PAL_IMPLEMENTATION STREQUAL "WIN32") # Win32 Desktop for now. # TODO: define a separate PAL for Win10 cmake build -if(NOT MATSDK_USE_VCPKG_DEPS) - include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../zlib ${CMAKE_CURRENT_SOURCE_DIR}/../sqlite) -endif() add_definitions(-D_UNICODE -DUNICODE -DWIN32 -DMATSDK_PLATFORM_WINDOWS=1 -D_UTC_SDK -DUSE_BOND -D_WINDOWS -D_USRDLL -DWINVER=_WIN32_WINNT_WIN7) remove_definitions(-D_MBCS) list(APPEND SRCS @@ -310,6 +306,15 @@ endif() create_source_files_groups_per_folder(${SRCS}) +if(APPLE) + set(_matsdk_objcxx_sources ${SRCS}) + list(FILTER _matsdk_objcxx_sources INCLUDE REGEX "\\.mm$") + if(_matsdk_objcxx_sources) + set_source_files_properties(${_matsdk_objcxx_sources} + PROPERTIES COMPILE_OPTIONS "-fobjc-arc;-Wno-error=shorten-64-to-32") + endif() +endif() + # Linux and Android require pthreads if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android") find_package(Threads REQUIRED) @@ -318,13 +323,29 @@ endif() ################################################################################################ # Build the library ################################################################################################ -if(BUILD_SHARED_LIBS) +if(MATSDK_LIBRARY_TYPE STREQUAL "SHARED") message(STATUS "Building shared SDK library") add_library(mat SHARED ${SRCS}) else() message(STATUS "Building static SDK library") add_library(mat STATIC ${SRCS}) endif() +target_link_libraries(mat PRIVATE $) +set_target_properties(mat PROPERTIES POSITION_INDEPENDENT_CODE ON) +if(MATSDK_LIBRARY_TYPE STREQUAL "SHARED") + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_link_options(mat PRIVATE + $<$>:-s> + $<$>:-Wl,--gc-sections>) + elseif(APPLE) + target_link_options(mat PRIVATE + $<$>:-Wl,-dead_strip>) + endif() +endif() +if(APPLE) + target_compile_options(mat PRIVATE + $<$:-Wno-error=shorten-64-to-32>) +endif() if(NOT TARGET MSTelemetry::mat) add_library(MSTelemetry::mat ALIAS mat) endif() @@ -343,7 +364,7 @@ endif() # a consumer DLL/.so that statically absorbs this library. Windows needs an # explicit (empty) MATSDK_STATIC_LIB; elsewhere the empty MATSDK_LIBABI default # plus -fvisibility=hidden (root CMakeLists.txt) already hides them. -if(BUILD_SHARED_LIBS) +if(MATSDK_LIBRARY_TYPE STREQUAL "SHARED") target_compile_definitions(mat PRIVATE MATSDK_SHARED_LIB=1) if(WIN32) target_compile_definitions(mat INTERFACE MATSDK_IMPORT_LIB=1) @@ -378,8 +399,8 @@ target_include_directories(mat ${CMAKE_CURRENT_SOURCE_DIR}/utils ) -if(APPLE AND BUILD_OBJC_WRAPPER) - if(BUILD_SHARED_LIBS AND OBJC_WRAPPER_SRCS) +if(APPLE AND MATSDK_BUILD_OBJC_WRAPPER) + if(MATSDK_LIBRARY_TYPE STREQUAL "SHARED" AND OBJC_WRAPPER_SRCS) # The root CMakeLists.txt applies -fvisibility=hidden globally to shrink the # exported symbol table of the core C++ SDK. For Objective-C that also hides # the wrapper class symbols (_OBJC_CLASS_$_ODW*), which are public API on @@ -410,7 +431,7 @@ endif() # The SDK uses SQLite only for its offline event-storage cache: plain tables, # indexes, transactions, WAL, autovacuum/VACUUM, a handful of PRAGMAs, and one # custom UTF-8 SQL function. None of SQLite's optional subsystems are needed, so -# when MATSDK_MINIMAL_SQLITE is set the bundled SQLite is compiled with these +# when MATSDK_SQLITE_PROVIDER=MINIMAL the bundled SQLite is compiled with these # options to strip out everything the SDK does not use (~10% smaller SQLite code). # They are all amalgamation-safe (no grammar/parser regeneration) and validated # against the offline-storage unit tests. @@ -450,22 +471,6 @@ set(MATSDK_SQLITE_MINIMAL_DEFS SQLITE_UNTESTABLE ) -# Bundle a vendored SQLite (built from sqlite/sqlite3.c) when MATSDK_MINIMAL_SQLITE -# is requested, or on the Android NDK legacy path (which has no system SQLite and -# has always built the vendored amalgamation). Otherwise an external/system SQLite -# is used. The feature-strip definitions above are applied ONLY when -# MATSDK_MINIMAL_SQLITE is ON, so the default Android legacy build keeps its -# existing (unstripped) bundled SQLite behavior. -set(MATSDK_BUNDLE_SQLITE OFF) -if(MATSDK_MINIMAL_SQLITE AND NOT APPLE) - # On Apple the SDK links the system libsqlite3/libz (see the Apple branch below), - # so MATSDK_MINIMAL_SQLITE has no effect there. - set(MATSDK_BUNDLE_SQLITE ON) -elseif(NOT MATSDK_USE_VCPKG_DEPS AND CMAKE_SYSTEM_NAME STREQUAL "Android") - # Android NDK ships no system SQLite, so the vendored amalgamation is always bundled. - set(MATSDK_BUNDLE_SQLITE ON) -endif() - if(MATSDK_BUNDLE_SQLITE AND NOT TARGET sqlite3_bundled) add_library(sqlite3_bundled STATIC "${CMAKE_CURRENT_SOURCE_DIR}/../sqlite/sqlite3.c") # Consumers of MSTelemetry::mat never include sqlite3.h (it is an internal @@ -473,8 +478,10 @@ if(MATSDK_BUNDLE_SQLITE AND NOT TARGET sqlite3_bundled) # SDK itself -- wrap it in BUILD_INTERFACE so install(EXPORT) stays valid. target_include_directories(sqlite3_bundled PUBLIC "$") - set_target_properties(sqlite3_bundled PROPERTIES POSITION_INDEPENDENT_CODE ON) - if(MATSDK_MINIMAL_SQLITE) + set_target_properties(sqlite3_bundled PROPERTIES + POSITION_INDEPENDENT_CODE ON + C_VISIBILITY_PRESET hidden) + if(MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "MINIMAL") # Feature-stripped build: apply the minimal definitions. target_compile_definitions(sqlite3_bundled PRIVATE ${MATSDK_SQLITE_MINIMAL_DEFS}) endif() @@ -482,143 +489,113 @@ if(MATSDK_BUNDLE_SQLITE AND NOT TARGET sqlite3_bundled) # Silence the vendored amalgamation's warnings (/w) and turn off # warning-as-error (/WX-) for this third-party translation unit, so the SDK's # /WX does not promote any amalgamation warning that survives /w to an error. - target_compile_options(sqlite3_bundled PRIVATE /w /WX-) - elseif(MATSDK_MINIMAL_SQLITE) + target_compile_options(sqlite3_bundled PRIVATE + /w /WX- /Gy + $<$:/Gw>) + elseif(MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "MINIMAL") # -w disables all warnings for this vendored translation unit so the SDK's # -Werror does not fire on amalgamation code (the OMIT_* options leave some # debug-build macros expanding to empty/unused statements). -fno-finite-math-only: # the amalgamation relies on the INFINITY macro, which -ffast-math / # -ffinite-math-only would break. - target_compile_options(sqlite3_bundled PRIVATE -w -fno-finite-math-only) + target_compile_options(sqlite3_bundled PRIVATE + -w -fno-finite-math-only -ffunction-sections + $<$>:-fdata-sections>) else() # Unstripped vendored build (Android legacy): keep the existing narrower # warning suppression. -fno-finite-math-only guards the INFINITY macro. - target_compile_options(sqlite3_bundled PRIVATE -fno-finite-math-only -Wno-unused-function) + target_compile_options(sqlite3_bundled PRIVATE + -fno-finite-math-only -Wno-unused-function -ffunction-sections + $<$>:-fdata-sections>) endif() endif() -# TODO: allow adding "${Tcmalloc_LIBRARIES}" to target_link_libraries for memory leak debugging -# (USE_TCMALLOC / FindTcmalloc.cmake are configured for Debug builds in the root CMakeLists.txt, -# but the library is not yet linked here). -if(MATSDK_USE_VCPKG_DEPS) - # vcpkg mode: all deps resolved via find_package() in root CMakeLists.txt - # These are PUBLIC so static-library consumers get the transitive link set - # through the exported MSTelemetry::mat target. - if(APPLE) - # macOS/iOS link the system libsqlite3 + libz (SQLite::SQLite3 / ZLIB::ZLIB - # resolve to the OS libraries via CMake's find modules), so the vcpkg - # sqlite3/zlib packages are neither pulled nor linked here. - target_link_libraries(mat - PUBLIC - SQLite::SQLite3 - ZLIB::ZLIB - nlohmann_json::nlohmann_json - ${LIBS} - ) +if(MATSDK_BUNDLE_ZLIB AND NOT TARGET zlib_bundled) + add_library(zlib_bundled STATIC + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/adler32.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/compress.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/crc32.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/deflate.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/gzclose.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/gzlib.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/gzread.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/gzwrite.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/infback.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/inffast.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/inflate.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/inftrees.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/trees.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/uncompr.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/zutil.c" + ) + target_include_directories(zlib_bundled PUBLIC + "$") + set_target_properties(zlib_bundled PROPERTIES + POSITION_INDEPENDENT_CODE ON + C_VISIBILITY_PRESET hidden) + if(NOT WIN32) + target_compile_definitions(zlib_bundled PRIVATE Z_HAVE_UNISTD_H) else() - if(MATSDK_BUNDLE_SQLITE) - # Private minimal SQLite instead of the vcpkg sqlite3 package. PRIVATE so its - # include dirs / compile definitions are not propagated as a public usage - # requirement. A static mat still propagates the archive itself for linking - # (via $), so it is added to the export set for static builds - # below; a shared mat absorbs it and propagates nothing. - target_link_libraries(mat PRIVATE sqlite3_bundled) - else() - target_link_libraries(mat PUBLIC unofficial::sqlite3::sqlite3) - endif() - target_link_libraries(mat - PUBLIC - ZLIB::ZLIB - nlohmann_json::nlohmann_json - ${LIBS} - ) + target_compile_definitions(zlib_bundled PRIVATE ZLIB_WINAPI) + target_compile_definitions(zlib_bundled INTERFACE + $) endif() + if(MSVC) + target_compile_options(zlib_bundled PRIVATE + /w /WX- /Gy + $<$:/Gw>) + else() + target_compile_options(zlib_bundled PRIVATE + -w -ffunction-sections + $<$>:-fdata-sections>) + endif() +endif() + +if(MATSDK_BUNDLE_SQLITE) + set(_matsdk_sqlite_target sqlite3_bundled) +elseif(MATSDK_SQLITE_TARGET) + set(_matsdk_sqlite_target "${MATSDK_SQLITE_TARGET}") +elseif(MATSDK_USE_VCPKG_DEPS AND NOT APPLE) + set(_matsdk_sqlite_target unofficial::sqlite3::sqlite3) +elseif(APPLE AND NOT MATSDK_USE_VCPKG_DEPS) + # Resolve from the selected Apple SDK, not host Homebrew/pkg-config paths. + set(_matsdk_sqlite_target sqlite3) else() - # Legacy mode: use vendored or system-installed deps - if(CMAKE_SYSTEM_NAME STREQUAL "Android") - # Build zlib from bundled source: the Android NDK ships no system zlib, and the - # vendored zlib renames its exports to act_z_* (via zlib/names.h). SQLite is - # provided by sqlite3_bundled, created above (MATSDK_BUNDLE_SQLITE is ON for - # the Android NDK path). - add_library(zlib_bundled STATIC - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/adler32.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/compress.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/crc32.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/deflate.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/gzclose.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/gzlib.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/gzread.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/gzwrite.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/infback.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/inffast.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/inflate.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/inftrees.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/trees.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/uncompr.c" - "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/zutil.c" - ) - target_include_directories(zlib_bundled PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../zlib") - set_target_properties(zlib_bundled PROPERTIES POSITION_INDEPENDENT_CODE ON) - # Bundled zlib compiles the pristine sources without zlib's configure step, - # so tell it is available (Android is POSIX). This gives gz*.c the - # real POSIX declarations for read/write/lseek/close instead of relying on - # implicit (int-returning) declarations. - target_compile_definitions(zlib_bundled PRIVATE Z_HAVE_UNISTD_H) + if(NOT TARGET SQLite::SQLite3) + find_package(SQLite3 REQUIRED) + endif() + set(_matsdk_sqlite_target SQLite::SQLite3) +endif() - target_link_libraries(mat PRIVATE sqlite3_bundled zlib_bundled ${LIBS}) - elseif(PAL_IMPLEMENTATION STREQUAL "WIN32") - # Windows legacy: vendored sqlite/zlib headers are included via - # include_directories in the PAL section above; link only explicit CMake deps - # (e.g. CURL if needed, or a parent-provided SQLite target). Parent-provided - # zlib is rejected in the root CMakeLists because the vendored zlib headers - # rename zlib symbols to act_z_* on this path. If no MATSDK_*_TARGET is - # supplied, legacy .vcxproj builds provide sqlite/zlib. - set(_matsdk_win32_deps ${LIBS}) - if(MATSDK_BUNDLE_SQLITE) - list(APPEND _matsdk_win32_deps sqlite3_bundled) - elseif(MATSDK_SQLITE_TARGET) - list(APPEND _matsdk_win32_deps "${MATSDK_SQLITE_TARGET}") - endif() - target_link_libraries(mat PRIVATE ${_matsdk_win32_deps}) - elseif(APPLE) - # macOS and iOS both ship system libsqlite3 and libz. Link them by portable - # names -- matching the SDK's own iOS Xcode projects (libsqlite3.tbd + libz.tbd - # from the SDKROOT), Package.swift (.linkedLibrary sqlite3/z), and the vcpkg - # Apple path -- so nothing is bundled and exported static packages stay - # relocatable. On Apple, #include / resolve from the SDK - # sysroot, so no explicit include dir or find_package is needed. - target_link_libraries(mat PRIVATE sqlite3 z ${LIBS}) - else() - # Linux legacy: system zlib + system (or private minimal) sqlite3. ZLIB::ZLIB - # and SQLite::SQLite3 are imported targets that carry their own include dirs. - if(MATSDK_ZLIB_TARGET) - set(_matsdk_zlib_target "${MATSDK_ZLIB_TARGET}") - else() - find_package(ZLIB REQUIRED) - set(_matsdk_zlib_target ZLIB::ZLIB) - endif() - if(MATSDK_BUNDLE_SQLITE) - target_link_libraries(mat PRIVATE sqlite3_bundled ${_matsdk_zlib_target} ${LIBS}) - else() - if(MATSDK_SQLITE_TARGET) - set(_matsdk_sqlite_target "${MATSDK_SQLITE_TARGET}") - else() - # find_package(SQLite3) needs CMake >= 3.14, guaranteed by the project floor; - # SQLite::SQLite3 is an imported target carrying its own include dirs. - find_package(SQLite3 REQUIRED) - set(_matsdk_sqlite_target SQLite::SQLite3) - endif() - target_link_libraries(mat PRIVATE ${_matsdk_sqlite_target} ${_matsdk_zlib_target} ${LIBS}) - endif() +if(MATSDK_BUNDLE_ZLIB) + set(_matsdk_zlib_target zlib_bundled) +elseif(MATSDK_ZLIB_TARGET) + set(_matsdk_zlib_target "${MATSDK_ZLIB_TARGET}") +elseif(APPLE AND NOT MATSDK_USE_VCPKG_DEPS) + # Resolve from the selected Apple SDK, not host Homebrew/pkg-config paths. + set(_matsdk_zlib_target z) +else() + if(NOT TARGET ZLIB::ZLIB) + find_package(ZLIB REQUIRED) endif() + set(_matsdk_zlib_target ZLIB::ZLIB) endif() +target_link_libraries(mat PRIVATE + ${_matsdk_sqlite_target} + ${_matsdk_zlib_target} + ${LIBS}) +if(MATSDK_USE_VCPKG_DEPS) + target_link_libraries(mat PRIVATE nlohmann_json::nlohmann_json) +endif() + +# TODO: allow adding "${Tcmalloc_LIBRARIES}" to target_link_libraries for memory leak debugging +# (USE_TCMALLOC / FindTcmalloc.cmake are configured for Debug builds in the root CMakeLists.txt, +# but the library is not yet linked here). + # Platform-specific link dependencies if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android") - target_link_libraries(mat PUBLIC "${CMAKE_THREAD_LIBS_INIT}" "${CMAKE_DL_LIBS}") - if(THREADS_HAVE_PTHREAD_ARG) - target_compile_options(mat PUBLIC "-pthread") - endif() + target_link_libraries(mat PUBLIC Threads::Threads "${CMAKE_DL_LIBS}") if(CMAKE_SYSTEM_NAME STREQUAL "Android") target_link_libraries(mat PUBLIC log) endif() @@ -632,7 +609,7 @@ elseif(APPLE) "-framework Network" "-framework SystemConfiguration" ) - if(BUILD_IOS OR CMAKE_SYSTEM_NAME STREQUAL "iOS") + if(MATSDK_BUILD_IOS OR CMAKE_SYSTEM_NAME STREQUAL "iOS") target_link_libraries(mat PUBLIC "-framework UIKit") else() target_link_libraries(mat PUBLIC "-framework IOKit") @@ -642,31 +619,40 @@ endif() ################################################################################################ # Installation ################################################################################################ -# The CMake package config / export workflow is used by vcpkg and any CMake-based -# consumer that does find_package(MSTelemetry). Legacy (non-vcpkg) builds install -# via install.sh or MSBuild output directories and don't need this. -if(MATSDK_USE_VCPKG_DEPS) - # A static libmat propagates its PRIVATE static dependencies through its link - # interface (as $), so the bundled SQLite must be part of the same - # export set and installed alongside mat for downstream find_package() consumers - # to link. A shared libmat absorbs sqlite3_bundled into the .so/.dylib/.dll and - # does not propagate the PRIVATE dep, so exporting the archive there is - # unnecessary (and risks a consumer linking a second SQLite copy) -- only export - # it for a static mat. - set(MATSDK_INSTALL_TARGETS mat) +# A static libmat propagates its private static dependencies at the final link, +# so install bundled archives beside it in both source and vcpkg workflows. +set(MATSDK_INSTALL_TARGETS mat) +get_target_property(_mat_type mat TYPE) +if(_mat_type STREQUAL "STATIC_LIBRARY") if(MATSDK_BUNDLE_SQLITE AND TARGET sqlite3_bundled) - get_target_property(_mat_type mat TYPE) - if(_mat_type STREQUAL "STATIC_LIBRARY") - list(APPEND MATSDK_INSTALL_TARGETS sqlite3_bundled) - endif() + list(APPEND MATSDK_INSTALL_TARGETS sqlite3_bundled) endif() + if(MATSDK_BUNDLE_ZLIB AND TARGET zlib_bundled) + list(APPEND MATSDK_INSTALL_TARGETS zlib_bundled) + endif() + foreach(_matsdk_fetched_target IN LISTS MATSDK_FETCHED_CURL_TARGETS) + if(TARGET ${_matsdk_fetched_target}) + list(APPEND MATSDK_INSTALL_TARGETS ${_matsdk_fetched_target}) + endif() + endforeach() +endif() + +if(MATSDK_USE_VCPKG_DEPS) install(TARGETS ${MATSDK_INSTALL_TARGETS} EXPORT MSTelemetryTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) +else() + install(TARGETS ${MATSDK_INSTALL_TARGETS} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) +endif() +if(MATSDK_USE_VCPKG_DEPS) message(STATUS "Library will be installed to ${CMAKE_INSTALL_LIBDIR}") # Generate and install CMake package config files @@ -698,11 +684,5 @@ if(MATSDK_USE_VCPKG_DEPS) DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MSTelemetry ) else() - # Legacy install: just put the library and headers in standard locations - install(TARGETS mat - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - ) message(STATUS "Library will be installed to ${CMAKE_INSTALL_LIBDIR}") endif() diff --git a/lib/pal/posix/DeviceInformationImpl_Android.cpp b/lib/pal/posix/DeviceInformationImpl_Android.cpp index 61746d664..fc132629d 100644 --- a/lib/pal/posix/DeviceInformationImpl_Android.cpp +++ b/lib/pal/posix/DeviceInformationImpl_Android.cpp @@ -52,8 +52,10 @@ namespace PAL_NS_BEGIN { ///// IDeviceInformation API DeviceInformationImpl::DeviceInformationImpl(IRuntimeConfig& configuration) : + m_os_architecture(OsArchitectureType_Unknown), + m_powerSource(PowerSource_Battery), m_info_helper(), - m_powerSource(PowerSource_Battery) + m_registeredCount(0) {} std::string DeviceInformationImpl::GetDeviceTicket() const @@ -260,4 +262,3 @@ Java_com_microsoft_applications_events_HttpClient_onPowerChange(JNIEnv* env, PAL::AndroidDeviceInformationConnector::setModel(std::string(start, end)); env->ReleaseStringUTFChars(model, start); } - diff --git a/lib/pal/posix/NetworkInformationImpl_Android.cpp b/lib/pal/posix/NetworkInformationImpl_Android.cpp index 0c12464b4..15e2d646d 100644 --- a/lib/pal/posix/NetworkInformationImpl_Android.cpp +++ b/lib/pal/posix/NetworkInformationImpl_Android.cpp @@ -42,9 +42,11 @@ namespace PAL_NS_BEGIN { NetworkCost AndroidNetcostConnector::s_cost = NetworkCost_Unknown; NetworkInformationImpl::NetworkInformationImpl(IRuntimeConfig& configuration) : - m_info_helper(), + m_type(NetworkType_Unknown), m_cost(NetworkCost_Unknown), - m_isNetDetectEnabled(configuration[CFG_BOOL_ENABLE_NET_DETECT]){}; + m_info_helper(), + m_registeredCount(0), + m_isNetDetectEnabled(configuration[CFG_BOOL_ENABLE_NET_DETECT]){} NetworkInformationImpl::~NetworkInformationImpl() {}; @@ -156,4 +158,3 @@ Java_com_microsoft_applications_events_HttpClient_onCostChange(JNIEnv* env, { PAL::AndroidNetcostConnector::UpdateCost(isMetered ? NetworkCost_Metered : NetworkCost_Unmetered); } - diff --git a/lib/pal/posix/SystemInformationImpl_Android.cpp b/lib/pal/posix/SystemInformationImpl_Android.cpp index 15e0bb9b1..b1911f8ae 100644 --- a/lib/pal/posix/SystemInformationImpl_Android.cpp +++ b/lib/pal/posix/SystemInformationImpl_Android.cpp @@ -163,8 +163,8 @@ namespace PAL_NS_BEGIN { std::string AndroidSystemInformationConnector::s_device_class; SystemInformationImpl::SystemInformationImpl(IRuntimeConfig& configuration) : - m_info_helper(), - m_os_name("Android") + m_os_name("Android"), + m_info_helper() { if (configuration.HasConfig(CFG_PTR_ANDROID_JVM) && configuration.HasConfig(CFG_JOBJECT_ANDROID_ACTIVITY)) { @@ -245,4 +245,3 @@ extern "C" JNIEXPORT void JNICALL Java_com_microsoft_applications_events_HttpCli PAL::AndroidSystemInformationConnector::s_device_class, deviceClass); } - diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a1d0a1351..e73c0d27b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -14,11 +14,11 @@ set(TESTS_COMMON_SRCS ../../lib/decoder/PayloadDecoder.cpp ) -if(BUILD_FUNC_TESTS) +if(MATSDK_BUILD_FUNC_TESTS) add_subdirectory(functests) endif() -if(BUILD_UNIT_TESTS) +if(MATSDK_BUILD_UNIT_TESTS) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/unittests) add_subdirectory(unittests) endif() diff --git a/tests/embedding/CMakeLists.txt b/tests/embedding/CMakeLists.txt index 58b9123e2..14ddbb803 100644 --- a/tests/embedding/CMakeLists.txt +++ b/tests/embedding/CMakeLists.txt @@ -5,14 +5,32 @@ set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -set(BUILD_HEADERS ON CACHE BOOL "" FORCE) -set(BUILD_LIBRARY ON CACHE BOOL "" FORCE) -set(BUILD_TEST_TOOL OFF CACHE BOOL "" FORCE) -set(BUILD_UNIT_TESTS OFF CACHE BOOL "" FORCE) -set(BUILD_FUNC_TESTS OFF CACHE BOOL "" FORCE) -set(BUILD_PACKAGE OFF CACHE BOOL "" FORCE) +set(MATSDK_LIBRARY_TYPE STATIC CACHE STRING "") +set(MATSDK_BUILD_HEADERS ON CACHE BOOL "" FORCE) +set(MATSDK_BUILD_LIBRARY ON CACHE BOOL "" FORCE) +set(MATSDK_BUILD_TEST_TOOL OFF CACHE BOOL "" FORCE) +set(MATSDK_BUILD_UNIT_TESTS OFF CACHE BOOL "" FORCE) +set(MATSDK_BUILD_FUNC_TESTS OFF CACHE BOOL "" FORCE) +set(MATSDK_BUILD_PACKAGE OFF CACHE BOOL "" FORCE) +set(MATSDK_BUILD_OBJC_WRAPPER OFF CACHE BOOL "" FORCE) +set(MATSDK_BUILD_SWIFT_WRAPPER OFF CACHE BOOL "" FORCE) +set(MATSDK_WARNINGS_AS_ERRORS ON CACHE BOOL "" FORCE) -add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../.." cpp_client_telemetry) +option(MATSDK_EMBEDDING_USE_FETCHCONTENT + "Exercise local-source FetchContent instead of add_subdirectory" OFF) +if(MATSDK_EMBEDDING_USE_FETCHCONTENT) + include(FetchContent) + FetchContent_Declare(cpp_client_telemetry + SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../..") + FetchContent_MakeAvailable(cpp_client_telemetry) +else() + add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../.." cpp_client_telemetry) +endif() add_executable(embedding_test "${CMAKE_CURRENT_LIST_DIR}/../vcpkg/main.cpp") target_link_libraries(embedding_test PRIVATE MSTelemetry::mat) +if(MSVC) + target_compile_options(embedding_test PRIVATE /W4 /WX) +else() + target_compile_options(embedding_test PRIVATE -Wall -Wextra -Werror) +endif() diff --git a/tests/functests/CMakeLists.txt b/tests/functests/CMakeLists.txt index d09e31f62..785926139 100644 --- a/tests/functests/CMakeLists.txt +++ b/tests/functests/CMakeLists.txt @@ -8,14 +8,14 @@ set(SRCS MultipleLogManagersTests.cpp ) -if(EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/privacyguard/" AND BUILD_PRIVACYGUARD) +if(EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/privacyguard/" AND MATSDK_BUILD_PRIVACYGUARD) add_definitions(-DHAVE_MAT_PRIVACYGUARD) list(APPEND SRCS "${PROJECT_SOURCE_DIR}/lib/modules/privacyguard/tests/functests/PrivacyGuardFuncTests.cpp" ) endif() -if(EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/sanitizer/" AND BUILD_SANITIZER) +if(EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/sanitizer/" AND MATSDK_BUILD_SANITIZER) list(APPEND SRCS "${PROJECT_SOURCE_DIR}/lib/modules/sanitizer/tests/functests/SanitizerFuncTests.cpp" ) @@ -27,7 +27,7 @@ if(EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/dataviewer/") ) endif() -if(EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/liveeventinspector/" AND BUILD_LIVEEVENTINSPECTOR) +if(EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/liveeventinspector/" AND MATSDK_BUILD_LIVEEVENTINSPECTOR) add_definitions(-DHAVE_MAT_LIVEEVENTINSPECTOR) list(APPEND SRCS "${PROJECT_SOURCE_DIR}/lib/modules/liveeventinspector/tests/functests/LiveEventInspectorFuncTests.cpp" @@ -48,7 +48,7 @@ endif() source_group(" " REGULAR_EXPRESSION "") source_group("common" REGULAR_EXPRESSION "/tests/common/") -if(BUILD_IOS) +if(MATSDK_BUILD_IOS) add_library(FuncTests ${SRCS} ${TESTS_COMMON_SRCS}) else() add_executable(FuncTests ${SRCS} ${TESTS_COMMON_SRCS}) @@ -61,15 +61,25 @@ if(PAL_IMPLEMENTATION STREQUAL "WIN32") message(STATUS "WIN32: ... ${PROJECT_BINARY_DIR}/gmock") message(STATUS "WIN32: ... ${PROJECT_BINARY_DIR}/zlib") message(STATUS "WIN32: ... ${PROJECT_BINARY_DIR}/sqlite") - # link_directories(${PROJECT_BINARY_DIR}/gtest/ ${PROJECT_BINARY_DIR}/gmock/ ${PROJECT_BINARY_DIR}/zlib/ ${PROJECT_BINARY_DIR}/sqlite/) include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../../zlib ) + if(TARGET zlib_bundled) + set(MATSDK_TEST_ZLIB zlib_bundled) + else() + set(MATSDK_TEST_ZLIB ${PROJECT_BINARY_DIR}/zlib/zlib.lib) + target_compile_definitions(FuncTests PRIVATE ZLIB_WINAPI) + endif() + if(TARGET sqlite3_bundled) + set(SQLITE3_LIB sqlite3_bundled) + else() + set(SQLITE3_LIB ${PROJECT_BINARY_DIR}/sqlite/sqlite.lib) + endif() target_link_libraries(FuncTests - mat - wininet.lib - ${PROJECT_BINARY_DIR}/gtest/gtest.lib - ${PROJECT_BINARY_DIR}/gmock/gmock.lib - ${PROJECT_BINARY_DIR}/zlib/zlib.lib - ${PROJECT_BINARY_DIR}/sqlite/sqlite.lib + mat + wininet.lib + ${PROJECT_BINARY_DIR}/gtest/gtest.lib + ${PROJECT_BINARY_DIR}/gmock/gmock.lib + ${MATSDK_TEST_ZLIB} + ${SQLITE3_LIB} ) else() @@ -99,7 +109,7 @@ else() # Add flags for obtaining system UUID via IOKit if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") set (PLATFORM_LIBS "-framework CoreFoundation -framework Foundation") - if(BUILD_IOS) + if(MATSDK_BUILD_IOS) set (PLATFORM_LIBS "${PLATFORM_LIBS} -framework UIKit -framework Network -framework SystemConfiguration") else() set (PLATFORM_LIBS "${PLATFORM_LIBS} -framework IOKit -framework Network -framework SystemConfiguration") @@ -154,4 +164,8 @@ else() endif() +if(TARGET nlohmann_json::nlohmann_json) + target_link_libraries(FuncTests PRIVATE nlohmann_json::nlohmann_json) +endif() + add_test(FuncTests FuncTests "--gtest_output=xml:${PROJECT_BINARY_DIR}/test-reports/FuncTests.xml") diff --git a/tests/unittests/CMakeLists.txt b/tests/unittests/CMakeLists.txt index 945fc23df..92f9eef8f 100644 --- a/tests/unittests/CMakeLists.txt +++ b/tests/unittests/CMakeLists.txt @@ -60,7 +60,7 @@ if (EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/azmon/AIJsonSerializer.hpp") endif() if (APPLE) - if (BUILD_IOS) + if (MATSDK_BUILD_IOS) list(APPEND SRCS SysInfoUtilsTests_iOS.cpp) else() list(APPEND SRCS SysInfoUtilsTests_Mac.cpp) @@ -75,7 +75,7 @@ if (EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/exp/tests") ) endif() -if(EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/privacyguard/" AND BUILD_PRIVACYGUARD) +if(EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/privacyguard/" AND MATSDK_BUILD_PRIVACYGUARD) add_definitions(-DHAVE_MAT_PRIVACYGUARD) list(APPEND SRCS "${PROJECT_SOURCE_DIR}/lib/modules/privacyguard/tests/unittests/InitializationConfigurationTests.cpp" @@ -86,7 +86,7 @@ if(EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/privacyguard/" AND BUILD_PRIVACYGUA ) endif() -if(EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/sanitizer/" AND BUILD_SANITIZER) +if(EXISTS "${PROJECT_SOURCE_DIR}/lib/modules/sanitizer/" AND MATSDK_BUILD_SANITIZER) list(APPEND SRCS "${PROJECT_SOURCE_DIR}/lib/modules/sanitizer/tests/unittests/SanitizerJwtTests.cpp" "${PROJECT_SOURCE_DIR}/lib/modules/sanitizer/tests/unittests/SanitizerProviderTests.cpp" @@ -108,7 +108,7 @@ endif() source_group(" " REGULAR_EXPRESSION "") source_group("common" REGULAR_EXPRESSION "/tests/common/") -if(BUILD_IOS) +if(MATSDK_BUILD_IOS) add_library(UnitTests STATIC ${SRCS} ${TESTS_COMMON_SRCS}) else() add_executable(UnitTests ${SRCS} ${TESTS_COMMON_SRCS}) @@ -121,15 +121,25 @@ if(PAL_IMPLEMENTATION STREQUAL "WIN32") message(STATUS "WIN32: ... ${PROJECT_BINARY_DIR}/gmock") message(STATUS "WIN32: ... ${PROJECT_BINARY_DIR}/zlib") message(STATUS "WIN32: ... ${PROJECT_BINARY_DIR}/sqlite") - # link_directories(${PROJECT_BINARY_DIR}/gtest/ ${PROJECT_BINARY_DIR}/gmock/ ${PROJECT_BINARY_DIR}/zlib/ ${PROJECT_BINARY_DIR}/sqlite/) include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../../zlib ) + if(TARGET zlib_bundled) + set(MATSDK_TEST_ZLIB zlib_bundled) + else() + set(MATSDK_TEST_ZLIB ${PROJECT_BINARY_DIR}/zlib/zlib.lib) + target_compile_definitions(UnitTests PRIVATE ZLIB_WINAPI) + endif() + if(TARGET sqlite3_bundled) + set(SQLITE3_LIB sqlite3_bundled) + else() + set(SQLITE3_LIB ${PROJECT_BINARY_DIR}/sqlite/sqlite.lib) + endif() target_link_libraries(UnitTests - mat - wininet.lib - ${PROJECT_BINARY_DIR}/gtest/gtest.lib - ${PROJECT_BINARY_DIR}/gmock/gmock.lib - ${PROJECT_BINARY_DIR}/zlib/zlib.lib - ${PROJECT_BINARY_DIR}/sqlite/sqlite.lib + mat + wininet.lib + ${PROJECT_BINARY_DIR}/gtest/gtest.lib + ${PROJECT_BINARY_DIR}/gmock/gmock.lib + ${MATSDK_TEST_ZLIB} + ${SQLITE3_LIB} ) else() @@ -162,7 +172,7 @@ else() # Add flags for obtaining system UUID via IOKit if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") set (PLATFORM_LIBS "-framework CoreFoundation -framework IOKit -framework SystemConfiguration -framework Foundation -framework Network") - if(BUILD_IOS) + if(MATSDK_BUILD_IOS) set (PLATFORM_LIBS "${PLATFORM_LIBS} -framework UIKit") endif() endif() @@ -220,4 +230,8 @@ else() endif() +if(TARGET nlohmann_json::nlohmann_json) + target_link_libraries(UnitTests PRIVATE nlohmann_json::nlohmann_json) +endif() + add_test(UnitTests UnitTests "--gtest_output=xml:${PROJECT_BINARY_DIR}/test-reports/UnitTests.xml") diff --git a/tools/ports/cpp-client-telemetry/portfile.cmake b/tools/ports/cpp-client-telemetry/portfile.cmake index c9ce3168c..e39854ff6 100644 --- a/tools/ports/cpp-client-telemetry/portfile.cmake +++ b/tools/ports/cpp-client-telemetry/portfile.cmake @@ -22,7 +22,7 @@ else() endif() # Determine if Apple HTTP should be used (no curl needed). -# Note: BUILD_APPLE_HTTP must remain ON for macOS/iOS because the vcpkg.json +# Note: MATSDK_BUILD_APPLE_HTTP must remain ON for macOS/iOS because the vcpkg.json # curl dependency is excluded on these platforms. set(MATSDK_BUILD_APPLE_HTTP OFF) if(VCPKG_TARGET_IS_OSX OR VCPKG_TARGET_IS_IOS) @@ -78,11 +78,35 @@ vcpkg_check_features( minimal-sqlite MATSDK_MINIMAL_SQLITE ) +if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic") + set(MATSDK_VCPKG_LIBRARY_TYPE SHARED) + set(MATSDK_VCPKG_BUILD_SHARED_LIBS ON) +else() + set(MATSDK_VCPKG_LIBRARY_TYPE STATIC) + set(MATSDK_VCPKG_BUILD_SHARED_LIBS OFF) +endif() + vcpkg_cmake_configure( SOURCE_PATH "${SOURCE_PATH}" OPTIONS ${FEATURE_OPTIONS} -DMATSDK_USE_VCPKG_DEPS=ON + -DMATSDK_LIBRARY_TYPE=${MATSDK_VCPKG_LIBRARY_TYPE} + -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_JNI_WRAPPER=OFF + -DMATSDK_BUILD_OBJC_WRAPPER=OFF + -DMATSDK_BUILD_SWIFT_WRAPPER=OFF + -DMATSDK_BUILD_PACKAGE=OFF + -DBUILD_VERSION=${VERSION} + -DMATSDK_BUILD_APPLE_HTTP=${MATSDK_BUILD_APPLE_HTTP} + -DMATSDK_BUILD_IOS=${MATSDK_BUILD_IOS} + # Legacy aliases keep the pinned release fallback buildable until the + # next release contains the canonical MATSDK_* options. + -DBUILD_SHARED_LIBS=${MATSDK_VCPKG_BUILD_SHARED_LIBS} -DBUILD_HEADERS=ON -DBUILD_LIBRARY=ON -DBUILD_TEST_TOOL=OFF @@ -92,7 +116,6 @@ vcpkg_cmake_configure( -DBUILD_OBJC_WRAPPER=OFF -DBUILD_SWIFT_WRAPPER=OFF -DBUILD_PACKAGE=OFF - -DBUILD_VERSION=${VERSION} -DBUILD_APPLE_HTTP=${MATSDK_BUILD_APPLE_HTTP} -DBUILD_IOS=${MATSDK_BUILD_IOS} ) From 0fbdc66df158d225fe385a3a41abe1732b678231 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 28 Jul 2026 18:49:11 -0500 Subject: [PATCH 6/9] Use typed libcurl write callbacks Pass curl_write_callback function pointers instead of converting function pointers to void*, and use void* only for callback userdata. This preserves portability on architectures where function and data pointers differ. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b12c5862-01e3-45e4-bf91-6389c20cae41 --- lib/http/HttpClient_Curl.hpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/http/HttpClient_Curl.hpp b/lib/http/HttpClient_Curl.hpp index 446bcd8a3..c8f70e36e 100644 --- a/lib/http/HttpClient_Curl.hpp +++ b/lib/http/HttpClient_Curl.hpp @@ -304,16 +304,18 @@ class CurlHttpOperation { if (rawResponse) { if (!SetOption(CURLOPT_HEADER, 1L) - || !SetOption(CURLOPT_WRITEFUNCTION, (void *)&WriteMemoryCallback) - || !SetOption(CURLOPT_WRITEDATA, (void *)&response)) + || !SetOption(CURLOPT_WRITEFUNCTION, + static_cast(&WriteMemoryCallback)) + || !SetOption(CURLOPT_WRITEDATA, static_cast(&response))) { DispatchEvent(OnSendFailed); goto cleanup; } } - else if (!SetOption(CURLOPT_WRITEFUNCTION, (void *)&WriteVectorCallback) - || !SetOption(CURLOPT_HEADERDATA, (void *)&respHeaders) - || !SetOption(CURLOPT_WRITEDATA, (void *)&respBody)) + else if (!SetOption(CURLOPT_WRITEFUNCTION, + static_cast(&WriteVectorCallback)) + || !SetOption(CURLOPT_HEADERDATA, static_cast(&respHeaders)) + || !SetOption(CURLOPT_WRITEDATA, static_cast(&respBody))) { DispatchEvent(OnSendFailed); goto cleanup; @@ -592,7 +594,7 @@ class CurlHttpOperation { * @param userp * @return */ - static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) + static size_t WriteMemoryCallback(char *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; struct MemoryStruct *mem = (struct MemoryStruct *)userp; @@ -624,10 +626,11 @@ class CurlHttpOperation { * @param data * @return */ - static size_t WriteVectorCallback(void *ptr, size_t size, size_t nmemb, std::vector* data) + static size_t WriteVectorCallback(char *ptr, size_t size, size_t nmemb, void* userp) { + auto* data = static_cast*>(userp); if (data != nullptr) { - const auto* begin = static_cast(ptr); + const auto* begin = reinterpret_cast(ptr); const auto* end = begin + size * nmemb; data->insert( data->end(), begin, end); } From 34137b6f56ed7edfd2930e11991ebd8a5aa752b8 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 28 Jul 2026 20:34:51 -0500 Subject: [PATCH 7/9] Use explicit Apple package-config boolean Substitute a build-platform boolean that is always TRUE or FALSE so generated package configs never depend on an undefined APPLE variable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b12c5862-01e3-45e4-bf91-6389c20cae41 --- CMakeLists.txt | 5 +++++ cmake/MSTelemetryConfig.cmake.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fa5950633..7cbc026dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,11 @@ if(NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET endif() project(MSTelemetry LANGUAGES C CXX) +if(APPLE) + set(MATSDK_BUILD_PLATFORM_APPLE TRUE) +else() + set(MATSDK_BUILD_PLATFORM_APPLE FALSE) +endif() ################################################################################################ # Vcpkg dependency mode: detect early so it can guard platform-specific flag logic diff --git a/cmake/MSTelemetryConfig.cmake.in b/cmake/MSTelemetryConfig.cmake.in index f51f4cb89..1f467cf23 100644 --- a/cmake/MSTelemetryConfig.cmake.in +++ b/cmake/MSTelemetryConfig.cmake.in @@ -4,7 +4,7 @@ include(CMakeFindDependencyMacro) # Re-find only dependencies that were external to the SDK package. if(NOT @MATSDK_BUNDLE_SQLITE@) - if(@APPLE@) + if(@MATSDK_BUILD_PLATFORM_APPLE@) find_dependency(SQLite3) else() find_dependency(unofficial-sqlite3 CONFIG) From abbe7bd8c441e69c59140e89e4d395a6826add35 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Tue, 28 Jul 2026 20:56:49 -0500 Subject: [PATCH 8/9] Finish curl response handling and build argument safety Capture response headers with an explicit typed callback, reject invalid or failed socket waits, and build CMake invocations as argv arrays so custom flags and universal architecture lists retain correct quoting. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b12c5862-01e3-45e4-bf91-6389c20cae41 --- build.sh | 27 ++++++++++++++++++++------- lib/http/HttpClient_Curl.hpp | 13 +++++++++---- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/build.sh b/build.sh index cf8f91ac3..e2f8bf121 100755 --- a/build.sh +++ b/build.sh @@ -70,7 +70,7 @@ while [[ $# -gt 0 ]]; do echo "MAC_ARCH = $MAC_ARCH" ;; CUSTOM_BUILD_FLAGS*) - CUSTOM_CMAKE_CXX_FLAG="\"${ARG:19:999}\"" + CUSTOM_CMAKE_CXX_FLAG="${ARG:19:999}" echo "custom compiler flags = $CUSTOM_CMAKE_CXX_FLAG" ;; *) @@ -185,17 +185,30 @@ fi # Fail on error set -e -APPLE_CMAKE_OPTS="" +cmake_args=(cmake) if [[ "$OS_NAME" == *Darwin* ]]; then if [[ "$MAC_ARCH" == "universal" ]]; then - APPLE_CMAKE_OPTS='-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"' + cmake_args+=("-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64") else - APPLE_CMAKE_OPTS="-DCMAKE_OSX_ARCHITECTURES=$MAC_ARCH" + cmake_args+=("-DCMAKE_OSX_ARCHITECTURES=$MAC_ARCH") fi fi -cmake_cmd="cmake $APPLE_CMAKE_OPTS -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_PACKAGE_TYPE=$CMAKE_PACKAGE_TYPE -DCMAKE_CXX_FLAGS="${CUSTOM_CMAKE_CXX_FLAG}" $CMAKE_OPTS .." -echo $cmake_cmd -eval $cmake_cmd +cmake_args+=( + "-DCMAKE_BUILD_TYPE=$BUILD_TYPE" + "-DCMAKE_PACKAGE_TYPE=$CMAKE_PACKAGE_TYPE" +) +if [[ -n "$CUSTOM_CMAKE_CXX_FLAG" ]]; then + cmake_args+=("-DCMAKE_CXX_FLAGS=$CUSTOM_CMAKE_CXX_FLAG") +fi +if [[ -n "$CMAKE_OPTS" ]]; then + # Preserve existing support for callers passing multiple quoted -D arguments. + eval "extra_cmake_args=($CMAKE_OPTS)" + cmake_args+=("${extra_cmake_args[@]}") +fi +cmake_args+=(..) +printf ' %q' "${cmake_args[@]}" +printf '\n' +"${cmake_args[@]}" # TODO: strip symbols to minimize (release-only) diff --git a/lib/http/HttpClient_Curl.hpp b/lib/http/HttpClient_Curl.hpp index c8f70e36e..391f5db55 100644 --- a/lib/http/HttpClient_Curl.hpp +++ b/lib/http/HttpClient_Curl.hpp @@ -230,6 +230,7 @@ class CurlHttpOperation { // Request buffer const void *request = requestBody.empty() ? nullptr : requestBody.data(); const size_t reqSize = requestBody.size(); + int socketWaitResult = 0; if(!curl || !m_isConfigured) { @@ -274,18 +275,20 @@ class CurlHttpOperation { sockextr = static_cast(lastSocket); } #endif - if(CURLE_OK != infoResult) + if(CURLE_OK != infoResult || sockextr == CURL_SOCKET_BAD) { - res = static_cast(infoResult); + res = static_cast( + infoResult != CURLE_OK ? infoResult : CURLE_COULDNT_CONNECT); DispatchEvent(OnConnectFailed); // couldn't connect - stage 2 - TRACE("Error #2: %s\n", curl_easy_strerror(infoResult)); + TRACE("Error #2: %s\n", curl_easy_strerror(static_cast(res))); goto cleanup; } } /* wait for the socket to become ready for sending */ sockfd = sockextr; - if( !WaitOnSocket(sockfd, 0, HTTP_CONN_TIMEOUT * 1000L) || isAborted) + socketWaitResult = WaitOnSocket(sockfd, 0, HTTP_CONN_TIMEOUT * 1000L); + if(socketWaitResult <= 0 || isAborted) { TRACE("Error #3: timeout, aborted=%u\n", isAborted.load() ); res = CURLE_OPERATION_TIMEDOUT; @@ -314,6 +317,8 @@ class CurlHttpOperation { } else if (!SetOption(CURLOPT_WRITEFUNCTION, static_cast(&WriteVectorCallback)) + || !SetOption(CURLOPT_HEADERFUNCTION, + static_cast(&WriteVectorCallback)) || !SetOption(CURLOPT_HEADERDATA, static_cast(&respHeaders)) || !SetOption(CURLOPT_WRITEDATA, static_cast(&respBody))) { From 00ce80ae173e41b8742c2ec694cf138bd9fe08d7 Mon Sep 17 00:00:00 2001 From: Bhagirath Mehta Date: Wed, 29 Jul 2026 11:23:01 -0500 Subject: [PATCH 9/9] Simplify recent CMake compatibility surface Remove recent redundant SQLite/vendor compatibility switches in favor of the explicit provider options, while retaining established legacy build inputs. Also reuse parent-provided CURL::libcurl automatically and make bundled Apple-mobile SQLite explicitly disable gethostuuid, matching the remaining useful ONNX Runtime patch behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b12c5862-01e3-45e4-bf91-6389c20cae41 --- .github/workflows/test-embedding.yml | 16 +++++++++--- CMakeLists.txt | 10 ++++++++ cmake/MatsdkOptions.cmake | 25 +++++-------------- lib/CMakeLists.txt | 8 ++++++ tests/embedding/CMakeLists.txt | 9 +++++++ .../ports/cpp-client-telemetry/portfile.cmake | 12 ++++----- 6 files changed, 51 insertions(+), 29 deletions(-) diff --git a/.github/workflows/test-embedding.yml b/.github/workflows/test-embedding.yml index f1049da92..bc0199b5c 100644 --- a/.github/workflows/test-embedding.yml +++ b/.github/workflows/test-embedding.yml @@ -28,12 +28,15 @@ jobs: - dependencies: system library-type: STATIC fetchcontent: OFF + preload-curl: ON - dependencies: system library-type: SHARED fetchcontent: ON + preload-curl: OFF - dependencies: self-contained library-type: STATIC fetchcontent: ON + preload-curl: OFF steps: - uses: actions/checkout@v4 - name: Install system dependencies @@ -48,6 +51,7 @@ jobs: -B build-embedding -DCMAKE_BUILD_TYPE=Release -DMATSDK_EMBEDDING_USE_FETCHCONTENT=${{ matrix.fetchcontent }} + -DMATSDK_EMBEDDING_PRELOAD_CURL=${{ matrix.preload-curl }} -DMATSDK_LIBRARY_TYPE=${{ matrix.library-type }} ) if [[ "${{ matrix.dependencies }}" == "self-contained" ]]; then @@ -107,7 +111,13 @@ jobs: runs-on: macos-latest strategy: matrix: - sdk: [iphoneos, iphonesimulator] + include: + - sdk: iphoneos + sqlite-provider: SYSTEM + zlib-provider: SYSTEM + - sdk: iphonesimulator + sqlite-provider: VENDORED + zlib-provider: VENDORED steps: - uses: actions/checkout@v4 - name: Configure @@ -121,8 +131,8 @@ jobs: -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=NO -DMATSDK_BUILD_IOS=ON -DMATSDK_EMBEDDING_USE_FETCHCONTENT=ON - -DMATSDK_SQLITE_PROVIDER=SYSTEM - -DMATSDK_ZLIB_PROVIDER=SYSTEM + -DMATSDK_SQLITE_PROVIDER=${{ matrix.sqlite-provider }} + -DMATSDK_ZLIB_PROVIDER=${{ matrix.zlib-provider }} - name: Build run: cmake --build build-embedding --config Release --target embedding_test --parallel 4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 7cbc026dd..4108ae131 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,13 @@ if(NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET set(CMAKE_OSX_DEPLOYMENT_TARGET "${IOS_DEPLOYMENT_TARGET}" CACHE STRING "Apple deployment target" FORCE) endif() +if((DEFINED FORCE_RESET_OSX_DEPLOYMENT_TARGET AND FORCE_RESET_OSX_DEPLOYMENT_TARGET) + OR (DEFINED FORCE_RESET_DEPLOYMENT_TARGET AND FORCE_RESET_DEPLOYMENT_TARGET)) + message(DEPRECATION + "FORCE_RESET_OSX_DEPLOYMENT_TARGET/FORCE_RESET_DEPLOYMENT_TARGET are no " + "longer needed. CMAKE_OSX_DEPLOYMENT_TARGET (or legacy " + "IOS_DEPLOYMENT_TARGET) is honored directly without mutating global flags.") +endif() project(MSTelemetry LANGUAGES C CXX) if(APPLE) @@ -273,6 +280,9 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11" include(cmake/MatsdkFetchCurl.cmake) matsdk_fetch_curl(_matsdk_curl_target) list(APPEND LIBS "${_matsdk_curl_target}") + elseif(TARGET CURL::libcurl) + # Parent superbuilds may create the canonical target before adding 1DS. + list(APPEND LIBS CURL::libcurl) else() find_package(CURL REQUIRED) # Prefer the imported target, which carries curl's include dirs and link diff --git a/cmake/MatsdkOptions.cmake b/cmake/MatsdkOptions.cmake index 111aa94b3..0adeec662 100644 --- a/cmake/MatsdkOptions.cmake +++ b/cmake/MatsdkOptions.cmake @@ -72,8 +72,8 @@ matsdk_bool_option(MATSDK_BUILD_IOS BUILD_IOS matsdk_bool_option(MATSDK_WARNINGS_AS_ERRORS "" "Treat warnings in SDK-owned targets as errors" "${MATSDK_PROJECT_IS_TOP_LEVEL}") -matsdk_bool_option(MATSDK_LINK_STATIC_DEPENDS LINK_STATIC_DEPENDS - "Link dependencies statically where supported" ON) +option(LINK_STATIC_DEPENDS + "Deprecated no-op retained for compatibility with legacy build scripts" ON) set(_matsdk_library_type_default STATIC) if(NOT DEFINED MATSDK_LIBRARY_TYPE AND DEFINED BUILD_SHARED_LIBS AND BUILD_SHARED_LIBS) @@ -94,10 +94,6 @@ set_property(CACHE MATSDK_SQLITE_PROVIDER PROPERTY STRINGS AUTO SYSTEM MINIMAL V set(MATSDK_ZLIB_PROVIDER "AUTO" CACHE STRING "zlib dependency provider: AUTO, SYSTEM, or VENDORED") set_property(CACHE MATSDK_ZLIB_PROVIDER PROPERTY STRINGS AUTO SYSTEM VENDORED) -option(MATSDK_MINIMAL_SQLITE - "Deprecated compatibility switch for MATSDK_SQLITE_PROVIDER=MINIMAL" OFF) -option(MATSDK_BUNDLE_VENDORED_DEPS - "Build the SDK's vendored SQLite and symbol-prefixed zlib" OFF) string(TOUPPER "${MATSDK_SQLITE_PROVIDER}" MATSDK_SQLITE_PROVIDER_RESOLVED) string(TOUPPER "${MATSDK_ZLIB_PROVIDER}" MATSDK_ZLIB_PROVIDER_RESOLVED) @@ -105,28 +101,19 @@ string(TOUPPER "${MATSDK_ZLIB_PROVIDER}" MATSDK_ZLIB_PROVIDER_RESOLVED) if(MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "AUTO") if(MATSDK_SQLITE_TARGET) set(MATSDK_SQLITE_PROVIDER_RESOLVED SYSTEM) - elseif(MATSDK_MINIMAL_SQLITE) - set(MATSDK_SQLITE_PROVIDER_RESOLVED MINIMAL) - elseif(MATSDK_BUNDLE_VENDORED_DEPS - OR (NOT MATSDK_USE_VCPKG_DEPS - AND (WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Android"))) + elseif(NOT MATSDK_USE_VCPKG_DEPS + AND (WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Android")) set(MATSDK_SQLITE_PROVIDER_RESOLVED VENDORED) else() set(MATSDK_SQLITE_PROVIDER_RESOLVED SYSTEM) endif() -elseif(MATSDK_MINIMAL_SQLITE - AND NOT MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "MINIMAL") - message(FATAL_ERROR - "MATSDK_MINIMAL_SQLITE=ON conflicts with " - "MATSDK_SQLITE_PROVIDER=${MATSDK_SQLITE_PROVIDER}.") endif() if(MATSDK_ZLIB_PROVIDER_RESOLVED STREQUAL "AUTO") if(MATSDK_ZLIB_TARGET) set(MATSDK_ZLIB_PROVIDER_RESOLVED SYSTEM) - elseif(MATSDK_BUNDLE_VENDORED_DEPS - OR (NOT MATSDK_USE_VCPKG_DEPS - AND (WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Android"))) + elseif(NOT MATSDK_USE_VCPKG_DEPS + AND (WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Android")) set(MATSDK_ZLIB_PROVIDER_RESOLVED VENDORED) else() set(MATSDK_ZLIB_PROVIDER_RESOLVED SYSTEM) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index b040def5c..0c46a861d 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -485,6 +485,14 @@ if(MATSDK_BUNDLE_SQLITE AND NOT TARGET sqlite3_bundled) # Feature-stripped build: apply the minimal definitions. target_compile_definitions(sqlite3_bundled PRIVATE ${MATSDK_SQLITE_MINIMAL_DEFS}) endif() + if(APPLE AND (MATSDK_BUILD_IOS + OR CMAKE_SYSTEM_NAME STREQUAL "iOS" + OR CMAKE_SYSTEM_NAME STREQUAL "visionOS")) + # SQLite already resolves this to false on Apple mobile platforms. Define it + # explicitly so the amalgamation does not emit its gethostuuid warning under + # consumer-provided warnings-as-errors. + target_compile_definitions(sqlite3_bundled PRIVATE HAVE_GETHOSTUUID=0) + endif() if(MSVC) # Silence the vendored amalgamation's warnings (/w) and turn off # warning-as-error (/WX-) for this third-party translation unit, so the SDK's diff --git a/tests/embedding/CMakeLists.txt b/tests/embedding/CMakeLists.txt index 14ddbb803..7c51fedf1 100644 --- a/tests/embedding/CMakeLists.txt +++ b/tests/embedding/CMakeLists.txt @@ -16,6 +16,15 @@ set(MATSDK_BUILD_OBJC_WRAPPER OFF CACHE BOOL "" FORCE) set(MATSDK_BUILD_SWIFT_WRAPPER OFF CACHE BOOL "" FORCE) set(MATSDK_WARNINGS_AS_ERRORS ON CACHE BOOL "" FORCE) +option(MATSDK_EMBEDDING_PRELOAD_CURL + "Pre-create CURL::libcurl and disable subsequent package discovery" OFF) +if(MATSDK_EMBEDDING_PRELOAD_CURL) + find_package(CURL REQUIRED) + # A later find_package(CURL REQUIRED) fails when this switch is enabled, so + # this configuration proves the SDK consumes the pre-created target directly. + set(CMAKE_DISABLE_FIND_PACKAGE_CURL ON CACHE BOOL "" FORCE) +endif() + option(MATSDK_EMBEDDING_USE_FETCHCONTENT "Exercise local-source FetchContent instead of add_subdirectory" OFF) if(MATSDK_EMBEDDING_USE_FETCHCONTENT) diff --git a/tools/ports/cpp-client-telemetry/portfile.cmake b/tools/ports/cpp-client-telemetry/portfile.cmake index e39854ff6..db547ae53 100644 --- a/tools/ports/cpp-client-telemetry/portfile.cmake +++ b/tools/ports/cpp-client-telemetry/portfile.cmake @@ -71,12 +71,10 @@ if(VCPKG_TARGET_IS_LINUX OR VCPKG_TARGET_IS_ANDROID) endif() endif() -# minimal-sqlite -> -DMATSDK_MINIMAL_SQLITE=ON (private feature-stripped SQLite). -vcpkg_check_features( - OUT_FEATURE_OPTIONS FEATURE_OPTIONS - FEATURES - minimal-sqlite MATSDK_MINIMAL_SQLITE -) +set(MATSDK_VCPKG_SQLITE_PROVIDER SYSTEM) +if("minimal-sqlite" IN_LIST FEATURES) + set(MATSDK_VCPKG_SQLITE_PROVIDER MINIMAL) +endif() if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic") set(MATSDK_VCPKG_LIBRARY_TYPE SHARED) @@ -89,8 +87,8 @@ endif() vcpkg_cmake_configure( SOURCE_PATH "${SOURCE_PATH}" OPTIONS - ${FEATURE_OPTIONS} -DMATSDK_USE_VCPKG_DEPS=ON + -DMATSDK_SQLITE_PROVIDER=${MATSDK_VCPKG_SQLITE_PROVIDER} -DMATSDK_LIBRARY_TYPE=${MATSDK_VCPKG_LIBRARY_TYPE} -DMATSDK_BUILD_HEADERS=ON -DMATSDK_BUILD_LIBRARY=ON