Compiling Gtkmm from source on windows with MinGW 32 bit and msys



(0) Why compiling from source

Because of the license.  Gtkmm and most of its dependencies are LGPL.
If I distribute proprietary programs, dynamically linked against
gtkmm, and also distribute the libraries, then I will need to also
distribute the source code of the LGPL libraries, either together with
the binaries or upon request.

I can only be sure that I can provide the correct and complete source
code if I compile the LGPL libraries myself.  If I used a precompiled
package, the producer of that package could have introduced a change
(e.g. to make the thing compile at all on windows), but I would not
know about that change and could not fulfill my obligations from
distributing LGPL software.

Consequently, I am not overly interested in compiling libraries from
source when the license does not require me to provide the source code
(like zlib).  In this case I will happily use a precompiled library.
Despite that, compiling from source was often more convenient than
finding a compatible binary, so this guide also contains instructions
how to compile most non-lgpl libraries.

(1) Set up development environment

(1a) Python

Python is needed to install glib on the build system.  Python can be
downloaded from
https://www.python.org/ftp/python/2.7.8/python-2.7.8.msi .  Install it
in the default location (C:\Python27)

(1b) MinGW and msys

Get the installer from
http://downloads.sourceforge.net/project/mingw/Installer/mingw-get-setup.exe
.  Do not click on anything on this page.  Sourceforge downloads are
surrounded by scam advertisements.  The download of the installer
starts automatically.

Execute the installer. Choose the following components:
In "Basic Setup" choose mingw32-base, mingw32-gcc-g++, msys-base.
In "All Packages", choose additionally:
- mingw32-libz (class dev)
- mingw32-pthreads-w32 (all three)
- msys-m4 (class bin)
- msys-patch (class bin)
- msys-perl (class bin)
- msys-wget (class bin)
- msys-vim (class bin)

Menu Installation -> ApplyChanges -> Apply

Execute the postinstall batch file \MinGW\msys\1.0\postinstall\pi.bat.

Create a desktop Link to c:\MinGW\msys\1.0\msys.bat.  Start it.

Create a file named .profile in the home directory of this shell,
using cat or vim or some other editor that can save text files with
unix line endings.  Contents:

 export PYTHON=/c/Python27/python.exe

Restart the shell and make sure that setting worked.

Inspect the PATH environment variable. Make sure it does not contain
another directory with compilers or unix tools apart from the
MinGW/msys installation.

Decide on an installation prefix directory. I use /opt/gtk and add
/opt/gtk/bin to the PATH in .profile

(2) zlib

zlib does not require source code distribution, and a binary from
MinGW is already installed:

mkdir -p /opt/gtk/{bin,include,lib}
cp /mingw/bin/zlib1.dll /opt/gtk/bin/
cp /mingw/include/z{lib,conf}.h /opt/gtk/include/
cp -v /mingw/lib/libz.*a /opt/gtk/lib/

(3) libpng

Homepage: http://www.libpng.org/pub/png/libpng.html

wget http://prdownloads.sourceforge.net/libpng/libpng-1.6.12.tar.xz?download
tar xf libpng-1.6.12.tar.xz
cd libpng-1.6.12
./configure --prefix=/opt/gtk/
make
make install
cd ..

(4) libjpeg

Homepage: http://ijg.org/

wget http://ijg.org/files/jpegsrc.v9a.tar.gz
tar xf jpegsrc.v9a.tar.gz
cd jpeg-9a
./configure --prefix=/opt/gtk/
make
make install
echo "this software is based in part on the work of the Independent
JPEG Group" >>/opt/gtk/legal.txt
cd ..

(5) freetype

Homepage: http://freetype.org/

wget http://download.savannah.gnu.org/releases/freetype/freetype-2.5.3.tar.bz2
tar xf freetype-2.5.3.tar.bz2
cd freetype-2.5.3
./configure --prefix=/opt/gtk/
make
make install
echo "the software is based in part of the work of the FreeType Team"
/opt/gtk/legal.txt
cd ..

(6) libiconv

Homepage: https://www.gnu.org/software/libiconv/

