Link SDL2 statically with Visual C++ 2012

Nathaniel J Fries wrote:

SDL does not attempt to replace the C runtime. You need to link to the Visual C++ runtime (which includes both the security cookie and _WinMainCRTStartup)!

That’s very clear, thanks.
I do not want to get rid of VC runtime if it’s not supported by SDL.
I do want to get the static VC runtime (libcmt.lib) instead of the dynamic VC runtime (msvcrt.lib) though.

Sam Lantinga wrote:

I’ve run into the chkstk assertion when I allocate more than 4k in a stack frame. If you’re allocating that much, I would recommend using SDL_stack_alloc() / SDL_stack_free() or dynamically allocating the data you need.

I am not allocating anything. The application crashes before my main is called, unless I remove _chkstk in SDL_stdlib.c. It seems that libcmt.lib does not want anyone else to declare _chkstk.

Jared Maddox wrote:

Ok, but what is your actual reason for WANTING to statically link everything?

I want a single file executable. I think that it’s the ideal way to distribute a very small game.

Don’t get me wrong, I have nothing against VC runtime.
I absolutely don’t want to implement a runtime by myself, but I want to use the static runtime provided by Microsoft (libcmt.lib), which is a method supported by Microsoft.
You can see that in the first chart in the link sent by Jared: http://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.80).aspx

My understanding is that SDL_stdlib.c and libcmt.lib conflict with each other.
You can find a reproduction solution - VS 2012 - here: http://www.files.com/set/517a947761bda
It contains three configurations:

  • ‘Libcmt with _chkstk’ > produces the error
  • ‘Libcmt without _chkstk’ > no error
  • ‘Msvcrt’ > no error
    (includes and libs are in the solution, so it should build straighforwardly)

Regarding the two other topics we discussed yesterday:

  • Yes, I don’t want CLR, I read the microsoft MSDN page too quick yesterday :slight_smile:
  • When linking SDL_image, I still get the _fltused conflict (between SDL_stdlib.c and libcmt.lib) even though I link everything at the very last step. I don’t want to make this thread too complex, so maybe we can let it aside for now, but I can setup a reproduction solution if you wish.

Actually, it might be useful to implement a C runtime that provides the bare minimum to implement SDL.
But, this is a project for another time, and maybe another programmer. I’m just trying to figure out how the CRT actually does stuff over here, and I’m already beating my head against the wall. Dx------------------------
Nate Fries

Considering SDL relies heavily on an OS to do stuff anyway (video,
audio, input, etc.) there isn’t much point in doing that when you’re
pretty much guaranteed to have a proper C runtime in such a situation.

2013/4/26, Nathaniel J Fries :> Actually, it might be useful to implement a C runtime that provides the bare

minimum to implement SDL.
But, this is a project for another time, and maybe another programmer. I’m
just trying to figure out how the CRT actually does stuff over here, and I’m
already beating my head against the wall. Dx


Nate Fries

Message-ID: <1366954833.m2f.36789 at forums.libsdl.org>
Content-Type: text/plain; charset=“iso-8859-1”

Trust me, I know, I’m implementing my own C runtime right now. Basic C++
support is important (in fact, I just finished getting MinGW static global
C++ constructors and destructors to work), but I never use exceptions so
that will probably be the last thing I make work (especially since MinGW and
Visual C++ do it completely differently (and in fact MinGW can do it two
different ways), and this means massive bloat in my runtime to implement it
both ways…)

Actually, I think that Visual C++ does it two ways too, and maybe one
of those is compatible with the G++ way.

As for setjmp/longjmp; you make it sound like capturing the current context
and resetting it later is difficult. :slight_smile:

I was thinking more “if you do it wrong, things will explode”, but it
WAS my first stab at it, and I was actually doing it as part of a
"Continuations for C" concept, and I was extending it with functions
to register destructors, and I basically never work in assembly, etc.,
so there was a lot of blind fumbling while I tried to figure out what
info to look for.

Incidentally, if you feel up to taking a stab at continuations then I
do suggest inserting stubs at a very early stage. You might not flesh
them out for some time, but at least it would always keep them in the
back of your mind.> Date: Thu, 25 Apr 2013 22:40:34 -0700

From: “Nathaniel J Fries”
To: sdl at lists.libsdl.org
Subject: Re: [SDL] Link SDL2 statically with Visual C++ 2012

Message-ID:
<CAEyBR+VGaeLrYohUMG3jmY8nDL4FJVYCOMOv05LJcYyjHaSBwQ at mail.gmail.com>
Content-Type: text/plain; charset=UTF-8

Considering SDL relies heavily on an OS to do stuff anyway (video,
audio, input, etc.) there isn’t much point in doing that when you’re
pretty much guaranteed to have a proper C runtime in such a situation.

There actually is a reason to do this. On Windows an application and
the libraries that it uses can each use a different C runtime. Not
only are there the open-source ones, but Microsoft itself has several
variants out there. The result of this is that you cannot safely
allocate memory in the code of one executable, and deallocate it in
another. By simply providing a malloc/realloc/free implementation in
SDL2 this headache could be greatly reduced (though if you somehow
included SDL2 repeatedly, and I’m thinking of the old requests to
provide a SDL interface for the NPAPI here, then this could require a
bit more work to achieve true “universalism”).> Date: Fri, 26 Apr 2013 14:40:18 -0300

