sentry-native icon indicating copy to clipboard operation
sentry-native copied to clipboard

Static CRT with Breakpad backend fails compiling

Open uvhannes opened this issue 4 years ago • 2 comments

Static CRT with Breakpad backend

When does the problem happen

  • [x ] During build
  • [ ] During run-time
  • [ ] When capturing a hard crash

Environment

  • OS: Windows 10, 64-bit
  • Compiler: e.g. MSVC 19
  • CMake version and config: 3.17.2, SENTRY_BACKEND=breakpad

Steps To Reproduce

  • compile with -DSENTRY_BUILD_SHARED_LIBS=Off -DSENTRY_BACKEND=breakpad -DSENTRY_BUILD_RUNTIMESTATIC=On

Fix for 0.4.10

diff --git "a/CMakeLists.txt" "b/CMakeLists.txt"
index 696d270..18bdf50 100644
--- "a/CMakeLists.txt"
+++ "b/CMakeLists.txt"
@@ -449,6 +449,12 @@ elseif(SENTRY_BACKEND_BREAKPAD)
 		target_link_libraries(sentry PRIVATE
 			breakpad_client
 		)
+		
+		# set static runime if enabled
+		if(SENTRY_BUILD_RUNTIMESTATIC AND MSVC)
+			set_property(TARGET breakpad_client PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
+		endif()
+
 		if(NOT SENTRY_BUILD_SHARED_LIBS)
 			sentry_install(TARGETS breakpad_client EXPORT sentry
 				LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"

uvhannes avatar Jun 26 '21 17:06 uvhannes

I’m a bit confused, we already have this here: https://github.com/getsentry/sentry-native/blob/43f628460fb383bb4eed8c118a7a241e6a811880/external/CMakeLists.txt#L160-L163

I don’t really understand why it would make a difference if that property is defined in the main cmake file or rather one included via add_subdirectory.

Swatinem avatar Jun 28 '21 10:06 Swatinem

that i cannot answer. i copied what you guys did for crashpad and this fixed the issue on my side. If others do not have this issue, feel free closing it.

uvhannes avatar Jun 28 '21 12:06 uvhannes

I am using breakpad backend on Windows as a static library.

My build steps are:

cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" -DSENTRY_BACKEND="breakpad" -DSENTRY_BUILD_SHARED_LIBS="OFF"
cmake --build build --parallel --config Release
cmake --install build --prefix dist/x64/Release --config Release

For my Debug builds I am using /MDd option, via:

cmake -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreadedDebugDLL" -DSENTRY_BACKEND="breakpad" -DSENTRY_BUILD_SHARED_LIBS="OFF"

I found that without setting the CMAKE_MSVC_RUNTIME_LIBRARY option to MultiThreaded the projects would default to /MD

I also had to set my Additional Dependencies to winhttp.lib;Dbghelp.lib;breakpad_client.lib;sentry.lib;%(AdditionalDependencies)

Lastly, before including the sentry.h header I set SENTRY_BUILD_STATIC:

#define SENTRY_BUILD_STATIC 1
#include <sentry.h>

dtlhlbs avatar Jan 17 '23 02:01 dtlhlbs

I’m a bit confused, we already have this here:

https://github.com/getsentry/sentry-native/blob/43f628460fb383bb4eed8c118a7a241e6a811880/external/CMakeLists.txt#L160-L163

I don’t really understand why it would make a difference if that property is defined in the main cmake file or rather one included via add_subdirectory.

Possibly should be CMAKE_MSVC_RUNTIME_LIBRARY?

dtlhlbs avatar Jan 17 '23 02:01 dtlhlbs

Possibly should be CMAKE_MSVC_RUNTIME_LIBRARY?

No, the name of the target property is MSVC_RUNTIME_LIBRARY (CMake docs). CMAKE_MSVC_RUNTIME_LIBRARY is a variable that you can set via the command line that initializes this property if you are not happy with the default (which is MultiThreaded$<$<CONFIG:Debug>:Debug>DLL).

In the breakpad build of the Native SDK, you have two options relevant to your static build:

  • SENTRY_BUILD_SHARED_LIBS: which only affects our targets, and
  • SENTRY_BUILD_RUNTIMESTATIC: which - if enabled - will select a static MSVC runtime consistent with your build conf

Those two must be specified together if you want to build the library as described above:

cmake -B build -DSENTRY_BACKEND=breakpad -DSENTRY_BUILD_SHARED_LIBS=Off -DSENTRY_BUILD_RUNTIMESTATIC=On
cmake --build build --config Release

the resulting *.lib will then show

/FAILIFMISMATCH:RuntimeLibrary=MT_StaticRelease

if you inspect the linker directives (using dumpbin /directives sentry.lib) and if you also build the example, then you will see that it only has the following dependents (using dumpbin /dependents sentry_example.exe):

dbghelp.dll
VERSION.dll
WINHTTP.dll
KERNEL32.dll
ADVAPI32.dll

which won't include any runtime DLL since they are already statically linked via sentry.lib.

So by passing CMAKE_MSVC_RUNTIME_LIBRARY directly, you're bypassing our option. This is fine at the moment but could be an issue if we do more than set this property, so we recommend using the SENTRY* options described above instead.

Also, be aware that MSBuild ignores -DCMAKE_BUILD_TYPE=Release at the configuration stage and only requires --config Release at the build stage, because MSBuild allows to build for all types with each configuration you define.

Consequently, your proposed dev build would look like this:

cmake -B dev_build -DSENTRY_BACKEND=breakpad -DSENTRY_BUILD_SHARED_LIBS=Off -DSENTRY_BUILD_RUNTIMESTATIC=Off
cmake --build dev_build --config Debug

Of course, since it is the default, you can leave out -DSENTRY_BUILD_RUNTIMESTATIC=Off in this case. Here you will get the following linker directive for sentry.lib:

/FAILIFMISMATCH:RuntimeLibrary=MDd_DynamicDebug

and the following dependents for sentry_example.exe:

dbghelp.dll
VERSION.dll
WINHTTP.dll
KERNEL32.dll
ADVAPI32.dll
MSVCP140D.dll
VCRUNTIME140D.dll
VCRUNTIME140_1D.dll
ucrtbased.dll

which include all runtime DLLs as the debug version.

I'll admit that having an additional option that doesn't default to SENTRY_BUILD_RUNTIMESTATIC=On when using SENTRY_BUILD_SHARED_LIBS=Off is probably a bit much configurability, given that this is the behavior most would opt for. The length of my comment is a sign that we need to improve the docs in that regard.

supervacuus avatar Jan 17 '23 16:01 supervacuus