Projects:GTK on DirectFB for Embedded Systems

= GTK on DirectFB for Embedded Systems v1.1 =

Introduction
Since GTK allows to build professional GUIs in a simple and fast way, and since the market of set-top-boxes and other devices, based on embedded Linux, is significantly growing, having the possibility of using GTK in embedded systems (thanks to DirectFB) is crucial, specially if the hardware provides graphics acceleration.

The previous version of this document can be seen in the GTK on DirectFB for Embedded Systems v1.0

Warnings
1. This documentation assumes you already have DirectFB install in $PREFIX/usr. Change it accordingly to your installation.

2. This documentation is still a work in progress, some steps of this procedure could be useless, ugly and/or dangerous. In order to make this procedure easier, it might be that there is the need of some patches, which are already in development.

3. The autotools are not very user-friendly when cross-compiling, thus, a lot of configure files and Makefile (that are generated by the autotools) have to be edited by hand.

4. GTK and all the packages underneath need a considerable amount of space and processor. If your embedded device provides a hard-drive/compact-flash and supports hardware accelerated graphics you can use GTK without problems.

Any help, suggestions and corrections are welcome.

Supported Architectures
This procedure should work on any architecture in which DirectFB is installed. It has been reported to work succesfully in the following architectures/processors:

- MIPS (Philips Nexperia PNX8550, AMD Au1200)

- ARM (Intel XScale)

- SH (STMicroelectronics ST40)

Requirements
Typically, when developing applications for an embedded system a cross-toolchain is needed. If you already have a cross-toolchain you don’t have to worry about building it yourself. Otherwise, a well known resource for building one is http://www.kegel.com/crosstool

When developing for embedded systems, there are very few Linux ditributions or packages that contain all the required software for building GTK, therefore you have to build everything from scratch.

The order in which the packages are compiled is important since some of them won't compile without the others. The packages, their versions and the order used for building GTK are the following:

glib-2.12.13

atk-1.19.3

freetype-2.3.5

libxml2-2.6.29

fontconfig-2.4.2

zlib-1.2.3

libpng-1.2.19

cairo-1.4.10

pango-1.16.4

gtk+-2.10.14

Environment configuration
Suppose that the libraries will be installed in /opt/gtkdfb/usr/local (may be /opt/gtkdfb is the root fs of your embedded target) and that the cross-toolchain (compiler, linker...) is in your path.

Start yourself off by opening a new terminal and setting up the following variables. Change the COMPILER variable accordingly to your compiler.

$ export PREFIX=/opt/gtkdfb/usr/local $ export LD_LIBRARY_PATH=$PREFIX/lib $ export PKG_CONFIG_PATH=$LD_LIBRARY_PATH/pkgconfig $ export COMPILER=sh4-linux-gcc $ export HOST=sh4-linux $ export BUILD=i386-linux

Building the requirements
GLib

Package: glib-2.12.13

Edit the "configure" file:

Search for the texts "cannot run test program while cross compiling" and "cross-compiling". Remove the following code that appears a couple of lines below the searched texts: { (exit 1); exit 1; };

While configuring there will be messages like checking for growing stack pointer... configure: error: cannot run test program while \ cross compiling See config.log for more details.

just ignore them. It's dirty but it works.

Configure, compile and install: $ CC=$COMPILER ./configure --build=$BUILD --host=$HOST --prefix=$PREFIX $ gmake $ gmake install

ATK

Package: atk-1.19.3

Configure: $ CC=$COMPILER ./configure --host=$HOST --build=$BUILD --prefix=$PREFIX --disable-glibtest

Edit the Makefiles found in /, /atk and /tests: Substitute the values of DEP_CFLAGS, DEP_LIBS, GLIB_CFLAGS, GLIB_LIBS with the following values: DEP_CFLAGS = -pthread -I/opt/gtkdfb/usr/local/include/glib-2.0 \ -I/opt/gtkdfb/usr/local/lib/glib-2.0/include DEP_LIBS = -L/opt/gtkdfb/usr/local/lib \ -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 GLIB_CFLAGS = -I/opt/gtkdfb/usr/local/include/glib-2.0 \ -I/opt/gtkdfb/usr/local/lib/glib-2.0/include GLIB_LIBS = -L/opt/gtkdfb/usr/local/lib -lgobject-2.0 \ -lgmodule-2.0 -ldl -lglib-2.0