wget http://ftp.jaist.ac.jp/pub/GNU/libiconv/libiconv-1.14.tar.gz
tar xf libiconv-1.14.tar.gz
cd libiconv-1.14
./configure --prefix=/opt/gtk/
make
make install
echo "libiconv is distributed under the terms of the GNU LIBRARY
GENERAL PUBLIC LICENSE Version 2" >>/opt/gtk/legal.txt
cp COPYING.LIB /opt/gtk/GNU_LIBRARY_GENERAL_PUBLIC_LICENSE_Version_2.txt
cd ..

(7) libtiff

Homepage: http://www.remotesensing.org/libtiff/

wget ftp://ftp.remotesensing.org/pub/libtiff/tiff-4.0.3.tar.gz
tar xf tiff-4.0.3.tar.gz
cd tiff-4.0.3
./configure --prefix=/opt/gtk/
make
make install
echo "the software is based in part on libtiff. See
share/doc/tiff-4.0.3/COPYRIGHT." >>/opt/gtk/legal.txt
cd ..

(8) pkg-config

Homepage: http://www.freedesktop.org/wiki/Software/pkg-config/

wget http://pkgconfig.freedesktop.org/releases/pkg-config-0.28.tar.gz
tar xf pkg-config-0.28.tar.gz
cd pkg-config-0.28
./configure --prefix=/opt/gtk/ --with-internal-glib
make
make install
cd ..

(9) gettext

Homepage: http://www.freedesktop.org/wiki/Software/pkg-config/

wget http://ftp.jaist.ac.jp/pub/GNU/gettext/gettext-0.19.2.tar.xz
tar xf gettext-0.19.2.tar.xz
cd gettext-0.19.2
./configure --prefix=/opt/gtk/
make
make install
echo "the software is based in part on libintl from the gettext
runtime which is distributed under the GNU LESSER GENERAL PUBLIC
LICENSE Version 2.1, see share/gettext/intl/COPYING.LIB" >>
/opt/gtk/legal.txt
cd ..

(9) pcre

Homepage: http://www.pcre.org/

wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.35.tar.bz2

tar xf pcre-8.35.tar.bz2
cd pcre-8.35
./configure --prefix=/opt/gtk/
echo "the software is based in part on PCRE which is distributed under
the PCRE LICENSE, see share/doc/pcre/LICENCE" >> /opt/gtk/legal.txt

(10) libxml2

Homepage: http://xmlsoft.org/

wget ftp://xmlsoft.org/libxml2/libxml2-2.9.1.tar.gz
tar xf libxml2-2.9.1.tar.gz
cd libxml2-2.9.1
./configure --prefix=/opt/gtk/ --without-python
make
echo "the software is based in part on libxml2, see
share/doc/libxml2-2.9.1/Copyright" >> /opt/gtk/legal.txt
cd ..

(10) expat

Homepage: http://www.libexpat.org/

wget http://prdownloads.sourceforge.net/expat/expat-2.1.0.tar.gz
tar xf expat-2.1.0.tar.gz
cd expat-2.1.0
./configure --prefix=/opt/gtk/
make
make install
cp COPYING /opt/gtk/COPYRIGHT.expat.txt
echo "the software is based in part on expat, see COPYRIGHT.expat.txt"
/opt/gtk/legal.txt
cd ..

(11) fontconfig

Homepage: http://www.freedesktop.org/wiki/Software/fontconfig/

wget http://www.freedesktop.org/software/fontconfig/release/fontconfig-2.11.1.tar.bz2
tar xf fontconfig-2.11.1.tar.bz2
cd fontconfig-2.11.1
./configure --prefix=/opt/gtk/
make
make install
cp COPYING /opt/gtk/COPYRIGHT.fontconfig.txt
echo "the software is based in part on fontconfig, see
COPYRIGHT.fontconfig.txt" >> /opt/gtk/legal.txt
cd ..

(12) libffi

Homepage: https://sourceware.org/libffi/

wget ftp://sourceware.org/pub/libffi/libffi-3.1.tar.gz
tar xf libffi-3.1.tar.gz
cd libffi-3.1
./configure --prefix=/opt/gtk/
make
make install
cp LICENSE /opt/gtk/COPYRIGHT.libffi.txt
echo "the software is based in part on libffi, see
COPYRIGHT.libffi.txt" >> /opt/gtk/legal.txt
cd ..

(13) glib

Homepage: https://developer.gnome.org/glib/stable/

