Autotools introduction
The goal of this topic is to know how to well works with the autotools in a cross-
compilation environement
The autotools process
 History :

     Historically, a shell configure script transformed a Makefile.in into a
     Makefile
     
     Autoconf 1 (1992): autoconf transformed a configure.in into a configure file
     
     Autoconf 2 (1994): added cross-compilation support, sub-directories, hidden
     results, more tests, …
     
     Automake (1994): automake transformed a Makefile.am into a Makefile
     
     Libtool (1996): changed the Automake behavior
Autotools introduction
 Here is the full power of the autotools in action that make build easier:
Autotools introduction
Autotools is a collection of OSS tools :

           GNU Automake is a tool for automatically generating `Makefile.in' files compliant
                with the GNU Coding Standards.
                http://www.gnu.org/software/automake/


           GNU Autoconf is an extensible package of M4 macros that produce shell scripts to automatically configure software source code packages. These scripts
           can adapt the packages to many kinds of UNIX-like systems without manual user intervention. Autoconf creates a configuration script for a package from a
           template file that lists the operating system features that the package can use, in the form of M4 macro calls.
           
                         Producing configuration scripts using Autoconf requires GNU M4. You should install GNU M4 (at least version 1.4.6, although 1.4.13 or
later is
                recommended) before configuring Autoconf, so that Autoconf's configure script can find it. The configuration scripts produced by Autoconf are self-
                contained, so their users do not need to have Autoconf (or GNU M4).
                         http://www.gnu.org/software/autoconf/


           GNU libtool is a generic library support script. Libtool hides the complexity of using shared libraries behind a consistent, portable interface.
            http://www.gnu.org/software/libtool/
           
           pkg-config is a helper tool used when compiling applications and libraries. It helps you insert the correct compiler options on the command line so an
           application can use gcc -o test test.c `pkg-config --libs --cflags glib-2.0` for instance, rather than hard-coding values on where to find glib (or other
           libraries). It is language-agnostic, so it can be used for defining the location of documentation tools, for instance.
            http://www.freedesktop.org/wiki/Software/pkg-config
           
         GNU M4 is an implementation of the traditional Unix macro processor. It is mostly SVR4 compatible although it has some extensions (for example,
        handling more than 9 positional parameters to macros). GNU M4 also has built-in functions for including files, running shell commands, doing arithmetic,
        etc.
                      GNU M4 is a macro processor in the sense that it copies its input to the output expanding macros as it goes. Macros are either builtin or user-
defined               and can take any number of arguments. Besides just doing macro expansion, m4 has builtin functions for including named files, running
UNIX                                    commands, doing integer arithmetic, manipulating text in various ways, recursion etc... m4 can be used either as a front-end
to a compiler or as a                                    macro processor in its own right.
                      http://www.gnu.org/software/m4/
        Autogen.sh (a.k.a. buildconf) provides automatic build system preparation and is generally very useful to projects that use the GNU build system (i.e. the
        GNU autotools: autoconf, automake, and libtool).
         http://buildconf.brlcad.org/


           A toolchain (GNU or other) that include binutils.
Autotools introduction
 Initial preparation :
./autogen.sh


 Configuration :
./configure --prefix=/usr

 Compiling :
make

 Installation :
make DESTDIR=«stagingdir» install
Mastering the build process



The goal of this topic is to know how the build process works.
Mastering the build process
The GNU Compiler Collection (GCC) :
   is a compiler system produced by the GNU Project
   is supporting various programming languages
   is a key component of the GNU toolchain
   has been adopted as the standard compiler by most other modern Unix-like computer operating
   systems, including Linux, the BSD family and Mac OS X
   has been ported to a wide variety of processor architectures
   is widely deployed as a tool in commercial, proprietary and closed source software
   development environments
   is also available for most embedded platforms, for example Symbian (called gcce), AMCC and
   Freescale Power Architecture-based chips
   can target a wide variety of platforms, including videogame consoles such as the PlayStation 2
   and Dreamcast. Several companies make a business out of supplying and supporting GCC ports
   to various platforms, and chip manufacturers today consider a GCC port almost essential to the
   success of an architecture.

 Originally named the GNU C Compiler, because it only handled the C programming language,
GCC 1.0 was released in 1987, and the compiler was extended to compile C++ in December of that
year. Front ends were later developed for Fortran, Pascal, Objective-C, Java, and Ada, among others.

 The Free Software Foundation (FSF) distributes GCC under the GNU General Public License
(GNU GPL). GCC has played an important role in the growth of free software, as both a tool and an
example.
                                         http://gcc.gnu.org
Mastering the build process
Linking : the compiler’s backend

    •Generates assembly code for the final output.
    •Generates ELF object (replace the old a.out one).
    •Uses ld through the gcc.
    •Can make:
         Binary: adds a main entry to the intermediate code.
         Dynamic library: if the -shared parameter has been given (cannot be
         runable except for the libc).
         
Direct usage with the ld linker : $ ld -o mybinary /lib/crt0.o file.o –lc

crt0 (or crt0.o, gcrt0.o, mcrt0.o) is a set of execution start-up routines (usually part of
the C standard library) that are platform dependent, and is required in order to compile
using GCC and other GNU tools. crt stands for "C runtime".

-e entry
Use entry as the explicit symbol for beginning execution of the program, rather than the
default entry point (main). If there is no symbol named entry, the linker will try to parse
entry as a number, and use that as the entry address (the number will be interpreted in base
10; you may use a leading 0x for base 16, or a leading 0 for base 8).
Mastering the build process
 GNU tools from the toolchain are set for an embedded usage :

--sysroot=staging directory
Use dir as the logical root directory for headers and libraries. For example, if the compiler would normally search for headers in
/usr/include and libraries in /usr/lib, it will instead search dir/usr/include and dir/usr/lib.


If you use both this option and the -isysroot option, then the --sysroot option will apply to libraries, but the -isysroot option will apply to
header files.


The GNU linker (beginning with version 2.16) has the necessary support for this option. If your linker does not support this option, the
header file aspect of --sysroot will still work, but the library aspect will not.


 Usually te environment is defined like this :

               export STAGING_DIR=<PATH TO THE STAGING DIRECTORY>
               export PREFIX=«i686-cm-linux-»
               export TOOLCHAIN_DIR=<PATH TO THE TOOLCHAIN>


               export CC=$(PREFIX)gcc --sysroot=$(STAGING_DIR)
               export LD=$(PREFIX)ls --sysroot=$(STAGING_DIR)
               export GCC=$(PREFIX)gcc --sysroot=$(STAGING_DIR)
               export CXX=$(PREFIX)gcc --sysroot=$(STAGING_DIR)


               export GDB="$(STAGING_DIR)/bin/$(PREFIX)gdb"
               export RANLIB="$(TOOLCHAIN_DIR)/bin/$(PREFIX)ranlib"
               export STRIP="$(TOOLCHAIN_DIR)/bin/$(PREFIX)strip"
               export OBJCOPY="$(TOOLCHAIN_DIR)/bin/$(PREFIX)objcopy"
               export AR="$(TOOLCHAIN_DIR)/bin/$(PREFIX)ar"
               export AS="$(TOOLCHAIN_DIR)/bin/$(PREFIX)as"
               export LD="$(TOOLCHAIN_DIR)/bin/$(PREFIX)ld"
Mastering the build process




                       BUILD PORCESS LAB
Mastering the build process

The main goal of this lab is to know how is working the
GNU/

Using the helloworld.c source code try several parameters
{--verbose/-E/-S}:

   gcc --verbose
   gcc -c helloworld.c
   gcc -c helloworld.c -o helloworld.o
   gcc -E helloworld.c
   gcc -S helloworld.c
   …
Quick GNU/make reminder
The goal of this topic is to know how works common GNU/make
Quick GNU/make reminder
 The final files generated are gnu/make based.

 Most Makefile.am can be extend with gnu/make features that‘s why this is
important to know how makefiles are made.

 We will remain some basic makefile usage.
Quick GNU/make reminder
With GNU/Makefiles :

     No target is buildin ; everything should be written from scratch
each time ;
     Doesn‘t use generic templates for binaries, libraries, … ;
     Cross-compilation support should be manualy specified ;
     Pkg-config can be used (not by M4 macros) ;
     Can make ugly Makefile ;
     Makefile are often more static than dynamic



            Everything done by gnu Makefile is automatically
                natively supported by the Autotools  !
Quick GNU/make reminder

 Other make engine exists:

   ocmake (http://www.cmake.org/)
   oqmake (http://doc.qt.nokia.com/4.4/qmake-manual.html)
   oand so on…

 For more information about the GNU/make:
 http://oreilly.com/catalog/make3/book/index.csp
 http://www.wanderinghorse.net/computing/make/book/ManagingProjectsWithG
 NUMake-3.1.3.pdf
 http://notendur.hi.is/~jonasson/software/make-book/
 http://www.gnu.org/software/make/manual/make.pdf
 http://en.wikipedia.org/wiki/Make_(software)#Modern_versions
 http://ecee.colorado.edu/~mcclurel/gnu_make_overview.pdf
 http://static.maemo.org/static/d/dcacc028fda611dd9062b3dd54505f765f76_gnu_
 make_and_makefiles.pdf
Quick GNU/make reminder




                    GNU/MAKE LAB
Quick GNU/make reminder
The main goal of the lab is to write a makefile with several targets:

 The project have three source code: data.c, main.c and io.c




The make file should support the following targets:
   Compilation:                        make (aka make all)
   Cleaning old objects:make clean
   Create tarball:                     make dist
   Create an installer:         make DESTDIR=«PATH» install
   Create an uninstaller:make DESTDIR=«PATH» uninstall
Quick GNU/make reminder



      So, if we check the several Makefiles written,
                 no one will be identical,
   that’s mean there is no uniformisation/no standard.
             That what the autotools provide.
The autotools process
The goal of this topic is to know how works the templates are written.
The autotools process
 working with the autotools means for a developer to manage templates and
potfiles :

    Makefile.am                              : used to define what should be build
    and how
                                                        using generic templates.

    configure.ac                             : used to define an autotools project.
    It can include


    <component>.*.in                : used to associate some metadata
     (this is used by *.pc.in used for managing
      dependencies or config files).

 Only those files have to be managed by the developers.

 No more files need to be stored in repository except if there are filled
(README, LICENCE, … ).
The autotools process
STEP #1 : autogen.sh

    The autogen.sh is a generic script used to prepare an autotool project for end users.

    Its goal is to check the environment need for the autotools scripts and binaries.

    This script need to be launched each time a template have been modified.

    It will generate several files:
          oa configure script from the configure.ac
          oa Makefile.in form the Makefile.am
          oa config.h.in if expected
                    configure.ac ---
    Roadmap :                          |
                                                 |   ------> autoconf* -----> configure
                    [aclocal.m4] --+--- |
                                                 |    -----> autoheader* --> [config.h.in]
                                                 |
                    [acsite.m4] -----

                     Makefile.am -------------------------------> Makefile.in
The autotools process
STEP #2 : configuration, compilation and installation

     This is the end user view.

     This step must start by the launch of the configure script in order to generate a final
     Makefile:

                    ./configure --prefix=/usr …


     Then, this is possible to use the several target from the Makefile:




 and so on…
The autotools process
Debugging via autom4te:

At times, it is desirable to see what was happening inside m4, to see why output was not matching expectations. However, post-
processing done by autom4te means that directly using the m4 builtin m4_traceon is likely to interfere with operation. Also, frequent
diversion changes and the concept of forbidden tokens make it difficult to use m4_defn to generate inline comments in the final output.
There are a couple of tools to help with this. One is the use of the --trace option provided by autom4te (as well as each of the programs
that wrap autom4te, such as autoconf), in order to inspect when a macro is called and with which arguments. For example, when this
paragraph was written, the autoconf version could be found by:


              $ autoconf --trace=AC_INIT
              configure.ac:23:AC_INIT:GNU Autoconf:2.63b.95-3963:bug-autoconf@gnu.org
              $ autoconf --trace='AC_INIT:version is $2‗
              version is 2.63b.95-3963


Another trick is to print out the expansion of various m4 expressions to standard error or to an independent file, with no further m4
expansion, and without interfering with diversion changes or the post-processing done to standard output. m4_errprintn shows a given
expression on standard error. For example, if you want to see the expansion of an autoconf primitive or of one of your autoconf macros,
you can do it like this:


$ cat <<EOF > configure.ac
AC_INIT
m4_errprintn([The definition of AC_DEFINE_UNQUOTED:])
m4_errprintn(m4_defn([AC_DEFINE_UNQUOTED]))
AC_OUTPUT
EOF


$ autoconf
error-->The definition of AC_DEFINE_UNQUOTED:
error-->_AC_DEFINE_Q([], $@)
The autotools process
• The essential files:

The smallest project requires you provide only two files:

              CONFIGURE.AC : an input file to autoconf that provides the macro invocations and shell code fragments
                                    autoconf uses to build a configure script.



MAKEFILE.AM: an input file to automake that specifies a projects build requirements: what needs to be built,
          and where it goes when installed.

The GNU Autotools will generate the rest of the files needed to build the project.

• The Directory Structure:

       Before writing any code for a new project you need to decide on the directory structure the project will use ;
       The top-level directory is used for configuration files, such as configure.in, and other sundry files like ChangeLog,
       COPY (a copy of the project license) and README ;
       Any unique library should have its own subdirectory containing all headers and sources, a Makefile.am, and any other
       library specific files ;
       The headers and sources for the main application should be in another subdirectory, typically called src ;
       Other directories can include: config for intermediate files, doc for the project documentation and test for the project
       self-test suite ;
       The following steps will take you through creating and building the HelloWorld project. The top-level directory for
       HelloWorld is <tests/project>. You will find the project's headers and sources in the src subdirectory. There are three
       files: helloworld.cc, helloworld.h and main.cc ;
The autotools process




                        AUTOTOOLS LAB
The autotools process
The goal of this lab if to use an hello world autotools project.

Experiment the several steps :

    Preparation:                             ./autogen.sh
    See the files before and after.

    Configuration:                 ./configure –prefix=/usr
 Read the config.log that detail the configuration step ; this is a good way to
debug a configure script.

    Compilation:                   make
    
    Installation:                            make DESTDIR=pwd install
    
    Delivery:                                make dist
Using the autoscan tool
The goal of this topic is to know how to use the autoscan tool
Using the autoscan tool
STEP #0 : autoscan

    The easiest way to create a (mostly) complete configure.ac file is to run the
    autoscan utility, which is part of the autoconf package.

    This utility examines the contents of a project directory and generates the basis for a
    configure.ac file (which autoscan names configure.scan) using existing makefiles and
    source files.

    The autoscan utility examines the project directory hierarchy and creates two files
    called configure.scan and autoscan.log.

    The project may or may not already be instrumented for Autotools ; it doesn’t really
    matter, because autoscan is decidedly non-destructive. It will never alter any existing
    files in a project.


                     your source files  autoscan*  configure.scan  configure.ac
Using the autoscan tool
First exampleof the autoscan tool, two files should appear in the current directory:
 After the launch with an empty directory:
         autoscan.log
         configure.scan                        should be renamed into a configure.ac file afterward

 As we see, the contents of the generated configure.scan is similar to our hand-crafted
 template:

 # -*- Autoconf -*-
 # Process this file with autoconf to produce a configure script.


 AC_PREREQ(2.56)
 AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)


 # Checks for programs.


 # Checks for libraries.


 # Checks for header files.


 # Checks for typedefs, structures, and compiler characteristics.


 # Checks for library functions.


 AC_OUTPUT


  As the name autoscan implies, you can guess that it can do other things as well, not only
Using the autoscan tool
Second example with two existing files in the project:
A header sleep.h :


#include <stdio.h>
#include <unistd.h>        /* Needed for sleep() */


A source code sleep.c :

              #include "sleep.h"


#define SECONDS_TO_SLEEP 3


int
main()
{
              unsigned int sleep_left = 0;


              /* sleep() for SECONDS_TO_SLEEP seconds, then print a message. */
              sleep(SECONDS_TO_SLEEP);


              printf("I woke up after %d seconds.n", SECONDS_TO_SLEEP);

              return 0;
}
Using the autoscan tool
That will automaticaly generate the following configure.scan script:
     #                              -*- Autoconf -*-
     # Process this file with autoconf to produce a configure script.

     AC_PREREQ(2.56)
     AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
     AC_CONFIG_SRCDIR([sleep.c])                  some file that is in the package's source directory.
     AC_CONFIG_HEADER([config.h])                 containing C preprocessor #define statements.


     # Checks for programs.
     AC_PROG_CC                                                                    determine the C compiler to use.


     # Checks for libraries.


     # Checks for header files.
     AC_CHECK_HEADERS([unistd.h])                                  check for existing header file(s) (in our case only one, unistd.h).


     # Checks for typedefs, structures, and compiler characteristics.


     # Checks for library functions.
 To get a very basic, but working input file to autoconf, rename configure.scan to
     AC_OUTPUT
configure.ac: mv configure.scan configure.ac

 Then update the AC_INIT macro, and add the AC_COPYRIGHT macro.
Using the autoscan tool




                          AUTOSCAN LAB
Using the autoscan tool


The main goal for this lab is to go into a directory where is
existing source code ;

Launch the autoscan command: ./autoscan

View the configure.scan generated.
The autogen.sh script
The goal of this topic is to know how works the autogen.sh script
The autogen.sh script
 The autogen.sh script is used for converting all the templates (configure.ac, Makefile.am, …) in
final files (Makefile, configure, …) needed for a common Autotools usage.

Thus, The autogen.sh script (a.k.a. buildconf) provides automatic build system preparation and is
generally very useful to projects that use the GNU build system (i.e. the GNU Autotools: autoconf,
automake, and libtool). It is a POSIX shell script that is used for preparing a build system for
compilation, verifying versions, ensuring necessary functionality, and overcoming many common
build preparation issues.

Official web site     : http://buildconf.brlcad.org/
Licence               : BSD
Latest stable release : 23.12.2009
http://downloads.sourceforge.net/project/buildconf/autogen/2009.12.23/buildconf.2009.12.23.tar.gz?u
se_mirror=freefr&ts=1278845776

This script is standalone, its usage is mainly limited to a call in the autotools directory :

           $ ./autogen.sh

Another way is to use the following command:                         autoreconf -i –force
 (This is what the script do in background)
The autogen.sh script
   Before the autoconf script some bootstrap command was used:
 first, we need to generate the required output files from the two input files configure.in and Makefile.am. First we need to
collect all the macro invocations in configure.in that Autoconf will need to build the configure script. This is done with the
following command:

$ aclocal

This generates the file aclocal.m4 and adds it to the current directory. Next, run autoconf:

$ autoconf

 After running autoconf you will find the configure script in the current directory. It's important to run aclocal first because
automake relies on the contents on configure.in and aclocal.m4.
There are a few files that the GNU standard says must be present in the top-level directory, and if not found Automake will
report an error. Enter the following command to create these files:

$ touch AUTHORS NEWS README ChangeLog

 Now we can run automake to create Makefile.in. The –add-missing argument copies some boilerplate files from your
Automake installation into the current directory.

$ automake --add-missing

By now, the contents of the directory should be looking a lot like the top-level directory of a GNU package you may have
installed before:
The autogen.sh script
What the autogen.sh really do :

    It tranforms the template into intermediate files:




Those files will complete the other files (component.pc.in), in order to be
ready for the configure script.

Note : configure.ac is by far the preferred naming for autoconf >= 2.50 while
configure.in is what was used by autoconf ⇐ 2.13 and was kept for *cough*
backward compatibility *cough*…
The autogen.sh script
     Parameters used to control the autogen.sh script :




   There is two controversal parameters with the --quiet and --verbose that can be set in the same
  time!! Indeed, the autogen.sh script will follow the last one provided at the launch.


     Check of the autotools components version:
$ ./autogen.sh –version
                                                                        Identical as :
Preparing the toe build system...please wait                            ./autoconf --version
Found GNU Autoconf version 2.67
Found GNU Automake version 1.11.1                                       ./automake –version
Found GNU Libtool version 2.2.6b                                        ./libtool --version
autogen.sh build preparation script by Christopher Sean Morrison
  + config.guess download patch by Sebastian Pipping (2008-12-03)
revised 3-clause BSD-style license, copyright (c) 2005-2009
script version 20090301, ISO/IEC 9945 POSIX shell script
---
Version requested. No preparation or configuration will be performed.
The autogen.sh script
  Autogen.sh usage can be obtain with the command line:

$ ./autogen.sh –help

Usage: ./autogen.sh [-h|--help] [-v|--verbose] [-q|--quiet] [-d|--download] [--version]
   --help Help on autogen.sh usage
   --verbose Verbose progress output
   --quiet Quiet suppressed progress output
   --download Download the latest config.guess from gnulib
   --version Only perform GNU Build System version checks
Description: This script will validate that minimum versions of the
GNU Build System tools are installed and then run autoreconf for you.
Should autoreconf fail, manual preparation steps will be run
potentially accounting for several common preparation issues. The
AUTORECONF, AUTOCONF, AUTOMAKE, LIBTOOLIZE, ACLOCAL, AUTOHEADER,
PROJECT, & CONFIGURE environment variables and corresponding _OPTIONS
variables (e.g. AUTORECONF_OPTIONS) may be used to override the
default automatic detection behavior.
autogen.sh build preparation script by Christopher Sean Morrison
 + config.guess download patch by Sebastian Pipping (2008-12-03)
revised 3-clause BSD-style license, copyright (c) 2005-2009
script version 20090301, ISO/IEC 9945 POSIX shell script
---
Help was requested. No preparation or configuration will be performed.
The autogen.sh script                          $ ./autogen.sh –verbose




 Silent launch (default):                                  Verbose output enabled
                                                            Found a configure template: ./configure.ac
                                                            Preparing the toe build system...please wait
                                                            Checking autoreconf version: autoreconf --version
$ ./autogen.sh                                              Checking autoconf version: autoconf --version


Preparing the toe build system...please wait
                                                            Found GNU Autoconf version 2.67
                                                            Checking if 2.67.0 is greater than 2.52.0
                                                            Checking automake version: automake --version
                                                                                                                                   Verbose launch
                                                            Found GNU Automake version 1.11.1
                                                            Checking if 1.11.1 is greater than 1.6.0
Found GNU Autoconf version 2.67                             Checking libtoolize version: libtoolize --version
                                                            Found GNU Libtool version 2.2.6b
Found GNU Automake version 1.11.1                           Checking if 2.2.6 is greater than 1.4.2
Found GNU Libtool version 2.2.6b                            Checking aclocal version: aclocal --version
                                                            Checking autoheader version: autoheader --version
                                                            Checking whether to only output version information
Automatically preparing build ... done                      Backing up COPYING in /home/gayetth/workspace/TOE
                                                            cp -p COPYING COPYING.25605.protect_from_automake.backup
                                                            Backing up INSTALL in /home/gayetth/workspace/TOE
                                                            cp -p INSTALL INSTALL.25605.protect_from_automake.backup
The toe build system is now prepared. To build here, run:   Found an autom4te.cache directory, deleting it
 ./configure                                                rm -rf autom4te.cache
 make                                                       mv -f "./config.guess" "./config.guess.backup"
                                                            mv -f "./config.sub" "./config.sub.backup"
                                                            mv -f "./ltmain.sh" "./ltmain.sh.backup"
                                                            Automatically preparing build ... autoreconf -i -f
                                                            libtoolize: putting auxiliary files in `.'.
                                                            libtoolize: copying file `./config.guess'
                                                            libtoolize: copying file `./config.sub'
                                                            libtoolize: copying file `./install-sh'
                                                            libtoolize: copying file `./ltmain.sh'
                                                            libtoolize: Consider adding `AC_CONFIG_MACRO_DIR([m4])' to configure.ac and
                                                            libtoolize: rerunning libtoolize, to keep the correct libtool macros in-tree.
                                                            libtoolize: Consider adding `-I m4' to ACLOCAL_AMFLAGS in Makefile.am.
                                                            rm -f COPYING.25605.protect_from_automake.backup
                                                            Restoring INSTALL from backup (automake -f likely clobbered it)
                                                            rm -f INSTALL
                                                            mv INSTALL.25605.protect_from_automake.backup INSTALL
                                                            rm -f INSTALL.25605.protect_from_automake.backup
                                                            rm -f "./config.guess.backup"
                                                            rm -f "./config.sub.backup"
                                                            rm -f "./ltmain.sh.backup"
                                                            done
                                                            The toe build system is now prepared. To build here, run:
                                                              ./configure
                                                              make
                                                            rm -f "./config.guess.backup"
                                                            rm -f "./config.sub.backup"
                                                            rm -f "./ltmain.sh.backup"
The autogen.sh script
 Useful variables used to control the autogen.sh script :




To skip autoreconf and prepare manually:                                    AUTORECONF=false
./autogen.sh


To verbosely try running with an older (unsupported) autoconf:   AUTOCONF_VERSION=2.50 ./autogen.sh
--verbose
The autogen.sh script
Impact on the autotools templates:

If we take the decision to use the autogen.sh script instead of the single autoreconf
command, this file is mandatorary to include in the tarball generated by the « make
dist » command.

          EXTRA_DIST                  = $(top_builddir)/autogen.sh

The autogen.sh script should be within the files of the project.

If this file is not added the tarball will miss this file and won‘t be standalone!
The environment




                  AUTOGEN.SH LAB
The autogen.sh script


Take an autotools project and check the differential before
and after the launch of the autogen.sh script.

 Check with: autoreconf –i –force

 Check with the autotools hierarchy poster provided.
Using libtool


The goal of this topic is to know how to uses libtool
Using libtool

   What libtool can do :
GNU Libtool simplifies your job by encapsulating both the platform-specific dependencies, and the user interface, in
a single script. GNU Libtool is designed so that the complete functionality of each host type is available via a generic
interface, but nasty quirks are hidden from the programmer.

GNU Libtool's consistent interface is reassuring... users don't need to read obscure documentation in order to have
their favorite source package build shared libraries. They just run your package configure script (or equivalent), and
libtool does all the dirty work.
Using libtool
 Libtool is a tool used:
The following issues need to be addressed in any reusable shared library system, specifically libtool:


The package installer should be able to control what sort of libraries are built.


It can be tricky to run dynamically linked programs whose libraries have not yet been installed. LD_LIBRARY_PATH must be set properly (if it is supported), or
programs fail to run.


The system must operate consistently even on hosts that don't support shared libraries.


The commands required to build shared libraries may differ wildly from host to host. These need to be determined at configure time in a consistent way. It is not
always obvious with what prefix or suffix a shared library should be installed. This makes it difficult for Makefile rules, since they generally assume that file names
are the same from host to host.



 Motivation for writing libtool :
The system needs a simple library version number abstraction, so that shared libraries can be upgraded in place. The programmer should be informed how to design
the interfaces to the library to maximize binary compatibility. The install Makefile target should warn the package installer to set the proper environment variables
(LD_LIBRARY_PATH or equivalent), or run ldconfig.
Since early 1995, several different GNU developers have recognized the importance of having shared library support for their packages. The primary motivation for
such a change is to encourage modularity and reuse of code (both conceptually and physically) in GNU programs.


Such a demand means that the way libraries are built in GNU packages needs to be general, to allow for any library type the package installer might want. The
problem is compounded by the absence of a standard procedure for creating shared libraries on different platforms.


The following sections outline the major issues facing shared library support in GNU, and how shared library support could be standardized with libtool.


The following specifications were used in developing and evaluating this system:


The system must be as elegant as possible.


The system must be fully integrated with the GNU Autoconf and Automake utilities, so that it will be easy for GNU maintainers to use. However, the system must not
require these tools, so that it can be used by non-GNU packages.
Using libtool
 Libtool is a tool used:   libtool [OPTION]... [MODE-ARG]...




 Listing of the several modes available:
Using libtool
 TAGs available :




The same tags can be overwritten in the autotool context (this often do in a
cross-compilation mode):

        CC=sh4-linux-gcc CXX=sh4-linux-g++ ./configure --prefix=/usr …
Using libtool
 Compilation mode :   $ libtool --mode=compile gcc -g -O -c foo.c
                       gcc -g -O -c foo.c -o foo.o
Using libtool
 Link mode :
Link mode links together object files (including library objects) to form another library or to create an executable program.


mode-args consist of a command using the C compiler to create an output file (with the -o flag) from several object files. The following
components of mode-args are treated specially:
Using libtool
                Link mode (cont)
Using libtool
                Link mode (cont)
Using libtool
                                                                                  Link mode (cont)
If the output-file ends in .la, then a libtool library is created, which must be built only from library
objects (.lo files). The -rpath option is required. In the current implementation, libtool libraries may
not depend on other uninstalled libtool libraries.

If the output-file ends in .a, then a standard library is created using ar and possibly ranlib.

If output-file ends in .o or .lo, then a reloadable object file is created from the input files (generally
using ‗ld -r‘). This method is often called partial linking.

Otherwise, an executable program is created.
Using libtool
 Execution mode :

For execute mode, the library path is automatically set, then a program is executed.

The first of the mode-args is treated as a program name, with the rest as arguments to that
program.

The following components of mode-args are treated specially:




If any of the args are libtool executable wrappers, then they are translated into the name of their
corresponding uninstalled binary, and any of their required library directories are added to the
library path.
Using libtool
 Installation mode :
In install mode, libtool interprets most of the elements of mode-args as an installation command beginning with cp, or a BSD-compatible install
program.


The following components of mode-args are treated specially:


-inst-prefix-dir inst-prefix-dir
                 When installing into a temporary staging area, rather than the final prefix, this argument is used to reflect the temporary path, in
                 much the          same way automake uses DESTDIR. For instance, if prefix is /usr/local, but inst-prefix-dir is /tmp, then the object will
                 be installed under              /tmp/usr/local/. If the installed object is a libtool library, then the internal fields of that library will
reflect only     prefix, not inst-prefix-dir:

                                 # Directory that this library needs to be installed in:
                                 libdir='/usr/local/lib'
                                 not
                         # Directory that this library needs to be installed in:
                                 libdir='/tmp/usr/local/lib‗

inst-prefix is also used to insure that if the installed object must be relinked upon installation, that it is relinked against the libraries in inst-prefix-
dir/prefix, not prefix.


In truth, this option is not really intended for use when calling libtool directly; it is automatically used when libtool --mode=install calls libtool --
mode=relink. Libtool does this by analyzing the destination path given in the original libtool --mode=install command and comparing it to the
expected installation path established during libtool --mode=link.


Thus, end-users need change nothing, and automake-style make install DESTDIR=/tmp will Just Work(tm) most of the time. For systems where fast
installation can not be turned on, relinking may be needed. In this case, a ‗DESTDIR‘ install will fail.


Currently it is not generally possible to install into a temporary staging area that contains needed third-party libraries which are not yet visible at their
final location.


The rest of the mode-args are interpreted as arguments to the cp or install command.
Using libtool
 Finish mode :
Finish mode has two functions. One is to help system administrators install libtool libraries so that
they can be located and linked into user programs.

To invoke this functionality, pass the name of a library directory as mode-arg:




The second is to facilitate transferring libtool libraries to a native compilation environment after
they were built in a cross-compilation environment. Cross-compilation environments may rely on
recent libtool features, and running libtool in finish mode will make it easier to work with older
versions of libtool. This task is performed whenever the mode-arg is a .la file.
Using libtool
 Uninstall mode :
Uninstall mode deletes installed libraries, executables and objects.

The first mode-arg is the name of the program to use to delete files (typically /bin/rm).

The remaining mode-args are either flags for the deletion program (beginning with a ‗-‘), or the
names of files to delete.
Using libtool
 Clean mode :
Clean mode deletes uninstalled libraries, executables, objects and libtool's temporary files associated
with them.

The first mode-arg is the name of the program to use to delete files (typically /bin/rm).

The remaining mode-args are either flags for the deletion program (beginning with a ‗-‘), or the
names of files to delete.
Using libtool




                LIBTOOL LAB
Using libtool

The goal of this lab is to understand what libtool is really working.

Try to compile a helloworld.c source code by the two way:

   gcc –c helloworld.c –o helloworld.o
   Libtool --mode=compile gcc -c helloworld.c


Same for the link step (should create a helloworld binary):

   gcc helloworld.o –o helloworld
   libtool --mode=link gcc –o helloworld helloworld.o
The configure.{ac/in} template
The goal of this topic is to know how to write a configure.ac template.
The configure.{in/ac} template

 A configure.ac is the template of the configure script that will be used by
the end user.

 A configure.ac is written using M4 macros while a configure script is a
shell script.

 The main goal of a configure script is to lead the configuration of a
component. The several flags provided to the configure script is like the ID
card of the build.

The configure.ac teamplate is equal to the configure.in that is the old
notation.

Those script are executed like shell script at the runtime (no compiled).

Can build libraries, binaries, … in the same files, by managing
dependencies.
The configure.{in/ac} template
 Preset Output Variables :




 Beware about all directories, because they can be override by configure options: ./configure –
prefix=/usr –srcdir=/tmp_srcdir …
If so, top_builddir can be different to top_srcdir and bring link problems, so be carefull !!
The configure.{in/ac} template
  Flags overriding :




http://www.gnu.org/software/hello/manual/autoconf/Preset-Output-Variables.html
The configure.{in/ac} template
  Tools overriding :




Examples:
            ./configure –prefix=/usrCC=gcc CFLAGS=-O3 LIBS=―-lposix‖ …
            or
            CC=sh4-linux-gcc AR=sha-linux-g++ ./configure –prefix=/usr …
The configure.{in/ac} template

 Special Characters in Output Variables :

Many output variables are intended to be evaluated both by make and by the shell. Some
characters are expanded differently in these two contexts, so to avoid confusion these
variables' values should not contain any of the following characters: " # $ & ' ( ) * ; < > ? [
^`|

Also, these variables' values should neither contain newlines, nor start with ‗~‘, nor contain
white space or ‗:‘ immediately followed by ‗~‘. The values can contain nonempty
sequences of white space characters like tabs and spaces, but each such sequence might
arbitrarily be replaced by a single space during substitution.

These restrictions apply both to the values that configure computes, and to the values set
directly by the user. For example, the following invocations of configure are problematic,
since they attempt to use special characters within CPPFLAGS and white space
within $(srcdir):

   CPPFLAGS='-DOUCH="&"#$*?"' '../My Source/ouch-1.0/configure'

   '../My Source/ouch-1.0/configure' CPPFLAGS='-DOUCH="&"#$*?"'
The configure.{in/ac} template
 Some of the useful built-in M4 macros:




  There are many others ; check the gnu/autoconf manual for more
  Information (http://www.gnu.org/software/autoconf/manual/autoconf.pdf).
The configure.{in/ac} template
 Printing messages :
Configure scripts need to give users running them several kinds of information. The following macros print messages
in ways appropriate for each kind. The arguments to all of them get enclosed in shell double quotes, so the shell
performs variable and back-quote substitution on them. These macros are all wrappers around the echo shell command.
They direct output to the appropriate file descriptor:

 Macro: AC_MSG_CHECKING (feature-description)
Notify the user that configure is checking for a particular feature. This macro prints a message that starts with
‗checking ‘ and ends with ‗...‘ and no newline. It must be followed by a call to AC_MSG_RESULT to print the result of
the check and the newline. The feature-descriptionshould be something like „whether the Fortran compiler accepts
C++ comments‟ or „for c89‟. This macro prints nothing if configure is run with the --quiet or --silent option. This is
quite similar to a echo -n.

 Macro: AC_MSG_RESULT (result-description)
Notify the user of the results of a check. result-description is almost always the value of the cache variable for the
check, typically „yes‟, „no‟, or a file name. This macro should follow a call to AC_MSG_CHECKING, and the result-
description should be the completion of the message printed by the call to AC_MSG_CHECKING. This macro prints
nothing if configure is run with the --quiet or --silent option. This is quite similar to an echo after an echo -n, so it will
be in the same line.

Example:
             AC_MSG_CHECKING(“Checking something”)
             (…)
             Something tested here…The result is a boolean variable such as « bchkSomething »
             (…)
              AC_MSG_RESULT(bchkSomething)
The configure.{in/ac} template

 Macros used for traces :

 Macro: AC_MSG_NOTICE (message)
Deliver the message to the user. It is useful mainly to print a general description of the overall purpose of a group
of feature checks, e.g., AC_MSG_NOTICE([checking if stack overflow is detectable]). This macro prints nothing
if configure is run with the --quiet or --silent option.



 Macro: AC_MSG_ERROR (error-description, [exit-status = „$?/1‟])
Notify the user of an error that prevents configure from completing. This macro prints an error message to the
standard error output and exits configure with exit-status („$?‟ by default, except that „0‟ is converted to „1‟). error-
description should be something like „invalid value $HOME for $HOME‟. The error-description should start with
a lower-case letter, and “cannot” is preferred to “can't”.

 Macro: AC_MSG_FAILURE (error-description, [exit-status])
This AC_MSG_ERROR wrapper notifies the user of an error that prevents configure from completing and that
additional details are provided in config.log. This is typically used when abnormal results are found during a
compilation.



Examples:
             AC_MSG_NOTICE(“this is just a message”)
The configure.{in/ac} template
 Initialisation of the configure script (including the requirements) :

The Autoconf language differs from many other computer languages because it treats actual code the same as plain text. Whereas in C,
for instance, data and instructions have different syntactic status, in Autoconf their status is rigorously the same. Therefore, we need a
means to distinguish literal strings from text to be expanded: quotation.


When calling macros that take arguments, there must not be any white space between the macro name and the open parenthesis.

               AC_INIT([hello], [1.0])       # good


Arguments should be enclosed within the quote characters ‗[‘ and ‗]‘, and be separated by commas. Any leading blanks or newlines in
arguments are ignored, unless they are quoted. You should always quote an argument that might contain a macro name, comma,
parenthesis, or a leading blank or newline. This rule applies recursively for every macro call, including macros called from other
macros.


 AC_COPYRIGHT (copyright-notice)
State that, in addition to the Free Software Foundation's copyright on the Autoconf macros, parts of your configure are covered by the
copyright-notice. The copyright-notice shows up in both the head of configure and in ‗configure --version‘.


 Some are mandatory :
      o AC_INIT([pyPackage], [myPackageVersion], [thierry.gayet2@technicolor.com])  initializes autoconf with information
      about your project, including the project name, version number, bug-reporting address, tarball name and the project homepage.
      o AC_PREREQ(2.59)  specify the autoconf version


 Others are not :
       o AC_AUTOMAKE()  adds several standard checks and initializes automake.


               • AM_INIT_AUTOMAKE([1.10 no-define])
               •AM_INIT_AUTOMAKE([1.10 no-define foreign])  specify that the component won‘t use the GNU file (NEWS
The configure.{in/ac} template
    PATH and source code definition :
AC_CONFIG_SRCDIR(unique-file-in-source-dir)
unique-file-in-source-dir is some file that is in the package's source directory; configure checks for this file's existence to make sure that
the directory that it is told contains the source code in fact does. Occasionally people accidentally specify the wrong directory with --
srcdir; this is a safety check. Packages that do manual configuration or use the install program might need to tell configure where to find
some other shell scripts by calling AC_CONFIG_AUX_DIR, though the default places it looks are correct for most cases.


AC_CONFIG_AUX_DIR(dir)
Use the auxiliary build tools (e.g., install-sh, config.sub, config.guess, Cygnus configure, Automake and Libtool scripts, etc.) that are in
directory dir. These are auxiliary files used in configuration. dir can be either absolute or relative to srcdir. The default is srcdir or srcdir/..
or srcdir/../.., whichever is the first that contains install-sh. The other files are not checked for, so that using AC_PROG_INSTALL does
not automatically require distributing the other auxiliary files. It checks for install.sh also, but that name is obsolete because some make
have a rule that creates install from it if there is no makefile. The auxiliary directory is commonly named build-aux. If you need
portability to DOS variants, do not name the auxiliary directory aux.


AC_REQUIRE_AUX_FILE(file)
Declares that file is expected in the directory defined above. In Autoconf proper, this macro does nothing: its sole purpose is to be traced
by third-party tools to produce a list of expected auxiliary files. For instance it is called by macros like AC_PROG_INSTALL (see
Particular Programs) or AC_CANONICAL_BUILD (see Canonicalizing) to register the auxiliary files they need. Similarly, packages that
use aclocal should declare where local macros can be found using AC_CONFIG_MACRO_DIR.


AC_CONFIG_MACRO_DIR(dir)
Specify dir as the location of additional local Autoconf macros. This macro is intended for use by future versions of commands like
autoreconf that trace macro calls. It should be called directly from configure.ac so that tools that install macros for aclocal can find the
macros' declarations. Note that if you use aclocal from Automake to generate aclocal.m4, you must also set ACLOCAL_AMFLAGS = -I
dir in your top-level Makefile.am. Due to a limitation in the Autoconf implementation of autoreconf, these include directives currently
must be set on a single line in Makefile.am, without any backslash-newlines.
The configure.{in/ac} template
 Checking for specific headers:

 AC_CHECK_HEADERS([unistd.h])
Then you could have code like the following in conf.h.in. The conf.h created by configure defines ‗HAVE_UNISTD_H‘ to 1, if and
only if the system has unistd.h.


   /* Define as 1 if you have unistd.h. */   #undef HAVE_UNISTD_H


The format of the template file is stricter than what the C preprocessor is required to accept. A directive line should contain only
whitespace, ‗#undef‘, and ‗HAVE_UNISTD_H‘. The use of ‗#define‘ instead of ‗#undef‘, or of comments on the same line as
‗#undef‘, is strongly discouraged. Each hook should only be listed once. Other preprocessor lines, such as ‗#ifdef‘ or ‗#include‘, are
copied verbatim from the template into the generated header.
The configure.{in/ac} template
  Default prefix :
By default, configure sets the prefix for files it installs to /usr/local. The user of configure can select a different prefix using the --
prefix and --exec-prefix options. There are two ways to change the default: when creating configure, and when running it. Some software
packages might want to install in a directory other than /usr/local by default. To accomplish that, use the AC_PREFIX_DEFAULT macro.


 AC_PREFIX_DEFAULT(prefix)
Set the default installation prefix to prefix instead of /usr/local.
It may be convenient for users to have configure guess the installation prefix from the location of a related program that they have
already installed. If you wish to do that, you can call AC_PREFIX_PROGRAM.


 AC_PREFIX_PROGRAM(program)
If the user did not specify an installation prefix (using the --prefix option), guess a value for it by looking for program in PATH, the way
the shell does. If program is found, set the prefix to the parent of the directory containing program, else default the prefix as described
above (/usr/local or AC_PREFIX_DEFAULT). For example, if program is gcc and the PATH contains /usr/local/gnu/bin/gcc, set the
prefix to /usr/local/gnu.


For example, if the AC_PREFIX_DEFAULT(/usr) is defined within a configure.ac, it won‘t be mandatory to specify the prefix at the
configure launch.

If not we should mantadory specify the prefix: ./configure --prefix=/usr
The configure.{in/ac} template
 In order to prevent autotools re-generating configure script automatically this is possible to
specify that we are in maintainer mode :

Sometimes due to the SCM not strictly remembering the timestamp of files the generated Makefile will think that it
needs to re-run "autoreconf -i" or equivalent to re-generate Makefile.in from Makefile.am, configure from
configure.ac, etc.

You need to look into maintainer mode - that should prevent the autoreconf step, which will fix the end-users'
problems.

In order to proceed, the following line should be add to the configure.ac:

             AM_MAINTAINER_MODE

Or provide set the --enable-maintainer-mode parameter to the configure script :

             ./configure --prefix=/usr                           
                                --enable-maintainer-mode
The configure.{in/ac} template
The version scheme used by Libtool tracks interfaces, where an interface is the set of exported entry
points into the library.

All Libtool libraries start with `-version-info' set to `0:0:0' -- this will be the default version number if
you don't explicitly set it on the Libtool link command line.

The meaning of these numbers (from left to right) is as follows:




 Beware, this can generate a warning if you want to generate a static library.
The configure.{in/ac} template
  Example of Makefile.am template that use the version:
lib_LTLIBRARIES = libtoe.la
libtoe_la_SOURCES = src/toe_assert.c                   
                                             src/toe_memory.c     
                                       src/toe_thread.c           
                                       src/toe_messageQueue.c 
                                       inc/utlist.h               
                                       inc/internal_api.h         
                                       inc/internal_config.h

libtoe_la_CFLAGS = -I$(HEADER_DIR)
                                                                   Makefile.am
                                                                       
                              $(LIBCONFIG_CFLAGS)

                              $(LIBLOG_CFLAGS)

                              -DLOG_NAME=TOE

                              -DLOG_MASK_PRIO=LOG_PRIO_ALL

libtoe_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) 
                    -lpthread
                  
                    -lrt
The configure.{in/ac} template
 Managing subdirs using AC_CONFIG_SUBDIRS (dir ...)

Make AC_OUTPUT run configure in each subdirectory dir in the given blank-or-newline-separated list. Each dir should be a literal, i.e.,
please do not use:

      if test "x$package_foo_enabled" = xyes; then
        my_subdirs="$my_subdirs foo"
      fi
      AC_CONFIG_SUBDIRS([$my_subdirs])


because this prevents ‗./configure --help=recursive‘ from displaying the options of the package foo. Instead, you should write:


      if test "x$package_foo_enabled" = xyes; then
       AC_CONFIG_SUBDIRS([foo])
      fi


If a given dir is not found at configure run time, a warning is reported; if the subdirectory is optional, write:


      if test -d "$srcdir/foo"; then
       AC_CONFIG_SUBDIRS([foo])
      fi


 If a given dir contains configure.gnu, it is run instead of configure. This is for packages that might use a non-Autoconf script
Configure, which can't be called through a configure wrapper since it would be the same file on case-insensitive file systems.


 Likewise, if a dir contains configure.in but no configure, the Cygnus configure script found by AC_CONFIG_AUX_DIR is used.
The configure.{in/ac} template
 Some operations are accomplished in several possible ways, depending on the OS variant. Checking for them essentially requires a
―case statement‖. Autoconf does not directly provide one; however, it is easy to simulate by using a shell variable to keep track of
whether a way to perform the operation has been found yet.


 Here is an example that uses the shell variable fstype to keep track of whether the remaining cases need to be checked. Note that
since the value of fstype is under our control, we don't have to use the longer ‗test "x$fstype" = xno‘.


  AC_MSG_CHECKING([how to get file system type])
  fstype=no
  # The order of these tests is important.
  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/statvfs.h>
  #include <sys/fstyp.h>]])],
               [AC_DEFINE([FSTYPE_STATVFS], [1],
                 [Define if statvfs exists.])
                fstype=SVR4])
  if test $fstype = no; then
                AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/statfs.h>
  #include <sys/fstyp.h>]])],
               [AC_DEFINE([FSTYPE_USG_STATFS], [1],
                 [Define if USG statfs.])
                fstype=SVR3])
  fi
  if test $fstype = no; then
                AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/statfs.h>
  #include <sys/vmount.h>]])]),
               [AC_DEFINE([FSTYPE_AIX_STATFS], [1],
                 [Define if AIX statfs.])
                fstype=AIX])
  fi
  # (more cases omitted here)
  AC_MSG_RESULT([$fstype])
The configure.{in/ac} template
   Creating variables exported to the Makefiles :
AC_DEFINE (variable, value, [description])
AC_DEFINE (variable)


Define variable to value (verbatim), by defining a C preprocessor macro for variable. variable should be a C identifier, optionally suffixed
by a parenthesized argument list to define a C preprocessor macro with arguments. The macro argument list, if present, should be a
comma-separated list of C identifiers, possibly terminated by an ellipsis ‗...‘ if C99 syntax is employed. variable should not contain
comments, white space, trigraphs, backslash-newlines, universal character names, or non-ASCII characters.


value may contain backslash-escaped newlines, which will be preserved if you use AC_CONFIG_HEADERS but flattened if passed via
@DEFS@ (with no effect on the compilation, since the preprocessor sees only one line in the first place). value should not contain raw
newlines. If you are not using AC_CONFIG_HEADERS, value should not contain any ‗#‘ characters, as make tends to eat them. To use a
shell variable, use AC_DEFINE_UNQUOTED instead.


description is only useful if you are using AC_CONFIG_HEADERS. In this case, description is put into the generated config.h.in as the
comment before the macro define. The following example defines the C preprocessor variable EQUATION to be the string constant ‗"$a
> $b"‘:


      AC_DEFINE([EQUATION], ["$a > $b"], [Equation string.])


If neither value nor description are given, then value defaults to 1 instead of to the empty string. This is for backwards compatibility with
older versions of Autoconf, but this usage is obsolescent and may be withdrawn in future versions of Autoconf.


If the variable is a literal string, it is passed to m4_pattern_allow.


If multiple AC_DEFINE statements are executed for the same variable name (not counting any parenthesized argument list), the last one
wins.
The configure.{in/ac} template
AC_DEFINE_UNQUOTED (variable, value, [description])
AC_DEFINE_UNQUOTED (variable)