Compile and install: $ gmake $ gmake install

Freetype2

Package: freetype-2.3.5

Configure, compile and install: $ CC=$COMPILER ./configure --host=$HOST --build=$BUILD --prefix=$PREFIX $ gmake $ gmake install

libxml2

Package: libxml2-2.6.29

Configure, compile and install: $ CC=$COMPILER ./configure --host=$HOST --build=$BUILD --prefix=$PREFIX --without-debug $ gmake $ gmake install

Fontconfig

Package: fontconfig-2.4.2

Configure, compile and install. Change the --with-arch flag to your arch: $ CC=$COMPILER ./configure --build=$BUILD --host=$HOST \ --prefix=/opt/gtkdfb/usr/local \ --with-freetype-config=$PREFIX/bin/freetype-config --enable-libxml2 --with-arch=sh4 $ gmake $ gmake install

zlib

Package: zlib-1.2.3

Configure, compile and install: $ CC=$COMPILER ./configure --prefix=$PREFIX --shared $ gmake $ gmake install

libpng

Package: libpng-1.2.19

Edit the configure file: Set to 'yes' the following variable: ac_cv_lib_z_zlibVersion=yes

Configure, compile and install: $ CC=$COMPILER ./configure --host=$HOST --build=$BUILD --prefix=$PREFIX $ gmake $ gmake install

Cairo

Package: cairo-1.4.10

Edit the configure file: Set to 'yes' the following variables: ac_cv_lib_z_compress=yes ac_header_compiler=yes ac_header_preproc=yes

Configure, compile and install: $ CC=$COMPILER \ directfb_CFLAGS="-I$PREFIX/../include/directfb" \ directfb_LIBS="$PREFIX/../lib/libdirectfb.so \ $PREFIX/../lib/libdirect.so \  $PREFIX/../lib/libfusion.so" \ png_REQUIRES="$PREFIX/lib/pkgconfig" \ png_CFLAGS="-I$PREFIX/include" \ png_LIBS=$PREFIX/lib/libpng12.so \ FONTCONFIG_CFLAGS="-I$PREFIX/include/fontconfig" \ FONTCONFIG_LIBS=$PREFIX/lib/libfontconfig.so \ FREETYPE_CFLAGS="-I$PREFIX/include/freetype2" \ FREETYPE_LIBS=$PREFIX/lib/libfreetype.so \ ./configure --prefix=$PREFIX --build=$BUILD --host=$HOST \ --enable-directfb=yes --without-x --disable-xlib --disable-xlib-xrender \ --disable-win32 --disable-pdf --disable-ps --disable-svg --enable-png

$ gmake $ gmake install

Pango

Package: pango-1.16.4

Edit, if necessary, the "configure" file:

Set to 'yes' the following variables: have_cairo=yes have_cairo_png=yes have_cairo_freetype=yes

Configure: $ CC=$COMPILER \ GLIB_CFLAGS="-I$PREFIX/include/glib-2.0 \ -I$PREFIX/lib/glib-2.0/include" \ GLIB_LIBS="$PREFIX/lib/libglib-2.0.so \ $PREFIX/lib/libgmodule-2.0.so \  $PREFIX/lib/libgobject-2.0.so \  $PREFIX/lib/libfontconfig.so \  $PREFIX/lib/libxml2.so \  $PREFIX/lib/libfreetype.so" \ CAIRO_CFLAGS="-I$PREFIX/include/cairo" \ CAIRO_LIBS=$PREFIX/lib/libcairo.so \ FONTCONFIG_CFLAGS="-I$PREFIX/include/fontconfig" \ FONTCONFIG_LIBS=$PREFIX/lib/libfontconfig.so \ FREETYPE_CFLAGS="-I$PREFIX/include/freetype2" \ FREETYPE_LIBS=$PREFIX/lib/libfreetype.so \ FREETYPE_CONFIG=$PREFIX/bin/freetype-config \ ./configure --host=$HOST --build=$BUILD --prefix=$PREFIX --without-x

Edit the examples/Makefile: Add to the GLIB_LIBS variable the following: /opt/gtkdfb/usr/local/lib/libpng12.so \ /opt/gtkdfb/usr/lib/libdirectfb.so \ /opt/gtkdfb/usr/lib/libdirect.so \ /opt/gtkdfb/usr/lib/libfusion.so