wget http://ftp.gnome.org/pub/gnome/sources/glib/2.40/glib-2.40.0.tar.xz
tar xf glib-2.40.0.tar.xz
cd glib-2.40.0

glib does not search for headers in prefix/include/.  This makes it
necessary to add the following environment variables to .profile:

export CFLAGS=-I/opt/gtk/include
export CXXFLAGS="$CFLAGS"
export LDFLAGS=-L/opt/gtk/lib

restart the shell.

On windows glib uses a function rand_s without checking if it is
available.  However, neither is this function declared in MinGW
headers, nor is it present in the Microsoft runtime DLL msvcrt.dll on
my windows 7.  Therefore, I have to modify the glib code that uses it.
Here is the patch:
--- glib/grand.c        2014-09-03 19:56:34 +0000
+++ glib/grand.c        2014-09-03 20:03:28 +0000
@@ -56,6 +56,7 @@

 #ifdef G_OS_WIN32
 #include <stdlib.h>
+#include <process.h>
 #endif

 /**
@@ -209,8 +210,6 @@
  * either from `/dev/urandom` (if existing) or from the current time
  * (as a fallback).
  *
- * On Windows, the seed is taken from rand_s().
- *
  * Returns: the new #GRand
  */
 GRand*
@@ -261,10 +260,12 @@
       seed[3] = getppid ();
     }
 #else /* G_OS_WIN32 */
-  gint i;
-
-  for (i = 0; i < G_N_ELEMENTS (seed); i++)
-    rand_s (&seed[i]);
+  GTimeVal now;
+  g_get_current_time (&now);
+  seed[0] = now.tv_sec;
+  seed[1] = now.tv_usec;
+  seed[2] = getpid ();
+  seed[3] = 0;
 #endif

   return g_rand_new_with_seed_array (seed, 4);

./configure --prefix=/opt/gtk/
make
make install
echo "glib is distributed under the terms of the GNU LIBRARY GENERAL
PUBLIC LICENSE Version 2" >>/opt/gtk/legal.txt
cd ..

(14) pixman

Homepage: ???

wget http://cairographics.org/releases/pixman-0.32.6.tar.gz
tar xf pixman-0.32.6.tar.gz
cd pixman-0.32.6
./configure --prefix=/opt/gtk/
make
make install
cp COPYING /opt/gtk/COPYRIGHT.pixman.txt
echo "the software is based in part on pixman, see
COPYRIGHT.pixman.txt" >> /opt/gtk/legal.txt
cd ..

(15) gdk-pixbuf

Homepage: https://developer.gnome.org/gdk-pixbuf/stable/

wget http://ftp.gnome.org/pub/GNOME/sources/gdk-pixbuf/2.30/gdk-pixbuf-2.30.8.tar.xz
tar xf gdk-pixbuf-2.30.8.tar.xz
cd gdk-pixbuf-2.30.8
./configure --prefix=/opt/gtk/
make
make install
echo "gdk-pixbuf is distributed under the terms of the GNU LIBRARY
GENERAL PUBLIC LICENSE Version 2" >>/opt/gtk/legal.txt
cd ..

(16) cairo

Homepage:  http://cairographics.org/

wget http://cairographics.org/releases/cairo-1.12.16.tar.xz
tar xf cairo-1.12.16.tar.xz
cd cairo-1.12.16

Somehow cairo thinks that ssize_t is not typedefed, although it is.
This results in a compilation error.  The fix is to comment out the
typedef to ssize_t in file util/cairo-missing/cairo-missing.h

./configure --prefix=/opt/gtk/
make
make install
echo "cairo is distributed under the GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, see share/gettext/intl/COPYING.LIB" >> /opt/gtk/legal.txt
cd ..

(17) atk

Homepage: https://developer.gnome.org/atk/2.10/

wget http://ftp.gnome.org/pub/GNOME/sources/atk/2.10/atk-2.10.0.tar.xz
tar xf atk-2.10.0.tar.xz
cd atk-2.10.0
./configure --prefix=/opt/gtk/
make
make install
echo "atk is distributed under the terms of the GNU LIBRARY GENERAL
PUBLIC LICENSE Version 2" >>/opt/gtk/legal.txt
cd ..

(18) pango

Homepage: http://www.pango.org/

