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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/test-embedding.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,24 @@ jobs:
cmake --build build-provided-consumer --parallel 4
ctest --test-dir build-provided-consumer --output-on-failure

linux-lifetime-sanitizers:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev libsqlite3-dev ninja-build zlib1g-dev
- name: Configure ASan and LSan embedding regressions
run: >
cmake -G Ninja -S tests/embedding -B build-lifetimes
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DMATSDK_EMBEDDING_ADDRESS_SANITIZER=ON
-DMATSDK_SQLITE_PROVIDER=SYSTEM
-DMATSDK_ZLIB_PROVIDER=SYSTEM
- name: Build and run
run: |
cmake --build build-lifetimes --target embedding_test --parallel 4
ctest --test-dir build-lifetimes --output-on-failure

windows:
runs-on: windows-2022
steps:
Expand Down
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ if(TARGET SQLite::SQLite3 AND NOT TARGET SQLite3::SQLite3)
matsdk_add_interface_dependency(SQLite3::SQLite3 SQLite::SQLite3)
endif()
if(MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "SYSTEM" AND NOT TARGET SQLite3::SQLite3)
if(APPLE AND NOT MATSDK_USING_VCPKG)
if(APPLE)
matsdk_add_apple_system_library(SQLite3::SQLite3 sqlite3)
set(MATSDK_SQLITE_DEPENDENCY_KIND APPLE_SYSTEM)
else()
Expand All @@ -253,7 +253,7 @@ if(MATSDK_SQLITE_PROVIDER_RESOLVED STREQUAL "SYSTEM" AND NOT TARGET SQLite3::SQL
endif()

if(MATSDK_ZLIB_PROVIDER_RESOLVED STREQUAL "SYSTEM" AND NOT TARGET ZLIB::ZLIB)
if(APPLE AND NOT MATSDK_USING_VCPKG)
if(APPLE)
matsdk_add_apple_system_library(ZLIB::ZLIB z)
set(MATSDK_ZLIB_DEPENDENCY_KIND APPLE_SYSTEM)
else()
Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ let package = Package(
name: "MATTelemetry",
path: "build/apple/MATTelemetry.xcframework") : .binaryTarget(
name: "MATTelemetry",
url: "https://github.com/microsoft/cpp_client_telemetry/releases/download/v3.10.309.1/MATTelemetry.xcframework.zip",
checksum: "12b20684bcf09f8daec9c5ee1a1ecd567c354d4dea3273ba7023a40b7d0c4589"),
url: "https://github.com/microsoft/cpp_client_telemetry/releases/download/v3.10.310.1/MATTelemetry.xcframework.zip",
checksum: "3d6d3b98e1696efce9bdad4d6eca177006b75b0a28fa866e75db6bf18e2cb8a9"),

