Development Guides: Moblin Linux
Using GNU Autotools 
Sample Code

Introduction
If there is an application that needs to work on both mobile and non-mobile platforms, besides adding appropriate pre-processor symbols around platform-specific code, the compiling process should be different for different platforms. This document gives an overview of GNU Autotools and specifies the process of using GNU Autotools to enable the compiling switch among different platforms. The document also describes how to check the build architecture to automatically compile properly, when creating debian packages.

This document assumes that the reader is familiar with the following:

  • Basic Linux knowledge
  • Understanding of Mobile Internet Device (MID)
  • Basic knowledge of GNU make utility and Autotools

This document contains two main sections:

  • GNU Autotools Overview Describes GNU make utility and how to use GNU Autotools to do the configuration & compilation.
  • Compiling Switch among Platforms Describes the process on how to use GNU Autotools to enable the proper compilation of applications on different platforms.

GNU Autotools Overview

Introduction to Makefile
When a software project becomes larger and more complicated, it is almost impossible to compile source code and install binaries by manually inputing single commands, one-by-one. The GNU make utility is introduced to control the compilation of the project, automatically determine which pieces of a large program need to be recompiled, and issue the commands to recompile them[1].

To prepare to use make, you must write a file called the Makefile to tell make how to compile and link a program. It describes the relationships among files in your program and provides commands for updating each file[1].

The content of a Makefile can become very complex considering the complexity of the project. Detailed information on how to write a Makefile and run make can be found at http://www.gnu.org/software/make/manual/make.html.

Using GNU Autotools
Although Makefiles are very powerful (especially when using pkg-config), they run against limitations in the following situations

  • The source code distribution has several subdirectories, most requiring their own Makefiles.
  • Several Makefiles share common components.
  • The installation process copies files into several user-configured places on your system.
  • Target platforms have slight incompatibilities requiring pre-processor directives or other circumvention methods.

The GNU Autotools (Automake, Autoconf, etc.) provide a powerful configuration and compilation system to avoid the limitations brought by the above situations.

Two main tools of GNU Autotools are Autoconf and Automake.

  • Autoconf produces a configuration shell script, named 'configure', which probes the installer platform for portability-related information, which is required to customize Makefiles, configuration header files, and other application specific files. Then it proceeds to generate customized versions of these files from generic templates. This way, the user will not need to customize these files manually[2]. Details on how to use Autoconf can be found at http://www.gnu.org/software/autoconf/manual/index.html.
  • Automake produces Makefile templates, named 'Makefile.in' to be used by Autoconf, from a very high level specification stored in a file called 'Makefile.am'. Automake produces Makefiles that conform to the GNU Makefile standards, taking away the extraordinary effort required to produce them by hand[3]. Automake requires Autoconf to be used properly. Details on how to use Automake can be found at http://www.gnu.org/software/automake/manual/index.html.

The general procedure for outfitting your source code and generating Makefiles with the GNU Autotools is as follows.

  • Create a configure.ac (configure.in) file in your top-level source distribution directory. This file not only defines GNU Autotool behavior, but later, a macro expansion creates the configure script. Details on how to write a configure.ac can be found at http://www.gnu.org/software/autoconf/manual/index.html.
  • Create a Makefile.am file in each subdirectory where the compiler or installer runs. Details on how to write a Makefile.am can be found http://www.gnu.org/software/automake/manual/index.html.
  • Run gettexttize for localization, intltoolize for additional translation support, and/or libtoolize to build your own libraries, if necessary.
  • Run aclocal to gather all necessary macros from the macro library into the aclocal.m4 file.
  • Run autoheader to create a config.h.in file — a template for the preprocessor macros necessary for your package.
  • Run automake to build a Makefile.in template from each of your Makefile.am files.
  • Use autoconf to run the m4 macro processor on configure.ac with the macros in aclocal.m4 to create the configure script.
  • Finally, run the configure script to generate config.h from config.h.in, and Makefiles from each of your Makefile.in files.

Here is the flow diagram of the above procedure.


Figure 2-1: Flow chart illustrating the previous procedure.

Compiling Switch among Platforms

Modifying configure.ac and Makefile.am
To enable the application to work on both mobile and non-mobile platforms, the user needs to add the appropriate pre-processor symbols around platform specific code, besides, Makefile needs to be modified (such as compiling rules, installing rules, etc.) before building the application on the target platform. The changes to Makefile can be made automatically by modifying configure.ac & Makefile.am when using GNU Autotools to generate Makefile.

Before following this example, you need to configure the development environment. We recommend that you develop in the target device's build-environment, which can be created using Moblin Image Creator. This SDK includes guides on installing and using Moblin Image Creator.