wget http://ftp.gnome.org/pub/GNOME/sources/pango/1.36/pango-1.36.7.tar.xz
tar xf pango-1.36.7.tar.xz
cd pango-1.36.7
./configure --prefix=/opt/gtk/
make
make install
echo "pango is distributed under the terms of the GNU LIBRARY GENERAL
PUBLIC LICENSE Version 2" >>/opt/gtk/legal.txt
cd ..

(19) gtk+

Homepage: http://www.gtk.org/

wget http://ftp.gnome.org/pub/gnome/sources/gtk+/3.12/gtk+-3.12.2.tar.xz
tar xf gtk+-3.12.2.tar.xz
cd gtk+-3.12.2
./configure --prefix=/opt/gtk/

The Makefile in gdk contains a dependency on gdk.def but no rule to
generate the gdk.def file.  This patch removes gdk.def from any
dependencies:

--- gtk+-3.12.2-orig/gdk/Makefile       2014-09-03 22:58:53 +0000
+++ gtk+-3.12.2/gdk/Makefile    2014-09-03 23:24:29 +0000
@@ -94,7 +94,7 @@
 #      $(am__append_1) $(am__append_3) \
 #      $(am__append_5) $(am__append_7) \
 #      $(am__append_8)
-am__append_6 = -Wl,win32/rc/gdk-win32-res.o -export-symbols $(srcdir)/gdk.def
+am__append_6 = -Wl,win32/rc/gdk-win32-res.o
 #am__append_7 = broadway/libgdk-broadway.la
 #am__append_8 = wayland/libgdk-wayland.la
 #am__append_9 = Gdk-3.0.gir
@@ -747,7 +747,7 @@
 libgdk_3_la_LIBADD = $(GDK_DEP_LIBS) $(am__append_1) $(am__append_3) \
        $(am__append_5) $(am__append_7) $(am__append_8)
 libgdk_3_la_LDFLAGS = $(LDADD) $(am__append_6)
-libgdk_3_la_DEPENDENCIES = win32/libgdk-win32.la win32/rc/gdk-win32-res.o gdk.d
ef
+libgdk_3_la_DEPENDENCIES = win32/libgdk-win32.la win32/rc/gdk-win32-res.o
 #introspection_files = \
 #      $(filter-out gdkkeysyms-compat.h, $(gdk_public_h_sources))      \
 #      $(gdk_c_sources)        \
@@ -1690,11 +1690,10 @@

 #GdkWin32-3.0.gir: libgdk-3.la Gdk-3.0.gir Makefile

-install-def-file: gdk.def
-       mkdir -p $(DESTDIR)$(libdir)
-       $(INSTALL) $(srcdir)/gdk.def $(DESTDIR)$(libdir)/gdk-win32-3.0.def
+install-def-file:
+       true
 uninstall-def-file:
-       -rm $(DESTDIR)$(libdir)/gdk-win32-3.0.def
+       true
 #install-def-file:
 #uninstall-def-file:


Then invoke make.  It will fail with
/bin/sh: ./gtk-update-icon-cache.exe: Bad file number

This is windows user access control preventing something. Start a new
shell as administrator, invoke make, wait till that make is past that
point, then hit Ctrl-C, and continue with make in the normal shell.

A little later there is again a problem wit a .def file dependency.
This is a patch for that:

--- gtk+-3.12.2-orig/gtk/Makefile       2014-09-03 22:58:56 +0000
+++ gtk+-3.12.2/gtk/Makefile    2014-09-04 00:11:12 +0000
@@ -1071,8 +1071,6 @@
        $(INCLUDED_IMMODULE_DEFINE)

 no_undefined = -no-undefined
-gtk_def = gtk.def
-gtk_win32_symbols = -export-symbols $(srcdir)/gtk.def
 gtk_win32_res = gtk-win32-res.o
 gtk_win32_res_ldflag = -Wl,gtk-win32-res.o
 #noinst_DATA = gtk-win32-$(GTK_API_VERSION).lib
@@ -5969,10 +5967,10 @@
 gtk-win32-res.o : gtk-win32.rc
        $(WINDRES) gtk-win32.rc $@

-install-def-file: gtk.def
-       $(INSTALL) $(srcdir)/gtk.def $(DESTDIR)$(libdir)/gtk-win32-3.0.def
+install-def-file:
+       true
 uninstall-def-file:
-       -rm $(DESTDIR)$(libdir)/gtk-win32-3.0.def
+       true
 #install-def-file:
 #uninstall-def-file:

make
make install

This fails somewhere in the "demos" subdirectory.  Again it is
gtk-update-icon-cache that fails, but this time, running as
administrator does not help.  Assuming that all content below "demos"
is non-essential, modifying the Makefile so that SUBDIRS is empty
helps and the next invocation of make install finishes.

echo "gtk+ is distributed under the terms of the GNU LIBRARY GENERAL
PUBLIC LICENSE Version 2" >>/opt/gtk/legal.txt
cd ..

(20) libsigc++

Homepage: http://libsigc.sourceforge.net/

wget http://ftp.gnome.org/pub/GNOME/sources/libsigc++/2.3/libsigc++-2.3.2.tar.xz
tar xf libsigc++-2.3.2.tar.xz
cd libsigc++-2.3.2
./configure --prefix=/opt/gtk/
make
make install
echo "libsigc++ is distributed under the GNU LESSER GENERAL PUBLIC
LICENSE Version 2.1, see share/gettext/intl/COPYING.LIB" >>
/opt/gtk/legal.txt
cd ..

(21) glibmm

Homepage: https://developer.gnome.org/glibmm/stable/

wget http://ftp.gnome.org/pub/GNOME/sources/glibmm/2.40/glibmm-2.40.0.tar.xz
tar xf glibmm-2.40.0.tar.xz
cd glibmm-2.40.0
./configure --prefix=/opt/gtk/
make
make install
echo "glibmm is distributed under the GNU LESSER GENERAL PUBLIC
LICENSE Version 2.1, see share/gettext/intl/COPYING.LIB" >>
/opt/gtk/legal.txt
cd ..

(22) cairomm

Homepage: http://cairographics.org/cairomm/

wget http://cairographics.org/releases/cairomm-1.11.2.tar.gz
tar xf cairomm-1.11.2.tar.gz
cd cairomm-1.11.2
./configure --prefix=/opt/gtk/
make
make install
echo "cairomm is distributed under the terms of the GNU LIBRARY
GENERAL PUBLIC LICENSE Version 2" >>/opt/gtk/legal.txt
cd ..

(23)

Homepage: https://developer.gnome.org/pangomm/stable/

wget http://ftp.gnome.org/pub/GNOME/sources/pangomm/2.34/pangomm-2.34.0.tar.xz
tar xf pangomm-2.34.0.tar.xz
cd pangomm-2.34.0
./configure --prefix=/opt/gtk/
make
make install
echo "pangomm is distributed under the GNU LESSER GENERAL PUBLIC
LICENSE Version 2.1, see share/gettext/intl/COPYING.LIB" >>
/opt/gtk/legal.txt
cd ..

(24) atkmm

Homepage: https://developer.gnome.org/atkmm/stable/

wget http://ftp.gnome.org/pub/GNOME/sources/atkmm/2.22/atkmm-2.22.7.tar.xz
tar xf atkmm-2.22.7.tar.xz
cd atkmm-2.22.7
./configure --prefix=/opt/gtk/
make
make install
echo "atkmm is distributed under the GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, see share/gettext/intl/COPYING.LIB" >> /opt/gtk/legal.txt
cd ..

(25) gtkmm

Homepage: http://www.gtkmm.org/en/

wget http://ftp.gnome.org/pub/GNOME/sources/gtkmm/3.12/gtkmm-3.12.0.tar.xz
tar xf gtkmm-3.12.0.tar.xz
cd gtkmm-3.12.0
./configure --prefix=/opt/gtk/
make
make install
echo "gtkmm is distributed under the GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, see share/gettext/intl/COPYING.LIB" >> /opt/gtk/legal.txt
cd ..

(26) Using gtkmm

cat >gtkmmexample.cpp
#include <gtkmm.h>

int main(int argc, char *argv[])
{
  Glib::RefPtr<Gtk::Application> app =
    Gtk::Application::create(argc, argv,
      "org.gtkmm.examples.base");

  Gtk::Window window;
  window.set_default_size(200, 200);

  return app->run(window);
}
^D
g++ -o gtkmmexample.exe $(pkg-config --cflags gtkmm-3.0)
gtkmmexample.cpp $(pkg-config --libs gtkmm-3.0)
./gtkmmexample.exe

works as expected


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]