Like AC_DEFINE, but three shell expansions are performed—once—on variable and value: variable expansion (‗$‘), command
substitution (‗`‘), and backslash escaping (‗‘), as if in an unquoted here-document. Single and double quote characters in the value have
no special meaning. Use this macro instead of AC_DEFINE when variable or value is a shell variable. Examples:


      AC_DEFINE_UNQUOTED([config_machfile], ["$machfile"],
       [Configuration machine file.])
      AC_DEFINE_UNQUOTED([GETGROUPS_T], [$ac_cv_type_getgroups],
       [getgroups return type.])
      AC_DEFINE_UNQUOTED([$ac_tr_hdr], [1],
       [Translated header name.])

Due to a syntactical bizarreness of the Bourne shell, do not use semicolons to separate AC_DEFINE or AC_DEFINE_UNQUOTED
calls from other macro calls or shell code; that can cause syntax errors in the resulting configure script. Use either blanks or newlines.
That is, do this:


   AC_CHECK_HEADER([elf.h],
    [AC_DEFINE([SVR4], [1], [System V Release 4]) LIBS="-lelf $LIBS"])


or this:


   AC_CHECK_HEADER([elf.h],
    [AC_DEFINE([SVR4], [1], [System V Release 4])
     LIBS="-lelf $LIBS"])


instead of this:
The configure.{in/ac} template
AC_SUBST (variable, [value])


Create an output variable from a shell variable. Make AC_OUTPUT substitute the variable variable into output files (typically one or
more makefiles). This means that AC_OUTPUT replaces instances of ‗@variable@‘ in input files with the value that the shell variable
has when AC_OUTPUT is called.


The value can contain any non-NUL character, including newline. If you are using automake 1.11 or newer, for newlines in values you
might want to consider using AM_SUBST_NOTMAKE to prevent automake from adding a line variable = @variable@ to the
Makefile.in files (see automake).


Variable occurrences should not overlap: e.g., an input file should not contain ‗@var1@var2@‘ if var1 and var2 are variable names.


The substituted value is not rescanned for more output variables; occurrences of ‗@variable@‘ in the value are inserted literally into the
output file. (The algorithm uses the special marker |#_!!_#| internally, so neither the substituted value nor the output file may contain
|#_!!_#|.)


If value is given, in addition assign it to variable.
 All the variables defined by :
      •AC_SUBST()
      •AC_DEFINED_*()
      •AM_CONDITIONAL()
      •…
 can be used in the Makefile.am.
The configure.{in/ac} template
AM_CONDITIONAL (conditional, condition):


The conditional name, conditional, should be a simple string starting with a letter and containing only letters, digits, and underscores. It
must be different from ‗TRUE‘ and ‗FALSE‘ that are reserved by automake.


The shell condition (suitable for use in a shell if statement) is evaluated when configure is run. Note that you must arrange for every
AM_CONDITIONAL to be invoked every time configure is run. If AM_CONDITIONAL is run conditionally (e.g., in a shell if
statement), then the result will confuse automake.


Conditionals typically depend upon options that the user provides to the configure script. Here is an example of how to write a
conditional that is true if the user uses the --enable-debug option.


   AC_ARG_ENABLE([debug],
   [ --enable-debug Turn on debugging],
   [case "${enableval}" in
    yes) debug=true ;;
    no) debug=false ;;
    *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
   esac],[debug=false])
   AM_CONDITIONAL([DEBUG], [test x$debug = xtrue])


Here is an example of how to use that conditional in Makefile.am:

   if DEBUG
   DBG = debug_program
   else
   DBG =
   endif
   noinst_PROGRAMS = $(DBG)
The configure.{in/ac} template
AM_COND_IF (conditional, [if-true], [if-false])


If conditional is fulfilled, execute if-true, otherwise execute if-false. If either branch contains AC_CONFIG_FILES, it will cause
automake to output the rules for the respective files only for the given condition.


AM_COND_IF macros may be nested when m4 quotation is used properly (see M4 Quotation).


Here is an example of how to define a conditional config file:


  AM_CONDITIONAL([SHELL_WRAPPER], [test "x$with_wrapper" = xtrue])
  AM_COND_IF([SHELL_WRAPPER],
      [AC_CONFIG_FILES([wrapper:wrapper.in])])
The configure.{in/ac} template
AC_ARG_WITH (package, help-string, [action-if-given], [action-if-not-given])


If the user gave configure the option --with-package or --without-package, run shell commands action-if-given. If neither option was
given, run shell commands action-if-not-given. The name package indicates another software package that this program should work
with. It should consist only of alphanumeric characters, dashes, plus signs, and dots.


The option's argument is available to the shell commands action-if-given in the shell variable with val, which is actually just the value
of the shell variable named with_package, with any non-alphanumeric characters in package changed into ‗_‘. You may use that
variable instead, if you wish.


The argument help-string is a description of the option that looks like this:


       --with-readline       support fancy command line editing

                                AC_ARG_WITH([readline],
help-string may be more than one line long, if more detail is needed. Just make sure the columns line up in ‗configure --help‘. Avoid
                                    [AS_HELP_STRING([--without-readline],
tabs in the help string              [disable support for readline])],
                                       [],
                                       [with_readline=yes])

                                      LIBREADLINE=
                                      AS_IF([test "x$with_readline" != xno],
                                       [AC_CHECK_LIB([readline], [main],
                                        [AC_SUBST([LIBREADLINE], ["-lreadline -lncurses"])
                                         AC_DEFINE([HAVE_LIBREADLINE], [1],
                                                [Define if you have libreadline])
                                        ],
                                        [AC_MSG_FAILURE(
                                           [readline test failed (--without-readline to disable)])],
                                        [-lncurses])])
The configure.{in/ac} template
Configuring Other Packages in Subdirectories


In most situations, calling AC_OUTPUT is sufficient to produce makefiles in subdirectories. However, configure scripts that control more than one
independent package can use AC_CONFIG_SUBDIRS to run configure scripts for other packages in subdirectories.


 AC_CONFIG_SUBDIRS(dir ...)


Make AC_OUTPUT run configure in each subdirectory dir in the given blank-or-newline-separated list. Each dir should be a literal, i.e., please do not
use:
     if test "x$package_foo_enabled" = xyes; then
       my_subdirs="$my_subdirs foo"
     fi
     AC_CONFIG_SUBDIRS([$my_subdirs])

because this prevents ‗./configure --help=recursive‘ from displaying the options of the package foo. Instead, you should write:
     if test "x$package_foo_enabled" = xyes; then
       AC_CONFIG_SUBDIRS([foo])
     fi

If a given dir is not found at configure run time, a warning is reported; if the subdirectory is optional, write:
     if test -d "$srcdir/foo"; then
       AC_CONFIG_SUBDIRS([foo])
     fi

If a given dir contains configure.gnu, it is run instead of configure. This is for packages that might use a non-Autoconf script Configure, which can't be
called through a wrapper configure since it would be the same file on case-insensitive file systems. Likewise, if a dir containsconfigure.in but
no configure, the Cygnus configure script found by AC_CONFIG_AUX_DIR is used.The subdirectory configure scripts are given the same command line
options that were given to this configure script, with minor changes if needed, which include:

·                adjusting a relative name for the cache file;
·                adjusting a relative name for the source directory;
·                propagating the current value of $prefix, including if it was defaulted, and if the default values of the top level and of the

subdirectory configure differ.This macro also sets the output variable subdirs to the list of directories ‗dir ...‟. Make rules can use this variable to
determine which subdirectories to recurse into.This macro may be called multiple times.
The configure.{in/ac} template
Generating final files :

It can be Makefiles, .pc files, config.h headers and so on :

 AC_CONFIG_FILES([
    Makefile
    src/Makefile                                                               New format
             foo.pc
    ])
 AC_OUTPUT
  It can be Makefiles, .pc files, config.h headers and so on :

        AC_OUTPUT([
                Makefile
                src/Makefile                                                   Old deprecated format
                foo.pc
                ])

   Both format are functional.

  The first one is the best format. It is the new one with new being relative because it has been that way for a while.

  The last one is the old format from way long ago.
The configure.{in/ac} template




                      CONFIGURE LAB
The configure.{in/ac} template

The main goal for this lab is to write a basic configure that :

   Check the C compiler
   Check Some standard headers
   Generate a Makefile in output


In case of problems with configure, you can consult the
―config.log‖ file that may provide more information about an
Autotools problem.

Read the ./configure --help to know all the parameters that
can be used by this script.
The Makefile.am template
The goal of this topic is to know how to write a Makefile.am template.
The Makefile.am templates

A makefile.am template will use a context prepared by the configure script.

 This is the second most important template after the configure.ac.

A GNU/Makefile can support more than one target.

 According to the final binary to build (binary, library, … ), the Makefile will run
them one by one in the same order than written in the template.

As seen before, Makefile.am are generic template ready for a conversion into a
Makefile.in

 The Makefile.in, contains variables between arobases in order to make the update by
the configure script easy to do.
The Makefile.am templates
 Template definition for binaries and libraries :
The Makefile.am templates
The Makefile.am templates
The Makefile.am templates
 Variables    used when building a program :

Occasionally it is useful to know which `Makefile' variables Automake uses for compilations; for instance you
might need to do your own compilation in some special cases. Some variables are inherited from Autoconf; these
are CC, CFLAGS, CPPFLAGS, DEFS, LDFLAGS, and LIBS.

 There are some global additional variables which Automake itself defines:




  This impact all components from the Makefile.am (binary, libarry, … )
The Makefile.am templates




                     MAKEFILE.AM LAB
The Makefile.am templates


The main goal for this lab is to :

1.Write a Makefile.am that will call another Makefile located
into a src directory

1.In this second Makefile.am, just generate a binary from
a helloworld.c.

1.Managed them using a single configure.ac
Using the library template
The goal of this topic is to know how to generate static/dynamic libraries.
Using the library template

 Autotools template make the makefile standard and portable.

Writting a library is quite identical as a binary.

A library either static or dynamic should also export its public api:
          <STAGINGDIR>/<PREFIX>/include/                              public headers
          <STAGINGDIR>/<PREFIX>/include/prefix/               metadata (.pc files)
          <STAGINGDIR>/<PREFIX>/lib/                                              static and/o

By default, the configure script generate both a static and dynamic library:

This is possible so specify just one type:
./configure --disable-static :          generate only a dynamic one
./configure –disable-dynamic :          force to generate only a static one
Using the library template
  Linking with a mix of shared and static libraries
By default, the linker will link against the shared libraries if they are available. If the -static flag is
given, the linker will try to use static libraries instead of dynamic one. But -Bdynamic and -Bstatic
provides finer control of which library, shared or static should searched for each library specified for
the linker. The library search option is toggled by each -Bdynamic or -Bstatic:

            ld ... -Bstatic -lfoo -Bdynamic -lbar ....

This command tells the linker to search the static library for libfoo, and search the shared version for
libbar and any libraries after it until a -Bstatic is seen.

To pass the -Bdynamic and -Bstatic options to the linker, one needs to do

            gcc -o main main.o -Wl,-Bstatic -lfoo -Wl,-Bdynamic –lbar

Since the gcc driver calls the linker with some default libraries,

            gcc -o main main.o -Wl,-Bstatic

 tells the linker to use the static versions for all default libraries like libc and etc.
http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
Using the library template
     Memory slicing with dynamic libraries :
Dynamic libraries are mapped by the dynamic linker in the process address
space,                                                                                          CODE
                                                                                                 BSS
                All processes share the same dynamic library code segment,                      HEAP

                                                                                                CODE
                                                                                        LIB 1
Each dynamic library data segment is of course per process,                                     DATA

                                                                                                CODE
                Each dynamic library data size must be counted in the process memory   LIB 2
               consumption.                                                                     DATA

                                                                                                Stack
Using the library template




                                Now with
the autotools 
Using the library template
This is possible to force the generation of a static library in case of a Makefile that generate
a static one before to link with :

noinst_lib_LTLIBRARIES = libfoo.la

The binary will be link using the internal LDFALGS.

Nb : the noinst prefix say that the library won‘t be install by the make install command.

The following prefix are accepted :

          check_LTLIBRARIES : generate a library for unitary tests
          noinst_LTLIBRARIES : generate a library for local usage (won‘t be installed)
Using the library template




                        LIBRARY LAB
Using the library template


 The main goal of this lab is to generate a library.

The library have two source code lib01.c and lib02.c located into
a src directory.

 The configure script should managed the version.

A single Makefile should be able to compile either a static or a
dynamic one.
Using the application template
The goal of this topic is to know how to generate binaries.
Using the application template
As well as for the library, binaries can accept some prefix :
        check_PROGRAM : generate a binary for the unitary tests
        noinst_PROGRAM : generate a binary for local usage (won‘t be installed)
 Internal link flags should be given to the LDFLAGS one. That‘s include internal
static library.

 External link flags should be given to the LDADD one. That‘s include all dependencies
checked by the PKG_CHECK_MODULE M4 macro
Using the application template
 Example of template used for a binary template :
bin_PROGRAMS = foo
foo_SOURCES = main.c
foo_SOURCES = main.c
foo_LDADD = libfoo.la @FLIBS@

pkglib_LTLIBRARIES = libfoo.la
libfoo_la_SOURCES = bar.f baz.c zardoz.cc
libfoo_la_LIBADD = $(FLIBS)
Using the application template
  From Executable Binary to Process Memory Map :
    0x0        Elf Header
                                                               0x400000
                                                                                  Code
                                                Code size
                  Code

                                                            0x10000000
                Padding
                                                                               Initialized
                                                              Data Size       Data (not 0)
               Initialized
                  Data                                                          Data set to
                                                                                 0 (BSS)
                                        Statically Linked
                                                                                  Heap
               Dyn Lib info              Mono-thread
                DWARF
    EOF        Debug Info                Simple Case                             Process
                                                                                  Stack
             Executable file               Not loaded
                                                                              Memory Map
                                           in memory

 The header is not load in memory as defined in this picture because it gives information about the binary format;
for instance it say at which memory address the code must be loaded.
Using the application template
    The multi-threaded case :
 Multiple threads share the entire process address space                                        CODE

         Each thread has its own user space stack that is allocated when doing                  DATA
          pthread_create system call. If stack size is not given, a default value is used.
                                                                                                  BSS

        Be Careful: on x86 and NPTL POSIX thread implementation this means 8 Mb. This is the     HEAP
        same value for default process stack size.                                              Thread #1
                                                                                                  Stack
        Always specify the stack size,                                                             .
                                                                                                    .
                                                                                                    .
 Try to kill the system created initial thread after creating your own init thread,
                                                                                                Thread #1
                                                                                                  Stack
Using the application template



Example of result for a process
with threads 




                                      Stack per thread.
Using the application template




                       APPLICATION LAB
Using the application template


The main goal for this lab is to:

1.First, generate a foobin binary from a foobin.c source code.
You will have to write a configure.ac and a Makefile.am.

1.Second, generate a library foolib from a foolib.c source code.
You will have to write a configure.ac and a Makefile.am

1.Third, merge the two configure.ac and Makefile.am
The library should compile first as a static library then link with
the binary.
The config.h support
The goal of this topic is to know how works the global config.h configuration header
The config.h header
  Impact on the configure.ac template :
The AC_CONFIG_HEADERS([config.h]) M4 macro indicates that we will use a config.h header file.

The generated header is included by your source code to pick up the results of the various configuration
tests in the form of C preprocessor macro definitions. Every variable exported by the configure script
through M4 macro (PKG_CHECK_MODULES(), AC_DEFINE(), AC_SUBST(), … ) will be set inside.

The     template        file    config.h.in   can    also     be   generated      automatically    by
the autoheader tool. autoreconf will invoke autoheader when AC_CONFIG_HEADERS is used
in configure.ac. If multiple configuration headers are used, autoheader will always only generate the
template for the first one in the list.

Example of usage in a configure.ac template
                       (…)


                       dnl ---------------------------------------
                       dnl Specify the internal toe_config.h
                       dnl ---------------------------------------
                       AC_CONFIG_HEADERS([inc/internal_config.h])


                       (..)
  That will generate a header called « internal_config.h » in the « inc » directory.

  Its content will include both all the boolean result of the internal check and also the custom checks made by
  Component itself.
The config.h header
 Impact on the Makefile.am template :
lib_LTLIBRARIES                   = libtoe.la


libtoe_la_SOURCES                 = src/toe_assert.c
                
                                                           src/toe_memory.c
                                         
                                                           src/toe_thread.c
                                                       
                                                           src/toe_messageQueue.c
                                         
                                                           inc/utlist.h
                                                            
                                                           inc/internal_api.h
                                                            
                                                           inc/internal_config.h

libtoe_la_CFLAGS                  = -I$(HEADER_DIR)
                      
                                                             $(LIBCONFIG_CFLAGS)
                                                  
                                                             $(LIBLOG_CFLAGS)
                                                  
                                                             -DLOG_NAME=TOE
                                                 
    Even if the config.h (here internal_config.h) is well include by the source code, this is important
                                                             -DLOG_MASK_PRIO=LOG_PRIO_ALL

libtoe_la_LDFLAGS the Makefile in = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
   to specify it in               order to include this dynamic file in the tarball generated by a make dist.
                                                                                                       
                                    -lpthread
The config.h header
 Config.h or not config.h that is the question…


Without config.h :                               With config.h :
 Every flags will be provided to the compiler    The command line is more silent.
over the command line (can be quite huge)
                                                  The config.h is the ID card of the build because
 Easy to manage with existent component         it defines all the activator, values, used during the
(don‘t need any modification for the header      compilation.
Import).
                                                  That need to import this header in all source
 The development process can check the          code (.c, .cpp, .cxx, …) or within a top header. The
variables either in this config.h header or      inclusion should be secured like this :
through the command line.
                                                 #ifdef HAVE_CONFIG_H
                                                 #include "config.h"
                                                 #endif /* HAVE_CONFIG_H */
The config.h header




                      GNU/MAKE LAB
The config.h header

The main goal of this lab is to write one autotool project
without any config.h and another with that support.

Compare the command line for the two build using « make v=1»
The config.h header
 More help about :
http://www.gnu.org/software/automake/manual/html_node/Optional.ht
ml#index-AC_005fCONFIG_005fHEADERS-219
The silent/verbose support
The goal of this topic is to know how works to manage the silent/verbose support
Managing silent/verbose support
When a big build is launch it can be nice to do not have too much traces
In the console screen.

The autotools can control the silent/verbose mode.

If the silent mode is selected, no build or warning traces won‘t be written to
stdio (err/out).

 Only errors will be displayed in detail and will stop the build process.
Managing silent/verbose support
Once the silent/verbose mode have been choosen by the configure script, this
Is possible to override it thanks to the « V » parameter:

 Silent mode selected by the configure script:

     o Silent mode :                    make

     o Verbose mode :         make V=1

 Verbose mode selected by the configure script:

     o Silent mode :                    make V=0

     o Verbose mode :         make

 This is possible to tune more the silent/verbose mode:

      $ export LIBTOOLFLAGS "--silent“
      $ make –s
Managing silent/verbose support




                       SILENT/VERBOSE LAB
Managing silent/verbose support


 The main goal of this lab is to add a verbose
 support by adding the –enable-verbose.

  The default state must be silent.
Managing dependencies with the pkg-config tool
The goal of this topic is to know how a pkgconfig file (.pc) are managed and how to use
the pkg-config tool.
The pkg-config tool




                         The PKG-
CONFIG tool

                         (aka
PaCKage CONFIGgurator)
The pkg-config tool

The pkg-config is a helper tool used when compiling applications and libraries.

It helps you insert the correct compiler options rather than hard-coding values on where to find
glib (or other libraries). It is language-agnostic, so it can be used for defining the location of
documentation tools, for instance.

It works fine both with native and cross-compile environnement.

The program is free software and licensed under the GPL version 2 or any later.

pkg-config works on multiple platforms: Linux and other UNIX-like operating systems, Mac OS
X and Windows. It does not require anything but a reasonably well working C compiler and a C
library, but can use an installed glib if that is present. (A copy of glib 1.2.10 is shipped together
with pkg-config and this is sufficient for pkg-config to compile and work properly.)

The first implementation was written in shell, by James Henstridge. Later, it was rewritten in C
by Havoc Pennington. It also grew an autoconf macro written by Tim Janik, later rewritten by
Scott James Remnant. The current maintainer is Tollef Fog Heen <tfheen@err.no>.

The current release of pkg-config is version 0.25 (March 2011).
The pkg-config tool
 Variables for Installation Directories :




  For more information : http://www.gnu.org/prep/standards/standards.pdf
The pkg-config tool
 The autootols can make a fine tuning of the installation directories :

 --bindir=DIR                          user executables [EPREFIX/bin]
 --sbindir=DIR                         system admin executables [EPREFIX/sbin]
 --libexecdir=DIR                      program executables [EPREFIX/libexec]
 --sysconfdir=DIR                      read-only single-machine data [PREFIX/etc]
 --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
 --localstatedir=DIR      modifiable single-machine data [PREFIX/var]
 --libdir=DIR                          object code libraries [EPREFIX/lib]
 --includedir=DIR                      C header files [PREFIX/include]
 --oldincludedir=DIR C header files for non-gcc [/usr/include]
 --datarootdir=DIR        read-only arch.-independent data root [PREFIX/share]
 --datadir=DIR                         read-only architecture-independent data [DATAROOTDIR]
 --infodir=DIR                         info documentation [DATAROOTDIR/info]
 --localedir=DIR                       locale-dependent data [DATAROOTDIR/locale]
 --mandir=DIR                          man documentation [DATAROOTDIR/man]
 --docdir=DIR                          documentation root [DATAROOTDIR/doc/toe]
 --htmldir=DIR                         html documentation [DOCDIR]
 --dvidir=DIR                          dvi documentation [DOCDIR]
 --pdfdir=DIR                          pdf documentation [DOCDIR]
 --psdir=DIR                           ps documentation [DOCDIR]
               --srcdir=DIR                         find the sources in DIR [configure dir or `..']

Example :                 ./configure --prefix=/usr               
                                                                  --srcdir=/tmp/tmp232123
The pkg-config tool
 Recent pkg-config tool version use several environment variables:
The pkg-config tool
$ pkg-config –help                                                                  Usage provided by pkg-config
Usage: pkg-config [OPTION...]
    --version                                            output version of pkg-config
    --modversion                                         output version for package
    --atleast-pkgconfig-version=VERSION   require given version of pkg-config
    --libs                                               output all linker flags
    --static                                             output linker flags for static linking
    --short-errors                                       print short errors
    --libs-only-l                                        output -l flags
    --libs-only-other                                    output other libs (e.g. -pthread)
    --libs-only-L                                        output -L flags
    --cflags                                             output all pre-processor and compiler flags
    --cflags-only-I                                      output -I flags
    --cflags-only-other                                  output cflags not covered by the cflags-only-I option
    --variable=NAME                       get the value of variable named NAME
    --define-variable=NAME=VALUE          set variable NAME to VALUE
    --exists                                             return 0 if the module(s) exist
    --print-variables                                    output list of variables defined by the module
    --uninstalled                                        return 0 if the uninstalled version of one or more module(s) or their
dependencies will be used
    --atleast-version=VERSION             return 0 if the module is at least version VERSION
    --exact-version=VERSION               return 0 if the module is at exactly version VERSION
    --max-version=VERSION                 return 0 if the module is at no newer than version VERSION
    --list-all                                            list all known packages
    --debug                                               show verbose debug information
    --print-errors                                        show verbose information about missing or conflicting packages,default if --
cflags or --libs
                                                                                         given on the command line
    --silence-errors                                     be silent about errors (default unless --cflags or --libsgiven on the command
line)
    --errors-to-stdout                                   print errors from --print-errors to stdout not stderr
The pkg-config tool
                                                           Ask for the LDFLAGS for a static link :
Example of metadata for bar.pc :
                                                                         $ pkg-config --libs bar
prefix=/usr                                                              –lbar
exec_prefix=${prefix}
includedir=${prefix}/include                               Ask for the LDFLAGS for a dynamic link:
libdir=${exec_prefix}/lib
fooname= Autotools are great :-)                                         $ pkg-config --libs --static bar
                                                                         -lbar
Name: bar
Description: The bar library                               ask for the LDFLAGS following a specific version :
Version: 2.1.2
Requires.private: foo >= 0.7                                             $ pkg-config --libs "bar >= 2.7―
Cflags: -I${includedir}                                                  Requested 'bar >= 2.7' but version of bar is 2.1.2
Libs: -L${libdir} –lbar
                                                           Ask for the CFLAGS :

  Check the component exists :                                          $ pkg-config --cflags bar
                                                                         -I/usr/include/foo
               $ pkg-config --exists --print-errors bar
               $ echo $?                                   Ask for the value of a specific name :
               0
                                                                         $ pkg-config –variable=fooname bar
  Check the version :                                                   Autotools are great :-)

               $ pkg-config --modversion bar               Multiple request for the CFLAGS & LDFLAGS :
               2.1.2
The pkg-config tool
 Listing of the packages installed :

$ pkg-config --list-all


libbsd                           libbsd - Utility functions from BSD systems
xtrans                           XTrans - Abstract network code for X
m17n-db                          m17n-db - The m17n database used by the m17n library.
autoopts                         AutoOpts - A semi-automated generated/library option parser
xcb                              XCB - X-protocol C Binding
gtest                            gtest - Google test framework for the C/C++ language
libdrm_nouveau                   libdrm_nouveau - Userspace interface to nouveau kernel DRM services
nautilus-sendto                  nautilus-sendto - Extend nautilus-sendto through plugins
gnome-screensaver                gnome-screensaver - gnome screensaver
xrandr                           Xrandr - X RandR Library
(...)


 Increase the trace during the pkg-config runtime :

$ pkg-config --debug --libs test


Parsing package file '/home/gayetth/Desktop/autotools-tests/pkg-config/001/test.pc'
  line>prefix=/usr
 Variable declaration, 'prefix' has value '/usr'
  line>exec_prefix=${prefix}
 Variable declaration, 'exec_prefix' has value '/usr'
  line>libdir=${exec_prefix}/lib
( … )
line>
  line>Name: test
  line>Description: test
  line>Requires:
  line>Version: 1.0.0
  line>Libs: -L${libdir} -ltest
  line>Cflags: -I${includedir}/test
The pkg-config tool




                          The PKG-
CONFIG metadata files
The pkg-config tool

Pkgconfig files are metadata provided by a specific component (eg: static/dynamic libray) for other
component that will work with:

     CFLAGS          : flags need for compiling with (-I<LIBPATH)>

     LDFLAGS         : flags need for linking with (-L<LIBPATH> -l<LIBNAME>)

     VERSION         : version of the package ; can be used to identify the public API
The pkg-config tool

Example of a pkg-config file used for the libglib-2.0:



   # This is a comment
   prefix=/home/hp/unst                  # this defines a variable                               Partie haute
   exec_prefix=${prefix}                               # defining another variable in terms of    Invariante
   the first
                                                                                                  « NAME »
   libdir=${exec_prefix}/lib
   includedir=${prefix}/include


   Name: Gobject              # human-readable name
   Description: Object/type system for GLib             # human-readable description
   Version: 1.3.1                                                                                Partie basse
   URL: http://www.gtk.org                                                                       customisable
   Requires: glib-2.0 = 1.3.1
   Conflicts: foobar <= 4.5 Libs: -L${libdir} -lgobject-1.3
   Libs.private: -lm Cflags: -I${includedir}/glib-2.0 -I${libdir}/glib/include
The pkg-config tool
Description of a pkg-config generic pattern that contain the metadata :
The pkg-config tool

This is possible to manage all the metadata within the configure.ac template :

dnl Variables declaration
PKG_DEFINITION=”Description: Thin OS Extension for native developments”
PKG_DEPEND=””


dnl For each PKG_CHECK_MODULE, upgrade the PKG_DEPEND variable.


dnl Export to the Makefile.am
AC_SUBST(PCK_DEFINITION)
AC_SUBST(PKG_DEPEND)


 Thus we can obtain the following toe.pc.in :

prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@


Name: @PACKAGE_NAME@
Description: @PCK_DEFINITION@
Requires: @PKG_DEPEND@
Version: @VERSION@
Libs: -L${libdir} -l@PACKAGE_NAME@
Cflags: -I${includedir}/@PACKAGE_NAME@/


 At the end, the pc.in template is really generic and dynamic.
The pkg-config tool


The autotools bring some M4 macros that can be used in order to work with the pkg-config‘s
metadata :

                               configure.ac

                                    PKG_PROG_PKG_CONFIG([MIN-VERSION])


                                    PKG_CHECK_EXISTS(MODULES, [ACTION-IF-
                                   FOUND], [ACTION-IF-NOT-FOUND])


                                    PKG_CHECK_MODULES(VARIABLE-PREFIX,
                                   MODULES, [ACTION-IF-FOUND], [ACTION-IF-
                                   NOT-FOUND])

                               Makefile.am
The pkg-config tool

PKG_PROG_PKG_CONFIG([MIN-VERSION])

 It locates the pkg-config tool on the system and checks its version for compatibility.

If you want to know which version is using :

           $ pkg-config --version
           0.25

Example of checking from a configure.ac file:

           (…)
           PKG_PROG_PKG_CONFIG([0.23])
           (…)

Output
           (…)
           checking pkg-config is at least version 0.23... Yes
           (…)

 If the version checked is not equal or above to the one expected, no other macro will work. So
beware is the result of this macro !!
The pkg-config tool

As well as with the which command tool, you can check first if this tools is available on the
current gnu/linux system, then where the command is located in the filesystem:

           $ which pkg-config
           /usr/bin/pkg-config

The autotools can do the same within the configure.ac :

           AC_PATH_PROG([PKG_CONFIG],[pkg-config])
           if test -z "$PKG_CONFIG" ; then
                    AC_MSG_ERROR([pkg-config tool not found])
           fi
The pkg-config tool
PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-
NOT-FOUND])

Verify if whether a particular library exist and check its version.
Check to see whether a particular set of modules exists. Similar to
PKG_CHECK_MODULES(), but does not set variables or print errors.


Example:

           (…)
           POLKIT_REQUIRED=3.2.1
           PKG_CHECK_EXISTS([polkit-dbus >= $POLKIT_REQUIRED],
           [have_polkit=yes], [have_polkit=no])
           (…)

The name polkit-dbus should follow the name of the pkg-config file (polkit-dbus.pc).
The pkg-config tool
PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
[ACTION-IF-NOT-FOUND])

 Checks to see whether a particular set of modules exists. If so, it sets <VARIABLE-
PREFIX>_CFLAGS and <VARIABLE-PREFIX>_LIBS according to the output from pkg-config --cflags and pkg-
config --libs.

Example that check the google/test library :

         LIBGTEST_REQUIRED_VERSION=1.5.0
         PKG_CHECK_MODULES([GTEST],[gtest >=
$LIBGTEST_REQUIRED_VERSION],[have_libgtest=yes],[have_libgtest=no])
         if test "$have_libgtest" = no ; then
                  AC_MSG_ERROR([Missing the libgtest library!!])
         fi

 Checking the version is not mandatory but is better.

 If pkg-config find the gtest.pc metadata, it will export to the Makefile two variables :
GTEST_CFLAGS and GTEST_LIBS. With old version of autotools this is needed to export them with the
AC_SUBST macro. This is not needed with recent one.

 This would result in MYSTUFF_LIBS and MYSTUFF_CFLAGS substitution variables, set to the libs and cflags
for the given module list. If a module is missing or has the wrong version, by default configure will abort with a
message. To replace the default action, specify an ACTION-IF-NOT-FOUND. PKG_CHECK_MODULES will not
print any error messages if you specify your own ACTION-IF-NOT-FOUND. However, it will set the variable
MYSTUFF_PKG_ERRORS, which you can use to display what went wrong.
The pkg-config tool

The two M4 macros PKG_CHECK_EXISTS and PKG_CHECK_MODULES can check more
than one dependency.

Example :

            (…)
            PKG_CHECK_EXISTS([gtkmm-2.4 >= 2.12.2 somethingelse-1.0 >= 1.0.2],
            [have_all_deps=yes],      [have_all_deps=no])
            (…)

            and

         (…)
          PKG_CHECK_MODULES([DEPS],[gtkmm-2.4 >= 2.12.2 somethingelse-1.0 >=
1.0.2],[have_all_deps=yes],[have_all_deps=no])
         (…)
The pkg-config tool
 Impact on the configure.ac template :

     #
     # Configure script for the foo component
     #


     # Check the version of the pkg-config tool
     # It will use pkg-config –version inside
     PKG_PROG_PKG_CONFIG([0.23])


     # Check the libconfig dependency
     # LIBCONFIG : is the prefix used with the two variable exported to the makefiles:
     #                   LIBCONFIG_CFLAGS    = pkg-config --cflags libconfig
     #                   LIBCONFIG_LIBS                = pkg-config --libs   libconfig
     # libconfig : specify the name of the pkg-config file that contain the metadata
     # (libconfig.pc)
     LIBCONFIG_REQUIRED_VERSION=1.4.6

     PKG_CHECK_MODULES([LIBCONFIG],[libconfig>=
     $LIBCONFIG_REQUIRED_VERSION],[have_libconfig=yes],[have_libconfig=no])


     if   test "$have_libconfig" = no ; then
                AC_MSG_ERROR([Missing the libconfig library 1.4.6 !!])
     fi


     AC_OUTPUT(
         Makefile
         foo.pc
     )
The pkg-config tool
 Impact on the Makefile.am template :

       EXTRA_DIST                          = $(top_srcdir)/autogen.sh

       HEADER_DIR            = $(top_srcdir)/inc

       lib_includedir                  = $(includedir)/foo
       lib_include_HEADERS    = $(HEADER_DIR)/foo/foo.h

       pkgconfigdir                        = $(libdir)/pkgconfig
       pkgconfig_DATA                      = foo.pc

       lib_LTLIBRARIES                     = libfoo.la

       libfoo_la_SOURCES     = src/foo.c                               
                                                           inc/config.h

       libfoo_la_CFLAGS                    = -I$(HEADER_DIR)            
                                                       $(LIBCONFIG_CFLAGS)

       libfoo_la_LDFLAGS     = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)   
                                                       -lpthread
                                           
                                                        -lrt

       libfoo_la_LIBADD      = $(LIBCONFIG_LIBS)
Note: external dependencies must be set to the _LIBADD variable. Internal/local one, should be
associated to _LDFLAGS.
        # EOF
The pkg-config tool




                      PKG-CONFIG LAB
The pkg-config tool                                       TP_PKG_CONFIG

 The goal of this lab is to manage


                                  DEPFOO1                   DEPFOO3
                                        2.5.6                    1.3
               FOO
                                  DEPFOO2
                                        1.4.2



The foo component will have two direct dependencies depfoo1 et depfoo2 and another one
depfoo3 pushed by depfoo1.

Workflow :
    1.Fill the content of the files from the depfoo3 component
    2.Fill the content of the files from the depfoo1 component
    3.Fill the content of the files from the depfoo2 component
    4.Fill the content of the files from the foo component

 In order to launch your TP, run the ./run_tp.sh script.
The pkg-config tool                                        TP_PKG_CONFIG

You should have after the installation :

/sdk/x86/
         lib/
                    libdepfoo1.so + libdepfoo1.a
                    libdepfoo2.so + libdepfoo2.a
                    libdepfoo3.so + libdepfoo3.a
                    pkgconfig/
                             depfoo1.pc
                             depfoo2.pc
                             depfoo3.pc
         include/
                    depfoo1/depfoo1.h
                    depfoo2/depfoo2.h
                    depfoo3/depfoo3.h
         bin/
                    foo
         More help: http://linux.die.net/man/1/pkg-config OR man pkgconfig
Generating a documentation
The goal of this topic is to know how to generate automatically a doxygen
documentation in a html format
Doxygen documentation in html format




                                           Generating a
default doxygen


                  documentation
Doxygen documentation in html format

 This feature will impact the two autotools templates :

     configure.ac
         This script will simply check that we have the doxygen file
         in the current path.

     Makefile.am
        This file will manage the documentation generation using the
        doxygen tool.
Doxygen documentation in html format

 Impact of the configure.ac template :
       dnl ---------------------------------------------------
       dnl                       Check for doxygen support
       dnl ---------------------------------------------------
       AC_PATH_PROG([DOXYGEN], [doxygen])

       dnl Export the boolean value of the doxygen check
       AM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN)

       dnl Display a warning in case the doxygen tool is not found
       dnl If not found, it will just display a warning.
       if test –z ―$DOXYGEN‖ then
                    AC_MSG_WARN([doxygen tool not found])
       fi

 This script will first test if the doxygen, then will export the result of this test to the other
makefile templates.
Doxygen documentation in html format

 Impact on the Makefile.am template :

In order to add the doxygen setting file in the tarball generated with make dist, we must
specify it explicitely:

         # Extra files to add in the archive
         EXTRA_DIST                      = $(top_builddir)/autogen.sh
                         
                                                         $(top_builddir)/default-
The   doxyfile should be define :
         Doxyfile

           DOXYFILE ?= $(top_builddir)/default-Doxyfile

 Then for the two targets we will :

        Make a directory that will be used for the html extraction
        Make a local copy of the default-Doxyfile
        Upgrade of the Doxyfile with data from the composant :
            oExtraction directory (HTML_OUTPUT)
            oIts name (PROJECT_NAME)
            oIts version (PROJECT_NUMBER)
            oThe path of the source code to parse (INPUT)
        Launch of the documentation by invoquing the doxygen tool
        Remove the temporarily Doxyfile
Doxygen documentation in html format




                                            Editing a
default doxygen


      configuration
Doxygen documentation in html format

Doxywizard is a GUI front-end used for configuring and running doxygen. In our case we will just use it
for generating a config file.

When you start doxywizard it will display the main window (the actual look depends on the OS used).
Doxygen documentation in html format




The doxywizard tool (also known as doxygen-gui) can be used in order to generate a default doxygen
configuration. The project‘s name and its relative version will update the file afterwards.

 This GUI can be also used to edit an existing setting.

 The configuration should be save into a default-Doxyfile file.
Doxygen documentation in html format




                          DOCUMENTATION LAB
Launching unitary test with covering support
The goal of this topic is to know how to automaticaly launch unitary tests with covering
support using gcov for PKI data.
Launching a unitary test with covering support

 Adaptations needed :

     configure.ac :

         Add the --enable-test support that will exports HAVE_TEST to the
        Makefiles.

         Add the --enable-covering support for adding the gcov flags
  to the build process.

     Makefile.am :

        Add the make check support to make the unit tests automatic

        Add the make covering support to make the lcov analysis automatic.
Launching a unitary test with covering support

 test flag for enabling the unit tests:

      Name                                 : --enable-test

      Mandatory                  : no

      Default’s state : enable

       If this flags is not set, the unit test binaries are not built. Thus, the “make check”
     command doesn’t do anything at all.
Launching a unitary test with covering support

 Adaptations needed :


                       dnl ---------------------------------------------------
                       dnl                           Check for lcov support
                       dnl ---------------------------------------------------
                       AC_PATH_PROG([LCOV], [lcov])
  configure.ac        AC_PATH_PROG([GENHTML], [genhtml])

  (first part)         dnl Export the boolean value of the lcov check
                       AM_CONDITIONAL(HAVE_LCOV, test $LCOV)

                       dnl Display a warning in case the lcov tool is not found
                       dnl If not found, it will just display a warning.
                       if test –z ―$LCOV‖ then
                                     AC_MSG_WARN([lcov/genhtml tools not found])
                       fi


   This initial test will check both if the lcov and genhtml tools are available in the current system.

   Thus we can be sure the make covering will be runable.
dnl --------------------------------------------
                           dnl Brief          : enable or disable the unitary test
                           dnl Mandatory           : no
                           dnl Values           : none (just enable the tests if set)
                           dnl Default's value : disable
                           dnl --------------------------------------------
                           AC_ARG_ENABLE(test,
                                     AS_HELP_STRING([--enable-test], [Enable the test unitary support [default=no]]),
                                                       [case "${enableval}" in
                                                         yes) have_test=true ;;
    configure.ac                                         no) have_test=false ;;
                                                *) AC_MSG_ERROR(bad value ${enableval} for --enable-test) ;;
                                   esac],
                                     [have_test=false])
    (second part)          dnl --------------------------------------------
                           dnl Export the conditional HAVE_TEST variable to the Makefiles
                           dnl --------------------------------------------
                           AM_CONDITIONAL(HAVE_TEST, $have_test)
                           dnl --------------------------------------------
                           dnl Test the have_test variable and if equal to true
                           dnl --------------------------------------------
                           AC_MSG_CHECKING(Checking the test support)
                           if test "$have_test" != "false" ; then
                                                   dnl --------------------------------------------
                                                   dnl Display the result of the test ... yes
                                                   dnl --------------------------------------------
                                                   AC_MSG_RESULT([yes])

                                        LIBGTEST_REQUIRED_VERSION=1.5.0
                                        PKG_CHECK_MODULES([GTEST],[gtest >=
                           $LIBGTEST_REQUIRED_VERSION],[have_libgtest=yes],[have_libgtest=no])
                                        if test "$have_libgtest" = no ; then
                                                               AC_MSG_ERROR([Missing libgtest library (http://code.google.com/p/googletest/) !!])
                                        fi
                                        LIBGMOCK_REQUIRED_VERSION=1.5.0
                                        PKG_CHECK_MODULES([GMOCK],[gmock >=
                           $LIBGMOCK_REQUIRED_VERSION],[have_libgmock=yes],[have_libgmock=no])
                                        if test "$have_libgmock" = no ; then
                                                               AC_MSG_ERROR([Missing libgmock library !!])
                                        fi
                           else
                                        dnl --------------------------------------------
                                        dnl Display the result of the test ... no
                                        dnl --------------------------------------------
                                        AC_MSG_RESULT([no])
If you are not using the Google test/mock you can avoid this step. If you need to check both the gtest and gmock
                           fi

dependencies.
Launching a unitary test with covering support
 Checking the dependencies :

        Check the Google test library :                                                                configure.ac
                dnl --------------------------------------------
                dnl Test if the libgtest is well available in the stagingdir
                dnl If so get the cflags and ldflag from the .pc file
                dnl --------------------------------------------
                LIBGTEST_REQUIRED_VERSION=1.5.0
                PKG_CHECK_MODULES([GTEST],[gtest >= $LIBGTEST_REQUIRED_VERSION],[have_libgtest=yes],[have_libgtest=no])
                if test "$have_libgtest" = no ; then
                                     AC_MSG_ERROR([Missing libgtest library (http://code.google.com/p/googletest/) !!])
                fi



         Check the Google mock library :                                                               configure.ac

                dnl --------------------------------------------
                dnl Test if the libgmock is well available in the stagingdir
                dnl If so get the cflags and ldflag from the .pc file
                dnl --------------------------------------------
                LIBGMOCK_REQUIRED_VERSION=1.5.0
                PKG_CHECK_MODULES([GMOCK],[gmock >= $LIBGMOCK_REQUIRED_VERSION],[have_libgmock=yes],[have_libgmock=no])
                if test "$have_libgmock" = no ; then
                                     AC_MSG_ERROR([Missing libgmock (http://code.google.com/p/googlemock/) library !!])
                fi


Dependencies are not mandatory. Indeed this is possible to use a single main in order to test our
development.
Launching a unitary test with covering support

 Unit test definition :

TESTS = myUnitTestExecutable

# Definition of the unit test :
check_PROGRAMS = myUnitTestExecutable
myUnitTestExecutable_SOURCES = test1.cpp
myUnitTestExecutable_CPPFLAGS =
myUnitTestExecutable_LDFLAGS =
myUnitTestExecutable_LDADD =

By specifying the unit test executable as check_PROGRAMS instead of using
something like bin_PROGRAMS or noinst_PROGRAMS, it generates the
makefiles such that the files will only be built when you run ―make check‖.

The same can be done for libraries as well. You can use check_LIBRARIES
instead of lib_LIBRARIES to specify libraries that should only be built for unit
tests.
Launching a unitary test with covering support

 Impact for the covering target in the configure.ac template :
  dnl --------------------------------------------
  dnl Brief            : enable or disable the buildin covering mode
  dnl Mandatory        : no
  dnl Values           : none (just enable the covering mode if set)
  dnl --------------------------------------------
  AC_ARG_ENABLE(covering,
                 AS_HELP_STRING([--enable-covering], [Enable the building covering (gnu/gcov) support [default=no]]),
                 [case "${enableval}" in
                   yes) have_covering=true ;;
                   no) have_covering=false ;;
                   *)   AC_MSG_ERROR(bad value ${enableval} for --enable-covering) ;;
                 esac],
               [have_covering=false])
  dnl --------------------------------------------
  dnl Test the have_covering variable and if equal to true
  dnl --------------------------------------------
  AC_MSG_CHECKING([Checking the covering support])
  if test "$have_covering" = "true" ; then
                dnl --------------------------------------------
                dnl Display the result of the test ... yes
                dnl --------------------------------------------                                   configure.ac
                AC_MSG_RESULT([yes])


               dnl --------------------------------------------
               dnl Update the CFLAGS and CPPFLAGS with gcov options for gcc
               dnl --------------------------------------------
               CFLAGS=" $CFLAGS -fprofile-arcs -ftest-coverage "
               CPPFLAGS=" $CPPFLAGS -fprofile-arcs -ftest-coverage "
               LDFLAGS=" $LDFLAGS -fprofile-arcs "
  else
               dnl --------------------------------------------
               dnl Display the result of the test ... no
               dnl --------------------------------------------
               AC_MSG_RESULT([no])
  fi
Launching a unitary test with covering support


Detail of the unit test covering for the current component by files:
Launching a unitary test with covering support

The html export details the real lines used by the unitary test at the runtime :
Launching a unitary test with covering support

Another detail from the html export :
Launching a unitary test with covering support

 Summary :

 The more the unitary tests (based on Google test/mock) will test
         functions, the more the KPI will give good data.

 The main goal is to target 100% but because some tests can
         be difficult to check (exception, interraction with the system, … )

 The tests should be runable on Hudson.

 Actually each component provides the following data:

     oNumber of lines (wc –l sloccount)
     o% of lines tested
     o% of functions tested
     o% of branches tested
Launching a unitary test with covering support




                          UNIT TEST & COVERING LAB
Launching a unitary test with covering support

The goal of this lab is to add a covering support to your component.

For this check you have lcov in your path. In the wrong case you can download
the runtime package here: http://downloads.sourceforge.net/ltp/lcov-1.9.tar.gz

Immagine how to integrate the slocount tool in the same way :
   •Sloccount command to launch : sloccount `pwd`
   •Download : http://www.dwheeler.com/sloccount/sloccount-2.26.tar.gz
   •http://www.dwheeler.com/sloccount/sloccount.html
   •http://www.dwheeler.com/sloccount/
   •Nb: don‘t forget to check the avaibility og the tool !
Launching a unitary test with covering support

 More help about :

    http://www.gnu.org/software/automake/
    http://www.gnu.org/software/autoconf/
    http://www.gnu.org/software/hello/manual/automake/Tests.html
    http://www.crsr.net/Notes/CheckAndAutotools.html
    http://gcc.gnu.org/onlinedocs/gcc/Gcov.html
    http://ltp.sourceforge.net/coverage/lcov.php
    http://codingfreak.blogspot.com/2009/02/gcov-analyzing-code-produced-
    with-gcc.html
    http://www.cmi.univ-
    mrs.fr/~contensi/coursC/index.php?section=env&page=test
Managing the debug mode
The goal of this topic is to know how to select a debug/release mode relative to a build
Managing the debug mode
 The main goal is to provide parameters to the GCC compiler and to the LD linker in order to
have a build usable with a debug mode.

 Gcc have a set of parameters that can be used for customizing the debug mode :




    For more detail : http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
Managing the debug mode




                          DEBUG MODE LAB
Managing the debug mode
The goal of this lab is to add a debug support to your
Autotools projet.

 Test a build using this one and another build without and check
the debug flags are well provided to gcc through the CFLAGS.

 Check the final ELF library have well the debug symbols :

   file ELFfile
   nm -gC ELFLib.so
   objdump -h ELFfile
   objdump -TC ELFLib
   readelf -Ws /usr/lib/libexample.so
   readelf -Ws /usr/lib/libstdc++.so.6 |
grep '^([[:space:]]+[^[:space:]]+){6}[[:space:]]+[[:digit:]]+‘
   readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
Manage the optimization level
The goal of this topic is to know how to select an optimization level relative to a build
Manage the optimization level




                        OPTIMIZATION LAB
Manage the optimization level

The goal of this lab is to update an autotools component
with an optimization level support by adding a
--with-optim-level=3 parameter.

Test a build using this one and another build without and
check the flags -Ox is well provided to gcc according to the
level expected.
Manage the profiling mode
The goal of this topic is to know how to select a debug/release mode relative to a build
Manage the profiling mode
 Cohabitation problems between gnu prof (aka gprof) and the pthread :

gprof is the GNU Profiler, a tool used when tracking which functions are eating CPU in your program. Anyway, you
should already be familiar with it if you got interested in this page.

One problem with gprof under certain kernels (such as Linux) is that it doesn‘t behave correctly with multithreaded
applications. It actually only profiles the main thread, which is quite useless.

 Workaround

There is an easy, but surprisingly not very widespread fix for this annoying gprof behaviour. Basically, gprof uses the
internalITIMER_PROF timer which makes the kernel deliver a signal to the application whenever it expires. So we just
need to pass this timer data to all spawned threads.

 Example

It wouldn‘t be too hard to put a call to setitimer in each function spawned by a thread, but I thought it would be more
elegant to implement a wrapper for pthread_create.

Daniel Jönsson enhanced my code so that it could be used in a preload library without having to modify the program. It
can also be very useful for libraries that spawn threads without warning, such as libSDL.

The result code is shown below and can be downloaded here: http://sam.zoy.org/writings/programming/gprof-helper.c

 more detail: http://sam.zoy.org/writings/programming/gprof.html
Manage the profiling mode




                            PROFILING LAB
Manage the profiling mode

The goal of this lab is to update an autotools component
with the profiling support by adding a –enable-profiling
parameter.

Test a build using this one and another build without
and check the flags -pg is well provided to gcc.
The cross-compilation
The goal of this topic is to know how cross-compile.
The cross-compilation
 Example of cross-compilation in action :

./configure --build i686-pc-linux-gnu --host i586-mingw32msvc

  checking for a BSD-compatible install... /usr/bin/install -c
  checking whether build environment is sane... yes
  checking for gawk... gawk
  checking whether make sets $(MAKE)... yes
  checking for i586-mingw32msvc-strip... i586-mingw32msvc-strip
  checking for i586-mingw32msvc-gcc... i586-mingw32msvc-gcc
  checking for C compiler default output file name... a.exe
  checking whether the C compiler works... yes
  checking whether we are cross compiling... yes
  checking for suffix of executables... .exe
  checking for suffix of object files... o
  checking whether we are using the GNU C compiler... yes
  checking whether i586-mingw32msvc-gcc accepts -g... yes
  checking for i586-mingw32msvc-gcc option to accept ANSI C
        etc ...
The cross-compilation
One of the main advantage of the autotools is to be portable to an architecture to another one.
The configure script have some parameters where we can specify the local and final architecture :




By default, the `configure' script will assume that the target is the same as the host. This is the more common case
; for example, it leads to a native compiler rather than a cross compiler.

The --host and --build options are usually all we need for cross-compiling. The only exception is if the package
being built is itself a cross-compiler: we need a third option to specify its target architecture.

 Native compiling (for the host):
           ./configure –prefix=/usr --host=i386-linux-gnu       …
           ./ configure –prefix=/usr                                                      …

 Cross-compiling :
          ./configure –prefix=/usr –host=i386-linux-gnu –build=mips-elf …
The cross-compilation
 Using the Host type :

In almost all cases the host system is the system on which you run the `configure' script, and on which
you build the tools (for the case when they differ, see section Canadian Cross).

If your configure script needs to know the configuration name of the host system, and the package is not
a cross compilation tool and therefore does not have a target, put `AC_CANONICAL_HOST' in
`configure.in'. This macro will arrange to define a few shell variables when the `configure' script is run.

      host
              The canonical configuration name of the host. This will normally be determined by running
the           `config.guess' shell script, although the user is permitted to override this by using an explicit
`--           host' option.

      host_alias
           In the unusual case that the user used an explicit `--host' option, this will be the argument to `-
-          host'. In the normal case, this will be the same as the `host' variable.

      host_cpu
      host_vendor
      host_os
           The first three parts of the canonical configuration name.
The cross-compilation
 Using the Target type :

If you want to build a cross compilation tool, you must specify the target explicitly by using the `--target' option when you run
`configure'. The argument to `--target' is the configuration name of the system for which you wish to generate code. See
section Configuration Names.

For example, to build tools which generate code for a MIPS ELF embedded system, you would use `--target mips-elf'.

When writing `configure.in' for a cross compilation tool, you will need to use information about the target. To do this, put
`AC_CANONICAL_SYSTEM' in `configure.in'.

`AC_CANONICAL_SYSTEM' will look for a `--target' option and canonicalize it using the `config.sub' shell script. It will
also run `AC_CANONICAL_HOST' (see section Using the Host Type).

The target type will be recorded in the following shell variables. Note that the host versions of these variables will also be
defined by `AC_CANONICAL_HOST'.

        target
              The canonical configuration name of the target.

        target_alias
              The argument to the `--target' option. If the user did not specify a `--target' option, this will be the same as
host_alias

        target_cpu
        target_vendor
        target_os
The cross-compilation
 This is a string of the form cpu-manufacturer-operating_system. In some cases, this is extended to a four part
form:
                          cpu-manufacturer-kernel-operating_system
                          (eg: i686-cm-linux)

 When using a configuration name in a configure option, it is normally not necessary to specify an entire name. In
particular, the manufacturer field is often omitted, leading to strings such as `i386-linux' or `sparc-sunos'. The shell
script `config.sub' will translate these shortened strings into the canonical form. autoconf will arrange for `config.sub'
to be run automatically when it is needed.




 The shell script `config.guess' will normally print the correct configuration name for the system on which it is run.
It does by running `uname' and by examining other characteristics of the system. Because `config.guess' can normally
determine the configuration name for a machine, it is normally only necessary to specify a configuration name when
building a cross-compiler or when building using a cross-compiler.

 This should be synchronize with the toolchain‘s prefix.
The cross-compilation
The configure script can detect the host system thanks to the
―AC_CANONICAL_HOST‖ or ‖AC_CANONICAL_SYSTEM‖ m4 macros:

    AC_CANONICAL_HOST

    case "${host}" in
    i[3456]86-*-linux-gnu*) do something ;;         Example of action that depend
    sparc*-sun-solaris2.[56789]*) do something ;;   on the host type.
    sparc*-sun-solaris*) do something ;;
    mips*-*-elf*) do something ;;
    esac