// Thin Swift API layer (source). Depends on the Obj-C module from the
// xcframework. The conditional source exclusions above must stay in sync
Expand Down
5 changes: 5 additions & 0 deletions cmake/MatsdkOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ option(MATSDK_BUILD_AZMON
"Build Azure Monitor / Application Insights support" ON)
option(MATSDK_BUILD_APPLE_HTTP
"Build the Apple-native HTTP client" "${APPLE}")
set(MATSDK_APPLE_HTTP_DELEGATE_CLASS "MATStreamingSessionDelegate" CACHE STRING
"Private Objective-C class name for the Apple HTTP session delegate")
if(NOT MATSDK_APPLE_HTTP_DELEGATE_CLASS MATCHES "^[A-Za-z_][A-Za-z0-9_]*$")
message(FATAL_ERROR "MATSDK_APPLE_HTTP_DELEGATE_CLASS must be a C identifier.")
endif()
option(MATSDK_USE_WININET
"Use WinInet instead of WinHTTP as the Win32 desktop HTTP client" OFF)
option(MATSDK_DISABLE_LOGGING
Expand Down
16 changes: 15 additions & 1 deletion docs/embedding-with-cmake.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ Recommended packaged-library policy:
| Android | `MINIMAL`, or `NONE` with Room | `VENDORED` | Java/JNI by default |

Apple's SQLite and zlib entries are system libraries: consumers link them but
do not ship private copies. A Linux host such as Foundry Local that already
do not ship private copies, including when a vcpkg toolchain is active. Existing
caller-provided canonical targets still take precedence. A Linux host such as Foundry Local that already
standardizes on libcurl/OpenSSL should provide `CURL::libcurl` and select
`MATSDK_CURL_PROVIDER=SYSTEM`; other self-contained Linux consumers can use the
SDK's pinned curl/mbedTLS build.
Expand All @@ -71,6 +72,19 @@ consumer must set `skipSqliteInitAndShutdown` to `"true"` and leave SQLite's
process-wide lifetime to the host. This is the required configuration for
coexisting Apple libraries that all link the system `libsqlite3`.

When independently embedded SDK copies coexist in an Apple process, choose a
different private HTTP delegate class name for each copy before adding the SDK:

```cmake
set(MATSDK_APPLE_HTTP_DELEGATE_CLASS MyProductMATStreamingSessionDelegate
CACHE STRING "" FORCE)
```

The default remains `MATStreamingSessionDelegate`. Objective-C class names are
process-global even when C++ symbols are hidden. This setting affects only the
Apple HTTP implementation and does not propagate to consumers or rename public
Objective-C wrapper classes.

## Non-vcpkg dependency selection

When the CPP11 PAL uses the curl HTTP transport outside vcpkg, the SDK normally
Expand Down
5 changes: 5 additions & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,11 @@ else()
message(STATUS "Building static SDK library")
add_library(mat STATIC ${SRCS})
endif()
if(APPLE AND MATSDK_BUILD_APPLE_HTTP)
# Objective-C class names are process-global, even with hidden symbol visibility.
target_compile_definitions(mat PRIVATE
"MATStreamingSessionDelegate=${MATSDK_APPLE_HTTP_DELEGATE_CLASS}")
endif()
target_link_libraries(mat PRIVATE
$<BUILD_INTERFACE:matsdk_build_options>
$<BUILD_INTERFACE:matsdk_internal_config>)
Expand Down
8 changes: 6 additions & 2 deletions lib/api/AuthTokensController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "AuthTokensController.hpp"
#include "ILogManager.hpp"
#include "utils/Utils.hpp"
#include <new>

namespace MAT_NS_BEGIN {

Expand All @@ -24,8 +25,11 @@ namespace MAT_NS_BEGIN {

std::mutex& AuthTokensController::GetMutex()
{
static std::mutex mutex;
return mutex;
// Like GetPAL(), this lock must survive late upload workers.
using AuthMutex = std::mutex;
alignas(AuthMutex) static unsigned char storage[sizeof(AuthMutex)];
static AuthMutex* mutex = ::new (storage) AuthMutex;
return *mutex;
}

status_t AuthTokensController::SetTicketToken(TicketType type, char const* tokenValue)
Expand Down
6 changes: 3 additions & 3 deletions lib/include/public/Version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#define MAT_VERSION_HPP
// WARNING: DO NOT MODIFY THIS FILE!
// This file has been automatically generated, manual changes will be lost.
#define BUILD_VERSION_STR "3.10.310.1"
#define BUILD_VERSION 3,10,310,1
#define BUILD_VERSION_STR "3.10.312.1"
#define BUILD_VERSION 3,10,312,1

#ifndef RESOURCE_COMPILER_INVOKED
#include "ctmacros.hpp"
Expand All @@ -18,7 +18,7 @@ namespace MAT_NS_BEGIN {
uint64_t const Version =
((uint64_t)3 << 48) |
((uint64_t)10 << 32) |
((uint64_t)310 << 16) |
((uint64_t)312 << 16) |
((uint64_t)1);

} MAT_NS_END
Expand Down
6 changes: 3 additions & 3 deletions lib/pal/PAL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,10 +629,10 @@ namespace PAL_NS_BEGIN {
#define OS_NAME "Unknown"
#endif

const std::string& PlatformAbstractionLayer::getSdkVersion() const
const char* PlatformAbstractionLayer::getSdkVersion() const
{
static const std::string sdkVersion(EVTSDK_VERSION_PREFIX "-" OS_NAME "-C++-" ECS_SUPP "-" BUILD_VERSION_STR);
return sdkVersion;
// A literal survives late workers without leaking a string buffer on library unload.
return EVTSDK_VERSION_PREFIX "-" OS_NAME "-C++-" ECS_SUPP "-" BUILD_VERSION_STR;
}

void PlatformAbstractionLayer::initialize(IRuntimeConfig& configuration)
Expand Down
4 changes: 2 additions & 2 deletions lib/pal/PAL.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ namespace PAL_NS_BEGIN
public:
void sleep(unsigned delayMs) const noexcept;

const std::string& getSdkVersion() const;
const char* getSdkVersion() const;

std::string generateUuidString() const;

Expand Down Expand Up @@ -136,7 +136,7 @@ namespace PAL_NS_BEGIN
/**
* Return SDK version in format "<Prefix>-<Platform>-<SKU>-<Projection>-<BuildVersion>".
*/
inline const std::string& getSdkVersion()
inline const char* getSdkVersion()
{
return GetPAL().getSdkVersion();
}
Expand Down
43 changes: 43 additions & 0 deletions tests/apple/embedding-options-tests.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
cmake_minimum_required(VERSION 3.19)
get_filename_component(sdk_root "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
if(NOT DEFINED OUTPUT_DIR)
set(OUTPUT_DIR "${sdk_root}/out/apple-embedding-options")
endif()
set(generator_args)
if(TEST_GENERATOR)
list(APPEND generator_args -G "${TEST_GENERATOR}")
endif()
if(TEST_GENERATOR_PLATFORM)
list(APPEND generator_args -A "${TEST_GENERATOR_PLATFORM}")
endif()

function(check_options apple vcpkg provided http class)
# Keep MSBuild's nested compiler-probe paths below its legacy path limit.
string(SHA1 name "${apple}-${vcpkg}-${provided}-${http}-${class}")
string(SUBSTRING "${name}" 0 6 name)
execute_process(COMMAND "${CMAKE_COMMAND}" ${generator_args}
-S "${CMAKE_CURRENT_LIST_DIR}/embedding-options" -B "${OUTPUT_DIR}/${name}"
"-DSDK_ROOT=${sdk_root}" "-DTEST_APPLE=${apple}" "-DTEST_VCPKG=${vcpkg}"
"-DTEST_PROVIDED=${provided}" "-DTEST_HTTP=${http}"
"-DMATSDK_APPLE_HTTP_DELEGATE_CLASS=${class}"
RESULT_VARIABLE result OUTPUT_VARIABLE output ERROR_VARIABLE error)
if(class STREQUAL "invalid-class")
if(result EQUAL 0 OR NOT error MATCHES "must be a C identifier")
message(FATAL_ERROR "Invalid delegate name was not rejected:\n${output}\n${error}")
endif()
elseif(NOT result EQUAL 0)
message(FATAL_ERROR "${apple}/${vcpkg}/${provided}/${http}/${class} failed:\n${output}\n${error}")
endif()
endfunction()

foreach(apple ON OFF)
foreach(vcpkg ON OFF)
foreach(provided ON OFF)
check_options("${apple}" "${vcpkg}" "${provided}" ON MATStreamingSessionDelegate)
check_options("${apple}" "${vcpkg}" "${provided}" ON ProductMATStreamingSessionDelegate)
endforeach()
endforeach()
endforeach()
check_options(ON ON OFF OFF ProductMATStreamingSessionDelegate)
check_options(ON ON OFF ON invalid-class)
message(STATUS "18 Apple dependency/delegate configurations passed")
70 changes: 70 additions & 0 deletions tests/apple/embedding-options/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
cmake_minimum_required(VERSION 3.19)
project(apple_embedding_options LANGUAGES C CXX)

file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/platform.cmake" "set(APPLE ${TEST_APPLE})\n")
set(CMAKE_PROJECT_INCLUDE "${CMAKE_CURRENT_BINARY_DIR}/platform.cmake")
set(APPLE "${TEST_APPLE}")
if(TEST_VCPKG)
set(VCPKG_TARGET_TRIPLET test-triplet)
endif()
set(MATSDK_BUILD_HEADERS OFF CACHE BOOL "" FORCE)
set(MATSDK_BUILD_LIBRARY OFF 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_APPLE_HTTP "${TEST_HTTP}" CACHE BOOL "" FORCE)
set(MATSDK_SQLITE_PROVIDER SYSTEM CACHE STRING "" FORCE)
set(MATSDK_ZLIB_PROVIDER SYSTEM CACHE STRING "" FORCE)
add_library(CURL::libcurl INTERFACE IMPORTED)
add_library(nlohmann_json::nlohmann_json INTERFACE IMPORTED)
if(TEST_PROVIDED OR NOT TEST_APPLE)
add_library(SQLite3::SQLite3 INTERFACE IMPORTED)
add_library(ZLIB::ZLIB INTERFACE IMPORTED)
set_property(TARGET SQLite3::SQLite3 PROPERTY INTERFACE_LINK_LIBRARIES caller-sqlite)
set_property(TARGET ZLIB::ZLIB PROPERTY INTERFACE_LINK_LIBRARIES caller-zlib)
endif()
foreach(package SQLite3 unofficial-sqlite3 ZLIB nlohmann_json)
set(CMAKE_DISABLE_FIND_PACKAGE_${package} ON)
endforeach()
add_subdirectory("${SDK_ROOT}" sdk)
foreach(pair "SQLite3::SQLite3|sqlite3|caller-sqlite" "ZLIB::ZLIB|z|caller-zlib")
string(REPLACE "|" ";" pair "${pair}")
list(GET pair 0 target)
list(GET pair 1 expected)
if(TEST_PROVIDED OR NOT TEST_APPLE)
list(GET pair 2 expected)
endif()
get_target_property(links "${target}" INTERFACE_LINK_LIBRARIES)
if(NOT links STREQUAL expected)
message(FATAL_ERROR "${target} links ${links}, expected ${expected}")
endif()
endforeach()

# Evaluate the production target guard without requiring an Apple compiler or SDK.
file(READ "${SDK_ROOT}/lib/CMakeLists.txt" library)
string(FIND "${library}" "if(APPLE AND MATSDK_BUILD_APPLE_HTTP)" start)
if(start EQUAL -1)
message(FATAL_ERROR "Update Apple delegate target instrumentation")
endif()
string(SUBSTRING "${library}" ${start} -1 definition)
string(FIND "${definition}" "\nendif()" end)
math(EXPR end "${end} + 8")
string(SUBSTRING "${definition}" 0 ${end} definition)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/delegate.cpp" "")
add_library(mat STATIC "${CMAKE_CURRENT_BINARY_DIR}/delegate.cpp")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/delegate.cmake" "${definition}")
include("${CMAKE_CURRENT_BINARY_DIR}/delegate.cmake")
get_target_property(private mat COMPILE_DEFINITIONS)
get_target_property(public mat INTERFACE_COMPILE_DEFINITIONS)
set(expected "MATStreamingSessionDelegate=${MATSDK_APPLE_HTTP_DELEGATE_CLASS}")
if(TEST_APPLE AND TEST_HTTP)
if(NOT expected IN_LIST private)
message(FATAL_ERROR "Missing private Apple delegate definition: ${private}")
endif()
elseif(expected IN_LIST private)
message(FATAL_ERROR "Delegate definition leaked into a non-Apple HTTP build")
endif()
if(expected IN_LIST public)
message(FATAL_ERROR "Delegate definition propagated to consumers")
endif()
26 changes: 26 additions & 0 deletions tests/embedding/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,22 @@ set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

option(MATSDK_EMBEDDING_ADDRESS_SANITIZER
"Run embedding regressions with AddressSanitizer and leak detection" OFF)
if(MATSDK_EMBEDDING_ADDRESS_SANITIZER)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
message(FATAL_ERROR "Embedding ASan/LSan coverage requires Linux with GCC or Clang")
endif()
add_compile_options(-fsanitize=address -fno-omit-frame-pointer)
add_link_options(-fsanitize=address)
endif()

set(BUILD_SHARED_LIBS OFF CACHE BOOL "")
if(MATSDK_EMBEDDING_ADDRESS_SANITIZER AND BUILD_SHARED_LIBS)
message(FATAL_ERROR "Embedding ASan/LSan coverage requires static SDK embedding")
endif()

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)
Expand Down Expand Up @@ -114,3 +129,14 @@ endif()

enable_testing()
add_test(NAME embedding_test COMMAND embedding_test)
include("${CMAKE_CURRENT_LIST_DIR}/lifetime-tests.cmake")
if(MATSDK_EMBEDDING_ADDRESS_SANITIZER)
set_tests_properties(sdk_version_reload PROPERTIES
ENVIRONMENT "ASAN_OPTIONS=detect_leaks=1;LSAN_OPTIONS=exitcode=23")
endif()
add_test(NAME apple_embedding_options
COMMAND "${CMAKE_COMMAND}"
"-DOUTPUT_DIR=${CMAKE_CURRENT_BINARY_DIR}/apple-options"
"-DTEST_GENERATOR=${CMAKE_GENERATOR}"
"-DTEST_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}"
-P "${CMAKE_CURRENT_LIST_DIR}/../apple/embedding-options-tests.cmake")
Loading
Loading