From: Sik the hedgehog <sik.the.hedgehog at gmail.com>
To: sdl at lists.libsdl.org
Subject: Re: [SDL] Link SDL2 statically with Visual C++ 2012

Sik wrote:

Considering SDL relies heavily on an OS to do stuff anyway (video,
audio, input, etc.) there isn’t much point in doing that when you’re
pretty much guaranteed to have a proper C runtime in such a situation.

It’s not about lacking a proper C runtime.

One reason is what Jarod said:

There actually is a reason to do this. On Windows an application and
the libraries that it uses can each use a different C runtime… By simply providing a malloc/realloc/free implementation in
SDL2 this headache could be greatly reduced

Another reason is the issue the OP is facing.

Yet another reason is the original purpose of libctiny, which is to not bring the bloat of MSVCRT to all applications using SDL.

You could also use it to implement a main() that takes argv as UTF-8 instead of in a codepage or wide character (although SDL2_main could accomplish this instead).

And let’s say you’re a C purist (I’ve seen a few on here before). Maybe you don’t need all those functions required to support C++ exceptions, RTTI, static constructors and destructors, or even name demangling (MSVCRT includes a function, _unDNameEx, which is quite large; and G++ has abi::__cxa_demangle which is similarly large). This can trim down the size of an executable considerably!

Anyway, this is all irrelevant. If someone really wants it bad enough, they’ll do it themselves, and then hopefully they’ll be kind enough to share. :)------------------------
Nate Fries

Actually, if it’s all about the memory managers, whatever program you’re using SDL in is going to have its own malloc anyway.? (Assuming you’re writing from a native code language, at least.)? Why not have a SDL_RegisterMemoryManager() function, where you pass in a set of function pointers, for malloc, realloc, and free?

This would certainly be useful to me, since I use SDL with Delphi code and Delphi’s memory manager has a bunch of useful debug features (leak tracing, corruption guards, etc) that most memory managers don’t come with.? If I could extend that into SDL it would be awesome. :slight_smile:

Mason________________________________
From: Nathaniel J Fries
To: sdl at lists.libsdl.org
Sent: Friday, April 26, 2013 12:51 PM
Subject: Re: [SDL] Link SDL2 statically with Visual C++ 2012

Sik wrote:
Considering SDL relies heavily on an OS to do stuff anyway (video,
audio, input, etc.) there isn’t much point in doing that when you’re
pretty much guaranteed to have a proper C runtime in such a situation.

It’s not about lacking a proper C runtime.

One reason is what Jarod said:

Quote:
There actually is a reason to do this. On Windows an application and
the libraries that it uses can each use a different C runtime… By simply providing a malloc/realloc/free implementation in
SDL2 this headache could be greatly reduced

Another reason is the issue the OP is facing.

Yet another reason is the original purpose of libctiny, which is to not bring the bloat of MSVCRT to all applications using SDL.

You could also use it to implement a main() that takes argv as UTF-8 instead of in a codepage or wide character (although SDL2_main could accomplish this instead).

And let’s say you’re a C purist (I’ve seen a few on here before). Maybe you don’t need all those functions required to support C++ exceptions, RTTI, static constructors and destructors, or even name demangling (MSVCRT includes a function, _unDNameEx, which is quite large; and G++ has abi::__cxa_demangle which is similarly large). This can trim down the size of an executable considerably!

Anyway, this is all irrelevant. If someone really wants it bad enough, they’ll do it themselves, and then hopefully they’ll be kind enough to share.


Nate Fries


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

Oops. Too used to text editors. Let’s try that again:

That is a good idea. Perhaps something like this:

/* Arbitrary .c file /
static void malloc_data = (void)( &malloc ),
realloc_data = (void)( &realloc ),
free_data = (void)( &free );
static void
(malloc_function)( void /* Data /, size_t ) = SDL_mallocwrapper;
static void
(realloc_function)( void /* Data /, void, size_t ) =
SDL_reallocwrapper;
static void (free_function)( void /* Data /, void ) = SDL_freewrapper;

void* SDL_mallocwrapper( void data, size_t size )
{
if( data )
{ return( ( ( void
()( size_t ) )data )( size ) ); }
return( 0 );
}
void
SDL_reallocwrapper( void data, void mem, size_t size )
{
if( data )
{ return( ( ( void* ()( void, size_t ) )data )( mem, size ) ); }
return( 0 );
}
void SDL_freewrapper( void data, void mem )
{
if( data )
{ ( ( void ()( void ) )data )( mem ); }
return( 0 );
}

void* SDL_malloc( size_t size )
{
if( malloc_function )
{ return( malloc_function( malloc_data, size ) ); }
return( 0 );
}
void* SDL_realloc( void *old, size_t size )
{
if( realloc_function )
{ return( realloc_function( realloc_data, old, size ) ); }
return( 0 );
}
void SDL_free( void *mem )
{
if( free_function )
{ free_function( free_data, mem ); }
}

void SDL_SetAllocators
(
void maldata, void (malfun)( void, size_t ),
void redata, void (refun)( void, void*, size_t ),
void fredata, void (frefun)( void, void )
)
{
malloc_data = maldata; malloc_function = malfun;
realloc_data = redata; realloc_function = refun;
free_data = fredata; free_function = frefun;
}

/* End of code. */

Not the prettiest code in the world, but effective. Thoughts?