Linking SDL2 statically on Win32 Visual Studio 2017 using CMake

Hello!

I’m trying to build a single file executable with no dll dependencies on the win32 platform. I’m building SDL2 through CMake.

Everything works in debug mode, but in Release, I get a single multiply defined symbol: _ftol2_sse, which appears in both libcmt.lib and SDL_stdlib.o

I’ve found someone with a similar issue, and everywhere the recommendation is to define HAVE_LIBC. Since I’m building with CMake, I tried to call cmake with the following argument: “-DLIBC=ON”, which defines HAVE_LIBC, but this doesn’t solve the issue, I get a bunch of linker warnings and errors instead.

If I just modify the SDL_stdlib.c file to not include the _ftol2_sse function, the static lib(the .dll doesn’t link) and my application compile and run properly.

One more interesting thing is that I tried to find where is this _ftol2_sse even used in the source, but I couldn’t find ftol mentioned anywhere, even though the .dll linking fails with symbol _ftol2_sse undefined.

Is this an issue in SDL2? If so, how do I create a reproducible issue? (I need to create a program that calls both the libcmt.lib ftol and the SDL2 ftol)
If not, what am I doing wrong?

Did you mean to write VC++ runtime library DLLs? SDL can’t do much if you don’t give it access to the Win32 API. :wink:

As you noticed, when linking SDL2 statically with VC++ it is very strongly recommended to link with the VC++ runtime library. This is because the MSVC compiler emits code that sometimes depends on functions included in the runtime library. Examples are SSE and 64-bit integer helper functions on the IA32 arch or the guard-page prober function which is called if you have a large array on the stack. There was an attempt at providing these functions with SDL2, but it was scrapped and won’t work anymore.

If you haven’t already, also use the FORCE_STATIC_VCRT option in the CMake configuration. It seems Visual Studio instructs lib.exe to put a dependency on the VC++ runtime library DLL in the SDL2.lib file with the default /MD option.

Obviously, you need to mirror the /MT option (under ‘C/C++’ -> ‘Code Generation’ -> ‘Runtime Library’ in the project properties) in your application as well to only include one form of the runtime library.

If this wasn’t it, it may be helpful to post the errors here.

Thanks a lot for the FORCE_STATIC_VCRT option, I somehow assumed SDL2-static would already link with /MT. Adding -DFORCE_STATIC_VCRT=ON to my build script solved the issue.

What I meant in my first post is that I want no dll dependencies. And I also want it to be on the win32 platform, not that I don’t want a dependency on win32 platform.