You can download a our sample hello world application from here.  We will use this to describe the process.  By supporting Hildon for Moblin platform and GTK+ for desktop platform in the code, this application can run on both platforms.

  1. In the file src/hello-world.c, add the preprocessor symbol USE_HILDON around platform specific code to enable the code switch between Moblin and desktop platforms.
  2. In the file configure.ac,
    1. Enable one more argument --enable-hildon to the configure script. Thus, you can run the script configure to generate proper Makefiles for the target platform by using or not using this argument. The code added into configure.ac can be as follows:
    2. # Enables '--enable-hildon' argument.
      AC_ARG_ENABLE(hildon,
                   [AC_HELP_STRING([--enable-hildon],
                                   [compile with Hildon-based internet tablet user interface (default: enabled)])],
                    enable_hildon="$enableval",
                    enable_hildon="yes")


    3. Then, if the argument --enable-hildon is using, it is required to
      1. Check the existence and versions of Hildon libraries;
      2. Define the preprocessor symbol USE_HILDON;
      3. Add Hildon specific preprocessor, compile & link flags.
    4. Here is the related code in configure.ac,

      # Checks for hildon libraries.
      HILDON_REQUIRED=1.0.5
      if test "x$enable_hildon" = "xyes"; then
          # Check hildon libraries
          PKG_CHECK_MODULES(HILDON,
                           [
                            hildon-1 >= $HILDON_REQUIRED
                            libosso
                           ])

          # Define USE_HILDON
          AC_DEFINE(USE_HILDON, 1, [Define if we're using hildon])

          # Add hildon specific preprocessor, compile & link flags
          CFLAGS="$CFLAGS $HILDON_CFLAGS"
          LIBS="$LIBS $HILDON_LIBS"

      fi

    5. If you to add Moblin-specific code in the Makefile.am with conditional, you should first define a conditional in configure.ac like below:

    # Define a conditional USE_HILDON for the use in Makefile.am
    AM_CONDITIONAL(USE_HILDON, [test "x$enable_hildon" = "xyes"])

    Here, USE_HILDON is the conditonal name which will be used in Makefile.am.
  3. In the file Makefile.am, some Moblin-specific code is added to define the generating, installing & cleaning rules of Moblin-specific desktop, service and icon files. Such code should be written under the conditional USE_HILDON that is defined by AM_CONDITIONAL in configure.ac.
    1. In src/Makefile.am, it defines the rules to generate, install, and clean the service file specifically for Moblin platform. Here is the related code:
    2. if USE_HILDON
      # Generate the service file and set its install path
      servicedir = $(datadir)/dbus-1/services
      service_in_files = org.moblin.helloworld.service.in
      service_DATA = $(service_in_files:.service.in=.service)

      # Rules to generate the service file
      org.moblin.helloworld.service: org.moblin.helloworld.service.in Makefile
      @sed -e "s|\@bindir\@|$(bindir)|" $< > $@
      BUILT_SOURCES = org.moblin.helloworld.service
      endif
      ...
      if USE_HILDON
      # Add the additional clean rule of the generated service file
      CLEANFILES = $(BUILT_SOURCES)
      endif


    3. In data/Makefile.am, it defines the rules to install the desktop file specifically for Moblin platform. Here is the related code:

      if USE_HILDON
      # Set the desktop file install path
      desktopdir = $(datadir)/applications
      desktop_DATA = hello-world.desktop
      endif


    4. In data/16x16/Makefile.am, data/32x32/Makefile.am & data/64x64/Makefile.am, they define the rules to install the icon files specifically for Moblin platform. Here is the related code:

      if USE_HILDON
      # Set the icon file install path
      icondir = $(datadir)/icons/hicolor/16x16/apps
      icon_DATA = hello-world.png
      endif


  4. After the above three steps, run ./autogen.sh to regenerate configure script.
Thus, you can simply run configure script with/without the argument --enable-hildon to generate the correct Makefile and config.h and do the proper compilation for the target platform. For example, if running ./configure --prefix=/usr --disable-hildon & make, a GTK+ based application binary hello-world for desktop platform will be built; while running ./configure --prefix=/usr --enable-hildon (or ./configure --prefix=/usr) & make, a Hildon-based application binary hello-world for Moblin platform will be built.

Checking Build Architecture when Creating Debian Packages
When creating debian packages of applications, for example, hello-world, you can check the build architecture of the application first, so that you can automatically decide whether to use the argument --enable-hildon of the configure script or not. One way to check the build architecture is to add similar judgment, as follows, into the file debian/rules of hello-world:

# If compiling for lpia, enable Hildon interface
ifeq ($(DEB_BUILD_ARCH), lpia)
./configure --enable-hildon ....
else
./configure --disable-hildon ....
endif

Thus, if running dpkg-buildpackage to create the debian package of hello-world on Moblin platform, whose architecture is lpia (Low Power Intel Architecture), it will use the argument --enable-hildon when running the configure script, and finally generate a Hildon-based application binary hello-world. Else, the argument --disable-hildon will be used, and a GTK+-based hello-world will be built.

Reference Documents
The following documents are used as references in the writing of this document. Please refer to these documents for further details.

  1. The GNU make manual - http://www.gnu.org/software/make/manual/make.html
  2. The GNU Autoconf manual - http://www.gnu.org/software/autoconf/manual/index.html
  3. The GNU Automake manual - http://www.gnu.org/software/automake/manual/index.html