From 85913c6dbbad740b917ba43012e0f865e3f43b07 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 9 Apr 2026 10:52:14 +0200 Subject: [PATCH 1/6] fix: Embed debug info in static library to avoid LNK4099 warnings 3442a21b (#1610) added CMP0141 NEW for sccache support. This policy defaults CMAKE_MSVC_DEBUG_INFORMATION_FORMAT to ProgramDatabase (/Zi) for Debug and RelWithDebInfo configurations: https://cmake.org/cmake/help/latest/policy/CMP0141.html This causes static libraries to reference an external PDB. Since static libraries are distributed without a PDB, consumers get LNK4099 warnings when linking, which breaks builds using MSBuildTreatWarningsAsErrors or TreatWarningsAsErrors. Set the MSVC_DEBUG_INFORMATION_FORMAT target property to Embedded (/Z7) for static builds so debug types are embedded directly in the .obj files and no external PDB is needed. --- CMakeLists.txt | 7 +++++++ tests/cmake.py | 3 +++ tests/test_build_static.py | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a631ae7fe..5728e7d4f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -476,6 +476,13 @@ endif() set_property(TARGET sentry PROPERTY C_VISIBILITY_PRESET hidden) if(MSVC) + # Static libraries are typically distributed without a PDB, so default to + # embedding debug info in the .obj files (/Z7) rather than referencing + # an external PDB (/Zi), which would cause LNK4099 warnings for consumers. + if(NOT SENTRY_BUILD_SHARED_LIBS AND NOT CMAKE_MSVC_DEBUG_INFORMATION_FORMAT) + set_target_properties(sentry PROPERTIES MSVC_DEBUG_INFORMATION_FORMAT Embedded) + endif() + if(CMAKE_SIZEOF_VOID_P EQUAL 4) set(CMAKE_ASM_MASM_FLAGS "${CMAKE_ASM_MASM_FLAGS} /safeseh") endif() diff --git a/tests/cmake.py b/tests/cmake.py index 069d5b9577..4fab3c368f 100644 --- a/tests/cmake.py +++ b/tests/cmake.py @@ -153,6 +153,9 @@ def cmake_configure(cwd, options, cflags=None): "CMAKE_LIBRARY_OUTPUT_DIRECTORY": cwd, "CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG": cwd, "CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE": cwd, + "CMAKE_ARCHIVE_OUTPUT_DIRECTORY": cwd, + "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG": cwd, + "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE": cwd, } ) diff --git a/tests/test_build_static.py b/tests/test_build_static.py index 6dab8ca505..923db9c44e 100644 --- a/tests/test_build_static.py +++ b/tests/test_build_static.py @@ -35,6 +35,11 @@ def test_static_lib(cmake): else: expected = b"PE\x00\x00\x64\x86" # IMAGE_FILE_MACHINE_AMD64 assert magic == expected + # check that no external PDB (/Zi) is produced for the static library. + # debug info should be embedded in the .obj files (/Z7) instead. + assert not os.path.exists(os.path.join(tmp_path, "sentry.pdb")), ( + "Expected /Z7 (embedded debug info), not /Zi (external PDB)" + ) # similarly, we use `file` on linux if sys.platform == "linux": output = subprocess.check_output( From 7d50512f835225f458af87223da45f51122efb1d Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 9 Apr 2026 12:23:32 +0200 Subject: [PATCH 2/6] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90da9674bd..df30a293c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - Add WinGDK (Gaming.Desktop.x64) platform support ([#1631](https://github.com/getsentry/sentry-native/pull/1631)) +**Fixes**: + +- Embed debug info in static library to avoid LNK4099 warnings. ([#1630](https://github.com/getsentry/sentry-native/pull/1630)) + ## 0.13.5 **Features**: From 4b95d2011a680a55334a3a9dff6af7cec9d98974 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 9 Apr 2026 12:25:46 +0200 Subject: [PATCH 3/6] style: Fix black formatting in test_build_static.py Co-Authored-By: Claude Opus 4.6 (1M context) --- tests/test_build_static.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_build_static.py b/tests/test_build_static.py index 923db9c44e..135204ed59 100644 --- a/tests/test_build_static.py +++ b/tests/test_build_static.py @@ -37,9 +37,9 @@ def test_static_lib(cmake): assert magic == expected # check that no external PDB (/Zi) is produced for the static library. # debug info should be embedded in the .obj files (/Z7) instead. - assert not os.path.exists(os.path.join(tmp_path, "sentry.pdb")), ( - "Expected /Z7 (embedded debug info), not /Zi (external PDB)" - ) + assert not os.path.exists( + os.path.join(tmp_path, "sentry.pdb") + ), "Expected /Z7 (embedded debug info), not /Zi (external PDB)" # similarly, we use `file` on linux if sys.platform == "linux": output = subprocess.check_output( From 0c2bb16bbc45c46b97133489598c3dcc152dda5f Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 9 Apr 2026 14:55:00 +0200 Subject: [PATCH 4/6] Set CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY in test fixture Ensures the compiler PDB lands in the build root with multi-config generators (Visual Studio), so the sentry.pdb assertion in test_build_static checks the correct path. Co-Authored-By: Claude Opus 4.6 (1M context) --- tests/cmake.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/cmake.py b/tests/cmake.py index 4fab3c368f..0820b050dc 100644 --- a/tests/cmake.py +++ b/tests/cmake.py @@ -156,6 +156,9 @@ def cmake_configure(cwd, options, cflags=None): "CMAKE_ARCHIVE_OUTPUT_DIRECTORY": cwd, "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG": cwd, "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE": cwd, + "CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY": cwd, + "CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_DEBUG": cwd, + "CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_RELEASE": cwd, } ) From d8b2c7730de3f9ba21c1740f3e0582b8eb5ea163 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 9 Apr 2026 15:12:48 +0200 Subject: [PATCH 5/6] Scope Embedded debug info to Debug and RelWithDebInfo only Use a generator expression to avoid adding /Z7 to Release and MinSizeRel configurations where debug info is not needed. Co-Authored-By: Claude Opus 4.6 (1M context) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5728e7d4f6..71b6c4bd2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -480,7 +480,7 @@ if(MSVC) # embedding debug info in the .obj files (/Z7) rather than referencing # an external PDB (/Zi), which would cause LNK4099 warnings for consumers. if(NOT SENTRY_BUILD_SHARED_LIBS AND NOT CMAKE_MSVC_DEBUG_INFORMATION_FORMAT) - set_target_properties(sentry PROPERTIES MSVC_DEBUG_INFORMATION_FORMAT Embedded) + set_target_properties(sentry PROPERTIES MSVC_DEBUG_INFORMATION_FORMAT "$<$:Embedded>") endif() if(CMAKE_SIZEOF_VOID_P EQUAL 4) From 91c72a087faff2dd35a012cbeb9f68da54b99432 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 9 Apr 2026 19:12:18 +0200 Subject: [PATCH 6/6] Revert CMP0141 policy, scope to test infrastructure only The top-level CMP0141 policy broke downstream consumers (e.g. sentry-dotnet) that rely on flag-based debug info control. Move the policy and CMAKE_MSVC_DEBUG_INFORMATION_FORMAT to the test fixture where sccache needs it, and remove the /Z7 target property and PDB assertion that were added alongside it. Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 2 +- CMakeLists.txt | 12 ------------ tests/cmake.py | 4 +--- tests/fixtures/crash_reporter/CMakeLists.txt | 3 --- tests/fixtures/inproc_stress/CMakeLists.txt | 3 --- tests/fixtures/screenshot/CMakeLists.txt | 3 --- tests/test_build_static.py | 5 ----- 7 files changed, 2 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df30a293c3..8e3fdd9268 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ **Fixes**: -- Embed debug info in static library to avoid LNK4099 warnings. ([#1630](https://github.com/getsentry/sentry-native/pull/1630)) +- Revert `CMP0141` policy that broke debug info settings for downstream consumers. ([#1630](https://github.com/getsentry/sentry-native/pull/1630)) ## 0.13.5 diff --git a/CMakeLists.txt b/CMakeLists.txt index 71b6c4bd2a..6c933e9f34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,11 +14,6 @@ if(POLICY CMP0079) cmake_policy(SET CMP0079 NEW) endif() -# Enable CMAKE_MSVC_DEBUG_INFORMATION_FORMAT -if(POLICY CMP0141) - cmake_policy(SET CMP0141 NEW) -endif() - # Allow downstream SDKs to override the SDK version at CMake configuration time set(SENTRY_SDK_VERSION "" CACHE STRING "Override the SDK version (supports full semver format with build metadata)") @@ -476,13 +471,6 @@ endif() set_property(TARGET sentry PROPERTY C_VISIBILITY_PRESET hidden) if(MSVC) - # Static libraries are typically distributed without a PDB, so default to - # embedding debug info in the .obj files (/Z7) rather than referencing - # an external PDB (/Zi), which would cause LNK4099 warnings for consumers. - if(NOT SENTRY_BUILD_SHARED_LIBS AND NOT CMAKE_MSVC_DEBUG_INFORMATION_FORMAT) - set_target_properties(sentry PROPERTIES MSVC_DEBUG_INFORMATION_FORMAT "$<$:Embedded>") - endif() - if(CMAKE_SIZEOF_VOID_P EQUAL 4) set(CMAKE_ASM_MASM_FLAGS "${CMAKE_ASM_MASM_FLAGS} /safeseh") endif() diff --git a/tests/cmake.py b/tests/cmake.py index 0820b050dc..9e8c00a0a1 100644 --- a/tests/cmake.py +++ b/tests/cmake.py @@ -142,6 +142,7 @@ def cmake_configure(cwd, options, cflags=None): # Use /Z7 instead of /Zi to embed debug info in object files. /Zi creates # a shared PDB that conflicts with sccache's parallelized compilation. options["CMAKE_MSVC_DEBUG_INFORMATION_FORMAT"] = "Embedded" + options["CMAKE_POLICY_DEFAULT_CMP0141"] = "NEW" options.update( { "CMAKE_RUNTIME_OUTPUT_DIRECTORY": cwd, @@ -156,9 +157,6 @@ def cmake_configure(cwd, options, cflags=None): "CMAKE_ARCHIVE_OUTPUT_DIRECTORY": cwd, "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG": cwd, "CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE": cwd, - "CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY": cwd, - "CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_DEBUG": cwd, - "CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_RELEASE": cwd, } ) diff --git a/tests/fixtures/crash_reporter/CMakeLists.txt b/tests/fixtures/crash_reporter/CMakeLists.txt index b849039460..c6c4b15537 100644 --- a/tests/fixtures/crash_reporter/CMakeLists.txt +++ b/tests/fixtures/crash_reporter/CMakeLists.txt @@ -1,7 +1,4 @@ cmake_minimum_required(VERSION 3.10) -if(POLICY CMP0141) - cmake_policy(SET CMP0141 NEW) -endif() project(sentry_crash_reporter LANGUAGES C) add_executable(sentry_crash_reporter crash_reporter.c) diff --git a/tests/fixtures/inproc_stress/CMakeLists.txt b/tests/fixtures/inproc_stress/CMakeLists.txt index 95bb49a886..2b664ce153 100644 --- a/tests/fixtures/inproc_stress/CMakeLists.txt +++ b/tests/fixtures/inproc_stress/CMakeLists.txt @@ -1,7 +1,4 @@ cmake_minimum_required(VERSION 3.10) -if(POLICY CMP0141) - cmake_policy(SET CMP0141 NEW) -endif() project(inproc_stress_test C) # SENTRY_LIB_DIR and SENTRY_INCLUDE_DIR are passed from the pytest diff --git a/tests/fixtures/screenshot/CMakeLists.txt b/tests/fixtures/screenshot/CMakeLists.txt index 3f55ec9fbe..bcb4083fef 100644 --- a/tests/fixtures/screenshot/CMakeLists.txt +++ b/tests/fixtures/screenshot/CMakeLists.txt @@ -1,7 +1,4 @@ cmake_minimum_required(VERSION 3.10) -if(POLICY CMP0141) - cmake_policy(SET CMP0141 NEW) -endif() project(sentry_screenshot LANGUAGES C) if(WIN32 AND NOT XBOX) diff --git a/tests/test_build_static.py b/tests/test_build_static.py index 135204ed59..6dab8ca505 100644 --- a/tests/test_build_static.py +++ b/tests/test_build_static.py @@ -35,11 +35,6 @@ def test_static_lib(cmake): else: expected = b"PE\x00\x00\x64\x86" # IMAGE_FILE_MACHINE_AMD64 assert magic == expected - # check that no external PDB (/Zi) is produced for the static library. - # debug info should be embedded in the .obj files (/Z7) instead. - assert not os.path.exists( - os.path.join(tmp_path, "sentry.pdb") - ), "Expected /Z7 (embedded debug info), not /Zi (external PDB)" # similarly, we use `file` on linux if sys.platform == "linux": output = subprocess.check_output(