The cross-compilation
In cross-compilation mode, binaries will be generate with a prefix that will follow the one
provide to the target argument.

     In other word, native build will generate : mybinary

     And with a target equal to i686-cm-linux prefix the binary will become : i686-cm-linux-
     mybinary

 This is possible to do not add the prefix in cross-compilation mode if the following parameter is set
to the configure script:

           ./configure --prefix=/usr                                           
                                  --program-transform-name=""

 Thus the final name won‘t have any impact and won‘t change.
The cross-compilation




                    CROSS-COMPILATIONLAB
The cross-compilation
The main goal of this lab is to compile a helloworld binary in
three times:

   For the host: ./configure --prefix=/usr

   For a target: ./configure --prefix=/usr
                      
                                      --host=i386-linux-gnu
                      
                                      --build=mips-elf

   For a target: ./configure --prefix=/usr
                      
                                      --host=i386-linux-gnu
                      
                                      --build=mips-elf
Check the autotools for hudson
             SPECIFIC TECHNICOLOR
The goal of this topic is to be sure the autotools will work with hudson.
Check the autotools for hudson

Hudson make the autotools usage more difficult to use.

 Objets are not generated in the top_srcdir path but in top_builddir

So because top_srcdir != top_builddir, developers should valide their
autotools template before to apply a baseline on clearcase.
Check the autotools for hudson




                     HUDSON LAB
Check the autotools for hudson


The main goal of this lab if to valid your autotools by
Following the previous steps.

 After the « make dist », the extraction, and the configuring,
we should be able to compile and link.

If you have time, you can write a bash script for automating
This checking.
The M4 macros
The goal of this topic is to know how M4 macros are written.
The M4 macros
Autoconf modifies the M4 environment in a few ways. First, as mentioned earlier, it changes the
default quote characters from the backtick and single quote characters to the open and close square
bracket characters. In addition, it configures M4 built-in macros such that most are prefixed with m4_,
thereby creating a unique namespace for M4 macros. Thus, the M4 define macro becomes m4_define,
and so on.

Autoconf provides its own version of m4_define called AC_DEFUN. You should use AC_DEFUN
instead of m4_define because it ensures that certain environmental constraints important to Autoconf
are in place when your macro is called!!

The AC_DEFUN macro supports a prerequisite framework, so you can specify which macros are
required to have been called before your macro may be called.

This framework is accessed by using the AC_REQUIRE macro to indicate your macro‘s requirements
at the beginning of your macro definition, like so:

# Test for option A
AC_DEFUN([TEST_A],
[AC_REQUIRE([TEST_B])dnl
test " $A" = "yes" && options=" $options A"])
The M4 macros
This is possible to write a custom m4 macro :
There are two ways to organize custom macros in a package:

      The first possibility (the historical practice) is to list all your macros in acinclude.m4. This file
     will be included in aclocal.m4 when you run aclocal, and its macro(s) will henceforth be visible
     toautoconf. However if it contains numerous macros, it will rapidly become difficult to maintain,
     and it will be almost impossible to share macros between packages.

      The second possibility, which we do recommend, is to write each macro in its own file and
     gather all these files in a directory. This directory is usually called m4/. To build aclocal.m4, one
     should therefore instruct aclocal to scan m4/. From the command line, this is done with ‗aclocal -I
     m4‘. The top-level Makefile.am should also be updated to define:
     
                                  ACLOCAL_AMFLAGS = -I m4

 ACLOCAL_AMFLAGS contains options to pass to aclocal when aclocal.m4 is to be rebuilt
by make.

This line is also used by autoreconf.
The M4 macros
 Example:

         AC_DEFUN([TRAVOLTA],
           [test "$body_temperature_in_celsius" -gt "38" && dance_floor=occupied])

         AC_DEFUN([NEWTON_JOHN],
           [test "$hair_style" = "curly" && dance_floor=occupied])                   my_macros.m4
         AC_DEFUN([RESERVE_DANCE_FLOOR],
           [if date | grep '^Sat.*pm' >/dev/null 2>&1; then
            AC_REQUIRE([TRAVOLTA])
            AC_REQUIRE([NEWTON_JOHN])
           fi])