Edit tools/Makefile and tests/Makefile: Set the LIBS variables to the following value: LIBS = $(GLIB_LIBS)

Compile and install: $ gmake $ gmake install

GTK+

Package: gtk+-2.10.14

Configure:

Set the PKG_CONFIG variable accordingly to your environment. It could be /opt/gtkdfb/usr/local/lib/pkg-config $ CC=$COMPILER \ PKG_CONFIG=/opt/STM/STLinux-2.3ear/host/bin/pkg-config \ BASE_DEPENDENCIES_CFLAGS="-I$PREFIX/include -I$PREFIX/lib/glib-2.0/include -I$PREFIX/include/glib-2.0 \ -I$PREFIX/include/pango-1.0 -I$PREFIX/include/cairo -I$PREFIX/include/atk-1.0" \ BASE_DEPENDENCIES_LIBS="-L$PREFIX/lib $PREFIX/lib/libglib-2.0.so $PREFIX/lib/libgobject-2.0.so \ $PREFIX/lib/libgmodule-2.0.so $PREFIX/lib/libfontconfig.so $PREFIX/lib/libxml2.so" \ GLIB_CFLAGS="-I$PREFIX/include -I$PREFIX/lib/glib-2.0/include -I$PREFIX/include/glib-2.0" \ GLIB_LIBS="-L$PREFIX/lib $PREFIX/lib/libglib-2.0.so $PREFIX/lib/libgobject-2.0.so \ $PREFIX/lib/libgmodule-2.0.so $PREFIX/lib/libfontconfig.so $PREFIX/lib/libxml2.so" \ PANGO_CFLAGS="-I$PREFIX/include/pango-1.0" \ PANGO_LIBS="-L$PREFIX/lib $PREFIX/lib/libpango-1.0.so $PREFIX/lib/libpangoft2-1.0.so \ $PREFIX/lib/libpangocairo-1.0.so" \ GDK_DEP_CFLAGS="-pthread -I$PREFIX/include/glib-2.0 -I$PREFIX/lib/glib-2.0/include \ -I$PREFIX/include/pango-1.0 -I$PREFIX/include/cairo -I$PREFIX/include -D_REENTRANT -D_GNU_SOURCE \  -I$PREFIX/../include -I$PREFIX/../include/directfb" \ GDK_DEP_LIBS="-L$PREFIX/lib -ldirectfb -lfusion -ldirect -lpthread -ldl -lpangocairo-1.0 \ -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lpng12 -ljpeg -lm" \ GDK_PIXBUF_DEP_CFLAGS="-pthread -I$PREFIX/include/glib-2.0 -I$PREFIX/lib/glib-2.0/include \ -I$PREFIX/include -I$PREFIX/../include" \ GDK_PIXBUF_DEP_LIBS="-L$PREFIX/lib -lgmodule-2.0 -ldl -lgobject-2.0 -lglib-2.0 -lpng12 -ljpeg -lm" \ GTK_DEP_CFLAGS="-pthread -I$PREFIX/include/glib-2.0 -I$PREFIX/lib/glib-2.0/include \ -I$PREFIX/include/pango-1.0 -I$PREFIX/include/cairo -I$PREFIX/include -D_REENTRANT -D_GNU_SOURCE \  -I$PREFIX/../include/directfb -I$PREFIX/include/atk-1.0 -I$PREFIX/../include" \ GTK_DEP_LIBS="-L$PREFIX/lib -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lgobject-2.0 -lgmodule-2.0 \ -ldl -lglib-2.0 -lcairo -lpng12 -ljpeg -lm" \ GDK_EXTRA_CFLAGS="-I$PREFIX/../include" \ GDK_EXTRA_LIBS="-L$PREFIX/../lib -ldirectfb -lz -lfusion -ldirect -lpthread -ldl" \ ./configure \ --host=$HOST \ --build=$BUILD \ --prefix=$PREFIX \ --with-gdktarget=directfb \ --without-libtiff \ --disable-glibtest \ --disable-largefile \ --disable-modules \ --with-included-loaders=jpeg,gif,png,xpm

Edit, if necessary, all Makefiles: Modify the following variables with the given values (they were supposed to be set during the configure, but for some reason they were set incorrectly): BASE_DEPENDENCIES_CFLAGS = -I/opt/gtkdfb/usr/local/include/glib-2.0 \ -I/opt/gtkdfb/usr/local/lib/glib-2.0/include \ -I/opt/gtkdfb/usr/local/include/pango-1.0 \ -I/opt/gtkdfb/usr/local/include/cairo \ -I/opt/gtkdfb/usr/local/include/atk-1.0 BASE_DEPENDENCIES_LIBS = -L/opt/gtkdfb/usr/local/lib \ -latk-1.0 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -lcairo GDK_DEP_CFLAGS = -pthread -I/opt/gtkdfb/usr/local/include/glib-2.0 \ -I/opt/gtkdfb/usr/local/lib/glib-2.0/include \ -I/opt/gtkdfb/usr/local/include/pango-1.0 \ -I/opt/gtkdfb/usr/local/include/cairo \ -I/opt/gtkdfb/usr/local/include \ -I/opt/gtkdfb/usr/local/freetype2 \ -I/opt/gtkdfb/usr/local/libpng12 -D_REENTRANT -D_GNU_SOURCE \ -I/opt/gtkdfb/usr/include/directfb GDK_DEP_LIBS = -L/opt/gtkdfb/usr/local/lib \ -L/opt/gtkdfb/usr/lib -ldirectfb -lfusion -ldirect -lpthread \ -ldl -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lpng12 -lm GDK_PIXBUF_DEP_CFLAGS = -pthread -I/opt/gtkdfb/usr/local/include/glib-2.0 \ -I/opt/gtkdfb/usr/local/lib/glib-2.0/include \ -I/opt/gtkdfb/usr/local/include GDK_PIXBUF_DEP_LIBS = -L/opt/gtkdfb/usr/local/lib \ -L/opt/gtkdfb/usr/local/lib -lgmodule-2.0 -ldl -lgobject-2.0 -lglib-2.0 -lpng12 -ljpeg -lm GLIB_CFLAGS = -pthread -I/opt/gtkdfb/usr/local/include/glib-2.0 \ -I/opt/gtkdfb/usr/local/lib/glib-2.0/include GLIB_LIBS = -pthread -L/opt/gtkdfb/usr/local/lib \ -lgobject-2.0 -lgmodule-2.0 -ldl -lgthread-2.0 -lglib-2.0 GTK_DEP_CFLAGS = -pthread -I/opt/gtkdfb/usr/local/include/glib-2.0 \ -I/opt/gtkdfb/usr/local/lib/glib-2.0/include \ -I/opt/gtkdfb/usr/local/include/pango-1.0 \ -I/opt/gtkdfb/usr/local/include/cairo \ -I/opt/gtkdfb/usr/local/include/atk-1.0 \ -I/opt/gtkdfb/usr/local/include -D_REENTRANT -D_GNU_SOURCE \ -I/opt/gtkdfb/usr/include/directfb GTK_DEP_LIBS = -L/opt/gtkdfb/usr/local/lib \ /opt/gtkdfb/usr/lib/libdirectfb.so -lpangocairo-1.0 -lpango-1.0 \ -latk-1.0 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -lcairo -lpng12 -lfontconfig -lxml2 -lm

Edit gdk/directfb/Makefile: Substitute the last line of the INCLUDE variable with the following variable: $(GDK_DEP_CFLAGS)

Edit gdk/Makefile: Set the variable GDK_DEP_LIBS to the following value: GDK_DEP_LIBS = -L/opt/gtkdfb/usr/local/lib \ -lpthread -ldl -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 \ -lgmodule-2.0 -lglib-2.0 -lpng12 -lm

Edit gtk/Makefile: Comment the following line:

Attention: This action will not generate the gtk-query-immodules-2.0-xx program that creates the modules configuration file. But since we configured it with the --disable-modules flag, it should not be a problem. $(gtk_query_immodules_2_0_LDADD) $(LIBS)
 * 1) $(LINK) $(gtk_query_immodules_2_0_LDFLAGS) $(gtk_query_immodules_2_0_OBJECTS) \

Edit demos/gtk-demo/Makefile: Set the variable GDK_DEP_LIBS to the following value: GDK_DEP_LIBS = -L/opt/gtkdfb/usr/local/lib -lpthread -ldl \ -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 \ -lpng12 -lm /opt/gtkdfb/usr/lib/libdirectfb.so \ /opt/gtkdfb/usr/lib/libdirect.so /opt/gtkdfb/usr/lib/libfusion.so

Edit demos/gtk-demo/Makefile, demos/Makefile, tests/Makefile and perf/Makefile: Set the variable LIBS to the following value: LIBS = /opt/gtkdfb/usr/lib/libdirectfb.so \ /opt/gtkdfb/usr/lib/libdirect.so /opt/gtkdfb/usr/lib/libfusion.so

Dangerous/ugly step:

GTK needs a cairo-pdf/ps printing support for compiling, but it’s unlikely that PDF/PS will be needed in an embedded system. There is no flag to compile it without this setting. There are some patches in development to solve this issue, meanwhile it was compiled without the cairo-pdf support by doing the following very ugly and dangerous step. If you want to add to add PDF/PS support you can try Poppler.

Edit the files:

gtk/gtkprintoperation.c

gtk/gtkprintoperation-unix.c

modules/printbackends/lpr/gtkprintbackendlpr.c

modules/printbackends/file/gtkprintbackendfile.c

Comment the lines in all these files that contains the following includes or function calls:
 * 1) include 
 * 2) include 

cairo_pdf_surface_set_size cairo_pdf_surface_create cairo_ps_surface_create_for_stream

This is dangerous because if for any reason your program wants to print a PDF/PS it will probably crash. Again, as soon as time permits, a patch will be sent to solve this issue.

Compile and install: $ gmake $ gmake install

That’s it. It’s not a short and clean procedure, but it works.

Note
There is a over-optimization at CFLAGS as '-O3' will be set in configure script. For other architectures (e.g. XScale), the option is not certified for gcc. You should make a patch for configure.in

--- configure.in.org	2006-05-03 16:22:38.000000000 +0900 +++ configure.in	2006-10-24 14:00:18.739632700 +0900 @@ -155,7 +155,7 @@  CFLAGS= fi -CFLAGS="-O3 -ffast-math -pipe $CFLAGS" +CFLAGS="-O2 -ffast-math -pipe $CFLAGS" DFB_INTERNAL_CFLAGS="-D_GNU_SOURCE $DFB_INTERNAL_CFLAGS"

= GTK on DirectFB for Embedded Systems - TinyGentoo / x86 =

Introduction
I succeed building GtkDfb inside gentoo development chroot, an uclibc based one. It quite simply way, hot to build root file system for your device. You can see the full TinyGentoo description here.

I'll try to make these steps more clear, because there is mess between versions and dependencies. Maybe I''ll make ebuilds, which would be the best imho.

Preparing the main development chroot
If you were following the TinyGentoo steps, you have the main development chroot and the final ramfs directory /tinygentoo. You have to emerge DirectFB (use flags: fbcon, ~x86 mask to get the newest version),  gettext, freetype,fontconfig; all of them into main chroot and also into /tinygentoo. Inside the ramfs directory, you should remove docs, includes, strip everything, just to make it as small as possible.

GTK parts
Make sure, you have emerged pkgconfig in the main chroot and configure $PKG_CONFIG_PATH export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/opt/gtkdfb/lib

glib-2.12.0
./configure --prefix=/opt/gtkdfb make, make install configure --with-libiconv=no -> not working for me, have to unmask dev-libs/libiconv in /etc/protage/package.unmask and emerge it

atk-1.12.1
./configure --prefix=/opt/gtkdfb make, make install

cairo-1.2.0
./configure --enable-static --enable-directfb=yes --disable-xlib --disable-win32 --prefix=/opt/gtkdfb make, make install

pango-1.13.3
./configure --enable-static --without-x  --prefix=/opt/gtkdfb make, make install

gtk+-2.10.0
Build gtk-doc, if there are problems: - Remove docbook related from configure script of gtk-doc - Make this small aclocal hack : ln -s /usr/local/share/aclocal/* ./

Get gtk from cvs recent version was not compilable for me, will test again soon; nor was head

let's get something older: cvs -d:pserver:anonymous@anoncvs.gnome.org:/cvs/gnome -z3 co -P -D "20060628" gtk+

sh autogen.sh --with-gdktarget=directfb --enable-static --with-gdktarget=directfb \ --without-libtiff --prefix=/opt/gtkdfb make && make install && make clean

Packing all together
Strip all libs ( --enable-debug=no  brings not any big size savements).

Remove all unnecessary from /tinygentoo (doc/man/include)

Copy some fonts, to the place, where fontconfig is configured to have them.

After this you should be able to run in your /tinygentoo environment.