You are here

Tutorial : cross-compile a C/GTK+3 program from Linux to Windows

Objectives : compile a C/GTK+3 application under Linux, and produce a valid Windows© binary.

We have a C application using GTK+ 3 as its graphical toolkit :

As the GTK+ 3 Windows binaries now have an official distribution, we will be able to use to create a Windows version of our application, without modifiying the source code nor having a Windows box available.


A Linux Debian or Ubuntu distribution.

1) Install the compilation toolchain

- Install the GCC compiler for Windows (namely MinGW) :

apt-get install mingw32

- Download the latest all-in-one bundle ZIP archive directly from the official website (here's a direct link for impatients...).

(ps : Create a folder named "gtk3-win32" where you want, put the ZIP archive therein and extract it with :

- Adapt GTK+ to its location :
In a terminal, move to the "gtk3-win32" folder you just created. If you extracted it to "/opt/gtk3-win32" e.g. :
cd /opt/gtk3-win32
then do :
find -name '*.pc' | while read pc; do sed -e "s@^prefix=.*@prefix=$PWD@" -i "$pc"; done

2) Compile

- We will tell "pkg-config" to locate GTK+ libraries in our custom path. If you extracted to "/opt/gtk3-win32" e.g. :
export PKG_CONFIG_PATH=/opt/gtk3-win32/lib/pkgconfig

We are ready to compile an sample C source ! Let's use a command in this style :

i586-mingw32msvc-gcc source.c -o executable.exe `pkg-config --cflags --libs gtk+-3.0`

A new executable should have been created if everything went well.
It won't run on our Linux system, because it's targeting Windows !

3) Release

- Create a folder containing the binary and the Windows .dll files. If you extracted to "/opt/gtk3-win32" e.g. :
mkdir ~/distri
cp executable.exe ~/distri
cp /opt/gtk3-win32/bin/*.dll ~/distri

- Here we go ! Transfer this folder to a Windows box. Double-click on the executable and...

Well done !


Thanks for posting this hint. I'd never thought of modifying the .pc files with an sed script. I'm working on a cross compiled Gtk3 project where that turns out to be a very useful addition to the toolbox. If you could provide a link to your gtk test program source, it would save some folks some effort. On my Ubuntu 13.10 (x86_64) system the compiler is 'i686-w64-mingw32-gcc' . Even more importantly, the test program I compiled runs well using Wine.

Hi Cecil,

Good remark, thanks. Here is a simple sample ; I've put it in the article, too.

Salut Tarnyko,

I followed your tut step by step. Everthing seems to be so smooth but in during comilation i got this compiler error:

#$ i586-mingw32msvc-gcc /home/spivvi/Desktop/test.c -o test.exe `pkg-config --cflags --libs gtk+-3.0`
i586-mingw32msvc-gcc: unrecognized option '-pthread'
In file included from /usr/include/glib-2.0/glib.h:108,
from /usr/include/gtk-3.0/gdk/gdkconfig.h:13,
from /usr/include/gtk-3.0/gdk/gdk.h:30,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from /home/spivvi/Desktop/test.c:1:
/usr/include/glib-2.0/glib/deprecated/gthread.h:123:21: error: pthread.h: No such file or directory
In file included from /usr/include/glib-2.0/glib.h:108,
from /usr/include/gtk-3.0/gdk/gdkconfig.h:13,
from /usr/include/gtk-3.0/gdk/gdk.h:30,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from /home/spivvi/Desktop/test.c:1:
/usr/include/glib-2.0/glib/deprecated/gthread.h:133: error: expected specifier-qualifier-list before ‘pthread_mutex_t’
/usr/include/glib-2.0/glib/deprecated/gthread.h:162: error: expected specifier-qualifier-list before ‘pthread_t’
In file included from /usr/include/glib-2.0/gio/gio.h:47,
from /usr/include/gtk-3.0/gdk/gdkapplaunchcontext.h:28,
from /usr/include/gtk-3.0/gdk/gdk.h:32,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from /home/spivvi/Desktop/test.c:1:

My test.c file contains this:

void main (int argc, char *argv[]) {
GtkWidget *window;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Hello World");
gtk_widget_show (window);
gtk_main ();

I'm on Ubuntu12.04LTS.

dpkg -l | grep -i pthread
ii libevent-pthreads-2.0-5 2.0.16-stable-1 Asynchronous event notification library (pthreads)
ii libpthread-stubs0 0.3-3 pthread stubs not provided by native libc
ii libpthread-stubs0-dev 0.3-3 pthread stubs not provided by native libc, development files
ii libpthread-workqueue-dev 0.8.2-1 thread pool library (development files)
ii libpthread-workqueue0 0.8.2-1 thread pool library

Do you have any clue on this issue?
Thanks splivv.


Try on a newer Ubuntu version, there are known issues with pthread in old MinGW versions


Thank you for the tutorial! I'll use it in our build bot :-)

If you want native looking anti-aliased fonts, add this to etc\gtk-3.0\settings.ini:

gtk-font-name = Segoe UI 9
gtk-xft-rgba = rgb


Je suis grand débutant et la commande suivante
find -name '*.pc' | while read pc; do sed -e "s@^prefix=.*@prefix=$PWD@" -i "$pc"; done
retourne l'erreur: Erreur de syntaxe près du symbole inattendu "done"
Et là, j'aurais besoin d'un peu d'aide.
Merci d'avance

Je viens d'essayer la commande sur un bash ; ça a l'air de marcher... Peux tu vérifier que tu utilises bien bash ? Tape "echo $SHELL" et si ça ne renvoie pas "/bin/bash", lance-le manuellement avec "bash".
Sinon ça me paraîtrait surprenant que tu ne les aies pas, mais vérifie la présence des commandes "find" et "sed" en tapant leur nom. Si cela fait une erreur, il faudra les installer.