Skip to content

Instantly share code, notes, and snippets.

@zloedi
Last active April 1, 2022 09:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zloedi/2a9aab53ab05dc5728b01d2998d82f9e to your computer and use it in GitHub Desktop.
Save zloedi/2a9aab53ab05dc5728b01d2998d82f9e to your computer and use it in GitHub Desktop.
mingw minimal windows exe using SDL (exe size ~9K)
// for ExitProcess
#include <windows.h>
#include <SDL2/SDL.h>
SDL_Renderer *x_renderer;
SDL_Window *x_window;
SDL_Texture *x_fontTex;
int nocrt_main( int argc, char *argv[] ) {
if ( SDL_InitSubSystem( SDL_INIT_VIDEO ) < 0 ) {
return -1;
}
x_window = SDL_CreateWindow( NULL,
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
1024,
768,
SDL_WINDOW_RESIZABLE );
if( ! x_window ) {
return -1;
}
#ifdef HINT_OPENGL // if we want to be consistent with linux
SDL_SetHint( SDL_HINT_RENDER_DRIVER, "opengl" );
#endif
x_renderer = SDL_CreateRenderer( x_window, -1, SDL_RENDERER_ACCELERATED );
if ( ! x_renderer ) {
return -1;
}
SDL_SetWindowTitle( x_window, "No CRT" );
int run = 1;
while( run ) {
SDL_Event event;
while ( SDL_PollEvent( &event ) ) {
switch( event.type ) {
case SDL_QUIT:
run = 0;
break;
}
}
SDL_Delay( 20 );
}
// just for completeness, don't see a point
SDL_DestroyRenderer( x_renderer );
SDL_DestroyWindow( x_window );
SDL_Quit();
// the exe never quits without it, SDL bug maybe?
ExitProcess( 0 );
return 0;
}
// ? if mainCRTStartup/WinMainCRTStartup is not defined, the linker will pick the
// ? first function it encounters to be the entry point
#ifdef M_CONSOLE
void Print( int msgSize, const char *msg ) {
HANDLE conOut = GetStdHandle( STD_OUTPUT_HANDLE );
WriteFile( conOut, msg, msgSize, NULL, NULL );
}
int WINAPI mainCRTStartup( void ) {
const char msg[] = "Hello World Console\n";
Print( sizeof( msg ) - 1, msg );
return nocrt_main( 0, NULL );
}
#else
int WINAPI WinMainCRTStartup(void) {
return nocrt_main( 0, NULL );
}
#endif
# Thanks goes to https://nullprogram.com/blog/2016/01/31/ -- Small, Freestanding Windows Executables
no_crt.exe: main.c
x86_64-w64-mingw32-gcc -o no_crt.exe main.c -pedantic-errors \
-std=c99 -Wall -Wextra \
-O3 \
-fno-tree-loop-distribute-patterns \
-fno-stack-protector -mno-stack-arg-probe \
-mconsole -DM_CONSOLE \
-I/usr/local/x86_64-w64-mingw32/include \
`sdl2-config --static-libs` \
-nostdlib -nolibc -nostartfiles \
-lkernel32
# -fno-tree-loop-distribute-patterns -- prevent intoducing memset
# -mconsole -DM_CONSOLE -- remove this for GUI mode. is there a way to detect console link flag without our macro?
# -fno-stack-check -fno-stack-protector -mno-stack-arg-probe -- prevent linking to stack checks, 9k no change in my example
# -ffreestanding -- A freestanding environment is one in which the standard library may not exist, and program startup may not necessarily be at "main". The option -ffreestanding directs the compiler to not assume that standard functions have their usual definition. No difference in size
# -nolibc -nostartfiles -nodefaultlibs -- no difference for size
# -lkernel32 -- for ExitProcess
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment