Static linking SDL2 with /MT in MSVC

I wanted to be able to static link SDL2 and also avoid the CRT DLL which I generally find to be a very annoying dependency when trying to deploy a portable application. I played around a bit until I found the following set of steps to do so, which is as minimal as I could get it:

  1. Change the SDL2 and SDL2main project settings to use /MT (/MTd for debug) under C++ > Code Generation > Runtime Library.

  2. Change the SDL2 configuration to Static Library under General > Configuration Type.

  3. Comment out the implementation of _chkstk() in SDL_stdlib.c. This empty function appears to cause a breakpoint/crash during the CRT initialization in release (but not in debug)? I haven’t investigated the cause, but removing this function definition entirely clears up the problem (maybe it’s an intrinsic for MSVC?).

  4. For your game project, add the following linker dependencies: version.lib, imm32.lib, winmm.lib.

For me, this was the minimal set of steps to get SDL 2.0.0 running statically linked with /MT, using Visual Studio 2010 express. (More precisely I use VS 2012 express but with the platform toolset set to 2010 for XP compatibility.) So far things look like they’re working correctly, but I haven’t thoroughly tested everything.

I wanted to post this here for anybody who might find it useful, and also if anyone wants to follow up on the _chkstk() problem, it might be worth obviating with some preprocessor directives (or fixing if it’s part of a bigger problem… why is the implementation empty anyway?).

This is quite interesting, should definitely be on the wiki :wink:
VittorioOn 17/ott/2013, at 20:56, rainwarrior wrote:

I wanted to be able to static link SDL2 and also avoid the CRT DLL which I generally find to be a very annoying dependency when trying to deploy a portable application. I played around a bit until I found the following set of steps to do so, which is as minimal as I could get it:

  1. Change the SDL2 and SDL2main project settings to use /MT (/MTd for debug) under C++ > Code Generation > Runtime Library.

  2. Change the SDL2 configuration to Static Library under General > Configuration Type.

  3. Comment out the implementation of _chkstk() in SDL_stdlib.c. This empty function appears to cause a breakpoint/crash during the CRT initialization in release (but not in debug)? I haven’t investigated the cause, but removing this function definition entirely clears up the problem (maybe it’s an intrinsic for MSVC?).

  4. For your game project, add the following linker dependencies: version.lib, imm32.lib, winmm.lib.

For me, this was the minimal set of steps to get SDL 2.0.0 running statically linked with /MT, using Visual Studio 2010 express. (More precisely I use VS 2012 express but with the platform toolset set to 2010 for XP compatibility.) So far things look like they’re working correctly, but I haven’t thoroughly tested everything.

I wanted to post this here for anybody who might find it useful, and also if anyone wants to follow up on the _chkstk() problem, it might be worth obviating with some preprocessor directives (or fixing if it’s part of a bigger problem… why is the implementation empty anyway?).


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

rainwarrior wrote:

  1. Comment out the implementation of _chkstk() in SDL_stdlib.c. This empty
    function appears to cause a breakpoint/crash during the CRT initialization
    in release (but not in debug)? I haven’t investigated the cause, but
    removing this function definition entirely clears up the problem (maybe it’s
    an intrinsic for MSVC?).

You don’t need to edit the source, just add HAVE_LIBC to the
preprocesser definitions when building SDL with the Visual C runtime
library. Withou that, SDL builds without a C runtime library
dependency and some symbols are necessary to satisfy the Microsoft
compiler.

I wanted to post this here for anybody who might find it useful, and also if
anyone wants to follow up on the _chkstk() problem, it might be worth
obviating with some preprocessor directives (or fixing if it’s part of a
bigger problem… why is the implementation empty anyway?).

It’s apparently expected that SDL as a dynamic library won’t ever call
_chkstk. When linking statically, the C runtime library is required.
See https://bugzilla.libsdl.org/show_bug.cgi?id=2087 .

Oh, and if you still build 2.0.0 you might want to check out the new
SDL_config_windows.h. It has some changes that will correctly set the
HAVE_X defines for MSVC 2010 and 2012.

http://hg.libsdl.org/SDL/raw-file/a87057441d01/include/SDL_config_windows.h

Ah, thanks.

Using that updated SDL_config_windows.h and adding #define HAVE_LIBC at the top of it, everything seems to build fine, and there’s no longer a need to remove the empty _chkstk implementation.

Would it be appropriate to add this to SDL_config_windows.h?

Code:
#ifndef _WINDLL
#define HAVE_LIBC
#endif

#ifndef _WINDLL

This would force HAVE_LIBC for everyone that didn’t create the Visual
Studio project in a very specific way. It also seems to be a MFC
related define and doesn’t look like it applies in this context.
Unless there’s something I’m missing?

_WINDLL is automatically defined by the MSVC compiler when building as a DLL (and conversely it is not defined when building as a static library).

I don’t think MFC has anything to do with it. What do you mean by that?

Also, what do you mean by creating the visual studio project in a specific way? If you set the Configuration Type under general properties to DLL, the _WINDLL define is automatically part of the build command. As far as I know there isn’t a way to do this wrong, you’re either building a DLL or you’re not, and this is the define that indicates this. Am I mistaken about that?

To be more specific, it’s added to the compile command line by visual studio, not directly by the compiler (the compiler doesn’t have a special flag for targeting a DLL). There is information about it here:

http://msdn.microsoft.com/en-us/library/vstudio/8x480de8(v=vs.100).aspx

The only way I think a user could get it wrong is to manually define _WINDLL for a non-DLL build?

rainwarrior wrote:

To be more specific, it’s added to the compile command line by visual
studio, not directly by the compiler (the compiler doesn’t have a special
flag for targeting a DLL). There is information about it here:

http://msdn.microsoft.com/en-us/library/vstudio/8x480de8(v=vs.100).aspx

Oh, yeah. Now I see it. I guess I didn’t look careful enough and
failed at using google properly. It seems to add it once with a direct
definition and then with the %(PreprocessorDefinitions) macro. It’s an
IDE specific thing, but if it works…