With this configure.ac :

         AC_INIT
         sinclude(my_macro.m4)
         RESERVE_DANCE_FLOOR                                                           configure.ac
         if test "$dance_floor" = occupied; then
                     AC_MSG_ERROR([cannot pick up here, let's move])
         fi
The M4 macros
 If you have somme command you often use in your configure.ac :
                   make_command="―                                                           We suppose you have written a small
                   for a in "$MAKE" make gmake gnumake                                      check already used in your "configure" script
                   do test -z "$a" && continue
                        if ( sh -c "$a --version" 2>/dev/null | grep GNU >/dev/null )
                                                                                            - which is actually a bourne shell script that
                                        then make_command=$a ; break;                       calls other tools and possibly sets an
                        fi                                                                  AC_SUBST variable to be replaced in your
                   done                                                                     Makefile.in. It may look like the following
                   if test -z $make_command                                                 check for a "gnu make" in the build
                   then ifGNUmake="―
                   else ifGNUmake="#―
                                                                                            environment.
                   fi
                   AC_SUBST(ifGNUmake)


 In the first step, one would extract that part from the "configure" script and put it into its own file. For a first test, please use the
"acinclude.m4" file. The next call of `aclocal && autoconf` will copy the new macro to "aclocal.m4" and from there to "configure". So,
now you have an extra file "acinclude.m4" reading:
                   AC_DEFUN(CHECK_GNU,[
                      make_command=""
                      for a in "$MAKE" make gmake gnumake
                      do test -z "$a" && continue
                         if ( sh -c "$a --version" 2>/dev/null | grep GNU >/dev/null )
                         then make_command=$a ; break;
                         fi
                      done
                      if test -n $make_command
                      then ifGNUmake=""
                      else ifGNUmake="#"
                      fi
                      AC_SUBST(ifGNUmake)
                   ])



                   ....
                   CHECK_GNU
                   ...
The M4 macros
 Now you are already done with having your own autoconf macro. And you can be quite sure that it will work in
your project - and probably you have tested it on the platforms you do usually build for. Believe it or not, this is a
rather "controlled" environment - if you push the macro to the AC Macro Archive then your macro might make it
into other projects where they will meet lots of other macros, lots of other shell code, lots of different platforms. And
possibly, it will fail over there - however there are some steps that can be checked before.

 Add m4-quotings - AC_DEFUN([CHECK_GNU])
In the wild, your "CHECK_GNU" might have been already defined elsewhere. It is perfectly possible to redefine a macro but only if
AC_DEFUN will see the name. Without the m4-quotes "[...]" however, the predefined macro CHECK_GNU will be expandend before.
In many many cases it results in "syntax errors" occuring near your usage of CHECK_GNU and they are not telling about a redefine
problem at all. It is really hard to get after that one.


 Add m4-quotings - AC_SUBST([ifGNUmake])
For the same reason, you should put m4-quotes in any other places where actually an m4-macro is being created - or possibly you are
going to use a symbol that might be a complex macro. As a rule of thumb, all uppercase-symbols might be defined as a macro
somewhere else. Please put all of them into m4-quotes "[...]". By the way, if you need a pair of "[..]" to be output to the "configure"
script, just double (or triple) them as "[[...]]".


 var-settings need doublequotes - make_command="$a"
Most people forget about a problem here - if there is a single space between the "=" and anything to follow then the righthand side will
be executed as a command and the return value of that command gets assigned. In other words, 'a="echo foo" ; var= $a' will not set
"$var" to "foo" but instead print "foo" to the user screen. Putting doublequotes around the righthand side will ensure it gets never ever
executed errornously. If you really want to get the execution value, then use backticks to express just that: 'a=`echo foo`'.

 test emptyness as : test "x$var" = "x"
The "test" command happens to be implemented very very differently on the various platforms, in fact it is mostly a builtin to the shell
you happen to have your configure script get executed with. While "-z" is seen often, even "-n" is rarely implemented. Even more, there
are some buggy shells which remove an empty "" string completely instead of providing an empty argument to the "test" command, so
that "test" would see a 'test "$var" = ""' as a real 'test =' - and ask for a syntax error.
The M4 macros
 Use cache variables - _cv_make_command
Your macro might be used by other macros which get each expanded into the final "configure" script. That will make your
check code to be executed multiple times. Not necessary, and for a compile-and-run test it would be very time consuming.
Also, the cache-variables allow a packager guru to pre-set the check-result, yielding faster "configure" and allows to handle
problems with cross-compile setups. The configure script will automatically save-to-cache all shell variables containing a
"_cv_" in the name.

 Use AC_MSG_RESULT - after AC_MSG_CHECKING / AC_CACHE_CHECK
Inform the user when the "configure" script enters your macro and when it leaves your macro. If there are problems, they can
be identified faster - remember that an extra autoconf macro file is in a distant place perhaps and the original "configure.ac"
has only a macro name, and possibly not even your macro name but a different one that happens to use your macro in its
definition. At best, inform the user of the result - and try to avoid terminology that is not helpful to a non-coder.

 Don't be afraid of long names - use AS_VAR_PUSHDEF / POPDEF
You should avoid to destroy shell variable values possibly used somewhere else - or the ones of the other macro calling your
macro. As for short-lived variables that do not span over other macros, just use very short names - for the other ones use a long
prefix that resembles the name of your macro check.

 Use a specific prefix - do not use AC_ or AM_
Many macro names might be defined under the same name elsewhere. Usually, you would use a project prefix to avoid double
defines, i.e. MYPROJECT_CHECK_GNU. Do never use AC_CHECK_GNU since all AC_ names are reserved - even if you
know there is no such macro in the "autoconf" package then it might still be added later. If you intend to submit your macro the
AC Macro Archive then you can use the AX_ prefix - we take all macros and we will ensure all macros in the archive are
unique. Always and forever.
The M4 macros
 After applying all these guideline, the macro might now look like this:


            AC_DEFUN([AX_CHECK_GNU_MAKE],[
            AC_CACHE_CHECK([for GNU make],ax_cv_gnu_make_command,[
            AS_VAR_PUSHEDEF([_make_command],ax_cv_gnu_make_command)dnl
               _make_command="―
            for a in "$MAKE" make gmake gnumake
            do test "x$a" = "x" && continue
                 if ( sh -c "$a --version" 2>/dev/null | grep GNU >/dev/null )
                 then _make_command="$a" ; break;
                 fi
            done
            if test "x$_make_command" != "x"
               then ifGNUmake=""
                  AC_MSG_RESULT([$_make_command])
            else ifGNUmake="#"
                  AC_MSG_RESULT([nothing found])
            fi
            AC_SUBST([ifGNUmake])
            AS_VAR_POPDEF([_make_command])dnl
            ]])
The M4 macros
 Adding some action : ACTION-IF-TRUE / ACTION-IF-FALSE

If you have a look around then you will notice that most "CHECK" macros have additional and optional arguments.
Those may contain shell-code (or other autoconf macros) that should be executed when the autodection fails (or
additionally when it succeeds). Autoconf macros are numbered, and the first argument is generally reserved for sub-
specifications - e.g. additional "make" program names to check for

          dnl -------------------------------------------------------------------------------------------------------------------
          dnl AX_CHECK_GNU_MAKE([make names],[ACTION-IF-FOUND],[ACTION-IF-NOT])
          dnl -------------------------------------------------------------------------------------------------------------------
          AC_DEFUN([AX_CHECK_GNU_MAKE],[
            AC_CACHE_CHECK([for GNU make],ax_cv_gnu_make_command,[
            AS_VAR_PUSHEDEF([_make_command],ax_cv_gnu_make_command)dnl
            _make_command=""
            for a in "$MAKE" $1 make gmake gnumake
            do test "x$a" = "x" && continue
               if ( sh -c "$a --version" 2>/dev/null | grep GNU >/dev/null )
               then _make_command="$a" ; break;
               fi
            done
            if test "x$_make_command" != "x"
            then ifGNUmake=""
                 AC_MSG_RESULT([$_make_command])
                 $2
            else ifGNUmake="#"
                 AC_MSG_RESULT([nothing found])
                 $3
            fi
            AC_SUBST([ifGNUmake])
            AS_VAR_POPDEF([_make_command])
          ]])
The M4 macros
 Using a custom m4 functions is done by including

Automake supports an include directive which can be used to include other `Makefile' fragments when automake is
run. Note that these fragments are read and interpreted by automake, not by make. As with conditionals,make has no
idea that include is in use.

There are two forms of include:

      include $(srcdir)/file
            include a fragment which is found relative to the current source directory.

      include $(top_srcdir)/file
      include a fragment which is found relative to the top source directory. Note that if a fragment is included
    inside a conditional, then the condition applies to the entire contents of that fragment.

Example of m4 macro include:
           include(pkg.m4)
           sinclude(pkg.m4)
The M4 macros




                M4 MACROS LAB
The M4 macros
The main goal for this lab is to create a file called mymacros.m4
that will contains custom m4 macros for the autotools.

In this file create a new M4 macro called :
AX_CHECK_GNU_LINUX_KERNEL_VERSION used for testing the
gnu/linux kernel version. We are expecting a 2.6.X not bellow.

The current version can be obtain by several way:
       uname –a or uname –r


      cat /proc/version
              Linux version 2.6.35-28-generic (buildd@rothera) (gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) ) #50-
Ubuntu SMP Fri Mar 18 19:00:26 UTC 2011


       cat /proc/sys/kernel/osrelease
       2.6.35-28-generic


Then, test the new macro in your configure.ac script.
More help about the autotools
Links 1/2
• OFFICIAL GNU MANUALS:
•
      GNU Make manual : http://www.gnu.org/software/make/manual/
      GNU M4 macros manual : http://www.gnu.org/software/m4/manual/index.html
      GNU libtools manual : http://www.gnu.org/software/libtool/manual/
      GNU autoconf manual : http://www.gnu.org/software/autoconf/
      GNU automake manual : http://www.gnu.org/software/automake/manual/
      Old book on the Autotools : http://sources.redhat.com/autobook/

      Other GNU manuals : http://www.gnu.org/manual/manual.html



Some application notes have been uploaded into Sharepoint about the Autotools usage:

     http://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20-
     %20doxygen%20documentation%20with%20the%20autotools.docx
     
     http://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20-
     %20integration%20of%20the%20debug%20mode%20in%20autotools.docx


     http://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20-
     %20int%C3%A9gration%20of%20the%20tests%20in%20autotools.docx
     
     http://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20-
     %20pkgconfig%20with%20the%20autotools.docx


     http://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20-
     %20version%20management%20in%20autotools.docx
Links 2/2 : other useful links
http://www.murrayc.com/learning/linux/automake/automake.shtml
http://www.murrayc.com/learning/linux/using_libraries/using_libraries.shtml
http://www.murrayc.com/learning/linux/building_libraries/building_libraries.shtml
http://www.gnu.org/software/libtool/
http://www.gnu.org/software/make/
http://www.gnu.org/software/m4/m4.html
http://www.gnu.org/software/m4/manual/m4.html
http://www.developingprogrammers.com/index.php/2006/01/05/autotools-tutorial/
http://www.cppfrance.com/tutoriaux/AUTOTOOLS-AUTOCONF-AUTOMAKE-LIBTOOL_876.aspx
http://www.lrde.epita.fr/~adl/autotools.html
http://inti.sourceforge.net/tutorial/libinti/autotoolsproject.html
http://www.cs.wmich.edu/~kkaugars/projects/Automake.html
http://www.st-andrews.ac.uk/~iam/docs/tutorial.html
http://autotoolset.sourceforge.net/tutorial.html
http://www.linuxselfhelp.com/gnu/autoconf/html_chapter/autoconf_toc.html
http://media.vodka-pomme.net/autotools/autotools.pdf
http://www-igm.univ-mlv.fr/~dr/XPOSE/Breugnot/
http://irt.enseeiht.fr/boyer/Automake-Autoconf/Automake.htm
http://ymettier.free.fr/articles_lmag/lmag75/lmag75.html
http://sourceware.org/autobook/autobook/autobook_toc.html#SEC_Contents
http://developer.kde.org/documentation/other/makefile_am_howto/en/index.html
http://git.ademar.org/gitweb.cgi?p=autotools.git;a=summary
http://www.flameeyes.eu/autotools-mythbuster/
http://www-igm.univ-mlv.fr/~dr/XPOSE/Breugnot/
http://www.gnu.org/software/gnuradio/doc/howto-write-a-block.html
http://www.seul.org/docs/autotut/
http://www-lil.univ-littoral.fr/~quesnel/download/autotools.pdf
Books that can help
Thanks for your attention




06/17/10

Autotools pratical training

  • 3.
    Autotools introduction The goalof this topic is to know how to well works with the autotools in a cross- compilation environement
  • 4.
    The autotools process History : Historically, a shell configure script transformed a Makefile.in into a Makefile  Autoconf 1 (1992): autoconf transformed a configure.in into a configure file  Autoconf 2 (1994): added cross-compilation support, sub-directories, hidden results, more tests, …  Automake (1994): automake transformed a Makefile.am into a Makefile  Libtool (1996): changed the Automake behavior
  • 5.
    Autotools introduction  Hereis the full power of the autotools in action that make build easier:
  • 7.
    Autotools introduction Autotools isa collection of OSS tools : GNU Automake is a tool for automatically generating `Makefile.in' files compliant with the GNU Coding Standards. http://www.gnu.org/software/automake/ GNU Autoconf is an extensible package of M4 macros that produce shell scripts to automatically configure software source code packages. These scripts can adapt the packages to many kinds of UNIX-like systems without manual user intervention. Autoconf creates a configuration script for a package from a template file that lists the operating system features that the package can use, in the form of M4 macro calls.  Producing configuration scripts using Autoconf requires GNU M4. You should install GNU M4 (at least version 1.4.6, although 1.4.13 or later is recommended) before configuring Autoconf, so that Autoconf's configure script can find it. The configuration scripts produced by Autoconf are self- contained, so their users do not need to have Autoconf (or GNU M4). http://www.gnu.org/software/autoconf/ GNU libtool is a generic library support script. Libtool hides the complexity of using shared libraries behind a consistent, portable interface.  http://www.gnu.org/software/libtool/  pkg-config is a helper tool used when compiling applications and libraries. It helps you insert the correct compiler options on the command line so an application can use gcc -o test test.c `pkg-config --libs --cflags glib-2.0` for instance, rather than hard-coding values on where to find glib (or other libraries). It is language-agnostic, so it can be used for defining the location of documentation tools, for instance.  http://www.freedesktop.org/wiki/Software/pkg-config   GNU M4 is an implementation of the traditional Unix macro processor. It is mostly SVR4 compatible although it has some extensions (for example, handling more than 9 positional parameters to macros). GNU M4 also has built-in functions for including files, running shell commands, doing arithmetic, etc. GNU M4 is a macro processor in the sense that it copies its input to the output expanding macros as it goes. Macros are either builtin or user- defined and can take any number of arguments. Besides just doing macro expansion, m4 has builtin functions for including named files, running UNIX commands, doing integer arithmetic, manipulating text in various ways, recursion etc... m4 can be used either as a front-end to a compiler or as a macro processor in its own right. http://www.gnu.org/software/m4/ Autogen.sh (a.k.a. buildconf) provides automatic build system preparation and is generally very useful to projects that use the GNU build system (i.e. the GNU autotools: autoconf, automake, and libtool).  http://buildconf.brlcad.org/ A toolchain (GNU or other) that include binutils.
  • 13.
    Autotools introduction  Initialpreparation : ./autogen.sh  Configuration : ./configure --prefix=/usr  Compiling : make  Installation : make DESTDIR=«stagingdir» install
  • 14.
    Mastering the buildprocess The goal of this topic is to know how the build process works.
  • 15.
    Mastering the buildprocess The GNU Compiler Collection (GCC) : is a compiler system produced by the GNU Project is supporting various programming languages is a key component of the GNU toolchain has been adopted as the standard compiler by most other modern Unix-like computer operating systems, including Linux, the BSD family and Mac OS X has been ported to a wide variety of processor architectures is widely deployed as a tool in commercial, proprietary and closed source software development environments is also available for most embedded platforms, for example Symbian (called gcce), AMCC and Freescale Power Architecture-based chips can target a wide variety of platforms, including videogame consoles such as the PlayStation 2 and Dreamcast. Several companies make a business out of supplying and supporting GCC ports to various platforms, and chip manufacturers today consider a GCC port almost essential to the success of an architecture.  Originally named the GNU C Compiler, because it only handled the C programming language, GCC 1.0 was released in 1987, and the compiler was extended to compile C++ in December of that year. Front ends were later developed for Fortran, Pascal, Objective-C, Java, and Ada, among others.  The Free Software Foundation (FSF) distributes GCC under the GNU General Public License (GNU GPL). GCC has played an important role in the growth of free software, as both a tool and an example. http://gcc.gnu.org
  • 20.
    Mastering the buildprocess Linking : the compiler’s backend •Generates assembly code for the final output. •Generates ELF object (replace the old a.out one). •Uses ld through the gcc. •Can make: Binary: adds a main entry to the intermediate code. Dynamic library: if the -shared parameter has been given (cannot be runable except for the libc).  Direct usage with the ld linker : $ ld -o mybinary /lib/crt0.o file.o –lc crt0 (or crt0.o, gcrt0.o, mcrt0.o) is a set of execution start-up routines (usually part of the C standard library) that are platform dependent, and is required in order to compile using GCC and other GNU tools. crt stands for "C runtime".  -e entry Use entry as the explicit symbol for beginning execution of the program, rather than the default entry point (main). If there is no symbol named entry, the linker will try to parse entry as a number, and use that as the entry address (the number will be interpreted in base 10; you may use a leading 0x for base 16, or a leading 0 for base 8).
  • 21.
    Mastering the buildprocess  GNU tools from the toolchain are set for an embedded usage : --sysroot=staging directory Use dir as the logical root directory for headers and libraries. For example, if the compiler would normally search for headers in /usr/include and libraries in /usr/lib, it will instead search dir/usr/include and dir/usr/lib. If you use both this option and the -isysroot option, then the --sysroot option will apply to libraries, but the -isysroot option will apply to header files. The GNU linker (beginning with version 2.16) has the necessary support for this option. If your linker does not support this option, the header file aspect of --sysroot will still work, but the library aspect will not.  Usually te environment is defined like this : export STAGING_DIR=<PATH TO THE STAGING DIRECTORY> export PREFIX=«i686-cm-linux-» export TOOLCHAIN_DIR=<PATH TO THE TOOLCHAIN> export CC=$(PREFIX)gcc --sysroot=$(STAGING_DIR) export LD=$(PREFIX)ls --sysroot=$(STAGING_DIR) export GCC=$(PREFIX)gcc --sysroot=$(STAGING_DIR) export CXX=$(PREFIX)gcc --sysroot=$(STAGING_DIR) export GDB="$(STAGING_DIR)/bin/$(PREFIX)gdb" export RANLIB="$(TOOLCHAIN_DIR)/bin/$(PREFIX)ranlib" export STRIP="$(TOOLCHAIN_DIR)/bin/$(PREFIX)strip" export OBJCOPY="$(TOOLCHAIN_DIR)/bin/$(PREFIX)objcopy" export AR="$(TOOLCHAIN_DIR)/bin/$(PREFIX)ar" export AS="$(TOOLCHAIN_DIR)/bin/$(PREFIX)as" export LD="$(TOOLCHAIN_DIR)/bin/$(PREFIX)ld"
  • 22.
    Mastering the buildprocess BUILD PORCESS LAB
  • 23.
    Mastering the buildprocess The main goal of this lab is to know how is working the GNU/ Using the helloworld.c source code try several parameters {--verbose/-E/-S}: gcc --verbose gcc -c helloworld.c gcc -c helloworld.c -o helloworld.o gcc -E helloworld.c gcc -S helloworld.c …
  • 24.
    Quick GNU/make reminder Thegoal of this topic is to know how works common GNU/make
  • 25.
    Quick GNU/make reminder The final files generated are gnu/make based.  Most Makefile.am can be extend with gnu/make features that‘s why this is important to know how makefiles are made.  We will remain some basic makefile usage.
  • 31.
    Quick GNU/make reminder WithGNU/Makefiles :  No target is buildin ; everything should be written from scratch each time ;  Doesn‘t use generic templates for binaries, libraries, … ;  Cross-compilation support should be manualy specified ;  Pkg-config can be used (not by M4 macros) ;  Can make ugly Makefile ;  Makefile are often more static than dynamic Everything done by gnu Makefile is automatically natively supported by the Autotools  !
  • 32.
    Quick GNU/make reminder Other make engine exists: ocmake (http://www.cmake.org/) oqmake (http://doc.qt.nokia.com/4.4/qmake-manual.html) oand so on…  For more information about the GNU/make: http://oreilly.com/catalog/make3/book/index.csp http://www.wanderinghorse.net/computing/make/book/ManagingProjectsWithG NUMake-3.1.3.pdf http://notendur.hi.is/~jonasson/software/make-book/ http://www.gnu.org/software/make/manual/make.pdf http://en.wikipedia.org/wiki/Make_(software)#Modern_versions http://ecee.colorado.edu/~mcclurel/gnu_make_overview.pdf http://static.maemo.org/static/d/dcacc028fda611dd9062b3dd54505f765f76_gnu_ make_and_makefiles.pdf
  • 33.
  • 34.
    Quick GNU/make reminder Themain goal of the lab is to write a makefile with several targets:  The project have three source code: data.c, main.c and io.c The make file should support the following targets: Compilation: make (aka make all) Cleaning old objects:make clean Create tarball: make dist Create an installer: make DESTDIR=«PATH» install Create an uninstaller:make DESTDIR=«PATH» uninstall
  • 35.
    Quick GNU/make reminder So, if we check the several Makefiles written, no one will be identical, that’s mean there is no uniformisation/no standard.  That what the autotools provide.
  • 36.
    The autotools process Thegoal of this topic is to know how works the templates are written.
  • 39.
    The autotools process working with the autotools means for a developer to manage templates and potfiles : Makefile.am : used to define what should be build and how using generic templates. configure.ac : used to define an autotools project. It can include <component>.*.in : used to associate some metadata (this is used by *.pc.in used for managing dependencies or config files).  Only those files have to be managed by the developers.  No more files need to be stored in repository except if there are filled (README, LICENCE, … ).
  • 40.
    The autotools process STEP#1 : autogen.sh The autogen.sh is a generic script used to prepare an autotool project for end users. Its goal is to check the environment need for the autotools scripts and binaries. This script need to be launched each time a template have been modified. It will generate several files: oa configure script from the configure.ac oa Makefile.in form the Makefile.am oa config.h.in if expected configure.ac --- Roadmap : | | ------> autoconf* -----> configure [aclocal.m4] --+--- | | -----> autoheader* --> [config.h.in] | [acsite.m4] ----- Makefile.am -------------------------------> Makefile.in
  • 41.
    The autotools process STEP#2 : configuration, compilation and installation This is the end user view. This step must start by the launch of the configure script in order to generate a final Makefile: ./configure --prefix=/usr … Then, this is possible to use the several target from the Makefile: and so on…
  • 44.
    The autotools process Debuggingvia autom4te: At times, it is desirable to see what was happening inside m4, to see why output was not matching expectations. However, post- processing done by autom4te means that directly using the m4 builtin m4_traceon is likely to interfere with operation. Also, frequent diversion changes and the concept of forbidden tokens make it difficult to use m4_defn to generate inline comments in the final output. There are a couple of tools to help with this. One is the use of the --trace option provided by autom4te (as well as each of the programs that wrap autom4te, such as autoconf), in order to inspect when a macro is called and with which arguments. For example, when this paragraph was written, the autoconf version could be found by: $ autoconf --trace=AC_INIT configure.ac:23:AC_INIT:GNU Autoconf:2.63b.95-3963:bug-autoconf@gnu.org $ autoconf --trace='AC_INIT:version is $2‗ version is 2.63b.95-3963 Another trick is to print out the expansion of various m4 expressions to standard error or to an independent file, with no further m4 expansion, and without interfering with diversion changes or the post-processing done to standard output. m4_errprintn shows a given expression on standard error. For example, if you want to see the expansion of an autoconf primitive or of one of your autoconf macros, you can do it like this: $ cat <<EOF > configure.ac AC_INIT m4_errprintn([The definition of AC_DEFINE_UNQUOTED:]) m4_errprintn(m4_defn([AC_DEFINE_UNQUOTED])) AC_OUTPUT EOF $ autoconf error-->The definition of AC_DEFINE_UNQUOTED: error-->_AC_DEFINE_Q([], $@)
  • 47.
    The autotools process •The essential files: The smallest project requires you provide only two files: CONFIGURE.AC : an input file to autoconf that provides the macro invocations and shell code fragments autoconf uses to build a configure script. MAKEFILE.AM: an input file to automake that specifies a projects build requirements: what needs to be built, and where it goes when installed. The GNU Autotools will generate the rest of the files needed to build the project. • The Directory Structure: Before writing any code for a new project you need to decide on the directory structure the project will use ; The top-level directory is used for configuration files, such as configure.in, and other sundry files like ChangeLog, COPY (a copy of the project license) and README ; Any unique library should have its own subdirectory containing all headers and sources, a Makefile.am, and any other library specific files ; The headers and sources for the main application should be in another subdirectory, typically called src ; Other directories can include: config for intermediate files, doc for the project documentation and test for the project self-test suite ; The following steps will take you through creating and building the HelloWorld project. The top-level directory for HelloWorld is <tests/project>. You will find the project's headers and sources in the src subdirectory. There are three files: helloworld.cc, helloworld.h and main.cc ;
  • 49.
  • 50.
    The autotools process Thegoal of this lab if to use an hello world autotools project. Experiment the several steps : Preparation: ./autogen.sh See the files before and after. Configuration: ./configure –prefix=/usr  Read the config.log that detail the configuration step ; this is a good way to debug a configure script. Compilation: make  Installation: make DESTDIR=pwd install  Delivery: make dist
  • 51.
    Using the autoscantool The goal of this topic is to know how to use the autoscan tool
  • 52.
    Using the autoscantool STEP #0 : autoscan The easiest way to create a (mostly) complete configure.ac file is to run the autoscan utility, which is part of the autoconf package. This utility examines the contents of a project directory and generates the basis for a configure.ac file (which autoscan names configure.scan) using existing makefiles and source files. The autoscan utility examines the project directory hierarchy and creates two files called configure.scan and autoscan.log. The project may or may not already be instrumented for Autotools ; it doesn’t really matter, because autoscan is decidedly non-destructive. It will never alter any existing files in a project. your source files  autoscan*  configure.scan  configure.ac
  • 53.
    Using the autoscantool First exampleof the autoscan tool, two files should appear in the current directory: After the launch with an empty directory:  autoscan.log  configure.scan  should be renamed into a configure.ac file afterward As we see, the contents of the generated configure.scan is similar to our hand-crafted template: # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.56) AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) # Checks for programs. # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_OUTPUT  As the name autoscan implies, you can guess that it can do other things as well, not only
  • 54.
    Using the autoscantool Second example with two existing files in the project: A header sleep.h : #include <stdio.h> #include <unistd.h> /* Needed for sleep() */ A source code sleep.c : #include "sleep.h" #define SECONDS_TO_SLEEP 3 int main() { unsigned int sleep_left = 0; /* sleep() for SECONDS_TO_SLEEP seconds, then print a message. */ sleep(SECONDS_TO_SLEEP); printf("I woke up after %d seconds.n", SECONDS_TO_SLEEP); return 0; }
  • 55.
    Using the autoscantool That will automaticaly generate the following configure.scan script: # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.56) AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) AC_CONFIG_SRCDIR([sleep.c])  some file that is in the package's source directory. AC_CONFIG_HEADER([config.h])  containing C preprocessor #define statements. # Checks for programs. AC_PROG_CC  determine the C compiler to use. # Checks for libraries. # Checks for header files. AC_CHECK_HEADERS([unistd.h])  check for existing header file(s) (in our case only one, unistd.h). # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions.  To get a very basic, but working input file to autoconf, rename configure.scan to AC_OUTPUT configure.ac: mv configure.scan configure.ac   Then update the AC_INIT macro, and add the AC_COPYRIGHT macro.
  • 56.
    Using the autoscantool AUTOSCAN LAB
  • 57.
    Using the autoscantool The main goal for this lab is to go into a directory where is existing source code ; Launch the autoscan command: ./autoscan View the configure.scan generated.
  • 58.
    The autogen.sh script Thegoal of this topic is to know how works the autogen.sh script
  • 59.
    The autogen.sh script The autogen.sh script is used for converting all the templates (configure.ac, Makefile.am, …) in final files (Makefile, configure, …) needed for a common Autotools usage. Thus, The autogen.sh script (a.k.a. buildconf) provides automatic build system preparation and is generally very useful to projects that use the GNU build system (i.e. the GNU Autotools: autoconf, automake, and libtool). It is a POSIX shell script that is used for preparing a build system for compilation, verifying versions, ensuring necessary functionality, and overcoming many common build preparation issues. Official web site : http://buildconf.brlcad.org/ Licence : BSD Latest stable release : 23.12.2009 http://downloads.sourceforge.net/project/buildconf/autogen/2009.12.23/buildconf.2009.12.23.tar.gz?u se_mirror=freefr&ts=1278845776 This script is standalone, its usage is mainly limited to a call in the autotools directory : $ ./autogen.sh Another way is to use the following command: autoreconf -i –force (This is what the script do in background)
  • 60.
    The autogen.sh script  Before the autoconf script some bootstrap command was used:  first, we need to generate the required output files from the two input files configure.in and Makefile.am. First we need to collect all the macro invocations in configure.in that Autoconf will need to build the configure script. This is done with the following command: $ aclocal This generates the file aclocal.m4 and adds it to the current directory. Next, run autoconf: $ autoconf  After running autoconf you will find the configure script in the current directory. It's important to run aclocal first because automake relies on the contents on configure.in and aclocal.m4. There are a few files that the GNU standard says must be present in the top-level directory, and if not found Automake will report an error. Enter the following command to create these files: $ touch AUTHORS NEWS README ChangeLog  Now we can run automake to create Makefile.in. The –add-missing argument copies some boilerplate files from your Automake installation into the current directory. $ automake --add-missing By now, the contents of the directory should be looking a lot like the top-level directory of a GNU package you may have installed before:
  • 61.
    The autogen.sh script Whatthe autogen.sh really do : It tranforms the template into intermediate files: Those files will complete the other files (component.pc.in), in order to be ready for the configure script. Note : configure.ac is by far the preferred naming for autoconf >= 2.50 while configure.in is what was used by autoconf ⇐ 2.13 and was kept for *cough* backward compatibility *cough*…
  • 62.
    The autogen.sh script  Parameters used to control the autogen.sh script :  There is two controversal parameters with the --quiet and --verbose that can be set in the same time!! Indeed, the autogen.sh script will follow the last one provided at the launch.  Check of the autotools components version: $ ./autogen.sh –version Identical as : Preparing the toe build system...please wait ./autoconf --version Found GNU Autoconf version 2.67 Found GNU Automake version 1.11.1 ./automake –version Found GNU Libtool version 2.2.6b ./libtool --version autogen.sh build preparation script by Christopher Sean Morrison + config.guess download patch by Sebastian Pipping (2008-12-03) revised 3-clause BSD-style license, copyright (c) 2005-2009 script version 20090301, ISO/IEC 9945 POSIX shell script --- Version requested. No preparation or configuration will be performed.
  • 63.
    The autogen.sh script  Autogen.sh usage can be obtain with the command line: $ ./autogen.sh –help Usage: ./autogen.sh [-h|--help] [-v|--verbose] [-q|--quiet] [-d|--download] [--version] --help Help on autogen.sh usage --verbose Verbose progress output --quiet Quiet suppressed progress output --download Download the latest config.guess from gnulib --version Only perform GNU Build System version checks Description: This script will validate that minimum versions of the GNU Build System tools are installed and then run autoreconf for you. Should autoreconf fail, manual preparation steps will be run potentially accounting for several common preparation issues. The AUTORECONF, AUTOCONF, AUTOMAKE, LIBTOOLIZE, ACLOCAL, AUTOHEADER, PROJECT, & CONFIGURE environment variables and corresponding _OPTIONS variables (e.g. AUTORECONF_OPTIONS) may be used to override the default automatic detection behavior. autogen.sh build preparation script by Christopher Sean Morrison + config.guess download patch by Sebastian Pipping (2008-12-03) revised 3-clause BSD-style license, copyright (c) 2005-2009 script version 20090301, ISO/IEC 9945 POSIX shell script --- Help was requested. No preparation or configuration will be performed.
  • 64.
    The autogen.sh script $ ./autogen.sh –verbose  Silent launch (default): Verbose output enabled Found a configure template: ./configure.ac Preparing the toe build system...please wait Checking autoreconf version: autoreconf --version $ ./autogen.sh Checking autoconf version: autoconf --version Preparing the toe build system...please wait Found GNU Autoconf version 2.67 Checking if 2.67.0 is greater than 2.52.0 Checking automake version: automake --version  Verbose launch Found GNU Automake version 1.11.1 Checking if 1.11.1 is greater than 1.6.0 Found GNU Autoconf version 2.67 Checking libtoolize version: libtoolize --version Found GNU Libtool version 2.2.6b Found GNU Automake version 1.11.1 Checking if 2.2.6 is greater than 1.4.2 Found GNU Libtool version 2.2.6b Checking aclocal version: aclocal --version Checking autoheader version: autoheader --version Checking whether to only output version information Automatically preparing build ... done Backing up COPYING in /home/gayetth/workspace/TOE cp -p COPYING COPYING.25605.protect_from_automake.backup Backing up INSTALL in /home/gayetth/workspace/TOE cp -p INSTALL INSTALL.25605.protect_from_automake.backup The toe build system is now prepared. To build here, run: Found an autom4te.cache directory, deleting it ./configure rm -rf autom4te.cache make mv -f "./config.guess" "./config.guess.backup" mv -f "./config.sub" "./config.sub.backup" mv -f "./ltmain.sh" "./ltmain.sh.backup" Automatically preparing build ... autoreconf -i -f libtoolize: putting auxiliary files in `.'. libtoolize: copying file `./config.guess' libtoolize: copying file `./config.sub' libtoolize: copying file `./install-sh' libtoolize: copying file `./ltmain.sh' libtoolize: Consider adding `AC_CONFIG_MACRO_DIR([m4])' to configure.ac and libtoolize: rerunning libtoolize, to keep the correct libtool macros in-tree. libtoolize: Consider adding `-I m4' to ACLOCAL_AMFLAGS in Makefile.am. rm -f COPYING.25605.protect_from_automake.backup Restoring INSTALL from backup (automake -f likely clobbered it) rm -f INSTALL mv INSTALL.25605.protect_from_automake.backup INSTALL rm -f INSTALL.25605.protect_from_automake.backup rm -f "./config.guess.backup" rm -f "./config.sub.backup" rm -f "./ltmain.sh.backup" done The toe build system is now prepared. To build here, run: ./configure make rm -f "./config.guess.backup" rm -f "./config.sub.backup" rm -f "./ltmain.sh.backup"
  • 65.
    The autogen.sh script Useful variables used to control the autogen.sh script : To skip autoreconf and prepare manually: AUTORECONF=false ./autogen.sh To verbosely try running with an older (unsupported) autoconf: AUTOCONF_VERSION=2.50 ./autogen.sh --verbose
  • 66.
    The autogen.sh script Impacton the autotools templates: If we take the decision to use the autogen.sh script instead of the single autoreconf command, this file is mandatorary to include in the tarball generated by the « make dist » command. EXTRA_DIST = $(top_builddir)/autogen.sh The autogen.sh script should be within the files of the project. If this file is not added the tarball will miss this file and won‘t be standalone!
  • 67.
    The environment AUTOGEN.SH LAB
  • 68.
    The autogen.sh script Takean autotools project and check the differential before and after the launch of the autogen.sh script.  Check with: autoreconf –i –force  Check with the autotools hierarchy poster provided.
  • 69.
    Using libtool The goalof this topic is to know how to uses libtool
  • 70.
    Using libtool  What libtool can do : GNU Libtool simplifies your job by encapsulating both the platform-specific dependencies, and the user interface, in a single script. GNU Libtool is designed so that the complete functionality of each host type is available via a generic interface, but nasty quirks are hidden from the programmer. GNU Libtool's consistent interface is reassuring... users don't need to read obscure documentation in order to have their favorite source package build shared libraries. They just run your package configure script (or equivalent), and libtool does all the dirty work.
  • 71.
    Using libtool  Libtoolis a tool used: The following issues need to be addressed in any reusable shared library system, specifically libtool: The package installer should be able to control what sort of libraries are built. It can be tricky to run dynamically linked programs whose libraries have not yet been installed. LD_LIBRARY_PATH must be set properly (if it is supported), or programs fail to run. The system must operate consistently even on hosts that don't support shared libraries. The commands required to build shared libraries may differ wildly from host to host. These need to be determined at configure time in a consistent way. It is not always obvious with what prefix or suffix a shared library should be installed. This makes it difficult for Makefile rules, since they generally assume that file names are the same from host to host.  Motivation for writing libtool : The system needs a simple library version number abstraction, so that shared libraries can be upgraded in place. The programmer should be informed how to design the interfaces to the library to maximize binary compatibility. The install Makefile target should warn the package installer to set the proper environment variables (LD_LIBRARY_PATH or equivalent), or run ldconfig. Since early 1995, several different GNU developers have recognized the importance of having shared library support for their packages. The primary motivation for such a change is to encourage modularity and reuse of code (both conceptually and physically) in GNU programs. Such a demand means that the way libraries are built in GNU packages needs to be general, to allow for any library type the package installer might want. The problem is compounded by the absence of a standard procedure for creating shared libraries on different platforms. The following sections outline the major issues facing shared library support in GNU, and how shared library support could be standardized with libtool. The following specifications were used in developing and evaluating this system: The system must be as elegant as possible. The system must be fully integrated with the GNU Autoconf and Automake utilities, so that it will be easy for GNU maintainers to use. However, the system must not require these tools, so that it can be used by non-GNU packages.
  • 73.
    Using libtool  Libtoolis a tool used: libtool [OPTION]... [MODE-ARG]...  Listing of the several modes available:
  • 74.
    Using libtool  TAGsavailable : The same tags can be overwritten in the autotool context (this often do in a cross-compilation mode): CC=sh4-linux-gcc CXX=sh4-linux-g++ ./configure --prefix=/usr …
  • 75.
    Using libtool  Compilationmode : $ libtool --mode=compile gcc -g -O -c foo.c gcc -g -O -c foo.c -o foo.o
  • 76.
    Using libtool  Linkmode : Link mode links together object files (including library objects) to form another library or to create an executable program. mode-args consist of a command using the C compiler to create an output file (with the -o flag) from several object files. The following components of mode-args are treated specially:
  • 77.
    Using libtool Link mode (cont)
  • 78.
    Using libtool Link mode (cont)
  • 79.
    Using libtool Link mode (cont) If the output-file ends in .la, then a libtool library is created, which must be built only from library objects (.lo files). The -rpath option is required. In the current implementation, libtool libraries may not depend on other uninstalled libtool libraries. If the output-file ends in .a, then a standard library is created using ar and possibly ranlib. If output-file ends in .o or .lo, then a reloadable object file is created from the input files (generally using ‗ld -r‘). This method is often called partial linking. Otherwise, an executable program is created.
  • 80.
    Using libtool  Executionmode : For execute mode, the library path is automatically set, then a program is executed. The first of the mode-args is treated as a program name, with the rest as arguments to that program. The following components of mode-args are treated specially: If any of the args are libtool executable wrappers, then they are translated into the name of their corresponding uninstalled binary, and any of their required library directories are added to the library path.
  • 81.
    Using libtool  Installationmode : In install mode, libtool interprets most of the elements of mode-args as an installation command beginning with cp, or a BSD-compatible install program. The following components of mode-args are treated specially: -inst-prefix-dir inst-prefix-dir When installing into a temporary staging area, rather than the final prefix, this argument is used to reflect the temporary path, in much the same way automake uses DESTDIR. For instance, if prefix is /usr/local, but inst-prefix-dir is /tmp, then the object will be installed under /tmp/usr/local/. If the installed object is a libtool library, then the internal fields of that library will reflect only prefix, not inst-prefix-dir: # Directory that this library needs to be installed in: libdir='/usr/local/lib' not # Directory that this library needs to be installed in: libdir='/tmp/usr/local/lib‗ inst-prefix is also used to insure that if the installed object must be relinked upon installation, that it is relinked against the libraries in inst-prefix- dir/prefix, not prefix. In truth, this option is not really intended for use when calling libtool directly; it is automatically used when libtool --mode=install calls libtool -- mode=relink. Libtool does this by analyzing the destination path given in the original libtool --mode=install command and comparing it to the expected installation path established during libtool --mode=link. Thus, end-users need change nothing, and automake-style make install DESTDIR=/tmp will Just Work(tm) most of the time. For systems where fast installation can not be turned on, relinking may be needed. In this case, a ‗DESTDIR‘ install will fail. Currently it is not generally possible to install into a temporary staging area that contains needed third-party libraries which are not yet visible at their final location. The rest of the mode-args are interpreted as arguments to the cp or install command.
  • 82.
    Using libtool  Finishmode : Finish mode has two functions. One is to help system administrators install libtool libraries so that they can be located and linked into user programs. To invoke this functionality, pass the name of a library directory as mode-arg: The second is to facilitate transferring libtool libraries to a native compilation environment after they were built in a cross-compilation environment. Cross-compilation environments may rely on recent libtool features, and running libtool in finish mode will make it easier to work with older versions of libtool. This task is performed whenever the mode-arg is a .la file.
  • 83.
    Using libtool  Uninstallmode : Uninstall mode deletes installed libraries, executables and objects. The first mode-arg is the name of the program to use to delete files (typically /bin/rm). The remaining mode-args are either flags for the deletion program (beginning with a ‗-‘), or the names of files to delete.
  • 84.
    Using libtool  Cleanmode : Clean mode deletes uninstalled libraries, executables, objects and libtool's temporary files associated with them. The first mode-arg is the name of the program to use to delete files (typically /bin/rm). The remaining mode-args are either flags for the deletion program (beginning with a ‗-‘), or the names of files to delete.
  • 85.
    Using libtool LIBTOOL LAB
  • 86.
    Using libtool The goalof this lab is to understand what libtool is really working. Try to compile a helloworld.c source code by the two way: gcc –c helloworld.c –o helloworld.o Libtool --mode=compile gcc -c helloworld.c Same for the link step (should create a helloworld binary): gcc helloworld.o –o helloworld libtool --mode=link gcc –o helloworld helloworld.o
  • 87.
    The configure.{ac/in} template Thegoal of this topic is to know how to write a configure.ac template.
  • 88.
    The configure.{in/ac} template A configure.ac is the template of the configure script that will be used by the end user.  A configure.ac is written using M4 macros while a configure script is a shell script.  The main goal of a configure script is to lead the configuration of a component. The several flags provided to the configure script is like the ID card of the build. The configure.ac teamplate is equal to the configure.in that is the old notation. Those script are executed like shell script at the runtime (no compiled). Can build libraries, binaries, … in the same files, by managing dependencies.
  • 90.
    The configure.{in/ac} template Preset Output Variables :  Beware about all directories, because they can be override by configure options: ./configure – prefix=/usr –srcdir=/tmp_srcdir … If so, top_builddir can be different to top_srcdir and bring link problems, so be carefull !!
  • 91.
    The configure.{in/ac} template  Flags overriding : http://www.gnu.org/software/hello/manual/autoconf/Preset-Output-Variables.html
  • 92.
    The configure.{in/ac} template  Tools overriding : Examples: ./configure –prefix=/usrCC=gcc CFLAGS=-O3 LIBS=―-lposix‖ … or CC=sh4-linux-gcc AR=sha-linux-g++ ./configure –prefix=/usr …
  • 93.
    The configure.{in/ac} template Special Characters in Output Variables : Many output variables are intended to be evaluated both by make and by the shell. Some characters are expanded differently in these two contexts, so to avoid confusion these variables' values should not contain any of the following characters: " # $ & ' ( ) * ; < > ? [ ^`| Also, these variables' values should neither contain newlines, nor start with ‗~‘, nor contain white space or ‗:‘ immediately followed by ‗~‘. The values can contain nonempty sequences of white space characters like tabs and spaces, but each such sequence might arbitrarily be replaced by a single space during substitution. These restrictions apply both to the values that configure computes, and to the values set directly by the user. For example, the following invocations of configure are problematic, since they attempt to use special characters within CPPFLAGS and white space within $(srcdir): CPPFLAGS='-DOUCH="&"#$*?"' '../My Source/ouch-1.0/configure' '../My Source/ouch-1.0/configure' CPPFLAGS='-DOUCH="&"#$*?"'
  • 94.
    The configure.{in/ac} template Some of the useful built-in M4 macros: There are many others ; check the gnu/autoconf manual for more Information (http://www.gnu.org/software/autoconf/manual/autoconf.pdf).
  • 97.
    The configure.{in/ac} template Printing messages : Configure scripts need to give users running them several kinds of information. The following macros print messages in ways appropriate for each kind. The arguments to all of them get enclosed in shell double quotes, so the shell performs variable and back-quote substitution on them. These macros are all wrappers around the echo shell command. They direct output to the appropriate file descriptor:  Macro: AC_MSG_CHECKING (feature-description) Notify the user that configure is checking for a particular feature. This macro prints a message that starts with ‗checking ‘ and ends with ‗...‘ and no newline. It must be followed by a call to AC_MSG_RESULT to print the result of the check and the newline. The feature-descriptionshould be something like „whether the Fortran compiler accepts C++ comments‟ or „for c89‟. This macro prints nothing if configure is run with the --quiet or --silent option. This is quite similar to a echo -n.  Macro: AC_MSG_RESULT (result-description) Notify the user of the results of a check. result-description is almost always the value of the cache variable for the check, typically „yes‟, „no‟, or a file name. This macro should follow a call to AC_MSG_CHECKING, and the result- description should be the completion of the message printed by the call to AC_MSG_CHECKING. This macro prints nothing if configure is run with the --quiet or --silent option. This is quite similar to an echo after an echo -n, so it will be in the same line. Example: AC_MSG_CHECKING(“Checking something”) (…) Something tested here…The result is a boolean variable such as « bchkSomething » (…) AC_MSG_RESULT(bchkSomething)
  • 98.
    The configure.{in/ac} template Macros used for traces :  Macro: AC_MSG_NOTICE (message) Deliver the message to the user. It is useful mainly to print a general description of the overall purpose of a group of feature checks, e.g., AC_MSG_NOTICE([checking if stack overflow is detectable]). This macro prints nothing if configure is run with the --quiet or --silent option.  Macro: AC_MSG_ERROR (error-description, [exit-status = „$?/1‟]) Notify the user of an error that prevents configure from completing. This macro prints an error message to the standard error output and exits configure with exit-status („$?‟ by default, except that „0‟ is converted to „1‟). error- description should be something like „invalid value $HOME for $HOME‟. The error-description should start with a lower-case letter, and “cannot” is preferred to “can't”.  Macro: AC_MSG_FAILURE (error-description, [exit-status]) This AC_MSG_ERROR wrapper notifies the user of an error that prevents configure from completing and that additional details are provided in config.log. This is typically used when abnormal results are found during a compilation. Examples: AC_MSG_NOTICE(“this is just a message”)
  • 99.
    The configure.{in/ac} template Initialisation of the configure script (including the requirements) : The Autoconf language differs from many other computer languages because it treats actual code the same as plain text. Whereas in C, for instance, data and instructions have different syntactic status, in Autoconf their status is rigorously the same. Therefore, we need a means to distinguish literal strings from text to be expanded: quotation. When calling macros that take arguments, there must not be any white space between the macro name and the open parenthesis. AC_INIT([hello], [1.0]) # good Arguments should be enclosed within the quote characters ‗[‘ and ‗]‘, and be separated by commas. Any leading blanks or newlines in arguments are ignored, unless they are quoted. You should always quote an argument that might contain a macro name, comma, parenthesis, or a leading blank or newline. This rule applies recursively for every macro call, including macros called from other macros.  AC_COPYRIGHT (copyright-notice) State that, in addition to the Free Software Foundation's copyright on the Autoconf macros, parts of your configure are covered by the copyright-notice. The copyright-notice shows up in both the head of configure and in ‗configure --version‘.  Some are mandatory : o AC_INIT([pyPackage], [myPackageVersion], [thierry.gayet2@technicolor.com])  initializes autoconf with information about your project, including the project name, version number, bug-reporting address, tarball name and the project homepage. o AC_PREREQ(2.59)  specify the autoconf version  Others are not : o AC_AUTOMAKE()  adds several standard checks and initializes automake. • AM_INIT_AUTOMAKE([1.10 no-define]) •AM_INIT_AUTOMAKE([1.10 no-define foreign])  specify that the component won‘t use the GNU file (NEWS
  • 100.
    The configure.{in/ac} template  PATH and source code definition : AC_CONFIG_SRCDIR(unique-file-in-source-dir) unique-file-in-source-dir is some file that is in the package's source directory; configure checks for this file's existence to make sure that the directory that it is told contains the source code in fact does. Occasionally people accidentally specify the wrong directory with -- srcdir; this is a safety check. Packages that do manual configuration or use the install program might need to tell configure where to find some other shell scripts by calling AC_CONFIG_AUX_DIR, though the default places it looks are correct for most cases. AC_CONFIG_AUX_DIR(dir) Use the auxiliary build tools (e.g., install-sh, config.sub, config.guess, Cygnus configure, Automake and Libtool scripts, etc.) that are in directory dir. These are auxiliary files used in configuration. dir can be either absolute or relative to srcdir. The default is srcdir or srcdir/.. or srcdir/../.., whichever is the first that contains install-sh. The other files are not checked for, so that using AC_PROG_INSTALL does not automatically require distributing the other auxiliary files. It checks for install.sh also, but that name is obsolete because some make have a rule that creates install from it if there is no makefile. The auxiliary directory is commonly named build-aux. If you need portability to DOS variants, do not name the auxiliary directory aux. AC_REQUIRE_AUX_FILE(file) Declares that file is expected in the directory defined above. In Autoconf proper, this macro does nothing: its sole purpose is to be traced by third-party tools to produce a list of expected auxiliary files. For instance it is called by macros like AC_PROG_INSTALL (see Particular Programs) or AC_CANONICAL_BUILD (see Canonicalizing) to register the auxiliary files they need. Similarly, packages that use aclocal should declare where local macros can be found using AC_CONFIG_MACRO_DIR. AC_CONFIG_MACRO_DIR(dir) Specify dir as the location of additional local Autoconf macros. This macro is intended for use by future versions of commands like autoreconf that trace macro calls. It should be called directly from configure.ac so that tools that install macros for aclocal can find the macros' declarations. Note that if you use aclocal from Automake to generate aclocal.m4, you must also set ACLOCAL_AMFLAGS = -I dir in your top-level Makefile.am. Due to a limitation in the Autoconf implementation of autoreconf, these include directives currently must be set on a single line in Makefile.am, without any backslash-newlines.
  • 101.
    The configure.{in/ac} template Checking for specific headers:  AC_CHECK_HEADERS([unistd.h]) Then you could have code like the following in conf.h.in. The conf.h created by configure defines ‗HAVE_UNISTD_H‘ to 1, if and only if the system has unistd.h. /* Define as 1 if you have unistd.h. */ #undef HAVE_UNISTD_H The format of the template file is stricter than what the C preprocessor is required to accept. A directive line should contain only whitespace, ‗#undef‘, and ‗HAVE_UNISTD_H‘. The use of ‗#define‘ instead of ‗#undef‘, or of comments on the same line as ‗#undef‘, is strongly discouraged. Each hook should only be listed once. Other preprocessor lines, such as ‗#ifdef‘ or ‗#include‘, are copied verbatim from the template into the generated header.
  • 102.
    The configure.{in/ac} template  Default prefix : By default, configure sets the prefix for files it installs to /usr/local. The user of configure can select a different prefix using the -- prefix and --exec-prefix options. There are two ways to change the default: when creating configure, and when running it. Some software packages might want to install in a directory other than /usr/local by default. To accomplish that, use the AC_PREFIX_DEFAULT macro.  AC_PREFIX_DEFAULT(prefix) Set the default installation prefix to prefix instead of /usr/local. It may be convenient for users to have configure guess the installation prefix from the location of a related program that they have already installed. If you wish to do that, you can call AC_PREFIX_PROGRAM.  AC_PREFIX_PROGRAM(program) If the user did not specify an installation prefix (using the --prefix option), guess a value for it by looking for program in PATH, the way the shell does. If program is found, set the prefix to the parent of the directory containing program, else default the prefix as described above (/usr/local or AC_PREFIX_DEFAULT). For example, if program is gcc and the PATH contains /usr/local/gnu/bin/gcc, set the prefix to /usr/local/gnu. For example, if the AC_PREFIX_DEFAULT(/usr) is defined within a configure.ac, it won‘t be mandatory to specify the prefix at the configure launch. If not we should mantadory specify the prefix: ./configure --prefix=/usr
  • 103.
    The configure.{in/ac} template In order to prevent autotools re-generating configure script automatically this is possible to specify that we are in maintainer mode : Sometimes due to the SCM not strictly remembering the timestamp of files the generated Makefile will think that it needs to re-run "autoreconf -i" or equivalent to re-generate Makefile.in from Makefile.am, configure from configure.ac, etc. You need to look into maintainer mode - that should prevent the autoreconf step, which will fix the end-users' problems. In order to proceed, the following line should be add to the configure.ac: AM_MAINTAINER_MODE Or provide set the --enable-maintainer-mode parameter to the configure script : ./configure --prefix=/usr --enable-maintainer-mode
  • 105.
    The configure.{in/ac} template Theversion scheme used by Libtool tracks interfaces, where an interface is the set of exported entry points into the library. All Libtool libraries start with `-version-info' set to `0:0:0' -- this will be the default version number if you don't explicitly set it on the Libtool link command line. The meaning of these numbers (from left to right) is as follows:  Beware, this can generate a warning if you want to generate a static library.
  • 107.
    The configure.{in/ac} template  Example of Makefile.am template that use the version: lib_LTLIBRARIES = libtoe.la libtoe_la_SOURCES = src/toe_assert.c src/toe_memory.c src/toe_thread.c src/toe_messageQueue.c inc/utlist.h inc/internal_api.h inc/internal_config.h libtoe_la_CFLAGS = -I$(HEADER_DIR)  Makefile.am $(LIBCONFIG_CFLAGS) $(LIBLOG_CFLAGS) -DLOG_NAME=TOE -DLOG_MASK_PRIO=LOG_PRIO_ALL libtoe_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -lpthread -lrt
  • 110.
    The configure.{in/ac} template Managing subdirs using AC_CONFIG_SUBDIRS (dir ...) Make AC_OUTPUT run configure in each subdirectory dir in the given blank-or-newline-separated list. Each dir should be a literal, i.e., please do not use: if test "x$package_foo_enabled" = xyes; then my_subdirs="$my_subdirs foo" fi AC_CONFIG_SUBDIRS([$my_subdirs]) because this prevents ‗./configure --help=recursive‘ from displaying the options of the package foo. Instead, you should write: if test "x$package_foo_enabled" = xyes; then AC_CONFIG_SUBDIRS([foo]) fi If a given dir is not found at configure run time, a warning is reported; if the subdirectory is optional, write: if test -d "$srcdir/foo"; then AC_CONFIG_SUBDIRS([foo]) fi  If a given dir contains configure.gnu, it is run instead of configure. This is for packages that might use a non-Autoconf script Configure, which can't be called through a configure wrapper since it would be the same file on case-insensitive file systems.  Likewise, if a dir contains configure.in but no configure, the Cygnus configure script found by AC_CONFIG_AUX_DIR is used.
  • 111.
    The configure.{in/ac} template Some operations are accomplished in several possible ways, depending on the OS variant. Checking for them essentially requires a ―case statement‖. Autoconf does not directly provide one; however, it is easy to simulate by using a shell variable to keep track of whether a way to perform the operation has been found yet.  Here is an example that uses the shell variable fstype to keep track of whether the remaining cases need to be checked. Note that since the value of fstype is under our control, we don't have to use the longer ‗test "x$fstype" = xno‘. AC_MSG_CHECKING([how to get file system type]) fstype=no # The order of these tests is important. AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/statvfs.h> #include <sys/fstyp.h>]])], [AC_DEFINE([FSTYPE_STATVFS], [1], [Define if statvfs exists.]) fstype=SVR4]) if test $fstype = no; then AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/statfs.h> #include <sys/fstyp.h>]])], [AC_DEFINE([FSTYPE_USG_STATFS], [1], [Define if USG statfs.]) fstype=SVR3]) fi if test $fstype = no; then AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/statfs.h> #include <sys/vmount.h>]])]), [AC_DEFINE([FSTYPE_AIX_STATFS], [1], [Define if AIX statfs.]) fstype=AIX]) fi # (more cases omitted here) AC_MSG_RESULT([$fstype])
  • 112.
    The configure.{in/ac} template  Creating variables exported to the Makefiles : AC_DEFINE (variable, value, [description]) AC_DEFINE (variable) Define variable to value (verbatim), by defining a C preprocessor macro for variable. variable should be a C identifier, optionally suffixed by a parenthesized argument list to define a C preprocessor macro with arguments. The macro argument list, if present, should be a comma-separated list of C identifiers, possibly terminated by an ellipsis ‗...‘ if C99 syntax is employed. variable should not contain comments, white space, trigraphs, backslash-newlines, universal character names, or non-ASCII characters. value may contain backslash-escaped newlines, which will be preserved if you use AC_CONFIG_HEADERS but flattened if passed via @DEFS@ (with no effect on the compilation, since the preprocessor sees only one line in the first place). value should not contain raw newlines. If you are not using AC_CONFIG_HEADERS, value should not contain any ‗#‘ characters, as make tends to eat them. To use a shell variable, use AC_DEFINE_UNQUOTED instead. description is only useful if you are using AC_CONFIG_HEADERS. In this case, description is put into the generated config.h.in as the comment before the macro define. The following example defines the C preprocessor variable EQUATION to be the string constant ‗"$a > $b"‘: AC_DEFINE([EQUATION], ["$a > $b"], [Equation string.]) If neither value nor description are given, then value defaults to 1 instead of to the empty string. This is for backwards compatibility with older versions of Autoconf, but this usage is obsolescent and may be withdrawn in future versions of Autoconf. If the variable is a literal string, it is passed to m4_pattern_allow. If multiple AC_DEFINE statements are executed for the same variable name (not counting any parenthesized argument list), the last one wins.
  • 113.
    The configure.{in/ac} template AC_DEFINE_UNQUOTED(variable, value, [description]) AC_DEFINE_UNQUOTED (variable) Like AC_DEFINE, but three shell expansions are performed—once—on variable and value: variable expansion (‗$‘), command substitution (‗`‘), and backslash escaping (‗‘), as if in an unquoted here-document. Single and double quote characters in the value have no special meaning. Use this macro instead of AC_DEFINE when variable or value is a shell variable. Examples: AC_DEFINE_UNQUOTED([config_machfile], ["$machfile"], [Configuration machine file.]) AC_DEFINE_UNQUOTED([GETGROUPS_T], [$ac_cv_type_getgroups], [getgroups return type.]) AC_DEFINE_UNQUOTED([$ac_tr_hdr], [1], [Translated header name.]) Due to a syntactical bizarreness of the Bourne shell, do not use semicolons to separate AC_DEFINE or AC_DEFINE_UNQUOTED calls from other macro calls or shell code; that can cause syntax errors in the resulting configure script. Use either blanks or newlines. That is, do this: AC_CHECK_HEADER([elf.h], [AC_DEFINE([SVR4], [1], [System V Release 4]) LIBS="-lelf $LIBS"]) or this: AC_CHECK_HEADER([elf.h], [AC_DEFINE([SVR4], [1], [System V Release 4]) LIBS="-lelf $LIBS"]) instead of this:
  • 114.
    The configure.{in/ac} template AC_SUBST(variable, [value]) Create an output variable from a shell variable. Make AC_OUTPUT substitute the variable variable into output files (typically one or more makefiles). This means that AC_OUTPUT replaces instances of ‗@variable@‘ in input files with the value that the shell variable has when AC_OUTPUT is called. The value can contain any non-NUL character, including newline. If you are using automake 1.11 or newer, for newlines in values you might want to consider using AM_SUBST_NOTMAKE to prevent automake from adding a line variable = @variable@ to the Makefile.in files (see automake). Variable occurrences should not overlap: e.g., an input file should not contain ‗@var1@var2@‘ if var1 and var2 are variable names. The substituted value is not rescanned for more output variables; occurrences of ‗@variable@‘ in the value are inserted literally into the output file. (The algorithm uses the special marker |#_!!_#| internally, so neither the substituted value nor the output file may contain |#_!!_#|.) If value is given, in addition assign it to variable. All the variables defined by : •AC_SUBST() •AC_DEFINED_*() •AM_CONDITIONAL() •… can be used in the Makefile.am.
  • 115.
    The configure.{in/ac} template AM_CONDITIONAL(conditional, condition): The conditional name, conditional, should be a simple string starting with a letter and containing only letters, digits, and underscores. It must be different from ‗TRUE‘ and ‗FALSE‘ that are reserved by automake. The shell condition (suitable for use in a shell if statement) is evaluated when configure is run. Note that you must arrange for every AM_CONDITIONAL to be invoked every time configure is run. If AM_CONDITIONAL is run conditionally (e.g., in a shell if statement), then the result will confuse automake. Conditionals typically depend upon options that the user provides to the configure script. Here is an example of how to write a conditional that is true if the user uses the --enable-debug option. AC_ARG_ENABLE([debug], [ --enable-debug Turn on debugging], [case "${enableval}" in yes) debug=true ;; no) debug=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;; esac],[debug=false]) AM_CONDITIONAL([DEBUG], [test x$debug = xtrue]) Here is an example of how to use that conditional in Makefile.am: if DEBUG DBG = debug_program else DBG = endif noinst_PROGRAMS = $(DBG)
  • 116.
    The configure.{in/ac} template AM_COND_IF(conditional, [if-true], [if-false]) If conditional is fulfilled, execute if-true, otherwise execute if-false. If either branch contains AC_CONFIG_FILES, it will cause automake to output the rules for the respective files only for the given condition. AM_COND_IF macros may be nested when m4 quotation is used properly (see M4 Quotation). Here is an example of how to define a conditional config file: AM_CONDITIONAL([SHELL_WRAPPER], [test "x$with_wrapper" = xtrue]) AM_COND_IF([SHELL_WRAPPER], [AC_CONFIG_FILES([wrapper:wrapper.in])])
  • 118.
    The configure.{in/ac} template AC_ARG_WITH(package, help-string, [action-if-given], [action-if-not-given]) If the user gave configure the option --with-package or --without-package, run shell commands action-if-given. If neither option was given, run shell commands action-if-not-given. The name package indicates another software package that this program should work with. It should consist only of alphanumeric characters, dashes, plus signs, and dots. The option's argument is available to the shell commands action-if-given in the shell variable with val, which is actually just the value of the shell variable named with_package, with any non-alphanumeric characters in package changed into ‗_‘. You may use that variable instead, if you wish. The argument help-string is a description of the option that looks like this: --with-readline support fancy command line editing AC_ARG_WITH([readline], help-string may be more than one line long, if more detail is needed. Just make sure the columns line up in ‗configure --help‘. Avoid [AS_HELP_STRING([--without-readline], tabs in the help string [disable support for readline])], [], [with_readline=yes]) LIBREADLINE= AS_IF([test "x$with_readline" != xno], [AC_CHECK_LIB([readline], [main], [AC_SUBST([LIBREADLINE], ["-lreadline -lncurses"]) AC_DEFINE([HAVE_LIBREADLINE], [1], [Define if you have libreadline]) ], [AC_MSG_FAILURE( [readline test failed (--without-readline to disable)])], [-lncurses])])
  • 121.
    The configure.{in/ac} template ConfiguringOther Packages in Subdirectories In most situations, calling AC_OUTPUT is sufficient to produce makefiles in subdirectories. However, configure scripts that control more than one independent package can use AC_CONFIG_SUBDIRS to run configure scripts for other packages in subdirectories.  AC_CONFIG_SUBDIRS(dir ...) Make AC_OUTPUT run configure in each subdirectory dir in the given blank-or-newline-separated list. Each dir should be a literal, i.e., please do not use: if test "x$package_foo_enabled" = xyes; then my_subdirs="$my_subdirs foo" fi AC_CONFIG_SUBDIRS([$my_subdirs]) because this prevents ‗./configure --help=recursive‘ from displaying the options of the package foo. Instead, you should write: if test "x$package_foo_enabled" = xyes; then AC_CONFIG_SUBDIRS([foo]) fi If a given dir is not found at configure run time, a warning is reported; if the subdirectory is optional, write: if test -d "$srcdir/foo"; then AC_CONFIG_SUBDIRS([foo]) fi If a given dir contains configure.gnu, it is run instead of configure. This is for packages that might use a non-Autoconf script Configure, which can't be called through a wrapper configure since it would be the same file on case-insensitive file systems. Likewise, if a dir containsconfigure.in but no configure, the Cygnus configure script found by AC_CONFIG_AUX_DIR is used.The subdirectory configure scripts are given the same command line options that were given to this configure script, with minor changes if needed, which include: · adjusting a relative name for the cache file; · adjusting a relative name for the source directory; · propagating the current value of $prefix, including if it was defaulted, and if the default values of the top level and of the subdirectory configure differ.This macro also sets the output variable subdirs to the list of directories ‗dir ...‟. Make rules can use this variable to determine which subdirectories to recurse into.This macro may be called multiple times.
  • 122.
    The configure.{in/ac} template Generatingfinal files : It can be Makefiles, .pc files, config.h headers and so on : AC_CONFIG_FILES([ Makefile src/Makefile  New format foo.pc ]) AC_OUTPUT It can be Makefiles, .pc files, config.h headers and so on : AC_OUTPUT([ Makefile src/Makefile  Old deprecated format foo.pc ])  Both format are functional. The first one is the best format. It is the new one with new being relative because it has been that way for a while. The last one is the old format from way long ago.
  • 123.
  • 124.
    The configure.{in/ac} template Themain goal for this lab is to write a basic configure that : Check the C compiler Check Some standard headers Generate a Makefile in output In case of problems with configure, you can consult the ―config.log‖ file that may provide more information about an Autotools problem. Read the ./configure --help to know all the parameters that can be used by this script.
  • 125.
    The Makefile.am template Thegoal of this topic is to know how to write a Makefile.am template.
  • 126.
    The Makefile.am templates Amakefile.am template will use a context prepared by the configure script.  This is the second most important template after the configure.ac. A GNU/Makefile can support more than one target.  According to the final binary to build (binary, library, … ), the Makefile will run them one by one in the same order than written in the template. As seen before, Makefile.am are generic template ready for a conversion into a Makefile.in  The Makefile.in, contains variables between arobases in order to make the update by the configure script easy to do.
  • 130.
    The Makefile.am templates Template definition for binaries and libraries :
  • 131.
  • 132.
  • 134.
    The Makefile.am templates Variables used when building a program : Occasionally it is useful to know which `Makefile' variables Automake uses for compilations; for instance you might need to do your own compilation in some special cases. Some variables are inherited from Autoconf; these are CC, CFLAGS, CPPFLAGS, DEFS, LDFLAGS, and LIBS.  There are some global additional variables which Automake itself defines:  This impact all components from the Makefile.am (binary, libarry, … )
  • 135.
  • 136.
    The Makefile.am templates Themain goal for this lab is to : 1.Write a Makefile.am that will call another Makefile located into a src directory 1.In this second Makefile.am, just generate a binary from a helloworld.c. 1.Managed them using a single configure.ac
  • 137.
    Using the librarytemplate The goal of this topic is to know how to generate static/dynamic libraries.
  • 138.
    Using the librarytemplate  Autotools template make the makefile standard and portable. Writting a library is quite identical as a binary. A library either static or dynamic should also export its public api: <STAGINGDIR>/<PREFIX>/include/  public headers <STAGINGDIR>/<PREFIX>/include/prefix/  metadata (.pc files) <STAGINGDIR>/<PREFIX>/lib/  static and/o By default, the configure script generate both a static and dynamic library: This is possible so specify just one type: ./configure --disable-static : generate only a dynamic one ./configure –disable-dynamic : force to generate only a static one
  • 146.
    Using the librarytemplate  Linking with a mix of shared and static libraries By default, the linker will link against the shared libraries if they are available. If the -static flag is given, the linker will try to use static libraries instead of dynamic one. But -Bdynamic and -Bstatic provides finer control of which library, shared or static should searched for each library specified for the linker. The library search option is toggled by each -Bdynamic or -Bstatic: ld ... -Bstatic -lfoo -Bdynamic -lbar .... This command tells the linker to search the static library for libfoo, and search the shared version for libbar and any libraries after it until a -Bstatic is seen. To pass the -Bdynamic and -Bstatic options to the linker, one needs to do gcc -o main main.o -Wl,-Bstatic -lfoo -Wl,-Bdynamic –lbar Since the gcc driver calls the linker with some default libraries, gcc -o main main.o -Wl,-Bstatic tells the linker to use the static versions for all default libraries like libc and etc. http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
  • 148.
    Using the librarytemplate  Memory slicing with dynamic libraries : Dynamic libraries are mapped by the dynamic linker in the process address space, CODE BSS All processes share the same dynamic library code segment, HEAP CODE LIB 1 Each dynamic library data segment is of course per process, DATA CODE  Each dynamic library data size must be counted in the process memory LIB 2 consumption. DATA Stack
  • 149.
    Using the librarytemplate Now with the autotools 
  • 151.
    Using the librarytemplate This is possible to force the generation of a static library in case of a Makefile that generate a static one before to link with : noinst_lib_LTLIBRARIES = libfoo.la The binary will be link using the internal LDFALGS. Nb : the noinst prefix say that the library won‘t be install by the make install command. The following prefix are accepted : check_LTLIBRARIES : generate a library for unitary tests noinst_LTLIBRARIES : generate a library for local usage (won‘t be installed)
  • 152.
    Using the librarytemplate LIBRARY LAB
  • 153.
    Using the librarytemplate  The main goal of this lab is to generate a library. The library have two source code lib01.c and lib02.c located into a src directory.  The configure script should managed the version. A single Makefile should be able to compile either a static or a dynamic one.
  • 154.
    Using the applicationtemplate The goal of this topic is to know how to generate binaries.
  • 155.
    Using the applicationtemplate As well as for the library, binaries can accept some prefix : check_PROGRAM : generate a binary for the unitary tests noinst_PROGRAM : generate a binary for local usage (won‘t be installed)  Internal link flags should be given to the LDFLAGS one. That‘s include internal static library.  External link flags should be given to the LDADD one. That‘s include all dependencies checked by the PKG_CHECK_MODULE M4 macro
  • 156.
    Using the applicationtemplate  Example of template used for a binary template : bin_PROGRAMS = foo foo_SOURCES = main.c foo_SOURCES = main.c foo_LDADD = libfoo.la @FLIBS@ pkglib_LTLIBRARIES = libfoo.la libfoo_la_SOURCES = bar.f baz.c zardoz.cc libfoo_la_LIBADD = $(FLIBS)
  • 157.
    Using the applicationtemplate  From Executable Binary to Process Memory Map : 0x0 Elf Header 0x400000 Code Code size Code 0x10000000 Padding Initialized Data Size Data (not 0) Initialized Data Data set to 0 (BSS) Statically Linked Heap Dyn Lib info Mono-thread DWARF EOF Debug Info Simple Case Process Stack Executable file Not loaded Memory Map in memory  The header is not load in memory as defined in this picture because it gives information about the binary format; for instance it say at which memory address the code must be loaded.
  • 158.
    Using the applicationtemplate  The multi-threaded case :  Multiple threads share the entire process address space CODE  Each thread has its own user space stack that is allocated when doing DATA pthread_create system call. If stack size is not given, a default value is used. BSS Be Careful: on x86 and NPTL POSIX thread implementation this means 8 Mb. This is the HEAP same value for default process stack size. Thread #1 Stack Always specify the stack size, . . .  Try to kill the system created initial thread after creating your own init thread, Thread #1 Stack
  • 159.
    Using the applicationtemplate Example of result for a process with threads   Stack per thread.
  • 160.
    Using the applicationtemplate APPLICATION LAB
  • 161.
    Using the applicationtemplate The main goal for this lab is to: 1.First, generate a foobin binary from a foobin.c source code. You will have to write a configure.ac and a Makefile.am. 1.Second, generate a library foolib from a foolib.c source code. You will have to write a configure.ac and a Makefile.am 1.Third, merge the two configure.ac and Makefile.am The library should compile first as a static library then link with the binary.
  • 162.
    The config.h support Thegoal of this topic is to know how works the global config.h configuration header
  • 165.
    The config.h header  Impact on the configure.ac template : The AC_CONFIG_HEADERS([config.h]) M4 macro indicates that we will use a config.h header file. The generated header is included by your source code to pick up the results of the various configuration tests in the form of C preprocessor macro definitions. Every variable exported by the configure script through M4 macro (PKG_CHECK_MODULES(), AC_DEFINE(), AC_SUBST(), … ) will be set inside. The template file config.h.in can also be generated automatically by the autoheader tool. autoreconf will invoke autoheader when AC_CONFIG_HEADERS is used in configure.ac. If multiple configuration headers are used, autoheader will always only generate the template for the first one in the list. Example of usage in a configure.ac template (…) dnl --------------------------------------- dnl Specify the internal toe_config.h dnl --------------------------------------- AC_CONFIG_HEADERS([inc/internal_config.h]) (..) That will generate a header called « internal_config.h » in the « inc » directory. Its content will include both all the boolean result of the internal check and also the custom checks made by Component itself.
  • 166.
    The config.h header Impact on the Makefile.am template : lib_LTLIBRARIES = libtoe.la libtoe_la_SOURCES = src/toe_assert.c src/toe_memory.c src/toe_thread.c src/toe_messageQueue.c inc/utlist.h inc/internal_api.h inc/internal_config.h libtoe_la_CFLAGS = -I$(HEADER_DIR) $(LIBCONFIG_CFLAGS) $(LIBLOG_CFLAGS) -DLOG_NAME=TOE  Even if the config.h (here internal_config.h) is well include by the source code, this is important -DLOG_MASK_PRIO=LOG_PRIO_ALL libtoe_la_LDFLAGS the Makefile in = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) to specify it in order to include this dynamic file in the tarball generated by a make dist. -lpthread
  • 167.
    The config.h header Config.h or not config.h that is the question… Without config.h : With config.h :  Every flags will be provided to the compiler  The command line is more silent. over the command line (can be quite huge)  The config.h is the ID card of the build because  Easy to manage with existent component it defines all the activator, values, used during the (don‘t need any modification for the header compilation. Import).  That need to import this header in all source  The development process can check the code (.c, .cpp, .cxx, …) or within a top header. The variables either in this config.h header or inclusion should be secured like this : through the command line. #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */
  • 168.
  • 169.
    The config.h header Themain goal of this lab is to write one autotool project without any config.h and another with that support. Compare the command line for the two build using « make v=1»
  • 170.
    The config.h header More help about : http://www.gnu.org/software/automake/manual/html_node/Optional.ht ml#index-AC_005fCONFIG_005fHEADERS-219
  • 171.
    The silent/verbose support Thegoal of this topic is to know how works to manage the silent/verbose support
  • 172.
    Managing silent/verbose support Whena big build is launch it can be nice to do not have too much traces In the console screen. The autotools can control the silent/verbose mode. If the silent mode is selected, no build or warning traces won‘t be written to stdio (err/out).  Only errors will be displayed in detail and will stop the build process.
  • 175.
    Managing silent/verbose support Oncethe silent/verbose mode have been choosen by the configure script, this Is possible to override it thanks to the « V » parameter:  Silent mode selected by the configure script: o Silent mode : make o Verbose mode : make V=1  Verbose mode selected by the configure script: o Silent mode : make V=0 o Verbose mode : make  This is possible to tune more the silent/verbose mode: $ export LIBTOOLFLAGS "--silent“ $ make –s
  • 176.
  • 177.
    Managing silent/verbose support The main goal of this lab is to add a verbose support by adding the –enable-verbose.  The default state must be silent.
  • 178.
    Managing dependencies withthe pkg-config tool The goal of this topic is to know how a pkgconfig file (.pc) are managed and how to use the pkg-config tool.
  • 179.
    The pkg-config tool The PKG- CONFIG tool (aka PaCKage CONFIGgurator)
  • 180.
    The pkg-config tool Thepkg-config is a helper tool used when compiling applications and libraries. It helps you insert the correct compiler options rather than hard-coding values on where to find glib (or other libraries). It is language-agnostic, so it can be used for defining the location of documentation tools, for instance. It works fine both with native and cross-compile environnement. The program is free software and licensed under the GPL version 2 or any later. pkg-config works on multiple platforms: Linux and other UNIX-like operating systems, Mac OS X and Windows. It does not require anything but a reasonably well working C compiler and a C library, but can use an installed glib if that is present. (A copy of glib 1.2.10 is shipped together with pkg-config and this is sufficient for pkg-config to compile and work properly.) The first implementation was written in shell, by James Henstridge. Later, it was rewritten in C by Havoc Pennington. It also grew an autoconf macro written by Tim Janik, later rewritten by Scott James Remnant. The current maintainer is Tollef Fog Heen <tfheen@err.no>. The current release of pkg-config is version 0.25 (March 2011).
  • 182.
    The pkg-config tool Variables for Installation Directories : For more information : http://www.gnu.org/prep/standards/standards.pdf
  • 183.
    The pkg-config tool The autootols can make a fine tuning of the installation directories : --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/toe] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] --srcdir=DIR find the sources in DIR [configure dir or `..'] Example : ./configure --prefix=/usr --srcdir=/tmp/tmp232123
  • 184.
    The pkg-config tool Recent pkg-config tool version use several environment variables:
  • 185.
    The pkg-config tool $pkg-config –help  Usage provided by pkg-config Usage: pkg-config [OPTION...] --version output version of pkg-config --modversion output version for package --atleast-pkgconfig-version=VERSION require given version of pkg-config --libs output all linker flags --static output linker flags for static linking --short-errors print short errors --libs-only-l output -l flags --libs-only-other output other libs (e.g. -pthread) --libs-only-L output -L flags --cflags output all pre-processor and compiler flags --cflags-only-I output -I flags --cflags-only-other output cflags not covered by the cflags-only-I option --variable=NAME get the value of variable named NAME --define-variable=NAME=VALUE set variable NAME to VALUE --exists return 0 if the module(s) exist --print-variables output list of variables defined by the module --uninstalled return 0 if the uninstalled version of one or more module(s) or their dependencies will be used --atleast-version=VERSION return 0 if the module is at least version VERSION --exact-version=VERSION return 0 if the module is at exactly version VERSION --max-version=VERSION return 0 if the module is at no newer than version VERSION --list-all list all known packages --debug show verbose debug information --print-errors show verbose information about missing or conflicting packages,default if -- cflags or --libs given on the command line --silence-errors be silent about errors (default unless --cflags or --libsgiven on the command line) --errors-to-stdout print errors from --print-errors to stdout not stderr
  • 186.
    The pkg-config tool  Ask for the LDFLAGS for a static link : Example of metadata for bar.pc : $ pkg-config --libs bar prefix=/usr –lbar exec_prefix=${prefix} includedir=${prefix}/include  Ask for the LDFLAGS for a dynamic link: libdir=${exec_prefix}/lib fooname= Autotools are great :-) $ pkg-config --libs --static bar -lbar Name: bar Description: The bar library  ask for the LDFLAGS following a specific version : Version: 2.1.2 Requires.private: foo >= 0.7 $ pkg-config --libs "bar >= 2.7― Cflags: -I${includedir} Requested 'bar >= 2.7' but version of bar is 2.1.2 Libs: -L${libdir} –lbar  Ask for the CFLAGS :  Check the component exists : $ pkg-config --cflags bar -I/usr/include/foo $ pkg-config --exists --print-errors bar $ echo $?  Ask for the value of a specific name : 0 $ pkg-config –variable=fooname bar  Check the version : Autotools are great :-) $ pkg-config --modversion bar  Multiple request for the CFLAGS & LDFLAGS : 2.1.2
  • 187.
    The pkg-config tool Listing of the packages installed : $ pkg-config --list-all libbsd libbsd - Utility functions from BSD systems xtrans XTrans - Abstract network code for X m17n-db m17n-db - The m17n database used by the m17n library. autoopts AutoOpts - A semi-automated generated/library option parser xcb XCB - X-protocol C Binding gtest gtest - Google test framework for the C/C++ language libdrm_nouveau libdrm_nouveau - Userspace interface to nouveau kernel DRM services nautilus-sendto nautilus-sendto - Extend nautilus-sendto through plugins gnome-screensaver gnome-screensaver - gnome screensaver xrandr Xrandr - X RandR Library (...)  Increase the trace during the pkg-config runtime : $ pkg-config --debug --libs test Parsing package file '/home/gayetth/Desktop/autotools-tests/pkg-config/001/test.pc' line>prefix=/usr Variable declaration, 'prefix' has value '/usr' line>exec_prefix=${prefix} Variable declaration, 'exec_prefix' has value '/usr' line>libdir=${exec_prefix}/lib ( … ) line> line>Name: test line>Description: test line>Requires: line>Version: 1.0.0 line>Libs: -L${libdir} -ltest line>Cflags: -I${includedir}/test
  • 188.
    The pkg-config tool The PKG- CONFIG metadata files
  • 189.
    The pkg-config tool Pkgconfigfiles are metadata provided by a specific component (eg: static/dynamic libray) for other component that will work with: CFLAGS : flags need for compiling with (-I<LIBPATH)> LDFLAGS : flags need for linking with (-L<LIBPATH> -l<LIBNAME>) VERSION : version of the package ; can be used to identify the public API
  • 190.
    The pkg-config tool Exampleof a pkg-config file used for the libglib-2.0: # This is a comment prefix=/home/hp/unst # this defines a variable Partie haute exec_prefix=${prefix} # defining another variable in terms of Invariante the first « NAME » libdir=${exec_prefix}/lib includedir=${prefix}/include Name: Gobject # human-readable name Description: Object/type system for GLib # human-readable description Version: 1.3.1 Partie basse URL: http://www.gtk.org customisable Requires: glib-2.0 = 1.3.1 Conflicts: foobar <= 4.5 Libs: -L${libdir} -lgobject-1.3 Libs.private: -lm Cflags: -I${includedir}/glib-2.0 -I${libdir}/glib/include
  • 191.
    The pkg-config tool Descriptionof a pkg-config generic pattern that contain the metadata :
  • 193.
    The pkg-config tool Thisis possible to manage all the metadata within the configure.ac template : dnl Variables declaration PKG_DEFINITION=”Description: Thin OS Extension for native developments” PKG_DEPEND=”” dnl For each PKG_CHECK_MODULE, upgrade the PKG_DEPEND variable. dnl Export to the Makefile.am AC_SUBST(PCK_DEFINITION) AC_SUBST(PKG_DEPEND)  Thus we can obtain the following toe.pc.in : prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: @PACKAGE_NAME@ Description: @PCK_DEFINITION@ Requires: @PKG_DEPEND@ Version: @VERSION@ Libs: -L${libdir} -l@PACKAGE_NAME@ Cflags: -I${includedir}/@PACKAGE_NAME@/  At the end, the pc.in template is really generic and dynamic.
  • 194.
    The pkg-config tool Theautotools bring some M4 macros that can be used in order to work with the pkg-config‘s metadata :  configure.ac  PKG_PROG_PKG_CONFIG([MIN-VERSION])  PKG_CHECK_EXISTS(MODULES, [ACTION-IF- FOUND], [ACTION-IF-NOT-FOUND])  PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], [ACTION-IF- NOT-FOUND])  Makefile.am
  • 195.
    The pkg-config tool PKG_PROG_PKG_CONFIG([MIN-VERSION]) It locates the pkg-config tool on the system and checks its version for compatibility. If you want to know which version is using : $ pkg-config --version 0.25 Example of checking from a configure.ac file: (…) PKG_PROG_PKG_CONFIG([0.23]) (…) Output (…) checking pkg-config is at least version 0.23... Yes (…)  If the version checked is not equal or above to the one expected, no other macro will work. So beware is the result of this macro !!
  • 196.
    The pkg-config tool Aswell as with the which command tool, you can check first if this tools is available on the current gnu/linux system, then where the command is located in the filesystem: $ which pkg-config /usr/bin/pkg-config The autotools can do the same within the configure.ac : AC_PATH_PROG([PKG_CONFIG],[pkg-config]) if test -z "$PKG_CONFIG" ; then AC_MSG_ERROR([pkg-config tool not found]) fi
  • 197.
    The pkg-config tool PKG_CHECK_EXISTS(MODULES,[ACTION-IF-FOUND], [ACTION-IF- NOT-FOUND]) Verify if whether a particular library exist and check its version. Check to see whether a particular set of modules exists. Similar to PKG_CHECK_MODULES(), but does not set variables or print errors. Example: (…) POLKIT_REQUIRED=3.2.1 PKG_CHECK_EXISTS([polkit-dbus >= $POLKIT_REQUIRED], [have_polkit=yes], [have_polkit=no]) (…) The name polkit-dbus should follow the name of the pkg-config file (polkit-dbus.pc).
  • 198.
    The pkg-config tool PKG_CHECK_MODULES(VARIABLE-PREFIX,MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])  Checks to see whether a particular set of modules exists. If so, it sets <VARIABLE- PREFIX>_CFLAGS and <VARIABLE-PREFIX>_LIBS according to the output from pkg-config --cflags and pkg- config --libs. Example that check the google/test library : LIBGTEST_REQUIRED_VERSION=1.5.0 PKG_CHECK_MODULES([GTEST],[gtest >= $LIBGTEST_REQUIRED_VERSION],[have_libgtest=yes],[have_libgtest=no]) if test "$have_libgtest" = no ; then AC_MSG_ERROR([Missing the libgtest library!!]) fi  Checking the version is not mandatory but is better.  If pkg-config find the gtest.pc metadata, it will export to the Makefile two variables : GTEST_CFLAGS and GTEST_LIBS. With old version of autotools this is needed to export them with the AC_SUBST macro. This is not needed with recent one.  This would result in MYSTUFF_LIBS and MYSTUFF_CFLAGS substitution variables, set to the libs and cflags for the given module list. If a module is missing or has the wrong version, by default configure will abort with a message. To replace the default action, specify an ACTION-IF-NOT-FOUND. PKG_CHECK_MODULES will not print any error messages if you specify your own ACTION-IF-NOT-FOUND. However, it will set the variable MYSTUFF_PKG_ERRORS, which you can use to display what went wrong.
  • 199.
    The pkg-config tool Thetwo M4 macros PKG_CHECK_EXISTS and PKG_CHECK_MODULES can check more than one dependency. Example : (…) PKG_CHECK_EXISTS([gtkmm-2.4 >= 2.12.2 somethingelse-1.0 >= 1.0.2], [have_all_deps=yes], [have_all_deps=no]) (…) and (…) PKG_CHECK_MODULES([DEPS],[gtkmm-2.4 >= 2.12.2 somethingelse-1.0 >= 1.0.2],[have_all_deps=yes],[have_all_deps=no]) (…)
  • 200.
    The pkg-config tool Impact on the configure.ac template : # # Configure script for the foo component # # Check the version of the pkg-config tool # It will use pkg-config –version inside PKG_PROG_PKG_CONFIG([0.23]) # Check the libconfig dependency # LIBCONFIG : is the prefix used with the two variable exported to the makefiles: # LIBCONFIG_CFLAGS = pkg-config --cflags libconfig # LIBCONFIG_LIBS = pkg-config --libs libconfig # libconfig : specify the name of the pkg-config file that contain the metadata # (libconfig.pc) LIBCONFIG_REQUIRED_VERSION=1.4.6 PKG_CHECK_MODULES([LIBCONFIG],[libconfig>= $LIBCONFIG_REQUIRED_VERSION],[have_libconfig=yes],[have_libconfig=no]) if test "$have_libconfig" = no ; then AC_MSG_ERROR([Missing the libconfig library 1.4.6 !!]) fi AC_OUTPUT( Makefile foo.pc )
  • 201.
    The pkg-config tool Impact on the Makefile.am template : EXTRA_DIST = $(top_srcdir)/autogen.sh HEADER_DIR = $(top_srcdir)/inc lib_includedir = $(includedir)/foo lib_include_HEADERS = $(HEADER_DIR)/foo/foo.h pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = foo.pc lib_LTLIBRARIES = libfoo.la libfoo_la_SOURCES = src/foo.c inc/config.h libfoo_la_CFLAGS = -I$(HEADER_DIR) $(LIBCONFIG_CFLAGS) libfoo_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -lpthread -lrt libfoo_la_LIBADD = $(LIBCONFIG_LIBS) Note: external dependencies must be set to the _LIBADD variable. Internal/local one, should be associated to _LDFLAGS. # EOF
  • 202.
    The pkg-config tool PKG-CONFIG LAB
  • 203.
    The pkg-config tool TP_PKG_CONFIG  The goal of this lab is to manage DEPFOO1 DEPFOO3 2.5.6 1.3 FOO DEPFOO2 1.4.2 The foo component will have two direct dependencies depfoo1 et depfoo2 and another one depfoo3 pushed by depfoo1. Workflow : 1.Fill the content of the files from the depfoo3 component 2.Fill the content of the files from the depfoo1 component 3.Fill the content of the files from the depfoo2 component 4.Fill the content of the files from the foo component  In order to launch your TP, run the ./run_tp.sh script.
  • 205.
    The pkg-config tool TP_PKG_CONFIG You should have after the installation : /sdk/x86/ lib/ libdepfoo1.so + libdepfoo1.a libdepfoo2.so + libdepfoo2.a libdepfoo3.so + libdepfoo3.a pkgconfig/ depfoo1.pc depfoo2.pc depfoo3.pc include/ depfoo1/depfoo1.h depfoo2/depfoo2.h depfoo3/depfoo3.h bin/ foo More help: http://linux.die.net/man/1/pkg-config OR man pkgconfig
  • 206.
    Generating a documentation Thegoal of this topic is to know how to generate automatically a doxygen documentation in a html format
  • 207.
    Doxygen documentation inhtml format Generating a default doxygen documentation
  • 208.
    Doxygen documentation inhtml format  This feature will impact the two autotools templates :  configure.ac This script will simply check that we have the doxygen file in the current path.  Makefile.am This file will manage the documentation generation using the doxygen tool.
  • 209.
    Doxygen documentation inhtml format  Impact of the configure.ac template : dnl --------------------------------------------------- dnl Check for doxygen support dnl --------------------------------------------------- AC_PATH_PROG([DOXYGEN], [doxygen]) dnl Export the boolean value of the doxygen check AM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN) dnl Display a warning in case the doxygen tool is not found dnl If not found, it will just display a warning. if test –z ―$DOXYGEN‖ then AC_MSG_WARN([doxygen tool not found]) fi  This script will first test if the doxygen, then will export the result of this test to the other makefile templates.
  • 210.
    Doxygen documentation inhtml format  Impact on the Makefile.am template : In order to add the doxygen setting file in the tarball generated with make dist, we must specify it explicitely: # Extra files to add in the archive EXTRA_DIST = $(top_builddir)/autogen.sh $(top_builddir)/default- The doxyfile should be define : Doxyfile DOXYFILE ?= $(top_builddir)/default-Doxyfile Then for the two targets we will : Make a directory that will be used for the html extraction Make a local copy of the default-Doxyfile Upgrade of the Doxyfile with data from the composant : oExtraction directory (HTML_OUTPUT) oIts name (PROJECT_NAME) oIts version (PROJECT_NUMBER) oThe path of the source code to parse (INPUT) Launch of the documentation by invoquing the doxygen tool Remove the temporarily Doxyfile
  • 213.
    Doxygen documentation inhtml format Editing a default doxygen configuration
  • 214.
    Doxygen documentation inhtml format Doxywizard is a GUI front-end used for configuring and running doxygen. In our case we will just use it for generating a config file. When you start doxywizard it will display the main window (the actual look depends on the OS used).
  • 215.
    Doxygen documentation inhtml format The doxywizard tool (also known as doxygen-gui) can be used in order to generate a default doxygen configuration. The project‘s name and its relative version will update the file afterwards.  This GUI can be also used to edit an existing setting.  The configuration should be save into a default-Doxyfile file.
  • 216.
    Doxygen documentation inhtml format DOCUMENTATION LAB
  • 218.
    Launching unitary testwith covering support The goal of this topic is to know how to automaticaly launch unitary tests with covering support using gcov for PKI data.
  • 222.
    Launching a unitarytest with covering support  Adaptations needed :  configure.ac :  Add the --enable-test support that will exports HAVE_TEST to the Makefiles. Add the --enable-covering support for adding the gcov flags to the build process.  Makefile.am : Add the make check support to make the unit tests automatic Add the make covering support to make the lcov analysis automatic.
  • 223.
    Launching a unitarytest with covering support  test flag for enabling the unit tests: Name : --enable-test Mandatory : no Default’s state : enable If this flags is not set, the unit test binaries are not built. Thus, the “make check” command doesn’t do anything at all.
  • 224.
    Launching a unitarytest with covering support  Adaptations needed : dnl --------------------------------------------------- dnl Check for lcov support dnl --------------------------------------------------- AC_PATH_PROG([LCOV], [lcov]) configure.ac  AC_PATH_PROG([GENHTML], [genhtml]) (first part) dnl Export the boolean value of the lcov check AM_CONDITIONAL(HAVE_LCOV, test $LCOV) dnl Display a warning in case the lcov tool is not found dnl If not found, it will just display a warning. if test –z ―$LCOV‖ then AC_MSG_WARN([lcov/genhtml tools not found]) fi  This initial test will check both if the lcov and genhtml tools are available in the current system.  Thus we can be sure the make covering will be runable.
  • 225.
    dnl -------------------------------------------- dnl Brief : enable or disable the unitary test dnl Mandatory : no dnl Values : none (just enable the tests if set) dnl Default's value : disable dnl -------------------------------------------- AC_ARG_ENABLE(test, AS_HELP_STRING([--enable-test], [Enable the test unitary support [default=no]]), [case "${enableval}" in yes) have_test=true ;; configure.ac  no) have_test=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-test) ;; esac], [have_test=false]) (second part) dnl -------------------------------------------- dnl Export the conditional HAVE_TEST variable to the Makefiles dnl -------------------------------------------- AM_CONDITIONAL(HAVE_TEST, $have_test) dnl -------------------------------------------- dnl Test the have_test variable and if equal to true dnl -------------------------------------------- AC_MSG_CHECKING(Checking the test support) if test "$have_test" != "false" ; then dnl -------------------------------------------- dnl Display the result of the test ... yes dnl -------------------------------------------- AC_MSG_RESULT([yes]) LIBGTEST_REQUIRED_VERSION=1.5.0 PKG_CHECK_MODULES([GTEST],[gtest >= $LIBGTEST_REQUIRED_VERSION],[have_libgtest=yes],[have_libgtest=no]) if test "$have_libgtest" = no ; then AC_MSG_ERROR([Missing libgtest library (http://code.google.com/p/googletest/) !!]) fi LIBGMOCK_REQUIRED_VERSION=1.5.0 PKG_CHECK_MODULES([GMOCK],[gmock >= $LIBGMOCK_REQUIRED_VERSION],[have_libgmock=yes],[have_libgmock=no]) if test "$have_libgmock" = no ; then AC_MSG_ERROR([Missing libgmock library !!]) fi else dnl -------------------------------------------- dnl Display the result of the test ... no dnl -------------------------------------------- AC_MSG_RESULT([no]) If you are not using the Google test/mock you can avoid this step. If you need to check both the gtest and gmock fi dependencies.
  • 226.
    Launching a unitarytest with covering support  Checking the dependencies :  Check the Google test library : configure.ac dnl -------------------------------------------- dnl Test if the libgtest is well available in the stagingdir dnl If so get the cflags and ldflag from the .pc file dnl -------------------------------------------- LIBGTEST_REQUIRED_VERSION=1.5.0 PKG_CHECK_MODULES([GTEST],[gtest >= $LIBGTEST_REQUIRED_VERSION],[have_libgtest=yes],[have_libgtest=no]) if test "$have_libgtest" = no ; then AC_MSG_ERROR([Missing libgtest library (http://code.google.com/p/googletest/) !!]) fi  Check the Google mock library : configure.ac dnl -------------------------------------------- dnl Test if the libgmock is well available in the stagingdir dnl If so get the cflags and ldflag from the .pc file dnl -------------------------------------------- LIBGMOCK_REQUIRED_VERSION=1.5.0 PKG_CHECK_MODULES([GMOCK],[gmock >= $LIBGMOCK_REQUIRED_VERSION],[have_libgmock=yes],[have_libgmock=no]) if test "$have_libgmock" = no ; then AC_MSG_ERROR([Missing libgmock (http://code.google.com/p/googlemock/) library !!]) fi Dependencies are not mandatory. Indeed this is possible to use a single main in order to test our development.
  • 227.
    Launching a unitarytest with covering support  Unit test definition : TESTS = myUnitTestExecutable # Definition of the unit test : check_PROGRAMS = myUnitTestExecutable myUnitTestExecutable_SOURCES = test1.cpp myUnitTestExecutable_CPPFLAGS = myUnitTestExecutable_LDFLAGS = myUnitTestExecutable_LDADD = By specifying the unit test executable as check_PROGRAMS instead of using something like bin_PROGRAMS or noinst_PROGRAMS, it generates the makefiles such that the files will only be built when you run ―make check‖. The same can be done for libraries as well. You can use check_LIBRARIES instead of lib_LIBRARIES to specify libraries that should only be built for unit tests.
  • 231.
    Launching a unitarytest with covering support  Impact for the covering target in the configure.ac template : dnl -------------------------------------------- dnl Brief : enable or disable the buildin covering mode dnl Mandatory : no dnl Values : none (just enable the covering mode if set) dnl -------------------------------------------- AC_ARG_ENABLE(covering, AS_HELP_STRING([--enable-covering], [Enable the building covering (gnu/gcov) support [default=no]]), [case "${enableval}" in yes) have_covering=true ;; no) have_covering=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-covering) ;; esac], [have_covering=false]) dnl -------------------------------------------- dnl Test the have_covering variable and if equal to true dnl -------------------------------------------- AC_MSG_CHECKING([Checking the covering support]) if test "$have_covering" = "true" ; then dnl -------------------------------------------- dnl Display the result of the test ... yes dnl --------------------------------------------  configure.ac AC_MSG_RESULT([yes]) dnl -------------------------------------------- dnl Update the CFLAGS and CPPFLAGS with gcov options for gcc dnl -------------------------------------------- CFLAGS=" $CFLAGS -fprofile-arcs -ftest-coverage " CPPFLAGS=" $CPPFLAGS -fprofile-arcs -ftest-coverage " LDFLAGS=" $LDFLAGS -fprofile-arcs " else dnl -------------------------------------------- dnl Display the result of the test ... no dnl -------------------------------------------- AC_MSG_RESULT([no]) fi
  • 236.
    Launching a unitarytest with covering support Detail of the unit test covering for the current component by files:
  • 237.
    Launching a unitarytest with covering support The html export details the real lines used by the unitary test at the runtime :
  • 238.
    Launching a unitarytest with covering support Another detail from the html export :
  • 239.
    Launching a unitarytest with covering support  Summary : The more the unitary tests (based on Google test/mock) will test functions, the more the KPI will give good data. The main goal is to target 100% but because some tests can be difficult to check (exception, interraction with the system, … ) The tests should be runable on Hudson. Actually each component provides the following data: oNumber of lines (wc –l sloccount) o% of lines tested o% of functions tested o% of branches tested
  • 240.
    Launching a unitarytest with covering support UNIT TEST & COVERING LAB
  • 241.
    Launching a unitarytest with covering support The goal of this lab is to add a covering support to your component. For this check you have lcov in your path. In the wrong case you can download the runtime package here: http://downloads.sourceforge.net/ltp/lcov-1.9.tar.gz Immagine how to integrate the slocount tool in the same way : •Sloccount command to launch : sloccount `pwd` •Download : http://www.dwheeler.com/sloccount/sloccount-2.26.tar.gz •http://www.dwheeler.com/sloccount/sloccount.html •http://www.dwheeler.com/sloccount/ •Nb: don‘t forget to check the avaibility og the tool !
  • 242.
    Launching a unitarytest with covering support  More help about : http://www.gnu.org/software/automake/ http://www.gnu.org/software/autoconf/ http://www.gnu.org/software/hello/manual/automake/Tests.html http://www.crsr.net/Notes/CheckAndAutotools.html http://gcc.gnu.org/onlinedocs/gcc/Gcov.html http://ltp.sourceforge.net/coverage/lcov.php http://codingfreak.blogspot.com/2009/02/gcov-analyzing-code-produced- with-gcc.html http://www.cmi.univ- mrs.fr/~contensi/coursC/index.php?section=env&page=test
  • 243.
    Managing the debugmode The goal of this topic is to know how to select a debug/release mode relative to a build
  • 244.
    Managing the debugmode  The main goal is to provide parameters to the GCC compiler and to the LD linker in order to have a build usable with a debug mode.  Gcc have a set of parameters that can be used for customizing the debug mode :  For more detail : http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
  • 246.
    Managing the debugmode DEBUG MODE LAB
  • 247.
    Managing the debugmode The goal of this lab is to add a debug support to your Autotools projet.  Test a build using this one and another build without and check the debug flags are well provided to gcc through the CFLAGS.  Check the final ELF library have well the debug symbols : file ELFfile nm -gC ELFLib.so objdump -h ELFfile objdump -TC ELFLib readelf -Ws /usr/lib/libexample.so readelf -Ws /usr/lib/libstdc++.so.6 | grep '^([[:space:]]+[^[:space:]]+){6}[[:space:]]+[[:digit:]]+‘ readelf -Ws /usr/lib/libstdc++.so.6 | awk '{print $8}';
  • 248.
    Manage the optimizationlevel The goal of this topic is to know how to select an optimization level relative to a build
  • 251.
    Manage the optimizationlevel OPTIMIZATION LAB
  • 252.
    Manage the optimizationlevel The goal of this lab is to update an autotools component with an optimization level support by adding a --with-optim-level=3 parameter. Test a build using this one and another build without and check the flags -Ox is well provided to gcc according to the level expected.
  • 253.
    Manage the profilingmode The goal of this topic is to know how to select a debug/release mode relative to a build
  • 256.
    Manage the profilingmode  Cohabitation problems between gnu prof (aka gprof) and the pthread : gprof is the GNU Profiler, a tool used when tracking which functions are eating CPU in your program. Anyway, you should already be familiar with it if you got interested in this page. One problem with gprof under certain kernels (such as Linux) is that it doesn‘t behave correctly with multithreaded applications. It actually only profiles the main thread, which is quite useless.  Workaround There is an easy, but surprisingly not very widespread fix for this annoying gprof behaviour. Basically, gprof uses the internalITIMER_PROF timer which makes the kernel deliver a signal to the application whenever it expires. So we just need to pass this timer data to all spawned threads.  Example It wouldn‘t be too hard to put a call to setitimer in each function spawned by a thread, but I thought it would be more elegant to implement a wrapper for pthread_create. Daniel Jönsson enhanced my code so that it could be used in a preload library without having to modify the program. It can also be very useful for libraries that spawn threads without warning, such as libSDL. The result code is shown below and can be downloaded here: http://sam.zoy.org/writings/programming/gprof-helper.c  more detail: http://sam.zoy.org/writings/programming/gprof.html
  • 259.
    Manage the profilingmode PROFILING LAB
  • 260.
    Manage the profilingmode The goal of this lab is to update an autotools component with the profiling support by adding a –enable-profiling parameter. Test a build using this one and another build without and check the flags -pg is well provided to gcc.
  • 261.
    The cross-compilation The goalof this topic is to know how cross-compile.
  • 262.
    The cross-compilation  Exampleof cross-compilation in action : ./configure --build i686-pc-linux-gnu --host i586-mingw32msvc checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for gawk... gawk checking whether make sets $(MAKE)... yes checking for i586-mingw32msvc-strip... i586-mingw32msvc-strip checking for i586-mingw32msvc-gcc... i586-mingw32msvc-gcc checking for C compiler default output file name... a.exe checking whether the C compiler works... yes checking whether we are cross compiling... yes checking for suffix of executables... .exe checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether i586-mingw32msvc-gcc accepts -g... yes checking for i586-mingw32msvc-gcc option to accept ANSI C etc ...
  • 263.
    The cross-compilation One ofthe main advantage of the autotools is to be portable to an architecture to another one. The configure script have some parameters where we can specify the local and final architecture : By default, the `configure' script will assume that the target is the same as the host. This is the more common case ; for example, it leads to a native compiler rather than a cross compiler.  The --host and --build options are usually all we need for cross-compiling. The only exception is if the package being built is itself a cross-compiler: we need a third option to specify its target architecture.  Native compiling (for the host): ./configure –prefix=/usr --host=i386-linux-gnu … ./ configure –prefix=/usr …  Cross-compiling : ./configure –prefix=/usr –host=i386-linux-gnu –build=mips-elf …
  • 264.
    The cross-compilation  Usingthe Host type : In almost all cases the host system is the system on which you run the `configure' script, and on which you build the tools (for the case when they differ, see section Canadian Cross). If your configure script needs to know the configuration name of the host system, and the package is not a cross compilation tool and therefore does not have a target, put `AC_CANONICAL_HOST' in `configure.in'. This macro will arrange to define a few shell variables when the `configure' script is run. host The canonical configuration name of the host. This will normally be determined by running the `config.guess' shell script, although the user is permitted to override this by using an explicit `-- host' option. host_alias In the unusual case that the user used an explicit `--host' option, this will be the argument to `- - host'. In the normal case, this will be the same as the `host' variable. host_cpu host_vendor host_os The first three parts of the canonical configuration name.
  • 265.
    The cross-compilation  Usingthe Target type : If you want to build a cross compilation tool, you must specify the target explicitly by using the `--target' option when you run `configure'. The argument to `--target' is the configuration name of the system for which you wish to generate code. See section Configuration Names. For example, to build tools which generate code for a MIPS ELF embedded system, you would use `--target mips-elf'. When writing `configure.in' for a cross compilation tool, you will need to use information about the target. To do this, put `AC_CANONICAL_SYSTEM' in `configure.in'. `AC_CANONICAL_SYSTEM' will look for a `--target' option and canonicalize it using the `config.sub' shell script. It will also run `AC_CANONICAL_HOST' (see section Using the Host Type). The target type will be recorded in the following shell variables. Note that the host versions of these variables will also be defined by `AC_CANONICAL_HOST'.  target The canonical configuration name of the target.  target_alias The argument to the `--target' option. If the user did not specify a `--target' option, this will be the same as host_alias  target_cpu  target_vendor  target_os
  • 266.
    The cross-compilation  Thisis a string of the form cpu-manufacturer-operating_system. In some cases, this is extended to a four part form: cpu-manufacturer-kernel-operating_system (eg: i686-cm-linux)  When using a configuration name in a configure option, it is normally not necessary to specify an entire name. In particular, the manufacturer field is often omitted, leading to strings such as `i386-linux' or `sparc-sunos'. The shell script `config.sub' will translate these shortened strings into the canonical form. autoconf will arrange for `config.sub' to be run automatically when it is needed.  The shell script `config.guess' will normally print the correct configuration name for the system on which it is run. It does by running `uname' and by examining other characteristics of the system. Because `config.guess' can normally determine the configuration name for a machine, it is normally only necessary to specify a configuration name when building a cross-compiler or when building using a cross-compiler.  This should be synchronize with the toolchain‘s prefix.
  • 267.
    The cross-compilation The configurescript can detect the host system thanks to the ―AC_CANONICAL_HOST‖ or ‖AC_CANONICAL_SYSTEM‖ m4 macros: AC_CANONICAL_HOST case "${host}" in i[3456]86-*-linux-gnu*) do something ;; Example of action that depend sparc*-sun-solaris2.[56789]*) do something ;; on the host type. sparc*-sun-solaris*) do something ;; mips*-*-elf*) do something ;; esac
  • 268.
    The cross-compilation In cross-compilationmode, binaries will be generate with a prefix that will follow the one provide to the target argument. In other word, native build will generate : mybinary And with a target equal to i686-cm-linux prefix the binary will become : i686-cm-linux- mybinary  This is possible to do not add the prefix in cross-compilation mode if the following parameter is set to the configure script: ./configure --prefix=/usr --program-transform-name=""  Thus the final name won‘t have any impact and won‘t change.
  • 269.
    The cross-compilation CROSS-COMPILATIONLAB
  • 270.
    The cross-compilation The maingoal of this lab is to compile a helloworld binary in three times: For the host: ./configure --prefix=/usr For a target: ./configure --prefix=/usr --host=i386-linux-gnu --build=mips-elf For a target: ./configure --prefix=/usr --host=i386-linux-gnu --build=mips-elf
  • 271.
    Check the autotoolsfor hudson SPECIFIC TECHNICOLOR The goal of this topic is to be sure the autotools will work with hudson.
  • 272.
    Check the autotoolsfor hudson Hudson make the autotools usage more difficult to use.  Objets are not generated in the top_srcdir path but in top_builddir So because top_srcdir != top_builddir, developers should valide their autotools template before to apply a baseline on clearcase.
  • 275.
    Check the autotoolsfor hudson HUDSON LAB
  • 276.
    Check the autotoolsfor hudson The main goal of this lab if to valid your autotools by Following the previous steps.  After the « make dist », the extraction, and the configuring, we should be able to compile and link. If you have time, you can write a bash script for automating This checking.
  • 277.
    The M4 macros Thegoal of this topic is to know how M4 macros are written.
  • 278.
    The M4 macros Autoconfmodifies the M4 environment in a few ways. First, as mentioned earlier, it changes the default quote characters from the backtick and single quote characters to the open and close square bracket characters. In addition, it configures M4 built-in macros such that most are prefixed with m4_, thereby creating a unique namespace for M4 macros. Thus, the M4 define macro becomes m4_define, and so on. Autoconf provides its own version of m4_define called AC_DEFUN. You should use AC_DEFUN instead of m4_define because it ensures that certain environmental constraints important to Autoconf are in place when your macro is called!! The AC_DEFUN macro supports a prerequisite framework, so you can specify which macros are required to have been called before your macro may be called. This framework is accessed by using the AC_REQUIRE macro to indicate your macro‘s requirements at the beginning of your macro definition, like so: # Test for option A AC_DEFUN([TEST_A], [AC_REQUIRE([TEST_B])dnl test " $A" = "yes" && options=" $options A"])
  • 279.
    The M4 macros Thisis possible to write a custom m4 macro : There are two ways to organize custom macros in a package:  The first possibility (the historical practice) is to list all your macros in acinclude.m4. This file will be included in aclocal.m4 when you run aclocal, and its macro(s) will henceforth be visible toautoconf. However if it contains numerous macros, it will rapidly become difficult to maintain, and it will be almost impossible to share macros between packages.  The second possibility, which we do recommend, is to write each macro in its own file and gather all these files in a directory. This directory is usually called m4/. To build aclocal.m4, one should therefore instruct aclocal to scan m4/. From the command line, this is done with ‗aclocal -I m4‘. The top-level Makefile.am should also be updated to define:  ACLOCAL_AMFLAGS = -I m4  ACLOCAL_AMFLAGS contains options to pass to aclocal when aclocal.m4 is to be rebuilt by make. This line is also used by autoreconf.
  • 280.
    The M4 macros Example: AC_DEFUN([TRAVOLTA], [test "$body_temperature_in_celsius" -gt "38" && dance_floor=occupied]) AC_DEFUN([NEWTON_JOHN], [test "$hair_style" = "curly" && dance_floor=occupied]) my_macros.m4 AC_DEFUN([RESERVE_DANCE_FLOOR], [if date | grep '^Sat.*pm' >/dev/null 2>&1; then AC_REQUIRE([TRAVOLTA]) AC_REQUIRE([NEWTON_JOHN]) fi]) With this configure.ac : AC_INIT sinclude(my_macro.m4) RESERVE_DANCE_FLOOR configure.ac if test "$dance_floor" = occupied; then AC_MSG_ERROR([cannot pick up here, let's move]) fi
  • 281.
    The M4 macros If you have somme command you often use in your configure.ac : make_command="―  We suppose you have written a small for a in "$MAKE" make gmake gnumake check already used in your "configure" script do test -z "$a" && continue if ( sh -c "$a --version" 2>/dev/null | grep GNU >/dev/null ) - which is actually a bourne shell script that then make_command=$a ; break; calls other tools and possibly sets an fi AC_SUBST variable to be replaced in your done Makefile.in. It may look like the following if test -z $make_command check for a "gnu make" in the build then ifGNUmake="― else ifGNUmake="#― environment. fi AC_SUBST(ifGNUmake)  In the first step, one would extract that part from the "configure" script and put it into its own file. For a first test, please use the "acinclude.m4" file. The next call of `aclocal && autoconf` will copy the new macro to "aclocal.m4" and from there to "configure". So, now you have an extra file "acinclude.m4" reading: AC_DEFUN(CHECK_GNU,[ make_command="" for a in "$MAKE" make gmake gnumake do test -z "$a" && continue if ( sh -c "$a --version" 2>/dev/null | grep GNU >/dev/null ) then make_command=$a ; break; fi done if test -n $make_command then ifGNUmake="" else ifGNUmake="#" fi AC_SUBST(ifGNUmake) ]) .... CHECK_GNU ...
  • 282.
    The M4 macros Now you are already done with having your own autoconf macro. And you can be quite sure that it will work in your project - and probably you have tested it on the platforms you do usually build for. Believe it or not, this is a rather "controlled" environment - if you push the macro to the AC Macro Archive then your macro might make it into other projects where they will meet lots of other macros, lots of other shell code, lots of different platforms. And possibly, it will fail over there - however there are some steps that can be checked before.  Add m4-quotings - AC_DEFUN([CHECK_GNU]) In the wild, your "CHECK_GNU" might have been already defined elsewhere. It is perfectly possible to redefine a macro but only if AC_DEFUN will see the name. Without the m4-quotes "[...]" however, the predefined macro CHECK_GNU will be expandend before. In many many cases it results in "syntax errors" occuring near your usage of CHECK_GNU and they are not telling about a redefine problem at all. It is really hard to get after that one.  Add m4-quotings - AC_SUBST([ifGNUmake]) For the same reason, you should put m4-quotes in any other places where actually an m4-macro is being created - or possibly you are going to use a symbol that might be a complex macro. As a rule of thumb, all uppercase-symbols might be defined as a macro somewhere else. Please put all of them into m4-quotes "[...]". By the way, if you need a pair of "[..]" to be output to the "configure" script, just double (or triple) them as "[[...]]".  var-settings need doublequotes - make_command="$a" Most people forget about a problem here - if there is a single space between the "=" and anything to follow then the righthand side will be executed as a command and the return value of that command gets assigned. In other words, 'a="echo foo" ; var= $a' will not set "$var" to "foo" but instead print "foo" to the user screen. Putting doublequotes around the righthand side will ensure it gets never ever executed errornously. If you really want to get the execution value, then use backticks to express just that: 'a=`echo foo`'.  test emptyness as : test "x$var" = "x" The "test" command happens to be implemented very very differently on the various platforms, in fact it is mostly a builtin to the shell you happen to have your configure script get executed with. While "-z" is seen often, even "-n" is rarely implemented. Even more, there are some buggy shells which remove an empty "" string completely instead of providing an empty argument to the "test" command, so that "test" would see a 'test "$var" = ""' as a real 'test =' - and ask for a syntax error.
  • 283.
    The M4 macros Use cache variables - _cv_make_command Your macro might be used by other macros which get each expanded into the final "configure" script. That will make your check code to be executed multiple times. Not necessary, and for a compile-and-run test it would be very time consuming. Also, the cache-variables allow a packager guru to pre-set the check-result, yielding faster "configure" and allows to handle problems with cross-compile setups. The configure script will automatically save-to-cache all shell variables containing a "_cv_" in the name.  Use AC_MSG_RESULT - after AC_MSG_CHECKING / AC_CACHE_CHECK Inform the user when the "configure" script enters your macro and when it leaves your macro. If there are problems, they can be identified faster - remember that an extra autoconf macro file is in a distant place perhaps and the original "configure.ac" has only a macro name, and possibly not even your macro name but a different one that happens to use your macro in its definition. At best, inform the user of the result - and try to avoid terminology that is not helpful to a non-coder.  Don't be afraid of long names - use AS_VAR_PUSHDEF / POPDEF You should avoid to destroy shell variable values possibly used somewhere else - or the ones of the other macro calling your macro. As for short-lived variables that do not span over other macros, just use very short names - for the other ones use a long prefix that resembles the name of your macro check.  Use a specific prefix - do not use AC_ or AM_ Many macro names might be defined under the same name elsewhere. Usually, you would use a project prefix to avoid double defines, i.e. MYPROJECT_CHECK_GNU. Do never use AC_CHECK_GNU since all AC_ names are reserved - even if you know there is no such macro in the "autoconf" package then it might still be added later. If you intend to submit your macro the AC Macro Archive then you can use the AX_ prefix - we take all macros and we will ensure all macros in the archive are unique. Always and forever.
  • 284.
    The M4 macros After applying all these guideline, the macro might now look like this: AC_DEFUN([AX_CHECK_GNU_MAKE],[ AC_CACHE_CHECK([for GNU make],ax_cv_gnu_make_command,[ AS_VAR_PUSHEDEF([_make_command],ax_cv_gnu_make_command)dnl _make_command="― for a in "$MAKE" make gmake gnumake do test "x$a" = "x" && continue if ( sh -c "$a --version" 2>/dev/null | grep GNU >/dev/null ) then _make_command="$a" ; break; fi done if test "x$_make_command" != "x" then ifGNUmake="" AC_MSG_RESULT([$_make_command]) else ifGNUmake="#" AC_MSG_RESULT([nothing found]) fi AC_SUBST([ifGNUmake]) AS_VAR_POPDEF([_make_command])dnl ]])
  • 285.
    The M4 macros Adding some action : ACTION-IF-TRUE / ACTION-IF-FALSE If you have a look around then you will notice that most "CHECK" macros have additional and optional arguments. Those may contain shell-code (or other autoconf macros) that should be executed when the autodection fails (or additionally when it succeeds). Autoconf macros are numbered, and the first argument is generally reserved for sub- specifications - e.g. additional "make" program names to check for dnl ------------------------------------------------------------------------------------------------------------------- dnl AX_CHECK_GNU_MAKE([make names],[ACTION-IF-FOUND],[ACTION-IF-NOT]) dnl ------------------------------------------------------------------------------------------------------------------- AC_DEFUN([AX_CHECK_GNU_MAKE],[ AC_CACHE_CHECK([for GNU make],ax_cv_gnu_make_command,[ AS_VAR_PUSHEDEF([_make_command],ax_cv_gnu_make_command)dnl _make_command="" for a in "$MAKE" $1 make gmake gnumake do test "x$a" = "x" && continue if ( sh -c "$a --version" 2>/dev/null | grep GNU >/dev/null ) then _make_command="$a" ; break; fi done if test "x$_make_command" != "x" then ifGNUmake="" AC_MSG_RESULT([$_make_command]) $2 else ifGNUmake="#" AC_MSG_RESULT([nothing found]) $3 fi AC_SUBST([ifGNUmake]) AS_VAR_POPDEF([_make_command]) ]])
  • 286.
    The M4 macros Using a custom m4 functions is done by including Automake supports an include directive which can be used to include other `Makefile' fragments when automake is run. Note that these fragments are read and interpreted by automake, not by make. As with conditionals,make has no idea that include is in use. There are two forms of include: include $(srcdir)/file include a fragment which is found relative to the current source directory. include $(top_srcdir)/file include a fragment which is found relative to the top source directory. Note that if a fragment is included inside a conditional, then the condition applies to the entire contents of that fragment. Example of m4 macro include: include(pkg.m4) sinclude(pkg.m4)
  • 287.
    The M4 macros M4 MACROS LAB
  • 288.
    The M4 macros Themain goal for this lab is to create a file called mymacros.m4 that will contains custom m4 macros for the autotools. In this file create a new M4 macro called : AX_CHECK_GNU_LINUX_KERNEL_VERSION used for testing the gnu/linux kernel version. We are expecting a 2.6.X not bellow. The current version can be obtain by several way: uname –a or uname –r cat /proc/version Linux version 2.6.35-28-generic (buildd@rothera) (gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) ) #50- Ubuntu SMP Fri Mar 18 19:00:26 UTC 2011 cat /proc/sys/kernel/osrelease 2.6.35-28-generic Then, test the new macro in your configure.ac script.
  • 289.
    More help aboutthe autotools
  • 290.
    Links 1/2 • OFFICIALGNU MANUALS: •  GNU Make manual : http://www.gnu.org/software/make/manual/  GNU M4 macros manual : http://www.gnu.org/software/m4/manual/index.html  GNU libtools manual : http://www.gnu.org/software/libtool/manual/  GNU autoconf manual : http://www.gnu.org/software/autoconf/  GNU automake manual : http://www.gnu.org/software/automake/manual/  Old book on the Autotools : http://sources.redhat.com/autobook/  Other GNU manuals : http://www.gnu.org/manual/manual.html Some application notes have been uploaded into Sharepoint about the Autotools usage: http://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20- %20doxygen%20documentation%20with%20the%20autotools.docx  http://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20- %20integration%20of%20the%20debug%20mode%20in%20autotools.docx http://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20- %20int%C3%A9gration%20of%20the%20tests%20in%20autotools.docx  http://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20- %20pkgconfig%20with%20the%20autotools.docx http://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20- %20version%20management%20in%20autotools.docx
  • 291.
    Links 2/2 :other useful links http://www.murrayc.com/learning/linux/automake/automake.shtml http://www.murrayc.com/learning/linux/using_libraries/using_libraries.shtml http://www.murrayc.com/learning/linux/building_libraries/building_libraries.shtml http://www.gnu.org/software/libtool/ http://www.gnu.org/software/make/ http://www.gnu.org/software/m4/m4.html http://www.gnu.org/software/m4/manual/m4.html http://www.developingprogrammers.com/index.php/2006/01/05/autotools-tutorial/ http://www.cppfrance.com/tutoriaux/AUTOTOOLS-AUTOCONF-AUTOMAKE-LIBTOOL_876.aspx http://www.lrde.epita.fr/~adl/autotools.html http://inti.sourceforge.net/tutorial/libinti/autotoolsproject.html http://www.cs.wmich.edu/~kkaugars/projects/Automake.html http://www.st-andrews.ac.uk/~iam/docs/tutorial.html http://autotoolset.sourceforge.net/tutorial.html http://www.linuxselfhelp.com/gnu/autoconf/html_chapter/autoconf_toc.html http://media.vodka-pomme.net/autotools/autotools.pdf http://www-igm.univ-mlv.fr/~dr/XPOSE/Breugnot/ http://irt.enseeiht.fr/boyer/Automake-Autoconf/Automake.htm http://ymettier.free.fr/articles_lmag/lmag75/lmag75.html http://sourceware.org/autobook/autobook/autobook_toc.html#SEC_Contents http://developer.kde.org/documentation/other/makefile_am_howto/en/index.html http://git.ademar.org/gitweb.cgi?p=autotools.git;a=summary http://www.flameeyes.eu/autotools-mythbuster/ http://www-igm.univ-mlv.fr/~dr/XPOSE/Breugnot/ http://www.gnu.org/software/gnuradio/doc/howto-write-a-block.html http://www.seul.org/docs/autotut/ http://www-lil.univ-littoral.fr/~quesnel/download/autotools.pdf
  • 292.
  • 293.
    Thanks for yourattention 06/17/10