As a prior reference https://code.google.com/archive/p/static-gtk2-mingw32/
the thing is no patch provided but hints, that's enough though.
So why GTK2? well, after maintaining pygi-aio
for several years, nothing really that good.. honestly
There is rough edges, regressions and more importantly it feel less responsive (with slower start-up). Overall GTK 3.x was turbulent version.
Just FYI, it's possible make GTK3 static build, especially prior to GDK's switch to adwaita as default theme, that is GTK 3.6.x where you get "somewhat" native theme, GTK 3.22 also have "somewahat" native theme returned and it break XP compatibility Well duh.
I made a mod of vispdisp (a streaming image viewer powered by VIPS) and make single exe with GTK 3.6
support huge tiff/jpg/png image (upx'ed 1.56MB)
That's just to prove I'm not making excuse for choosing GTK2 over GTK3 :)
The goal here is to make it barebone otherwise you may as well use the dll version, no?
1 the focus is GTK alone, the rest isn't that important
2 dependencies will be trimmed down until it become what's GTK only really can use from
3 optimization flags
1) With version 2.24.31 I choose Glib 2.34.x which is the minimum to build the latest librsvg (more about it later), Glib also getting bloated too overtime and there are some regressions I don't want to mess with in more recent versions. Supposedly the officially supported static build for Glib was version 2.28-2.30 but it seems my workaround is fine for 2.34. With this other dependencies are pretty much settled:
cairo 1.12.18 (I have crash with cairo 1.14.10)
pango 1.40.12 (1.40.14 claim need glib 2.34, but actually it need quite recent one)
2) Several libraries to be trimmed down:
pixman : has big chunk of SIMD code, configure with --disable-sse2 --disable-ssse3
cairo : only few features that needed by GTK2, configure with --enable-pthread --disable-interpreter --disable-fc --disable-ft --disable-gobject --disable-png --disable-svg --disable-script --disable-ps (note: pthread is needed for static build to avoid mutex crash)
glib : disabling debugging make it smaller, configure with --enable-debug=no
pango : ditto
gdk-pixbuf : only use gdiplus, configure with --with-included-loaders=gdip-png,gdip-gif,gdip-bmp,gdip-tiff,gdip-emf,gdip-jpeg,gdip-wmf,gdip-ico --without-libpng --with-gdiplus --without-libjasper --without-libtiff --without-libjpeg --disable-modules --enable-debug=no
gtk : --disable-modules --with-included-immodules=ime,ipa --enable-debug=no
Do we need svg support? hint: it was one of format that MS really "hate" and hey Qt has it.
if so things get complicated as there is circular dependencies between gdk-pixbuf and librsvg, to solve that merge librsvg objects into libgdk_pixbuf-2.0.a and pass all librsvg dependencies through LIBS that is libcroco and libxml2, overall adds 500KB.
Do we need fontconfig/freetype? it will solve problem of "complex/unusual" font rendering that plagued win32 backend, but it also add almost 700KB (including several config files) and annoying font caching startup once in a while... frankly for most of case it's redundant.
Do we need full jpeg, png and tiff support? gdiplus backend provide
less feature for these formats: no progressive mode, no png metadata,
incomplete tiiff format/compression and so on. but this will add even
more weight 1-1.5MB depends on configuration. Furthermore there is psd, webp, and raw modules that can be enabled
3) the flags is nothing special and for portability reason -flto is avoided (it will make your exe even smaller but you'll need gcc 4.6-4.8, I think)
cflags : -Os
add -fno-unwind-tables -fno-asynchronous-unwind-tables if EH is SJLJ, but not for DWARF or SEH
add -ffunction-sections -fdata-sections this is effective against simpleton app but lost it once app getting complex, in this case -flto is better replacement for dead code removal.
ldflags : -Os -Wl,-s
add -Wl,--gc-sections to correspond above cflags or -flto if you use it on cflags
cppflags : -DGLIB_STATIC_COMPILATION -DGOBJECT_STATIC_COMPILATION -DGDK_PIXBUF_STATIC_COMPILATION -DPANGO_STATIC_COMPILATION -DATK_STATIC_COMPILATION -DGTK_STATIC_COMPILATION -DGDK_STATIC_COMPILATION
The static library is intended for static exe, if monolithic dll desired then we need better replacement for GetModuleFileName (without relying on DllMain) such GetModuleHandleEx otherwise localization path will be unpredictable.
Produced exe for simpleton app is about 3.6MB, 3MB with LTO libraries, and a little over 1MB if compressed with 7zip.That's half of prior effort, not bad.
Patches (including new stock icons replacement) : gtk+-2.24.31-static_patch.7z
Libraries and (flattened) headers : gtk+-2.24.31_win32_win64_sjlj.7z
add to ldflags like: -lgtk-win32-2.0 -lgdk-win32-2.0 -lpangocairo-1.0 -lpangowin32-1.0
-lpango-1.0 -latk-1.0 -lcairo -lpixman-1 -lgdk_pixbuf-2.0 -lgio-2.0
-lgmodule-2.0 -lgobject-2.0 -lglib-2.0 -lintl -liconv -lz -lffi -lws2_32
-lole32 -lwinmm -ldnsapi -lshlwapi -luuid -lgdi32 -lgdiplus -lusp10
alternatively create text files named libgtk2.a with linker script:
GROUP(-lgtk-win32-2.0 -lgdk-win32-2.0 -lpangocairo-1.0 -lpangowin32-1.0 -lpango-1.0 -latk-1.0 -lcairo -lpixman-1 -lgdk_pixbuf-2.0 -lgio-2.0 -lgmodule-2.0 -lgobject-2.0 -lglib-2.0 -lintl -liconv -lz -lffi -lws2_32 -lole32 -lwinmm -ldnsapi -lshlwapi -luuid -lgdi32 -lgdiplus -lusp10 -lmsimg32 -limm32)
then we can just add only -lgtk2 in ldflags