OK, I managed to build the stand-alone executable.
I cross-compiled all SDL libraries manually because the binary
releases don’t provide static libs. I also cross-compiled freetype2
for SDL_ttf. There was a couple libtool fixes to do on SDL_gfx as
well.
Then I just add to specific ‘-static’ and ‘-lfreetype -lwinmm’ to gcc.
No need to specfic ‘disable-shared’ for me when building the
libraries, using ‘-static’ for my .exe takes care of using the static
libs appropriately.
Doing the same thing for GNU/Linux is quite more difficult, because
SDL’s dependencies require dlopen(), which in turn requires a
non-static build, so we have to use the scary -Wl,-Bstatic and
-Wl,-Bdynamic options. Moreover, some versions of SDL conflicts with
X11 when compiled statically (SDL_x11dyn.o). And of course, GNU/Linux
has numerous backends which can make your dependencies list grow very
large!
Building a dynamic executable that includes SDL + its dependencies
except X11 is easy enough though, once you listed the dependencies
and the matching distro packages.
I attach 2 files from my documentation for people interested in doing
the same thing for their project 
http://git.sv.gnu.org/gitweb/?p=freedink.git;a=blob;f=doc/cross.txt
http://git.sv.gnu.org/gitweb/?p=freedink.git;a=blob;f=doc/static-build.txt
Thanks to the list for the tips :)On Wed, Sep 26, 2007 at 03:57:30PM +0200, Sylvain Beucler wrote:
On Wed, Sep 26, 2007 at 03:14:25PM +0200, Gerry JJ wrote:
Den Wed, 26 Sep 2007 12:02:28 +0200
skrev Sylvain Beucler <@Sylvain_Beucler>:
I look for a kind of “partially static” compilation, as if SDL was
part of my own code, but I don’t have enough knowledge of GCC to know
how that can be done.
Do you know if that’s possible?
Yes, it’s possible, you just have to be a bit more specific when
telling the linker what you want to do, since -static affects the
entire linking process and not just part of it like you want. The
linker has some options called -Bstatic and -Bdynamic that can be used
to do exactly what you want, and you can pass args to the linker with
gcc’s -Wl arg, with commas in stead of spaces. So, just surround the
libraries you want to link statically with -Wl,-Bstatic and
-Wl,-Bdynamic:
gcc stuff -Wl,-Bstatic -lSDL etc -Wl,-Bdynamic
You can do this as many times as you want in a link. A -Wl,-Bdynamic
at the end ensures that gcc won’t try to statically link system libs
and such. If you still get a dynamically linked SDL after this, you
probably just have to sort out the order of the link args (a request
for a lib in a dynamic part after that lib’s already been statically
linked will pull it in dynamically as well if possible. If you’ve got
false dependencies interfering with your link, -Wl,–as-needed might
help (makes the target only depend on first-level dependencies)).
Thanks, I’ll dig more into those options.
I’m also having a first clean build by simply adding -lwinmm - I
thought that --static-libs would give me this kind of dependencies
automatically 
i586-mingw32msvc-gcc -static joytest.c
/usr/local/cross-tools/i386-mingw32msvc/bin/sdl-config --cflags --static-libs
-lwinmm
–
Sylvain
-------------- next part --------------
Statically compiling for GNU/Linux
Thread “[SDL] Embed SDL.dll in the .exe”
http://lists.libsdl.org/pipermail/sdl-libsdl.org/2007-September/062841.html
Distros compile libSDL with a number of backends (such as X11 and
AAlib for graphics, ALSA and OSS for sounds, etc.) which will trigger
a lot of dependencies.
You may need to statically compile against a manually-compiled libSDL
which fewer backends enabled.
Another solution may be to have SDL use relaytool (check
http://autopackage.org/docs/tutorials/glb-binport.html).
Technical note: maybe use -Wl,–as-needed, it’s supposed to reduce the
number of NEEDED symbols (objdump -x src/freedink | grep NEEDED). The
SDL list says it “makes the target only depend on first-level
dependencies”.
Compiling with the distro’s SDL
Here’s an attempt to list the minimum dependencies to statically
compile against Debian Etch’s libsdl1.2-dev:
Dynamic
glibc-related, better keep them dynamic I think
-ldl # dlopen
-lpthreads # threads
X11 - conflicts with SDL_x11dyn.o if statically
compiled. Something to do with ./configure --enable-x11-shared ?
-lX11
Static
Maths
-lm
AAlib text-mode graphics backend
aptitude install libaa1-dev
aptitude install libgpmg1-dev # mouse support
-laa -lgpm
caca text-mode graphics backend
aptitude install libcaca-dev
aptitude install libslang2-dev
aptitude install libncurses5-dev
-lcaca -lslang -lncurses -lcucul
Direct frame buffer graphics backend
aptitude install libdirectfb-dev
aptitude install libfusionsound-0.9-25
-ldirectfb -ldirect -lfusion
SVGA graphics backend
aptitude install libsvga1-dev
-lvga
ALSA sound backend
aptitude install libasound2-dev
-lasound
aRts sound backend
aptitude install libarts1-dev
-lartsc
ESD sound backend
aptitude install libesd0-dev
-lesd
NAS sound backend
aptitude install libaudio-dev
-laudio
$ gcc -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT joytest.c
-L/usr/lib -Wl,–as-needed -Wl,-Bstatic -lSDL -lcaca -lslang -laa
-laudio -lesd -lartsc -lvga -ldirectfb -ldirect -lfusion -lcurses
-lcucul -lasound -lgpm -lm -Wl,-Bdynamic -lX11 -ldl -lpthread -o
joytest
–as-needed doesn’t seem useful here.
$ ls -lh joytest
-rwxr-xr-x 1 me me 2,5M 2007-09-26 22:24 joytest
$ strip joytest
$ ls -lh joytest
-rwxr-xr-x 1 me me 2,0M 2007-09-26 22:24 joytest
me at dmc:~/freedink/test/sdl$ ldd joytest
linux-gate.so.1 => (0xffffe000)
libX11.so.6 => /usr/lib/libX11.so.6 (0xb7ee2000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7ede000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7ecc000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7d9b000)
libXau.so.6 => /usr/lib/libXau.so.6 (0xb7d98000)
/lib/ld-linux.so.2 (0xb7fe8000)
libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0xb7d92000)
Here we still have a dynamic executable, with the usual glibc
issues. Compiling with apgcc from Apbuild (Autopackage) may help.
Compiling with a custom simpler SDL
We can try to recompile SDL ourself and get rid of the X11 conflicts,
allowing for a truly static executable:
$ cd SDL-1.2.12
not sure if both options are mandatory:
$ ./configure --disable-x11-shared --disable-shared
$ make && make install
…
$ gcc -static -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT
joytest.c -L/usr/local/lib -L/usr/lib -lSDL -laudio -lvga -ldirectfb
-ldirect -lfusion -lm -lXrandr -lXrender -lX11 -lXau -lXdmcp
-lXext -ldl -lpthread -o joytest
/usr/local/lib/libSDL.a(SDL_alsa_audio.o): In function LoadALSALibrary': ./src/audio/alsa/SDL_alsa_audio.c:139: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/libdirect.a(stream.o): In function
tcp_open’:
(.text+0x891): warning: Using ‘getaddrinfo’ in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/libaudio.a(ConnSvr.o): In function MakeTCPConnection': /home/steve/debian/nas/nas-1.8/lib/audio/ConnSvr.c:981: warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/libX11.a(x11_trans.o): In function
_X11TransSocketINETConnect’:
(.text+0x1da4): warning: Using ‘getservbyname’ in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$ ls -lh joytest
-rwxr-xr-x 1 me me 4,4M 2007-09-26 23:52 joytest
$ strip joytest
$ ls -lh joytest
-rwxr-xr-x 1 me me 2,3M 2007-09-26 23:52 joytest
$ ldd joytest
not a dynamic executable
$ ./joytest
Runs fine until I exit the app:
*** glibc detected *** double free or corruption (out): 0xb7ba4230 ***
Abandon
The resulting binary also crashes with a floating point exception
under Fedora 7 
Maybe it can work with a different SDL setup, namely one that wouldn’t
use dlopen.
Something in-between works. The improvement over using the distro’s
SDL is that X11 is now statically linked:
$ gcc -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT joytest.c
-L/usr/local/lib -L/usr/lib -Wl,-Bstatic -lSDL -laudio -lvga
-ldirectfb -ldirect -lfusion -lm -lXrandr -lXrender -lX11 -lXau
-lXdmcp -lXext -o joytest -Wl,-Bdynamic -ldl -lpthread
$ ls -lh joytest
-rwxr-xr-x 1 me me 3,6M 2007-09-26 23:50 joytest
$ strip joytest
me at dmc:~/freedink/test/sdl$ ls -lh joytest
-rwxr-xr-x 1 me me 1,8M 2007-09-26 23:50 joytest
$ ldd joytest
linux-gate.so.1 => (0xffffe000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7f5a000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7f48000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e17000)
/lib/ld-linux.so.2 (0xb7f78000)
Try switching from dlopen to relaytool
Left as exercise to the reader 
-------------- next part --------------
Cross-compilation
Install a cross-compiler version of GCC
aptitude install mingw32
Prepare directory to store cross-compiled libraries
mkdir -p -m 775 /usr/local/cross-tools/i386-mingw32msvc
cd /usr/local/cross-tools
ln -s i386-mingw32msvc i386-mingw32
Install precompiled SDL binaries
VERSION=1.2.12
wget http://libsdl.org/release/SDL-devel-$VERSION-mingw32.tar.gz
tar xzf SDL-devel-$VERSION-mingw32.tar.gz
mv SDL-$VERSION/* i386-mingw32msvc/
rmdir SDL-$VERSION
Install precompiled SDL_mixer binaries
VERSION=1.2.8
wget http://libsdl.org/projects/SDL_mixer/release/SDL_mixer-devel-$VERSION-VC8.zip
unzip SDL_mixer-devel-$VERSION-VC8.zip
cp -r SDL_mixer-$VERSION/include/* i386-mingw32msvc/include/SDL/
cp -r SDL_mixer-$VERSION/lib/* i386-mingw32msvc/lib/
rm -rf SDL_mixer-$VERSION/
Install precompiled SDL_mixer binaries
VERSION=2.0.9
wget http://libsdl.org/projects/SDL_ttf/release/SDL_ttf-devel-$VERSION-VC8.zip
unzip SDL_ttf-devel-$VERSION-VC8.zip
cp -r SDL_ttf-$VERSION/include/* i386-mingw32msvc/include/SDL/
cp -r SDL_ttf-$VERSION/lib/* i386-mingw32msvc/lib/
rm -rf SDL_ttf-$VERSION/
Cross-compile SDL_gfx (no binaries available)
cd /usr/src
VERSION=2.0.16
wget http://www.ferzkopp.net/Software/SDL_gfx-2.0/SDL_gfx-$VERSION.tar.gz
tar xzf SDL_gfx-$VERSION.tar.gz
cd SDL_gfx-$VERSION
Refresh and mark as DLL-compliant (patch sent)
rm -f acinclude.m4
sed -i -e ‘s/-version-info/-no-undefined -version-info/’ Makefile.am
autoreconf --force --install --symlink
patch -p1 < /tmp/SDL_gfx-libtool.diff # see below
export SDL_CONFIG=/usr/local/cross-tools/i386-mingw32msvc/bin/sdl-config
./configure --host=i586-mingw32msvc --build=i686-pc-linux-gnu
make
make install
Cross-compile FreeDink
cd ~/freedink/
mkdir cross
cd cross/
SDL_CONFIG=/usr/local/cross-tools/i386-mingw32msvc/bin/sdl-config
…/configure --host=i586-mingw32msvc --build=i686-pc-linux-gnu
make clean # just in case
make
make install-strip DESTDIR=/tmp/distribute/
Alternative: cross-compile yourself
Among others, necessary for static builds (not static libraries with
the official releases).
SDL
VERSION=1.2.12
wget http://libsdl.org/release/SDL-$VERSION.tar.gz
tar xzf SDL-$VERSION.tar.gz
cd SDL-$VERSION
./configure --host=i586-mingw32msvc --build=i686-pc-linux-gnu
make
make install # /usr/local/cross-tools/i386-mingw32/ by default
SDL_mixer
VERSION=1.2.8
wget http://libsdl.org/projects/SDL_mixer/release/SDL_mixer-$VERSION.tar.gz
tar xzf SDL_mixer-$VERSION.tar.gz
cd SDL_mixer-$VERSION
Disable MP3 support (not needed in FreeDink and avoid a dependency)
SDL_CONFIG=/usr/local/cross-tools/i386-mingw32msvc/bin/sdl-config ./configure
–host=i586-mingw32msvc --build=i686-pc-linux-gnu
–disable-music-mp3
make
make install # /usr/local/cross-tools/i386-mingw32/ by default
FreeType (SDL_ttf dependency)
VERSION=2.3.5
wget http://download.savannah.gnu.org/releases/freetype/freetype-$VERSION.tar.bz2
tar xjf freetype-$VERSION.tar.bz2
cd freetype-$VERSION
./configure --host=i586-mingw32msvc --build=i686-pc-linux-gnu --prefix=/usr/local/cross-tools/i386-mingw32msvc
make
make install
SDL_ttf
VERSION=2.0.9
wget http://libsdl.org/projects/SDL_ttf/release/SDL_ttf-$VERSION.tar.gz
tar xzf SDL_ttf-$VERSION.tar.gz
cd SDL_ttf-$VERSION
SDL_CONFIG=/usr/local/cross-tools/i386-mingw32msvc/bin/sdl-config
FREETYPE_CONFIG=/usr/local/cross-tools/i386-mingw32msvc/bin/freetype-config
./configure --host=i586-mingw32msvc --build=i686-pc-linux-gnu
make
make install # /usr/local/cross-tools/i386-mingw32/ by default
Static build
I want to cross-compile statically, to provide a single .exe that
includes SDL and SDL_* 
i586-mingw32msvc-gcc mousetest.c
/usr/local/cross-tools/i386-mingw32msvc/bin/sdl-config --cflags \ --static-libs
-lwinmm
-
If you have some troubles with SDL_gfx which tries to use
__imp__SDL_setFramerate, you need a build system patch (see below) -
maybe it will make it to 2.0.17 
-
You need to specify -lfreetype, a dependency of SDL_ttf
You get a 1.1MB standalone stripped executable.
Now we need to integrate the additional library in our build system
and provide ./configure option to build statically (LIBS+=“-lfreetype
-lwinmm”, LDFLAGS+=“-static”)
diff -ru SDL_gfx-2.0.16/SDL_framerate.h SDL_gfx-2.0.16.beuc/SDL_framerate.h
— SDL_gfx-2.0.16/SDL_framerate.h 2006-12-22 13:36:10.000000000 +0100
+++ SDL_gfx-2.0.16.beuc/SDL_framerate.h 2007-09-27 01:46:10.000000000 +0200
@@ -39,21 +39,24 @@
/* --------- Function prototypes */
#ifdef WIN32
-#ifdef BUILD_DLL
-#define DLLINTERFACE __declspec(dllexport)
-#else
-#define DLLINTERFACE __declspec(dllimport)
+# ifdef DLL_EXPORT
+# define SDL_FRAMERATE_SCOPE __declspec(dllexport)
+# else
+# ifdef LIBSDL_GFX_DLL_IMPORT
+# define SDL_FRAMERATE_SCOPE __declspec(dllimport)
+# endif
+# endif
#endif
-#else
-#define DLLINTERFACE
+#ifndef SDL_FRAMERATE_SCOPE
+# define SDL_FRAMERATE_SCOPE extern
#endif
/* Functions return 0 or value for sucess and -1 for error */
- DLLINTERFACE void SDL_initFramerate(FPSmanager * manager);
- DLLINTERFACE int SDL_setFramerate(FPSmanager * manager, int rate);
- DLLINTERFACE int SDL_getFramerate(FPSmanager * manager);
- DLLINTERFACE void SDL_framerateDelay(FPSmanager * manager);
- SDL_FRAMERATE_SCOPE void SDL_initFramerate(FPSmanager * manager);
- SDL_FRAMERATE_SCOPE int SDL_setFramerate(FPSmanager * manager, int rate);
- SDL_FRAMERATE_SCOPE int SDL_getFramerate(FPSmanager * manager);
- SDL_FRAMERATE_SCOPE void SDL_framerateDelay(FPSmanager * manager);
/* — */
diff -ru SDL_gfx-2.0.16/SDL_rotozoom.h SDL_gfx-2.0.16.beuc/SDL_rotozoom.h
— SDL_gfx-2.0.16/SDL_rotozoom.h 2006-12-22 13:36:10.000000000 +0100
+++ SDL_gfx-2.0.16.beuc/SDL_rotozoom.h 2007-09-27 01:45:58.000000000 +0200
@@ -45,13 +45,16 @@
/* ---- Prototypes */
#ifdef WIN32
-#ifdef BUILD_DLL
-#define DLLINTERFACE __declspec(dllexport)
-#else
-#define DLLINTERFACE __declspec(dllimport)
+# ifdef DLL_EXPORT
+# define SDL_ROTOZOOM_SCOPE __declspec(dllexport)
+# else
+# ifdef LIBSDL_GFX_DLL_IMPORT
+# define SDL_ROTOZOOM_SCOPE __declspec(dllimport)
+# endif
+# endif
#endif
-#else
-#define DLLINTERFACE
+#ifndef SDL_ROTOZOOM_SCOPE
+# define SDL_ROTOZOOM_SCOPE extern
#endif
/*
@@ -65,17 +68,17 @@
*/
- DLLINTERFACE SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth);
- SDL_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth);
- DLLINTERFACE SDL_Surface *rotozoomSurfaceXY
- SDL_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurfaceXY
(SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth);
/* Returns the size of the target surface for a rotozoomSurface() call */
- DLLINTERFACE void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth,
- SDL_ROTOZOOM_SCOPE void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth,
int *dstheight);
- DLLINTERFACE void rotozoomSurfaceSizeXY
- SDL_ROTOZOOM_SCOPE void rotozoomSurfaceSizeXY
(int width, int height, double angle, double zoomx, double zoomy,
int *dstwidth, int *dstheight);
@@ -90,11 +93,11 @@
*/
- DLLINTERFACE SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth);
- SDL_ROTOZOOM_SCOPE SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth);
/* Returns the size of the target surface for a zoomSurface() call */
- DLLINTERFACE void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight);
- SDL_ROTOZOOM_SCOPE void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight);
/*
@@ -107,7 +110,7 @@
or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
*/
- DLLINTERFACE SDL_Surface *shrinkSurface(SDL_Surface * src, int factorx, int factory);
- SDL_ROTOZOOM_SCOPE SDL_Surface *shrinkSurface(SDL_Surface * src, int factorx, int factory);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus