From 36bc8500bae1988a0372db840c6c6eb7e0144aaf Mon Sep 17 00:00:00 2001 From: Alex Forsythe Date: Mon, 2 Mar 2026 14:40:55 -0500 Subject: [PATCH 1/7] chore: Allow integration with dd-win-prof when DD_ENABLE_PROFILER=ON --- CMakeLists.txt | 10 ++++++--- cmake/DatadogConfig.cmake.in | 4 ++++ cmake/DatadogConvenience.cmake | 13 ++++++++++++ cmake/profiler.cmake | 37 ++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 7 +++++++ 5 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 cmake/profiler.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 5faef8e1..2afb5c81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,10 @@ endif() set(DD_ENABLE_SANITIZERS "${DD_ENABLE_SANITIZERS}" CACHE STRING "Comma-separated list of sanitizers to enable, e.g. 'ASan,UBSan', 'MSan,UBSan', 'TSan'") option(DD_ENABLE_ASSERTS "Enable assertions in Datadog SDK implementation" ${DD_DEVELOPMENT}) option(DD_ENABLE_TEST_ALLOCATION_TRACKING "Enable allocation tracking (via instrumented new/delete) in test binaries" ON) +option(DD_ENABLE_PROFILER "Enable integration with Datadog Windows Profiler" OFF) +if(DD_ENABLE_PROFILER AND NOT WIN32) + message(FATAL_ERROR "DD_ENABLE_PROFILER is only supported on Windows") +endif() # C API targets C99; C++ API targets C++17 if(DD_IS_TOP_LEVEL) @@ -57,9 +61,9 @@ if(DD_IS_TOP_LEVEL) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - # Crashpad requires C++20, so building the SDK with crashpad support requires - # targeting C++20 - if(DD_CRASH_MODE STREQUAL "crashpad") + # Crashpad and dd-win-prof both require C++20, so building the SDK with either + # enabled requires targeting C++20 + if(DD_CRASH_MODE STREQUAL "crashpad" OR DD_ENABLE_PROFILER) set(CMAKE_CXX_STANDARD 20) endif() endif() diff --git a/cmake/DatadogConfig.cmake.in b/cmake/DatadogConfig.cmake.in index 4e4a12bf..74a33b5e 100644 --- a/cmake/DatadogConfig.cmake.in +++ b/cmake/DatadogConfig.cmake.in @@ -27,6 +27,10 @@ if(DATADOG_BUILT_WITH_DD_HTTP_USE_SYSTEM_LIBCURL) find_dependency(CURL REQUIRED) endif() +# If the SDK was built with profiler support, expose this to consumers so that +# datadog_enable() can invoke dd_win_prof_copy_runtime_deps() as needed +set(DATADOG_BUILT_WITH_DD_ENABLE_PROFILER @DD_ENABLE_PROFILER@) + # If the SDK was built with Crashpad support, include CrashpadConfig.cmake, ensuring # that crashpad::client and crashpad::handler targets are defined set(DATADOG_BUILT_WITH_DD_CRASH_MODE "@DD_CRASH_MODE@") diff --git a/cmake/DatadogConvenience.cmake b/cmake/DatadogConvenience.cmake index 6ec9fce1..9c1e46d3 100644 --- a/cmake/DatadogConvenience.cmake +++ b/cmake/DatadogConvenience.cmake @@ -39,6 +39,19 @@ function(datadog_enable target) message(FATAL_ERROR "datadog_enable(): target crashpad::handler does not exist") endif() endif() + + # If the SDK was built with profiler support, copy the required runtime DLLs + # (dd-win-prof.dll and datadog_profiling_ffi.dll) alongside the application + # binary so they can be found at runtime. + if(DD_ENABLE_PROFILER OR DATADOG_BUILT_WITH_DD_ENABLE_PROFILER) + if(COMMAND dd_win_prof_copy_runtime_deps) + dd_win_prof_copy_runtime_deps(${target}) + else() + message(FATAL_ERROR + "datadog_enable(): dd_win_prof_copy_runtime_deps is not available; " + "ensure dd-win-prof was fetched before calling datadog_enable()") + endif() + endif() endfunction() # datadog_install(bin): diff --git a/cmake/profiler.cmake b/cmake/profiler.cmake new file mode 100644 index 00000000..77562520 --- /dev/null +++ b/cmake/profiler.cmake @@ -0,0 +1,37 @@ +include(FetchContent) + +# Allow overriding the GitHub fetch with a local clone of dd-win-prof. When +# set, CMake skips the network fetch and uses the local source directory +# directly. +set(DD_WIN_PROF_SOURCE_DIR "" CACHE PATH + "Local path to dd-win-prof source tree (overrides GitHub fetch)") + +if(DD_WIN_PROF_SOURCE_DIR) + FetchContent_Declare( + dd-win-prof + SOURCE_DIR "${DD_WIN_PROF_SOURCE_DIR}" + ) +else() + FetchContent_Declare( + dd-win-prof + GIT_REPOSITORY https://github.com/DataDog/dd-win-prof.git + GIT_TAG main + ) +endif() + +FetchContent_MakeAvailable(dd-win-prof) + +# Link the profiler into the SDK and expose the DD_PROFILER_ENABLED preprocessor +# macro so that consuming code can conditionally compile profiler-dependent paths. +target_link_libraries(dd_native PRIVATE dd-win-prof) +target_compile_definitions(dd_native PUBLIC DD_PROFILER_ENABLED) + +if(DD_BUILD_INSTALL) + # Install dd-win-prof.dll to bin/ so it ships alongside the SDK + install(TARGETS dd-win-prof RUNTIME DESTINATION bin) + + # Install datadog_profiling_ffi.dll, which dd-win-prof.dll loads at runtime. + # The path is config-specific; DD_WIN_PROF_LIBDATADOG_DIR is set by dd-win-prof's + # own CMakeLists via PARENT_SCOPE when FetchContent_MakeAvailable processes it. + install(FILES "$" DESTINATION bin) +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 74c55845..9046adb7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -234,3 +234,10 @@ if(DD_BUILD_INSTALL) RUNTIME DESTINATION bin ) endif() + +# If profiling support is enabled, fetch dd-win-prof and link it into the SDK. +# This must come after dd_native is fully configured so that the profiler module +# can read and modify its compile/link settings. +if(DD_ENABLE_PROFILER) + include(${DD_SDK_ROOT_DIR}/cmake/profiler.cmake) +endif() From 401dcdb99a18bfc828be1769a4a71d81fe412195 Mon Sep 17 00:00:00 2001 From: Alex Forsythe Date: Mon, 2 Mar 2026 14:42:04 -0500 Subject: [PATCH 2/7] chore: Fetch dd-win-prof at the aforsythe/cmake branch for now --- cmake/profiler.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/profiler.cmake b/cmake/profiler.cmake index 77562520..e4df1fe7 100644 --- a/cmake/profiler.cmake +++ b/cmake/profiler.cmake @@ -15,7 +15,7 @@ else() FetchContent_Declare( dd-win-prof GIT_REPOSITORY https://github.com/DataDog/dd-win-prof.git - GIT_TAG main + GIT_TAG aforsythe/cmake ) endif() From 98ed9a2c8ae71fcca92b144f6a43d3f1f9379982 Mon Sep 17 00:00:00 2001 From: Alex Forsythe Date: Mon, 2 Mar 2026 14:57:17 -0500 Subject: [PATCH 3/7] chore: Ensure that the dd-win-prof target is included in the export set --- cmake/profiler.cmake | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cmake/profiler.cmake b/cmake/profiler.cmake index e4df1fe7..6a088640 100644 --- a/cmake/profiler.cmake +++ b/cmake/profiler.cmake @@ -27,8 +27,12 @@ target_link_libraries(dd_native PRIVATE dd-win-prof) target_compile_definitions(dd_native PUBLIC DD_PROFILER_ENABLED) if(DD_BUILD_INSTALL) - # Install dd-win-prof.dll to bin/ so it ships alongside the SDK - install(TARGETS dd-win-prof RUNTIME DESTINATION bin) + # Install dd-win-prof.dll to bin/ so it ships alongside the SDK. Include it in + # the DatadogTargets export set since dd_native depends on it. + install(TARGETS dd-win-prof + EXPORT DatadogTargets + RUNTIME DESTINATION bin + ) # Install datadog_profiling_ffi.dll, which dd-win-prof.dll loads at runtime. # The path is config-specific; DD_WIN_PROF_LIBDATADOG_DIR is set by dd-win-prof's From 61d02dbcbc1fe4f80af512024ff9259474cb9f97 Mon Sep 17 00:00:00 2001 From: Alex Forsythe Date: Mon, 2 Mar 2026 16:08:05 -0500 Subject: [PATCH 4/7] chore: Suppress strict errors in Catch2 headers --- cmake/deps/catch2.cmake | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmake/deps/catch2.cmake b/cmake/deps/catch2.cmake index 0b5208b8..222bd779 100644 --- a/cmake/deps/catch2.cmake +++ b/cmake/deps/catch2.cmake @@ -15,3 +15,11 @@ FetchContent_Declare( DOWNLOAD_EXTRACT_TIMESTAMP true ) FetchContent_MakeAvailable(Catch2) + +# Mark Catch2 includes as SYSTEM to suppress warnings from its headers +set_target_properties(Catch2 PROPERTIES + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $ +) +set_target_properties(Catch2WithMain PROPERTIES + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $ +) From e2a9c5a8eac880acfbd61c76f385e8218395fed8 Mon Sep 17 00:00:00 2001 From: Alex Forsythe Date: Mon, 2 Mar 2026 18:01:30 -0500 Subject: [PATCH 5/7] chore: Explicit suppress pesky Catch2 warnings in MSVC --- tests/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e9818fa4..111fdf3d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -122,6 +122,11 @@ target_link_libraries(dd_native_tests Catch2::Catch2WithMain ) +# Suppress unreachable code warnings from Catch2 headers on MSVC +if(MSVC) + target_compile_options(dd_native_tests PRIVATE /wd4702) +endif() + # Register tests with CTest include(CTest) include(Catch) From 96585995ce0afae9d9d3beace094de9588887a92 Mon Sep 17 00:00:00 2001 From: Alex Forsythe Date: Tue, 3 Mar 2026 11:54:29 -0500 Subject: [PATCH 6/7] chore: Update `datadog_install` to deploy profiler DLLs if needed --- cmake/DatadogConvenience.cmake | 41 ++++++++++++++++++++++++++++------ cmake/profiler.cmake | 2 -- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/cmake/DatadogConvenience.cmake b/cmake/DatadogConvenience.cmake index 9c1e46d3..1cd80c5c 100644 --- a/cmake/DatadogConvenience.cmake +++ b/cmake/DatadogConvenience.cmake @@ -54,16 +54,17 @@ function(datadog_enable target) endif() endfunction() -# datadog_install(bin): +# datadog_install(destination): # -# - (if Crashpad support is enabled) ensures that the crashpad_handler executable will -# be copied to bin/ alongside your application +# Installs runtime dependencies required by the SDK alongside your application: +# - (if Crashpad support is enabled) copies the crashpad_handler executable +# - (if Profiler support is enabled) copies dd-win-prof.dll and datadog_profiling_ffi.dll # # Call this function after defining `install(TARGETS my-app ...)` for your app, -# specifying the destination directory for your application's binaries in lieu of `bin`. -# You may elect not to call this function if a.) your project does not use CMake -# installation rules, b.) you don't need Crashpad support, or c.) you are ensuring that -# the crashpad_handler exectuable makes its way into your builds through other means. +# specifying the destination directory for your application's binaries (typically "bin"). +# You may elect not to call this function if: a.) your project does not use CMake +# installation rules, b.) you don't need Crashpad or Profiler support, or c.) you are +# handling runtime dependencies through other means. # function(datadog_install destination) # If the SDK was built with crashpad support, install the crashpad_handler @@ -76,4 +77,30 @@ function(datadog_install destination) message(FATAL_ERROR "datadog_install(): target crashpad::handler does not exist") endif() endif() + + # If the SDK was built with profiler support, install the required runtime DLLs + # to the destination directory + if((DD_ENABLE_PROFILER) OR (DATADOG_BUILT_WITH_DD_ENABLE_PROFILER)) + if(TARGET dd-win-prof) + # Try to get imported location (for find_package case) + get_target_property(DD_WIN_PROF_DLL dd-win-prof IMPORTED_LOCATION) + + if(DD_WIN_PROF_DLL AND NOT DD_WIN_PROF_DLL MATCHES "-NOTFOUND$") + # Imported target case: install the DLL from its imported location + install(PROGRAMS ${DD_WIN_PROF_DLL} DESTINATION ${destination}) + + # Also install datadog_profiling_ffi.dll from the same directory + get_filename_component(DD_WIN_PROF_DIR ${DD_WIN_PROF_DLL} DIRECTORY) + install(PROGRAMS "${DD_WIN_PROF_DIR}/datadog_profiling_ffi.dll" DESTINATION ${destination}) + else() + # FetchContent case: use generator expressions to get target files + install(FILES "$" DESTINATION ${destination}) + if(TARGET libdatadog_dynamic) + install(FILES "$" DESTINATION ${destination}) + endif() + endif() + else() + message(FATAL_ERROR "datadog_install(): target dd-win-prof does not exist") + endif() + endif() endfunction() diff --git a/cmake/profiler.cmake b/cmake/profiler.cmake index 6a088640..715d4a32 100644 --- a/cmake/profiler.cmake +++ b/cmake/profiler.cmake @@ -35,7 +35,5 @@ if(DD_BUILD_INSTALL) ) # Install datadog_profiling_ffi.dll, which dd-win-prof.dll loads at runtime. - # The path is config-specific; DD_WIN_PROF_LIBDATADOG_DIR is set by dd-win-prof's - # own CMakeLists via PARENT_SCOPE when FetchContent_MakeAvailable processes it. install(FILES "$" DESTINATION bin) endif() From 1a4202fd02157046436ad5bc2f3d455f2994516b Mon Sep 17 00:00:00 2001 From: Alex Forsythe Date: Wed, 4 Mar 2026 10:24:28 -0500 Subject: [PATCH 7/7] chore: Make dd-win-prof a public dependency --- cmake/profiler.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/profiler.cmake b/cmake/profiler.cmake index 715d4a32..fe69d876 100644 --- a/cmake/profiler.cmake +++ b/cmake/profiler.cmake @@ -21,10 +21,10 @@ endif() FetchContent_MakeAvailable(dd-win-prof) -# Link the profiler into the SDK and expose the DD_PROFILER_ENABLED preprocessor -# macro so that consuming code can conditionally compile profiler-dependent paths. -target_link_libraries(dd_native PRIVATE dd-win-prof) -target_compile_definitions(dd_native PUBLIC DD_PROFILER_ENABLED) +# Link dd-win-prof into the SDK. For the time being, we don't wrap dd-win-prof in an SDK +# feature: the application is just expected to include dd-win-prof.h and call the +# profiling API directly. Therefore, it's declared as a PUBLIC dependency. +target_link_libraries(dd_native PUBLIC dd-win-prof) if(DD_BUILD_INSTALL) # Install dd-win-prof.dll to bin/ so it ships alongside the SDK. Include it in