Autotools
Upcoming SlideShare
Loading in...5
×
 

Autotools

on

  • 479 views

Introduction aux GNU/autotools.

Introduction aux GNU/autotools.

Statistics

Views

Total Views
479
Views on SlideShare
479
Embed Views
0

Actions

Likes
2
Downloads
17
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Autotools Autotools Presentation Transcript

  • AUTOTOOLS : beyond the theory, some practical usageAutotoolsAUTOTOOLS : beyond the theory, some practical usageThierry GAYET (EUROGICIEL)
  • PLAN1. Autotools introduction2. Mastering the build process3. Quick GNU/Make reminder4. The autotools process5. Using the autoscan tool6. The autogen.sh script7. Using libtool7. Using libtool8. The configure.{ac/in} template9. The Makefile.am template10.Using the library’s template11.Using the application’s template12.Many more usage ….13.Conclusion
  • Autotools introductionThe goal of this topic is to know how to well works with the autotools in a cross-compilation environement
  • History :Historically, a shell configure script transformed a Makefile.in into aMakefileAutoconf 1 (1992): autoconf transformed a configure.in into a configurefileThe autotools processAutoconf 2 (1994): added cross-compilation support, sub-directories,hidden results, more tests, …Automake (1994): automake transformed a Makefile.am into a MakefileLibtool (1996): changed the Automake behavior
  • Here is the full power of the autotools in action that make build easier:Autotools introduction
  • The Autotools are a set of scripts (automake, autoconf, aclocal, autoheader, libtools, … )that use M4 macros.Template make the component portable (not dependant from a specific build system)Lot of built-in rules needed for transformations(.c→.o, .c→.s, .o→binary, .c→.a, .c→.so, … )Developers only write basic templates (configure.ac and makefile.am).Well adapt to the cross-compilationTemplates make the makefiles independant of an architectureAutotools introduction6Templates make the makefiles independant of an architectureFinal makefile will be written as standard GNU/make.Lot of built-in features:• Launch the build: make• Clean the environment: make clean or make distclean• Install the build into the stagingdir: make DESTDIR=<PATH> install• Uninstall the build from the stagingdir make DESTDIR=<PATH> uninstall• Generate an archive of the current build: make dist• Many other useful targets…
  • Autotools introductionAutotools is a collection of OSS tools :GNU Automake is a tool for automatically generating `Makefile.in files compliantwith 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. Thesescripts can adapt the packages to many kinds of UNIX-like systems without manual user intervention. Autoconf creates a configuration script for apackage 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 isrecommended) before configuring Autoconf, so that Autoconfs 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 anapplication 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 otherlibraries). 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-configGNU 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, doingarithmetic, 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-definedand can take any number of arguments. Besides just doing macro expansion, m4 has builtin functions for including named files, running UNIXcommands, doing integer arithmetic, manipulating text in various ways, recursion etc... m4 can be used either as a front-end to a compiler or as amacro 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.
  • The GNU Binutils are a collection of binary tools. The main ones are:* ld - the GNU linker.* as - the GNU assembler.But they also include:* addr2line - Converts addresses into filenames and line numbers.* ar - A utility for creating, modifying and extracting from archives.* gprof - Displays profiling information.* nm - Lists symbols from object files.* objcopy - Copies and translates object files.Autotools introduction* objcopy - Copies and translates object files.* objdump - Displays information from object files.* ranlib - Generates an index to the contents of an archive.* readelf - Displays information from any ELF format object file.* size - Lists the section sizes of an object or archive file.* strings - Lists printable strings from files.* strip - Discards symbols.For a cross-compilation usage a prefix is added before the name of the binutils (sh4-linux-ar, sh4-linux-nm, sh4-linux-strip, .... )As well as for the makefile, autotools can be used for the cross-compiling but it can be also used forgenerating pdf, html, latex, … in other words, this is a mechanism for managing file transformationsincluding dependencies.
  • SDK (stagingdir) :Temporary rootfs dedicated tothe target archToolchain :• gcc• headers• host tools• …(Local rootfs) Intermediate installation :make DESTDIR=<STAGINGDIR> installUsed for compilation (headers) : -I<headerpath>Autotools introduction9For each embedded device, another separated SDK is required.Le stagindir peut inclure les hosttools pour n’avoir qu’une zone de dev.Configuration Mngt(SVN, GIT, CC, … )Used for compilation (headers) : -I<headerpath>and links (libraries) : -L<libpath> -l<libname>Real rootfs fortheembedded target RealembeddedtargetFirmwaresFlashingNFSBOOTFinal installation :make DESTDIR=<ROOTFSDIR> install
  • Focus on the staging_dir (aka SDK environment) :/usr /lib libraries (.a/.so/.la)pkgconfig/ pkg-configmetadata (.pc)STAGING_DIRAutotools introduction/include/<comp_namespace>/ header / public API (.h)STAGING_DIRPREFIX(eg: /usr, /local/usr)The staging directory is used as an intermediate filesystem for development purpose.All packages should install their build into (make DESTDIR=<STAGINGDIR> install).This is a reference between packages that need to compile and link with (in other wordsthat have depencencies with external packages).Example: ./configure--prefix=/usr …
  • /usr /lib/include/<comp_namespace>/pkgconfig/SDK/local/stagingInstallation de :- liba.a + liba.so + liba.la dans /usr/lib- liba.pc dans /usr/lib/pkgconfigDependency with A throughPKG_CHECK_MODULE(A)BInstallation de :- libb.a + libb.so + libb.la dans /usr/lib- libb.pc dans /usr/lib/pkgconfigExample dependenciesbewteen twocomponents A and BAutotools introduction# Environment settingSDK=/local/stagingPREFIX=/usr# Configuration./configure --prefix=$(PREFIX)# Compilingmake# Installationmake DESTDIR=$(SDK) install- liba.pc dans /usr/lib/pkgconfig- a.h dans /usr/include# Environment settingSDK=/local/stagingPKG_CONFIG_PATH=$(SDK)/lib/pkgconfigPREFIX=/usr# Configuration./configure --prefix=$(PREFIX)# Va récupérer B_CFLAGS: -I$(SDK)/$(PREFIX)/include# B_LDFLAGS: -L$(SDK)/$(PREFIX)/lib -la# Compilingmake# Installationmake DESTDIR=$(SDK) installAB- libb.pc dans /usr/lib/pkgconfig- b.h dans /usr/includeThe A package don’t have any dependencies except the libc.
  • xxx.pc.inFor each package a developper will ONLY have to managed some templates : Makefile.am + configure.ac• provided by the developers• stored in repository ( CC UCM)config.cacheconfig.logautogen.shautoconfThe autotools process in detail :Autotools introductionMakefile.amconfigure.ac aclocal.m4configureconfig.h.inMakefile.inconfig.hMakefilexxx.pcautomakeautoheaderaclocalUSER VIEWDEV. VIEW
  • Initial preparation :./autogen.shConfiguration :./configure --prefix=/usrCompiling :Autotools introductionCompiling :makeInstallation :make DESTDIR=«stagingdir» install
  • Mastering the build processThe goal of this topic is to know how the build process works.
  • Mastering the build processThe GNU Compiler Collection (GCC) :is a compiler system produced by the GNU Projectis supporting various programming languagesis a key component of the GNU toolchainhas been adopted as the standard compiler by most other modern Unix-like computeroperating systems, including Linux, the BSD family and Mac OS Xhas been ported to a wide variety of processor architecturesis widely deployed as a tool in commercial, proprietary and closed source softwaredevelopment environmentsis also available for most embedded platforms, for example Symbian (called gcce), AMCCand Freescale Power Architecture-based chipsand Freescale Power Architecture-based chipscan target a wide variety of platforms, including videogame consoles such as the PlayStation2 and Dreamcast. Several companies make a business out of supplying and supporting GCCports to various platforms, and chip manufacturers today consider a GCC port almostessential 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 thatyear. 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 anexample.http://gcc.gnu.org
  • Summary :Dynamic library .soStatic library .aObjetcs .oMastering the build processSource code.c / .cppHeaders.hPreprocessinggcc -ELinkingldCompilinggcc -c.oOutputELFObjectAssemblingasgcc --verboseprovides lot of information for each step.
  • C preprocessing:• Lexical preprocessors.• Operate on the source text.• Prior to any parsing by performing simple substitution of tokenizedcharacter sequences.• Typically perform macro substitutions by inlining and templates, textualinclusion of other files, and conditional compilation or inclusion.Mastering the build processinclusion of other files, and conditional compilation or inclusion.• Take lines beginning with # as directivesThis is possible to stop the Compiler at this specific step. The stdout willgenerate the result of the C preprocessing. This command is equivalent to abuild command (compiling or link) with no output file expected:$ gcc -E file.chttp://www.crasseux.com/books/ctutorial/Preprocessor-directives.html
  • Assembler :If the –S parameter is given to gcc, it stops after the compilation stage; it doesnot assemble. The output is in the form of an assembler code file for each non-assembler input file specified.By default, the assembler file name for a source file is made by replacing the suffix.c, .i, etc., with .sMastering the build processInput files that do not require compilation are ignored.Example for getting the assembly code of a .c source code:$ gcc -S file.chttp://homepage.fudan.edu.cn/~euler/gcc_asm/
  • Compiling : the compiler’s frontend :• Parses the source code through a lexical/semantic analyzer (such as GNU/flex) .• Builds an internal representation of the program.• In a first step it generates non-optimized intermediate code.• In a second step it generates optimized intermediate code (if required).• The intermediate code is adapted to the target architecture.Mastering the build processExample for generating an intermediate object:$ gcc -c file.c -o file.o$ file file.ofile.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not strippedGCC = GNU Compiler collectionGCCC JAVA Fortran PascalASM...
  • 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 berunable except for the libc).Mastering the build processrunable except for the libc).Direct usage with the ld linker : $ ld -o mybinary /lib/crt0.o file.o –lccrt0 (or crt0.o, gcrt0.o, mcrt0.o) is a set of execution start-up routines (usually part ofthe C standard library) that are platform dependent, and is required in order to compileusing GCC and other GNU tools. crt stands for "C runtime".-e entryUse entry as the explicit symbol for beginning execution of the program, rather than thedefault entry point (main). If there is no symbol named entry, the linker will try to parseentry as a number, and use that as the entry address (the number will be interpreted inbase 10; you may use a leading 0x for base 16, or a leading 0 for base 8).
  • Mastering the build processGNU tools from the toolchain are set for an embedded usage :--sysroot=staging directoryUse 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 toheader files.The GNU linker (beginning with version 2.16) has the necessary support for this option. If your linker does not support this option, theheader file aspect of --sysroot will still work, but the library aspect will not.Usually te environment is defined like this :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"export NM="$(TOOLCHAIN_DIR)/bin/$(PREFIX)nm”etc …
  • BUILD PORCESS LABMastering the build processBUILD PORCESS LAB
  • Mastering the build processThe main goal of this lab is to know how is working theGNU/Using the helloworld.c source code try several parameters{--verbose/-E/-S}:gcc --verbosegcc -c helloworld.cgcc -c helloworld.c -o helloworld.ogcc -E helloworld.cgcc -S helloworld.c…
  • Quick GNU/make reminderThe goal of this topic is to know how works common GNU/make
  • Quick GNU/make reminderThe final files generated are gnu/make based.Most Makefile.am can be extend with gnu/make features that’s why this isimportant to know how makefiles are made.We will remain some basic makefile usage.
  • The make program gets its dependency "graph" from a text file called makefile orMakefile which resides in the same directory as the source files. Make checks themodification times of the files, and whenever a file becomes "newer" than somethingthat depends on it, (in other words, modified) it runs the compiler accordingly.Quick GNU/make reminder26Project1 is a target and the name of the final binary. Its dependencies are the threeobjects data.o, main.o and io.o. Each one have in teir turn their own dependencies thatmake will resolve one by one.If you edit io.c, it becomes "newer" than io.o, meaning that make must run gcc -c io.c tocreate a new io.o, then run gcc data.o main.o io.o -o project1 for project1.
  • Each dependency shown in the graph is circled with a corresponding color in theMakefile, and each uses the following format:target : source file(s)command (must be preceded by a tab)A target given in the Makefile is a file which will be created or updated when any of itssource files are modified. The command(s) given in the subsequent line(s) (which must bepreceded by a tab character) are executed in order to create the target file.Quick GNU/make reminder27For more information : http://www.gnu.org/doc/doc.html
  • By default make will look for a “Makefile” file. We can specify another one through the –fparameter :$ make –f myMakefile will use myMakefile instead$ make –C /myProject will use the makefile present in /myProject directoryIf no Makefile is found, the make program will display:make: *** No targets specified and no makefile found. Stop.Make is compatible with native code and with cross-compilation. Adding specific rules forusing a toolchain is very easy:Quick GNU/make reminder28CC=$(PREFIX)-gcc.c.o:$(CC) –c $(CFLAG) –o $@ $<Make can get setting from environment variables or parameters:export TOOLCHAIN_BIN=<PATH_TOOLCHAIN>/binexport PREFIX=sh4-linuxormake ARCH=sh CROSS_COMPILE=sh4-linuxthen launch the “make” command.Command used for cross-compiling theGNU/Linux kernel.
  • In addition to those macros which you can create yourself, there are a few macros whichare used internally by the make program.Here are some of those, listed below:CC Contains the current C compiler. Defaults to gcc.CFLAGS Special options which are added to the built-in C rule.$@ Full name of the current target.$? A list of files for current dependency which are out-of-date.Quick GNU/make reminderYou can also manipulate the way these macros are evaluated, as follow, assuming that OBJS =data.o io.o main.o, using $(OBJS:.o=.c) within the Makefile substitutes .o at the end with .c, givingyou the following result: data.c io.c main.cFor debugging a Makefile : $ make -d$? A list of files for current dependency which are out-of-date.$< The source file of the current (single) dependency.LDFLAGS Special options which are added to the link.
  • Compilation and link:Uses “make” from the command line (it will call the default target such as “all”)Will look for the current Makefile or another file given with -f)Does not include lot of default rules and everything should be manually implementedInstallation:Uses “make install” for the command lineNot in standard … should be done by your ownThe install/cp command can be usedInput file.cSeveral targets used by gnu/makefile :Quick GNU/make reminder30The install/cp command can be usedCleaning:Uses “make clean” from the command lineRemove temporally and intermediate objects generateduring the build processArchive/delivery:Uses “make delivery” from the command lineNot in standard … should be also done by your ownThe tar.gz/tar.bz2/.7z/zip/... compression algorithms can be usedTransformationOutput file.c.o
  • With GNU/Makefiles :No target is buildin ; everything should be written from scratcheach 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 ;Quick GNU/make reminderCan make ugly Makefile ;Makefile are often more static than dynamicEverything done by gnu Makefile is automaticallynatively supported by the Autotools ☺☺☺☺ !Everything done by gnu Makefile is automaticallynatively supported by the Autotools ☺☺☺☺ !
  • Other make engine exists:o cmake (http://www.cmake.org/)o qmake (http://doc.qt.nokia.com/4.4/qmake-manual.html)o and so on…For more information about the GNU/make:Quick GNU/make reminderFor more information about the GNU/make:http://oreilly.com/catalog/make3/book/index.csphttp://www.wanderinghorse.net/computing/make/book/ManagingProjectsWithGNUMake-3.1.3.pdfhttp://notendur.hi.is/~jonasson/software/make-book/http://www.gnu.org/software/make/manual/make.pdfhttp://en.wikipedia.org/wiki/Make_(software)#Modern_versionshttp://ecee.colorado.edu/~mcclurel/gnu_make_overview.pdfhttp://static.maemo.org/static/d/dcacc028fda611dd9062b3dd54505f765f76_gnu_make_and_makefiles.pdf
  • GNU/MAKE LABQuick GNU/make reminderGNU/MAKE LAB
  • 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.cQuick GNU/make reminderThe make file should support the following targets:Compilation: make (aka make all)Cleaning old objects: make cleanCreate tarball: make distCreate an installer: make DESTDIR=«PATH» installCreate an uninstaller: make DESTDIR=«PATH» uninstall
  • 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.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.Quick GNU/make reminder
  • The autotools processThe goal of this topic is to know how works the templates are written.
  • Developers, will work only on the followingtemplates:configure.acMakefile.am<component>.pc.inOnly those files will be saved in the repository.The autotools processSTEP 0 : introspection with existing sourcecode. Will generate a configure.san (to berenamed into a configure.ac)STEP 2 : this is what the end user will workwith:./configure …makemake installSTEP 1 : this is an intermediate step doneby the autogen.sh script. This should bedone each time the templates are updated.
  • ./autogen.sh./configure --prefix …make distmake or make –j7make htmlThis target generates adocumentation from thelatest public API (headers).This target generates atarball..Generates the final files (Makefile, config.h, … )The autotools processmake DESTDIR=<PATH> install make checkThis target launches the unitary tests using the Googletest/mock and provides junit.xml report per unit test.If gcov has been set, it will generate some informationthat will be analysed by lcov.--enable-test should be set to the configure scriptlatest public API (headers).This target generates the(cross)compilationand the link of the component.This target intalls the files generatedduring the build process.make DESTDIR=<PATH> uninstallThis target unintalls the files already installed by aprevious install process.
  • The autotools processworking with the autotools means for a developer to manage templates andpotfiles :Makefile.am : used to define what should be build and howusing 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 managingdependencies 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 processSTEP #1 : autogen.shThe 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:o a configure script from the configure.aca Makefile.in form the Makefile.amo a Makefile.in form the Makefile.amo a config.h.in if expectedRoadmap : configure.acconfigure.acconfigure.acconfigure.ac ---|| ------> autoconfautoconfautoconfautoconf* -----> configureconfigureconfigureconfigure[aclocal.m4] --+--- || -----> autoheaderautoheaderautoheaderautoheader* --> [[[[config.h.inconfig.h.inconfig.h.inconfig.h.in]]]]|[acsite.m4] -----Makefile.amMakefile.amMakefile.amMakefile.am -------------------------------> Makefile.inMakefile.inMakefile.inMakefile.in
  • The autotools processSTEP #2 : configuration, compilation and installationThis is the end user view.This step must start by the launch of the configure script in order to generate a finalMakefile:./configure --prefix=/usr …Then, this is possible to use the several target from the Makefile:Targets Descriptionsmakemake –j7make allBuild programs, libraries, documentation, etc …make install Install what needs to be installed, copying the files from the packages tree to system-wide directories.make install-strip Same as make install, then strip debugging symbols. Some users like to trade space for useful bug reports...make uninstall The opposite of make install: erase the installed files. (This needs to be run from the same build tree that wasinstalled.)make clean Erase from the build tree the files built by make all.make distclean Additionally erase anything ./configure created.make check Run the test suite, if any.make installcheck Check the installed programs or libraries, if supported.make dist Recreate package-version.tar.gz from all the source files.and so on…
  • Global summary :STEP 0 : Reverse from the existent source code:your source files --> autoscanautoscanautoscanautoscan****--> [[[[configure.scanconfigure.scanconfigure.scanconfigure.scan]]]] --> configure.acconfigure.acconfigure.acconfigure.acSTEP 1 : preparing a software package :configure.acconfigure.acconfigure.acconfigure.ac ---|| ------> autoconfautoconfautoconfautoconf* -----> configureconfigureconfigureconfigure[aclocal.m4] --+--- || -----> autoheaderautoheaderautoheaderautoheader* --> [[[[config.h.inconfig.h.inconfig.h.inconfig.h.in]]]]|Make by the autogen.sh scriptThe autotools process|[acsite.m4] -----Makefile.amMakefile.amMakefile.amMakefile.am -------------------------------> Makefile.inMakefile.inMakefile.inMakefile.inSTEP 2 : configure/compile/install/… the package:.-------------> [config.cacheconfig.cacheconfig.cacheconfig.cache]]]]|configureconfigureconfigureconfigure* ----------------+-------------> [config.logconfig.logconfig.logconfig.log]||[[[[config.h.inconfig.h.inconfig.h.inconfig.h.in]]]] -- | ----> [[[[config.hconfig.hconfig.hconfig.h]]]] -----| v | ||------ config.statusconfig.statusconfig.statusconfig.status**** ---- | | --> makemakemakemake*| | |Makefile.inMakefile.inMakefile.inMakefile.in --- ----> MakefileMakefileMakefileMakefile ---| |[<comp>.pc.in ]--- -----> [<[<[<[<comp.pccomp.pccomp.pccomp.pc>]>]>]>]Make by the configure script
  • We are seeing the existing files before to launch autoconf :$ cat configure.acAC_INITAC_CONFIG_FILES([Makefile])AC_OUTPUT$ cat Makefile.inprefix = @prefix@datadir = @datadir@We are launching the autoconf (or autoreconf):The autotools processThus, variables between areobases such as@prefix@ will be replace by the valuegiven to the configure script:$ autoconfWe are launching the configuration step:$ configure –prefix=/usr/localconfigure: creating ./config.statusconfig.status: creating Makefileconfig.status: WARNING:Makefile.in seems to ignore the --datarootdir settingWe are consulting the files after the configuring step:$ cat Makefileprefix = /usr/localdatadir = ${prefix}/share@prefix@ /usr/local
  • The autotools processDebugging 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, frequentdiversion 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 programsthat wrap autom4te, such as autoconf), in order to inspect when a macro is called and with which arguments. For example, when thisparagraph was written, the autoconf version could be found by:$ autoconf --trace=AC_INITconfigure.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-3963version is 2.63b.95-3963Another trick is to print out the expansion of various m4 expressions to standard error or to an independent file, with no further m4expansion, and without interfering with diversion changes or the post-processing done to standard output. m4_errprintn shows a givenexpression 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.acAC_INITm4_errprintn([The definition of AC_DEFINE_UNQUOTED:])m4_errprintn(m4_defn([AC_DEFINE_UNQUOTED]))AC_OUTPUTEOF$ autoconferror-->The definition of AC_DEFINE_UNQUOTED:error-->_AC_DEFINE_Q([], $@)
  • Template #1: basic projectmakefile.amconfigure.acautogen.shTemplate for the projectTemplate for the MakefileGenerate the final filesThe autotools process45 06/17/10src/include/If you prefer to generate intermediate objects in a obj/ directory (or src/), you can move themakefile.am to the chosen directory). For information, all the intermediate objects aregenerated in the same directory than the Makefile.am template.Contains all the source codeContains all the headersThe configure.in is equivalent to the configure.ac
  • Template #2 : project with subdirectoriesmakefile.amconfigure.acsrc/include/autogen.shTemplate for the projectMain template for the MakefileGenerate the final filesThe autotools processinclude/module1/module2/makefile.am Sub-template1 for theMakefilesrc/include/makefile.am Sub-template2 for theMakefileAnother project example with subdirectories.
  • • 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 fragmentsautoconf 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 autotools process• 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 anyother 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 theproject self-test suite ;The following steps will take you through creating and building the HelloWorld project. The top-level directory forHelloWorld is <tests/project>. You will find the projects headers and sources in the src subdirectory. There are threefiles: helloworld.cc, helloworld.h and main.cc ;
  • Using an Autotools project at a glanceThen, using this Autotools project is simple:1. Generate the final files from the autotools templates: $ ./autogen.shmakefile.am Makefile.inconfigure.ac configure(it also generate config.h.in if used)2. Launch the configure script with parameters:$ ./configure -–prefix=/usr -–enable-debug3. Launch the compilation: $ make4. Install the files: $ make DESTDIR=${stagingdir} install5. Launch the unitary tests: $ make check6. Generate the documentation: $ make htmlAll the intermediate files have a .in extension ; they will be used as input by the configurescript for generating all the final files.Thus, by providing *.pc.in files we are providing intermediate file ready for the updateprocess…
  • AUTOTOOLS LABThe autotools processAUTOTOOLS LAB
  • The goal of this lab if to use an hello world autotools project.Experiment the several steps :Preparation: ./autogen.shSee the files before and after.The autotools processConfiguration: ./configure –prefix=/usrRead the config.log that detail the configuration step ; this is a good wayto debug a configure script.Compilation: makeInstallation: make DESTDIR=pwd installDelivery: make dist
  • Using the autoscan toolThe goal of this topic is to know how to use the autoscan tool
  • Using the autoscan toolSTEP #0 : autoscanThe easiest way to create a (mostly) complete configure.ac file is to run theautoscan utility, which is part of the autoconf package.This utility examines the contents of a project directory and generates the basis fora configure.ac file (which autoscan names configure.scan) using existing makefilesand source files.The autoscan utility examines the project directory hierarchy and creates two filescalled configure.scan and autoscan.log.called configure.scan and autoscan.log.The project may or may not already be instrumented for Autotools ; it doesn’t reallymatter, because autoscan is decidedly non-destructive. It will never alter anyexisting files in a project.your source files autoscanautoscanautoscanautoscan**** configure.scanconfigure.scanconfigure.scanconfigure.scan configure.acconfigure.acconfigure.acconfigure.ac
  • After the launch of the autoscan tool, two files should appear in the current directory:autoscan.logconfigure.scan should be renamed into a configure.ac file afterwardAs we see, the contents of the generated configure.scan is similar to our hand-craftedtemplate:# -*- Autoconf -*-# Process this file with autoconf to produce a configure script.First example with an empty directory:Using the autoscan toolAC_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_OUTPUTAs the name autoscan implies, you can guess that it can do other things as well, not onlycreate empty configure.ac templates.
  • 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 3intUsing the autoscan toolintmain(){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;}
  • # -*- 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 packages 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.That will automaticaly generate the following configure.scan script:Using the autoscan tool# 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.AC_OUTPUTTo get a very basic, but working input file to autoconf, rename configure.scan toconfigure.ac: mv configure.scan configure.acThen update the AC_INIT macro, and add the AC_COPYRIGHT macro.
  • AUTOSCAN LABUsing the autoscan toolAUTOSCAN LAB
  • Using the autoscan toolThe main goal for this lab is to go into a directory where isexisting source code ;Launch the autoscan command: ./autoscanView the configure.scan generated.
  • The autogen.sh scriptThe goal of this topic is to know how works the autogen.sh script
  • The autogen.sh scriptThe autogen.sh script is used for converting all the templates (configure.ac, Makefile.am, …) infinal files (Makefile, configure, …) needed for a common Autotools usage.Thus, The autogen.sh script (a.k.a. buildconf) provides automatic build system preparation and isgenerally 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 forcompilation, verifying versions, ensuring necessary functionality, and overcoming many commonbuild preparation issues.Official web site : http://buildconf.brlcad.org/Official web site : http://buildconf.brlcad.org/Licence : BSDLatest stable release : 23.12.2009http://downloads.sourceforge.net/project/buildconf/autogen/2009.12.23/buildconf.2009.12.23.tar.gz?use_mirror=freefr&ts=1278845776This script is standalone, its usage is mainly limited to a call in the autotools directory :$ ./autogen.shAnother way is to use the following command: autoreconf -i –force(This is what the script do in background)
  • The autogen.sh scriptfirst, we need to generate the required output files from the two input files configure.in and Makefile.am. First we need tocollect all the macro invocations in configure.in that Autoconf will need to build the configure script. This is done with thefollowing command:$ aclocalThis generates the file aclocal.m4 and adds it to the current directory. Next, run autoconf:$ autoconfAfter running autoconf you will find the configure script in the current directory. Its important to run aclocal first becauseBefore the autoconf script some bootstrap command was used:After running autoconf you will find the configure script in the current directory. Its important to run aclocal first becauseautomake 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 willreport an error. Enter the following command to create these files:$ touch AUTHORS NEWS README ChangeLogNow we can run automake to create Makefile.in. The –add-missing argument copies some boilerplate files from yourAutomake installation into the current directory.$ automake --add-missingBy now, the contents of the directory should be looking a lot like the top-level directory of a GNU package you may haveinstalled before:aclocal.m4 autom4te.cache config.h.in configure.in depcomp install-sh Makefile.in mkinstalldirs README AUTHORSChangeLog configure COPYING INSTALL Makefile.am missing NEWS src
  • The autogen.sh scriptWhat the autogen.sh really do :It tranforms the template into intermediate files:Original file Final fileconfigure.ac/in configureMakefile.am Makefile.inConfig.h.in (if expected)Those files will complete the other files (component.pc.in), in order to beready for the configure script.Note : configure.ac is by far the preferred naming for autoconf >= 2.50 whileconfigure.in is what was used by autoconf ⇐ 2.13 and was kept for *cough*backward compatibility *cough*…
  • The autogen.sh scriptLong name ShortnameDescription Default--help -h Help on autogen.sh usage No--verbose -v Verbose progress output No--quiet -q Quiet suppressed progress output Yes--download -d Download the latest config.guess from gnulib No--version Only perform GNU Build System version checks NoParameters used to control the autogen.sh script :There is two controversal parameters with the --quiet and --verbose that can be set in the same$ ./autogen.sh –versionPreparing the toe build system...please waitFound GNU Autoconf version 2.67Found GNU Automake version 1.11.1Found GNU Libtool version 2.2.6bautogen.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-2009script version 20090301, ISO/IEC 9945 POSIX shell script---Version requested. No preparation or configuration will be performed.Check of the autotools components version:There is two controversal parameters with the --quiet and --verbose that can be set in the sametime!! Indeed, the autogen.sh script will follow the last one provided at the launch.Identical as :./autoconf --version./automake –version./libtool --version
  • The autogen.sh script$ ./autogen.sh –helpUsage: ./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 checksDescription: This script will validate that minimum versions of theGNU Build System tools are installed and then run autoreconf for you.Autogen.sh usage can be obtain with the command line:GNU Build System tools are installed and then run autoreconf for you.Should autoreconf fail, manual preparation steps will be runpotentially accounting for several common preparation issues. TheAUTORECONF, AUTOCONF, AUTOMAKE, LIBTOOLIZE, ACLOCAL,AUTOHEADER,PROJECT, & CONFIGURE environment variables and corresponding _OPTIONSvariables (e.g. AUTORECONF_OPTIONS) may be used to override thedefault 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-2009script version 20090301, ISO/IEC 9945 POSIX shell script---Help was requested. No preparation or configuration will be performed.
  • The autogen.sh script$ ./autogen.shPreparing the toe build system...please waitFound GNU Autoconf version 2.67Found GNU Automake version 1.11.1Found GNU Libtool version 2.2.6bAutomatically preparing build ... doneThe toe build system is now prepared. To build here, run:./configuremakeSilent launch (default):$ ./autogen.sh –verboseVerbose output enabledFound a configure template: ./configure.acPreparing the toe build system...please waitChecking autoreconf version: autoreconf --versionChecking autoconf version: autoconf --versionFound GNU Autoconf version 2.67Checking if 2.67.0 is greater than 2.52.0Checking automake version: automake --versionFound GNU Automake version 1.11.1Checking if 1.11.1 is greater than 1.6.0Checking libtoolize version: libtoolize --versionFound GNU Libtool version 2.2.6bChecking if 2.2.6 is greater than 1.4.2Checking aclocal version: aclocal --versionChecking autoheader version: autoheader --versionChecking whether to only output version informationBacking up COPYING in /home/gayetth/workspace/TOEcp -p COPYING COPYING.25605.protect_from_automake.backupBacking up INSTALL in /home/gayetth/workspace/TOEcp -p INSTALL INSTALL.25605.protect_from_automake.backupFound an autom4te.cache directory, deleting itrm -rf autom4te.cache Verbose launchmake rm -rf autom4te.cachemv -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 -flibtoolize: putting auxiliary files in `..libtoolize: copying file `./config.guesslibtoolize: copying file `./config.sublibtoolize: copying file `./install-shlibtoolize: copying file `./ltmain.shlibtoolize: Consider adding `AC_CONFIG_MACRO_DIR([m4]) to configure.ac andlibtoolize: 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.backupRestoring INSTALL from backup (automake -f likely clobbered it)rm -f INSTALLmv INSTALL.25605.protect_from_automake.backup INSTALLrm -f INSTALL.25605.protect_from_automake.backuprm -f "./config.guess.backup"rm -f "./config.sub.backup"rm -f "./ltmain.sh.backup"doneThe toe build system is now prepared. To build here, run:./configuremakerm -f "./config.guess.backup"rm -f "./config.sub.backup"rm -f "./ltmain.sh.backup"
  • The autogen.sh scriptName Type DescriptionAUTOCONF Boolean Enable/disable the autotconf launchAUTOCONF_VERSION String Specify a specific version for the autoconf packageAUTOCONF_OPTIONS String Specify the parameters to provide to the autoconf toolAUTORECONF Boolean Enable/disable the autotconf launchAUTORECONF_OPTIONS String Specify the parameters to provide to the autoreconf toolAUTOMAKE Boolean Enable/disable the automake launchAUTOMAKE_VERSION String Specify a specific version for the automake packageAUTOMAKE_OPTIONS String Specify the parameters to provide to the automake toolUseful variables used to control the autogen.sh script :To skip autoreconf and prepare manually: AUTORECONF=false ./autogen.shTo verbosely try running with an older (unsupported) autoconf: AUTOCONF_VERSION=2.50 ./autogen.sh --verboseAUTOMAKE_OPTIONS String Specify the parameters to provide to the automake toolLIBTOOLIZE Boolean Enable/disable the libtoolize launchLIBTOOL_VERSION String Specify a specific version for the autoconf packageLIBTOOLIZE_OPTIONS String Specify the parameters to provide to the libtoolize toolACLOCAL Boolean Enable/disable the aclocal launchACLOCAL_OPTIONS String Specify the parameters to provide to the aclocal toolAUTOHEADER Boolean Enable/disable the autoheader launchAUTOHEADER_OPTIONS String Specify the parameters to provide to the autoheader toolCONFIG_GUESS_URL String URL where the latest config.guess file can be download
  • The autogen.sh scriptImpact on the autotools templates:If we take the decision to use the autogen.sh script instead of the single autoreconfcommand, this file is mandatorary to include in the tarball generated by the « makedist » command.EXTRA_DIST = $(top_builddir)/autogen.shThe autogen.sh script should be within the files of the project.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 environmentPKGCONFIG LABPKGCONFIG LAB
  • The autogen.sh scriptTake an autotools project and check the differential beforeand after the launch of the autogen.sh script.Check with the autotools hierarchy poster provided.
  • Using libtoolThe goal of this topic is to know how to uses libtool
  • Using libtoolGNU Libtool simplifies your job by encapsulating both the platform-specific dependencies, and the user interface, ina single script. GNU Libtool is designed so that the complete functionality of each host type is available via a genericinterface, but nasty quirks are hidden from the programmer.GNU Libtools consistent interface is reassuring... users dont need to read obscure documentation in order to havetheir favorite source package build shared libraries. They just run your package configure script (or equivalent), andlibtool does all the dirty work.What libtool can do :
  • Using libtoolLibtool 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), orprograms fail to run.The system must operate consistently even on hosts that dont 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 notalways 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 namesare the same from host to host.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 designthe 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.Motivation for writing libtool :(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 forsuch 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. Theproblem 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 notrequire these tools, so that it can be used by non-GNU packages.Portability to other (non-GNU) architectures and tools is desirable.
  • Using libtoollibtool libtool mode=link CC=sh4-linux-gcc .libs/foo.o –o foobinlibtool mode=compile CC=sh4-linux-gcc –c foo.c -o .libs/foo.o$ libtool --mode=link gcc -g -O -o libhello.la foo.o hello.o*** Warning: Linking the shared library libhello.la against the*** non-libtool objects foo.o hello.o is not portable!ar cru .libs/libhello.aranlib .libs/libhello.a$ libtool --mode=compile gcc -g -O -c foo.cmkdir .libsgcc -g -O -c foo.c -fPIC -DPIC -o .libs/foo.ogcc -g -O -c foo.c -o foo.o >/dev/null 2>&1libtool mode=installSuffix used by libtool :Extension’s name Library BinaryObjects .lo (library object) .oIntermediate .la (library archive)ranlib .libs/libhello.acreating libhello.la(cd .libs && rm -f libhello.la && ln -s ../libhello.la libhello.la)$ libtool --mode=link gcc -g -O -o test test.o /usr/local/lib/libhello.la gcc -g -O -o.libs/test test.o -Wl,--rpath -Wl,/usr/local/lib /usr/local/lib/libhello.a -lm creating test$ libtool --mode=install cp libhello.la /usr/local/lib/libhello.lacp libhello.la /usr/local/lib/libhello.lacp .libs/libhello.a /usr/local/lib/libhello.aranlib /usr/local/lib/libhello.a
  • Using libtoolLibtool is a tool used: libtool [OPTION]... [MODE-ARG]...Parameters Description-n|--dry-run Dont create, modify, or delete any files, just show what commands would be executed by `libtool--mode=MODE Use MODE as the operation mode. By default, the operation mode is inferred from the MODE-ARGS--features Display basic configuration options. This provides a way for packages to determine whether sharedor static libraries will be built--finish Same as --mode=finish--debug Dump a trace of shell script execution to standard output. This produces a lot of output, so you maywish to pipe it to `less (or `more) or redirect to a file--config Display libtool configuration variables and exitMODE Descriptionclean Remove files from the build directorycompile Compile a source file into a `libtool objectexecute Automatically set the library path, then run a programfinish Complete the installation of libtool librariesinstall Install libraries or executableslink Create a library or an executableuninstall Remove libraries from an installed directoryListing of the several modes available:--quiet--silentDont print nformational messages.--tag=TAG Use configuration variables from tag TAG
  • Using libtoolTAGs available :Language name TAG nameC CCC++ CXXJava GCJFortran 77 F77Fortran FCWindows resource RCThe same tags can be overwritten in the autotool context (this often do in aThe same tags can be overwritten in the autotool context (this often do in across-compilation mode):CC=sh4-linux-gcc CXX=sh4-linux-g++ ./configure --prefix=/usr …
  • Using libtool$ libtool --mode=compile gcc -g -O -c foo.cgcc -g -O -c foo.c -o foo.oCompilation mode :Compilation flag Description-o Note that the -o option is now fully supported. It is emulated on the platforms that dont support it (bylocking and moving the objects), so it is really easy to use libtool, just with minor modifications to yourMakefiles.Typing for example: libtool --mode=compile gcc -c foo/x.c -o foo/x.lo will do what you expect.Note, however, that, if the compiler does not support -c and -o, it is impossible to compile foo/x.c withoutoverwriting an existing ./x.o.Therefore, if you do have a source file ./x.c, make sure you introduce dependencies in your Makefile tomake sure ./x.o (or ./x.lo) is re-created after any sub-directorys x.lo: x.o x.lo: foo/x.lo bar/x.lomake sure ./x.o (or ./x.lo) is re-created after any sub-directorys x.lo: x.o x.lo: foo/x.lo bar/x.loThis will also ensure that make wont try to use a temporarily corrupted x.o to create a program or library.It may cause needless recompilation on platforms that support -c and -o together, but its the only way tomake it safe for those that dont.-no-suppress If both PIC and non-PIC objects are being built, libtool will normally suppress the compiler output for thePIC object compilation to save showing very similar, if not identical duplicate output for each object. Ifthe -no-suppress option is given in compile mode, libtool will show the compiler output for both objects.-prefer-pic Libtool will try to build only PIC objects.-prefer-non-pic Libtool will try to build only non-PIC objects.-shared Even if Libtool was configured with --enable-static, the object file Libtool builds will not be suitable forstatic linking. Libtool will signal an error if it was configured with --disable-shared, or if the host does notsupport shared libraries-static Even if libtool was configured with --disable-static, the object file Libtool builds will be suitable for staticlinking-Wc,flag-Xcompiler flagPass a flag directly to the compiler. With -Wc,, multiple flags may be separated by commas, whereas -Xcompiler passes through commas unchanged
  • Using libtoolLink 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 followingcomponents of mode-args are treated specially:Link mode :Compilation flag Description-all-static If output-file is a program, then do not link it against any shared libraries at all. If output-file is a library,then only create a static library. In general, this flag cannot be used together with ‘disable-static’-avoid-version Tries to avoid versioning for libraries and modules, i.e. no version information is stored and no symbolic linksare created. If the platform requires versioning, this option has no effect.-bindir Pass the absolute name of the directory for installing executable programs. libtool may use this value to installshared libraries there on systems that do not provide for any library hardcoding and use the directory of ashared libraries there on systems that do not provide for any library hardcoding and use the directory of aprogram and the PATH variable as library search path. This is typically used for DLLs on Windows or othersystems using the PE (Portable Executable) format. On other systems, -bindir is ignored. The default valueused is libdir/../bin for libraries installed to libdir. You should not use -bindir for modules.-dlopen file Same as -dlpreopen file, if native dlopening is not supported on the host platform or if the program is linkedwith -static, -static-libtool-libs, or -all-static. Otherwise, no effect. If file is self Libtool will make sure thatthe program can dlopen itself, either by enabling -export-dynamic or by falling back to -dlpreopen self.-dlpreopen file Link file into the output program, and add its symbols to the list of preloaded symbols. If file is self, thesymbols of the program itself will be added to preloaded symbol lists. If fileis force Libtool will make sure thata preloaded symbol list is always defined, regardless of whether its empty or not.-export-dynamic Allow symbols from output-file to be resolved with dlsym-export-symbols symfileTells the linker to export only the symbols listed in symfile. The symbol file should end in .sym and mustcontain the name of one symbol per line. This option has no effect on some platforms. By default all symbolsare exported.-export-symbols-regex regexame as -export-symbols, except that only symbols matching the regular expression regex are exported. Bydefault all symbols are exported.
  • Using libtoolCompilation flag Description-Llibdir Search libdir for required libraries that have already been installed-lname output-file requires the installed library libname. This option is required even when output-file is not anexecutable-module reates a library that can be dlopened. This option doesnt work for programs. Module names dont need to beprefixed with ‘lib’. In order to prevent name clashes, however, libname and name must not be used at thesame time in your package-no-fast-install Disable fast-install mode for the executable output-file. Useful if the program wont be necessarily installed-no-install Link an executable output-file that cant be installed and therefore doesnt need a wrapper script on systemsthat allow hardcoding of library paths. Useful if the program is only used in the build tree, e.g., for testing orLink mode (cont)that allow hardcoding of library paths. Useful if the program is only used in the build tree, e.g., for testing orgenerating other files.-no-undefined Declare that output-file does not depend on any other libraries. Some platforms cannot create shared librariesthat depend on other libraries-o output-file Create output-file from the specified objects and libraries.-objectlist file Use a list of object files found in file to specify objects.-precious-files-regex regexPrevents removal of files from the temporary output directory whose names match this regular expression.You might specify ‘.bbg?$’ to keep those files created with gcc -ftest-coverage for example.-release release Specify that the library was generated by release release of your package, so that users can easily tell whichversions are newer than others. Be warned that no two releases of your package will be binary compatible ifyou use this flag. If you want binary compatibility, use the -version-info flag instead-rpath libdir output-file is a library, it will eventually be installed in libdir. If output-file is a program, add libdir to therun-time path of the program. On platforms that dont support hardcoding library paths into executables andonly search PATH for shared libraries, such as when output-file is a Windows (or other PE platform) DLL,the .la control file will be installed in libdir, but see -bindir above for the eventual destination of the .dll orother library file itself.
  • Using libtoolCompilation flag Description-R libdir If output-file is a program, add libdir to its run-time path. If output-file is a library, add -Rlibdir toits dependency_libs, so that, whenever the library is linked into a program, libdir will be added to its run-timepath.-shared If output-file is a program, then link it against any uninstalled shared libtool libraries (this is the default behavior).If output-file is a library, then only create a shared library. In the later case, libtool will signal an error if it wasconfigured with --disable-shared, or if the host does not support shared libraries.-shrext suffix If output-file is a libtool library, replace the systems standard file name extension for shared librarieswith suffix (most systems use .so here). This option is helpful in certain cases where an application requires thatshared libraries (typically modules) have an extension other than the default one. Please note you must supply thefull file name extension including any leading dot.-static If output-file is a program, then do not link it against any uninstalled shared libtool libraries. If output-file is alibrary, then only create a static library.-static-libtool-libs If output-file is a program, then do not link it against any shared libtool libraries. If output-file is a library, thenonly create a static library.Link mode (cont)only create a static library.-version-info current[:revision[:age]]If output-file is a libtool library, use interface version information current, revision, and age to build it. Do not usethis flag to specify package release information, rather see the -release flag.-version-number major[:minor[:revision]]If output-file is a libtool library, compute interface version information so that the resulting library uses thespecified major, minor and revision numbers. This is designed to permit libtool to be used with existing projectswhere identical version numbers are already used across operating systems. New projects should use the -version-info flag instead.-weak libname if output-file is a libtool library, declare that it provides a weak libname interface. This is a hint to libtool thatthere is no need to append libname to the list of dependency libraries of output-file, because linkingagainst output-file already supplies the same interface-Wc,flag-Xcompiler flagPass a linker-specific flag directly to the compiler. With -Wc,, multiple flags may be separated by commas,whereas -Xcompiler passes through commas unchanged.-Wl,flag-Xlinker flag Pass a linker-specific flag directly to the linker-XCClinker flag Pass a link-specific flag to the compiler driver (CC) during linking.
  • If the output-file ends in .la, then a libtool library is created, which must be built only from libraryobjects (.lo files). The -rpath option is required. In the current implementation, libtool libraries maynot 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 (generallyusing ‘ld -r’). This method is often called partial linking.Using libtoolLink mode (cont)Otherwise, an executable program is created.
  • Using libtoolExecution mode :Compilation flag DescriptionFor 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 thatprogram.The following components of mode-args are treated specially:-dlopen file Add the directory containing file to the library pathThis mode sets the library path environment variable according to any -dlopen flagsIf any of the args are libtool executable wrappers, then they are translated into the name of theircorresponding uninstalled binary, and any of their required library directories are added to thelibrary path.
  • Using libtoolInstallation mode :In install mode, libtool interprets most of the elements of mode-args as an installation command beginning with cp, or a BSD-compatible installprogram.The following components of mode-args are treated specially:-inst-prefix-dir inst-prefix-dirWhen installing into a temporary staging area, rather than the final prefix, this argument is used to reflect the temporary path, in much thesame 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/libnot# Directory that this library needs to be installed in:libdir=/tmp/usr/local/lib‘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 theexpected 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 fastinstallation 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 theirfinal location.The rest of the mode-args are interpreted as arguments to the cp or install command.The command is run, and any necessary unprivileged post-installation commands are also completed.
  • Using libtoolFinish mode :Compilation flag Description--dry-run Running this command may require superuser privileges, and the --dry-run option may be usefulFinish mode has two functions. One is to help system administrators install libtool libraries so thatthey 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 afterThe second is to facilitate transferring libtool libraries to a native compilation environment afterthey were built in a cross-compilation environment. Cross-compilation environments may rely onrecent libtool features, and running libtool in finish mode will make it easier to work with olderversions of libtool. This task is performed whenever the mode-arg is a .la file.
  • Using libtoolUninstall 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 thenames of files to delete.
  • Using libtoolClean mode :Clean mode deletes uninstalled libraries, executables, objects and libtools temporary files associatedwith 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 thenames of files to delete.
  • Using libtoolLIBTOOL LABLIBTOOL LAB
  • Using libtoolThe 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.oLibtool --mode=compile gcc -c helloworld.cSame for the link step (should create a helloworld binary):gcc helloworld.o –o helloworldlibtool --mode=link gcc –o helloworld helloworld.o
  • The configure.{ac/in} templateThe goal of this topic is to know how to write a configure.ac template.
  • The configure.{in/ac} templateA configure.ac is the template of the configure script that will be used bythe end user.A configure.ac is written using M4 macros while a configure script is ashell script.The main goal of a configure script is to lead the configuration of acomponent. The several flags provided to the configure script is like the IDcard of the build.card of the build.The configure.ac teamplate is equal to the configure.in that is the oldnotation.Those script are executed like shell script at the runtime (no compiled).Can build libraries, binaries, … in the same files, by managingdependencies.
  • The configure.{in/ac} templateCheck for programsCheck for (dynamic/static) librariesCheck for header filesCheck for typedefsVersion managementInitialisationSeveral usual stepsused by the configurationscript.Check for structuresCheck for compiler characteristicsCheck for libraries functionsCheck for system servicesGenerate output filesThere is M4 macros for each step…script.
  • Variable name Descriptionsrcdir The name of the directory that contains the source code for that makefile.top_srcdir The name of the top-level source code directory for the package. In the top-level directory, this is the sameas srcdir.top_builddir The relative name of the top level of the current build tree. In the top-level directory, this is the sameas builddir.abs_builddir Absolute name of builddir.builddir Rigorously equal to ‘.’. Added for symmetry only.top_build_prefix The relative name of the top level of the current build tree with final slash if nonemtpy. This is the samePreset Output Variables :The configure.{in/ac} templateBeware 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 !!top_build_prefix The relative name of the top level of the current build tree with final slash if nonemtpy. This is the sameas top_builddir, except that it contains zero or more runs of ../, so it should not be appended with a slash forconcatenation. This helps for make implementations that otherwise do not treat ./file and file as equal in thetoplevel build directory.abs_srcdir Absolute name of srcdir.abs_top_srcdir Absolute name of top_srcdir.abs_top_builddir Absolute name of top_builddir.
  • The configure.{in/ac} templateVariable name DescriptionLDFLAGS Options for the linkerLIBS -l options to pass to the linker. The default value is empty, but some Autoconf macros may prepend extralibraries to this variable if those libraries are found and provide necessary functions. configure uses thisvariable when linking programs to test for C, C++.OBJCFLAGS Debugging and optimization options for the Objective C compiler. It acts like CFLAGS, but for Objective Cinstead of C.CXXFLAGS Debugging and optimization options for the C++ compiler. It acts like CFLAGS, but for C++ instead of C.DEFS -D options to pass to the C compiler. If AC_CONFIG_HEADERS is called, configure replaces ‘@DEFS@’Flags overriding :http://www.gnu.org/software/hello/manual/autoconf/Preset-Output-Variables.htmlDEFS -D options to pass to the C compiler. If AC_CONFIG_HEADERS is called, configure replaces ‘@DEFS@’with -DHAVE_CONFIG_H instead. This variable is not defined while configure is performing its tests, onlywhen creating the output files.CFLAGS Debugging and optimization options for the C compiler. If it is not set in the environmentwhen configure runs, the default value is set when you call AC_PROG_CC (or empty if youdont).configure uses this variable when compiling or linking programs to test for C features.CPPFLAGS Preprocessor options for the C, C++, Objective C, and Objective C++ preprocessors and compilers. If it isnot set in the environment when configure runs, the default value is empty.configure uses this variablewhen preprocessing or compiling programs to test for C, C++, Objective C, and Objective C++ features.configure_input A comment saying that the file was generated automatically by configure and giving the name of theinput file. AC_OUTPUT adds a comment line containing this variable to the top of every makefile itcreates. For other files, you should reference this variable in a comment at the top of each input file.OBJCXXFLAGS Debugging and optimization options for the Objective C++ compiler. It acts like CXXFLAGS, but forObjective C++ instead of C++.
  • The configure.{in/ac} templateVariable’s name Description Variable associatedCC C compiler CFLAGSLD Linker LDFLAGSCXX C++ compiler CXXFLAGSTMPDIR Path used for compiling any source codeAR Tools used for creating static librariesTools overriding :NM Tool used for extraing sysmbolsetc..Examples:./configure –prefix=/usrCC=gcc CFLAGS=-O3 LIBS=“-lposix” …orCC=sh4-linux-gcc AR=sha-linux-g++ ./configure –prefix=/usr …
  • The configure.{in/ac} templateSpecial Characters in Output Variables :Many output variables are intended to be evaluated both by make and by the shell. Somecharacters are expanded differently in these two contexts, so to avoid confusion thesevariables values should not contain any of the following characters: " # $ & ( ) * ; < > ? [ ^ ` |Also, these variables values should neither contain newlines, nor start with ‘~’, nor containwhite space or ‘:’ immediately followed by ‘~’. The values can contain nonemptysequences of white space characters like tabs and spaces, but each such sequence mightsequences of white space characters like tabs and spaces, but each such sequence mightarbitrarily be replaced by a single space during substitution.These restrictions apply both to the values that configure computes, and to the values setdirectly by the user. For example, the following invocations of configure are problematic,since they attempt to use special characters within CPPFLAGS and white spacewithin $(srcdir):CPPFLAGS=-DOUCH="&"#$*?" ../My Source/ouch-1.0/configure../My Source/ouch-1.0/configure CPPFLAGS=-DOUCH="&"#$*?"
  • The configure.{in/ac} templateMacros DefinitionAC_INITPerforms essential initialization for the generated configure script. It takesas an argument a filename from the source directory, to ensure that thesource directory has been specified correctly.AM_INIT_AUTOMAKEDoes all the standard initialization required by Automake and takes twoarguments, the package name and version number.INTI_REQUIRED_VERSION Specifies the minimum required Inti version, in this case 1.0.7.Some of the useful built-in M4 macros:PKG_CHECK_MODULESChecks for the specified version of the Inti library and if found places thenecessary include flags in $(INTI_CFLAGS) and the libraries to link with$(INTI_LIBS). If the correct version is not found configure will report an error.AC_PROG_CXX Checks for the C++ compiler and sets the variables CXX, GXX and CXXFLAGS.AC_OUTPUT Must be called at the end of configure.in to create the Makefiles.There are many others ; check the gnu/autoconf manual for moreInformation (http://www.gnu.org/software/autoconf/manual/autoconf.pdf).
  • AC_PREREQ(2.59)AC_INIT([pyPackage], [myPackageVersion], [thierry.gayet2@technicolor.com])AC_ARG_ENABLE( debug,AS_HELP_STRING([--enable-debug],[enable debugging support]),[enable_debug=$enableval],[enable_debug=no] )if test "$enable_debug" = "yes" ; thenCXXFLAGS="$CXXFLAGS -Wall -ggdb -O0"InitializationCheck for the debug modeExample of configure.{in/ac} template using some m4 macros :The configure.{in/ac} templateCXXFLAGS="$CXXFLAGS -Wall -ggdb -O0"AC_DEFINE(DEBUG, 1, [Define to enable debug build])elseCXXFLAGS="$CXXFLAGS -Wall -O2"fiPKG_CHECK_MODULES([DIRECTFB],[directfb],[have_libdirectfb=yes],[have_libdirectfb=no])if test "$have_libdirectfb" = no ; thenAC_MSG_ERROR([Missing directfb-1.4.1 library!!])fiAC_OUTPUT(Makefile) File to generate from the Makefile.amtemplateCheck for the libdirectfb library
  • dnl ---------------------------------------dnl Load m4 macrosdnl ---------------------------------------(…)Adding comments or disabling lines into the configure.ac :1. Official comments that are important and should stay in the configure.ac file using the dnl keyword :2. Lines that are temporaly/definitively disabling in the configure file :The configure.{in/ac} templateAC_CANONICAL_HOST#AC_CANONICAL_TARGETAC_SUBST(PACKAGE_VERSION)Line disabled!!
  • The configure.{in/ac} templatePrinting messages :Configure scripts need to give users running them several kinds of information. The following macros print messagesin ways appropriate for each kind. The arguments to all of them get enclosed in shell double quotes, so the shellperforms 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 ofthe check and the newline. The feature-descriptionshould be something like ‘whether the Fortran compiler acceptsC++ comments’ or ‘for c89’. This macro prints nothing if configure is run with the --quiet or --silent option. This isquite similar to a echo -n.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 thecheck, 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 printsnothing if configure is run with the --quiet or --silent option. This is quite similar to an echo after an echo -n, so it willbe 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} templateMacros 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 groupof feature checks, e.g., AC_MSG_NOTICE([checking if stack overflow is detectable]). This macro prints nothingif 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 thestandard error output and exits configure with exit-status (‘$?’ by default, except that ‘0’ is converted to ‘1’). error-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 witha lower-case letter, and “cannot” is preferred to “cant”.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 thatadditional details are provided in config.log. This is typically used when abnormal results are found during acompilation.Examples:AC_MSG_NOTICE(“this is just a message”)
  • 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 ameans 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]) # goodArguments should be enclosed within the quote characters ‘[’ and ‘]’, and be separated by commas. Any leading blanks or newlines inarguments 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 othermacros.The configure.{in/ac} templateAC_COPYRIGHT (copyright-notice)State that, in addition to the Free Software Foundations copyright on the Autoconf macros, parts of your configure are covered by thecopyright-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 informationabout your project, including the project name, version number, bug-reporting address, tarball name and the projecthomepage.o AC_PREREQ(2.59) specify the autoconf versionOthers 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 (NEWSREADME AUTHORS ChangeLog).
  • The configure.{in/ac} templateAC_CONFIG_SRCDIR(unique-file-in-source-dir)unique-file-in-source-dir is some file that is in the packages source directory; configure checks for this files existence to make sure thatthe 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 findsome 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 indirectory 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 doesnot automatically require distributing the other auxiliary files. It checks for install.sh also, but that name is obsolete because some makehave a rule that creates install from it if there is no makefile. The auxiliary directory is commonly named build-aux. If you needPATH and source code definition :have a rule that creates install from it if there is no makefile. The auxiliary directory is commonly named build-aux. If you needportability 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 tracedby third-party tools to produce a list of expected auxiliary files. For instance it is called by macros like AC_PROG_INSTALL (seeParticular Programs) or AC_CANONICAL_BUILD (see Canonicalizing) to register the auxiliary files they need. Similarly, packages thatuse 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 likeautoreconf that trace macro calls. It should be called directly from configure.ac so that tools that install macros for aclocal can find themacros declarations. Note that if you use aclocal from Automake to generate aclocal.m4, you must also set ACLOCAL_AMFLAGS = -Idir in your top-level Makefile.am. Due to a limitation in the Autoconf implementation of autoreconf, these include directives currentlymust be set on a single line in Makefile.am, without any backslash-newlines.
  • The configure.{in/ac} templateChecking 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 andonly if the system has unistd.h./* Define as 1 if you have unistd.h. */ #undef HAVE_UNISTD_HThe format of the template file is stricter than what the C preprocessor is required to accept. A directive line should contain onlywhitespace, ‘#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’, arecopied verbatim from the template into the generated header.
  • The configure.{in/ac} templateDefault 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 softwarepackages 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 havealready 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 waythe shell does. If program is found, set the prefix to the parent of the directory containing program, else default the prefix as describedthe shell does. If program is found, set the prefix to the parent of the directory containing program, else default the prefix as describedabove (/usr/local or AC_PREFIX_DEFAULT). For example, if program is gcc and the PATH contains /usr/local/gnu/bin/gcc, set theprefix 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 theconfigure launch.If not we should mantadory specify the prefix: ./configure --prefix=/usr
  • In order to prevent autotools re-generating configure script automatically this is possible tospecify that we are in maintainer mode :Sometimes due to the SCM not strictly remembering the timestamp of files the generated Makefile will think that itneeds to re-run "autoreconf -i" or equivalent to re-generate Makefile.in from Makefile.am, configure fromconfigure.ac, etc.You need to look into maintainer mode - that should prevent the autoreconf step, which will fix the end-usersproblems.In order to proceed, the following line should be add to the configure.ac:The configure.{in/ac} templateAM_MAINTAINER_MODEOr provide set the --enable-maintainer-mode parameter to the configure script :./configure --prefix=/usr --enable-maintainer-mode
  • Managing version numbers for dynamic libraries:Your library can have two numbers - the release number and the version number.The release number uses a scheme of your own devising. Generally it indicates how much functionality has been added sincethe last version, and how many bugs were fixed.The version number uses an established scheme to indicate what type of changes happened to your librarys interface. Thefollowing diagram can be found in many configure.ac files:FOO_LIBRARY_RELEASE=2:1:3 FOO_LIBRARY_VERSION=3:0:0current : revision : ageThe configure.{in/ac} templatecurrent : revision : ageUse this version number in your Makefile.am file:lfoo_la_LDFLAGS= -version-info $(FOO_LIBRARY_VERSION) -release $(FOO_LIBRARY__RELEASE)If the config.h header is used, the version will be pushed into this file. In the other case, it will be providedinto the compilation line. For a library, the delivery will generate a dynamic library using the version (eg:libfake.so.1.0.2) using a symbolic link to the native dynamic library (eg: libfake.so). This is nice to also have abuildin function (eg: get_API_version) that can provide the PACKAGE_VERSION metadata.increment if interfaces have been added | | set tozero if interfaces have been removed | | or changedIncrement if source code has changed | set tozero if current is incrementedincrement if interfaces have been added,removed or changed
  • The configure.{in/ac} templateNumbers Definitioncurrent The number of the current interface exported by the library. A current value of `0, means that you arecalling the interface exported by this library interface 0.The version scheme used by Libtool tracks interfaces, where an interface is the set of exported entrypoints into the library.All Libtool libraries start with `-version-info set to `0:0:0 -- this will be the default version number ifyou dont explicitly set it on the Libtool link command line.The meaning of these numbers (from left to right) is as follows:calling the interface exported by this library interface 0.revision The implementation number of the most recent interface exported by this library. In this case,a revision value of `0 means that this is the first implementation of the interface.If the next release of this library exports the same interface, but has a different implementation (perhapssome bugs have been fixed), the revision number will be higher, but current number will be the same. Inthat case, when given a choice, the library with the highest revision will always be used by the runtimeloader.age The number of previous additional interfaces supported by this library. If age were `2, then this library canbe linked into executables which were built with a release of this library that exported the currentinterface number, current, or any of the previous two interfaces. By definition age must be less than orequal to current. At the outset, only the first ever interface is implemented, so age can only be `0.Beware, this can generate a warning if you want to generate a static library.
  • m4_define([gm_os_major_version], [1])m4_define([gm_os_minor_version], [0])m4_define([gm_os_micro_version], [0])m4_define([gm_os_version],[gm_os_major_version.gm_os_minor_version.gm_os_micro_version])AC_INIT([gm_os_posix],[gm_os_version],[thierry.gayet2@technicolor.com])LT_CURRENT=0LT_REVISION=0LT_AGE=0AC_SUBST(LT_CURRENT)In few steps, we can manage a package’s version:The configure.{in/ac} template Configure.acAC_SUBST(LT_CURRENT)AC_SUBST(LT_REVISION)AC_SUBST(LT_AGE)GM_OS_MAJOR_VERSION=gm_os_major_versionGM_OS_MINOR_VERSION=gm_os_minor_versionGM_OS_MICRO_VERSION=gm_os_micro_versionGM_OS_VERSION=gm_os_major_version.gm_os_minor_version.gm_os_micro_versionAC_SUBST(GM_OS_MAJOR_VERSION)AC_SUBST(GM_OS_MINOR_VERSION)AC_SUBST(GM_OS_MICRO_VERSION)AC_SUBST(GM_OS_VERSION)AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) Configure.ac
  •  Makefile.amThe configure.{in/ac} templatelib_LTLIBRARIES = libtoe.lalibtoe_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.hlibtoe_la_CFLAGS = -I$(HEADER_DIR) Example of Makefile.am template that use the version: Makefile.amlibtoe_la_CFLAGS = -I$(HEADER_DIR) $(LIBCONFIG_CFLAGS) $(LIBLOG_CFLAGS) -DLOG_NAME=TOE -DLOG_MASK_PRIO=LOG_PRIO_ALLlibtoe_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -lpthread -lrtlibtoe_la_LIBADD = $(LIBCONFIG_LIBS) $(LIBLOG_LIBS) $(EFENCE_LIBS)
  • Then we can check if the tools needed for the compilation exist as well as their version:Some are buildin m4 macro povided by the autoconf package :AC_C_CONSTAC_ISC_POSIXAC_HEADER_STDCAC_PROG_CCAC_PROG_CC_STDCAC_PROG_CXXChecking for the tools expected for the build:The configure.{in/ac} templateAC_PROG_CXXAC_PROG_CPPAC_PROG_LN_SAC_PROG_INSTALLAC_PROG_LIBTOOLAC_PROG_MAKE_SETOthers can be test manualy:AC_PATH_PROG([PKG_CONFIG], [pkg-config])if test -z "$PKG_CONFIG" ; thenAC_MSG_ERROR([pkg-config not found])fi
  • Checking for the dependencies (static/dynamic libraries) :For a complete automatic build process, it can be useful to get metadata from a library (version, name, cflags,ldflags, …. ). This is what pkg-config brings to the OSS community:Example: resolution of a dependancy:# libglib2.0 dependencyPKG_CHECK_MODULES([GLIB2],[glib-2.0],[have_libglib=yes],[have_libglib=no])if test "$have_libglib" = no ; thenAC_MSG_ERROR([Missing libglib-2.0 library])elseAC_SUBST(GLIB2_CFLAGS)The configure.{in/ac} templateAC_SUBST(GLIB2_CFLAGS)AC_SUBST(GLIB2_LIBS)fiThis will check the presence of the .pc file that contains the metdata (usually in /usr/local/lib/pkg-config):$ pkg-config –-exist libnameThe PKG_CONFIG_PATH should be set to the directory that contain the .pc files.Then the M4 macro will export both the CFLAGS and the CFLAGS :$ pkg-config –-cflags libname$ pkg-config –-libs libnameThis topic will be detail with the chapter related to pkg-config.
  • 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; thenmy_subdirs="$my_subdirs foo"fiAC_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; thenAC_CONFIG_SUBDIRS([foo])fiThe configure.{in/ac} templatefiIf 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"; thenAC_CONFIG_SUBDIRS([foo])fiIf a given dir contains configure.gnu, it is run instead of configure. This is for packages that might use a non-Autoconf scriptConfigure, which cant 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.
  • 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 ofwhether 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 thatsince the value of fstype is under our control, we dont 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])The configure.{in/ac} templatefstype=SVR4])if test $fstype = no; thenAC_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])fiif test $fstype = no; thenAC_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])
  • 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 suffixedby a parenthesized argument list to define a C preprocessor macro with arguments. The macro argument list, if present, should be acomma-separated list of C identifiers, possibly terminated by an ellipsis ‘...’ if C99 syntax is employed. variable should not containcomments, 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 rawnewlines. If you are not using AC_CONFIG_HEADERS, value should not contain any ‘#’ characters, as make tends to eat them. To use ashell variable, use AC_DEFINE_UNQUOTED instead.The configure.{in/ac} templateCreating variables exported to the Makefiles :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 thecomment 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 witholder 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 onewins.All variables exported to the Makefile.am will be given either the command line (-D<VAR_NAME>=<VALUE>) or a config.h header.
  • 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 (‘$’), commandsubstitution (‘`’), and backslash escaping (‘’), as if in an unquoted here-document. Single and double quote characters in the value haveno 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_UNQUOTEDThe configure.{in/ac} templateDue to a syntactical bizarreness of the Bourne shell, do not use semicolons to separate AC_DEFINE or AC_DEFINE_UNQUOTEDcalls 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:AC_CHECK_HEADER([elf.h],[AC_DEFINE([SVR4], [1], [System V Release 4]); LIBS="-lelf $LIBS"])
  • AC_SUBST (variable, [value])Create an output variable from a shell variable. Make AC_OUTPUT substitute the variable variable into output files (typically one ormore makefiles). This means that AC_OUTPUT replaces instances of ‘@variable@’ in input files with the value that the shell variablehas 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 youmight want to consider using AM_SUBST_NOTMAKE to prevent automake from adding a line variable = @variable@ to theMakefile.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 theoutput file. (The algorithm uses the special marker |#_!!_#| internally, so neither the substituted value nor the output file may containThe configure.{in/ac} templateoutput 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.
  • AM_CONDITIONAL (conditional, condition):The conditional name, conditional, should be a simple string starting with a letter and containing only letters, digits, and underscores. Itmust 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 everyAM_CONDITIONAL to be invoked every time configure is run. If AM_CONDITIONAL is run conditionally (e.g., in a shell ifstatement), 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 aconditional that is true if the user uses the --enable-debug option.AC_ARG_ENABLE([debug],[ --enable-debug Turn on debugging],The configure.{in/ac} template[ --enable-debug Turn on debugging],[case "${enableval}" inyes) 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 DEBUGDBG = debug_programelseDBG =endifnoinst_PROGRAMS = $(DBG)
  • 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 causeautomake 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_ENABLE (feature, help-string, [action-if-given], [action-if-not-given])If the user gave configure the option --enable-feature or --disable-feature, run shell commands action-if-given. If neither option wasgiven, run shell commands action-if-not-given. The name feature indicates an optional user-level facility. It should consist only ofalphanumeric characters, dashes, plus signs, and dots.The options argument is available to the shell commands action-if-given in the shell variable enableval, which is actually just the valueof the shell variable named enable_feature, with any non-alphanumeric characters in feature changed into ‘_’. You may use that variableinstead, if you wish.AC_ARG_ENABLE(instrumenting,AS_HELP_STRING([--enable-instrumenting], [Enable the test instrumenting support [default=no]]),[case "${enableval}" inyes) have_instrumenting=true ;;The configure.{in/ac} templateValue if the --enable-instrumenting is provided to the configureyes) have_instrumenting=true ;;no) have_instrumenting=false ;;*) AC_MSG_ERROR(bad value ${enableval} for --enable-instrumenting) ;;esac],[have_instrumenting=false])# Export HAVE_INTRUMENTING to the MakefilesAM_CONDITIONAL(HAVE_INTRUMENTING, $have_instrumenting)AC_MSG_CHECKING(Checking the intrumenting support)if test "$have_instrumenting" != "false" ; thenAC_MSG_RESULT(yes)AC_DEFINE(INSTRUMENTING, 1, [Define for the instrumenting support])elseAC_MSG_RESULT([no])fiValue is neither the parameters --enable-instrumenting nor --disable-instrumentingare provided to the configure script.Value if the --enable-instrumenting is provided to the configureValue if the --disable-instrumenting is provided to the configure
  • 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 wasgiven, run shell commands action-if-not-given. The name package indicates another software package that this program should workwith. It should consist only of alphanumeric characters, dashes, plus signs, and dots.The options argument is available to the shell commands action-if-given in the shell variable with val, which is actually just the valueof the shell variable named with_package, with any non-alphanumeric characters in package changed into ‘_’. You may use thatvariable instead, if you wish.The argument help-string is a description of the option that looks like this:--with-readline support fancy command line editingThe configure.{in/ac} templatehelp-string may be more than one line long, if more detail is needed. Just make sure the columns line up in ‘configure --help’. Avoidtabs in the help stringAC_ARG_WITH([readline],[AS_HELP_STRING([--without-readline],[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])])
  • Configure scripts have predefined rules and targets (which can be redefined) that can becustomized using macros:AC_ARG_ENABLE(test,AS_HELP_STRING([--enable-test], [Enable the test unitarysupport [default=no]]),[case "${enableval}" inyes) have_test=true ;;no) have_test=false ;;*) AC_MSG_ERROR(bad value ${enableval} for --enable-test) ;;esac],[have_test=false])boolean switchUsage: ./configure –enable-testThe configure.{in/ac} template[have_test=false])The listing of the available parameters can be displayed: $ ./configure --helpAC_ARG_WITH(optim-level,AS_HELP_STRING([--with-optim-level=<0,1,2,3>],[Provide theoptim level to give to gcc as -O<level>]),[current_optim_level=$withval],[current_optim_level=0])Switch with valueUsage: ./configure –with-optim-level=2
  • Example of integrating of the debug mode :AC_ARG_ENABLE(debug,AS_HELP_STRING([--enable-debug], [Enable the debug support [default=no]]),[case "${enableval}" inyes) have_debug=true ;;no) have_debug=false ;;*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;esac],[have_debug=false])AM_CONDITIONAL(HAVE_DEBUG, $have_debug)AC_MSG_CHECKING([Checking the debug support])if test "$have_debug" = "true" ; thenAC_MSG_RESULT([yes])The configure.{in/ac} templateAC_MSG_RESULT([yes])AC_DEFINE(DEBUG, 1, [Define to enable debug mode])DEBUG_CFLAGS=" -ggdb"DEBUG_CPPFLAGS=" -ggdb"DEBUG_LDFLAGS=" »m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([no])])Elsem4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])AC_MSG_RESULT([no])fiUsage: ./configure –enable-debugIf set, it will set all the flags needed in debug mode ; it will disable the silent mode.
  • The configure.{in/ac} templateConfiguring Other Packages in SubdirectoriesIn most situations, calling AC_OUTPUT is sufficient to produce makefiles in subdirectories. However, configure scripts that control more than oneindependent 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 notuse:if test "x$package_foo_enabled" = xyes; thenmy_subdirs="$my_subdirs foo"fiAC_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; thenAC_CONFIG_SUBDIRS([foo])AC_CONFIG_SUBDIRS([foo])fiIf 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"; thenAC_CONFIG_SUBDIRS([foo])fiIf 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 cant becalled through a wrapper configure since it would be the same file on case-insensitive file systems. Likewise, if a dir containsconfigure.in butno configure, the Cygnus configure script found by AC_CONFIG_AUX_DIR is used.The subdirectory configure scripts are given the same command lineoptions 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 thesubdirectory configure differ.This macro also sets the output variable subdirs to the list of directories ‘dir ...’. Make rules can use this variable todetermine which subdirectories to recurse into.This macro may be called multiple times.
  • The configure.{in/ac} templateGenerating final files :It can be Makefiles, .pc files, config.h headers and so on :AC_CONFIG_FILES([Makefilesrc/Makefilefoo.pc])AC_OUTPUTIt can be Makefiles, .pc files, config.h headers and so on :AC_OUTPUT([ New formatAC_OUTPUT([Makefilesrc/Makefilefoo.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. Old deprecated format
  • CONFIGURE LABThe configure.{in/ac} templateCONFIGURE LAB
  • The configure.{in/ac} templateThe main goal for this lab is to write a basic configure that :Check the C compilerCheck Some standard headersGenerate a Makefile in outputIn case of problems with configure, you can consult the“config.log” file that may provide more information about anAutotools problem.Read the ./configure --help to know all the parameters thatcan be used by this script.
  • The Makefile.am templateThe goal of this topic is to know how to write a Makefile.am template.
  • 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 runthem one by one in the same order than written in the template.The Makefile.am templatesAs seen before, Makefile.am are generic template ready for a conversion into aMakefile.inThe Makefile.in, contains variables between arobases in order to make the update bythe configure script easy to do.
  • The makefile.am templateList of the most useful targets that the GNU Coding Standards specify:make all Build programs, libraries, documentation, etc. (same as make).make install Install what needs to be installed, copying the files from the packages tree to system-wide directories.Same as make install, then strip debugging symbols. Some users like to trade space foruseful bug reports...make install-strip Same as make install, then strip debugging symbols. Some users like to trade space foruseful bug reports...make uninstall The opposite of make install: erase the installed files. (This needs to be run from themake uninstall The opposite of make install: erase the installed files. (This needs to be run from thesame build tree that was installed.)make clean Erase from the build tree the files built by make all.make distclean Additionally erase anything ./configure created.make check Run the test suite, if any.make installcheck Check the installed programs or libraries, if supported.make dist Recreate package-version.tar.gz from all the source files.Those targets can be completed with yours (html, … )
  • Example of a Makefile template used for generating a library :HEADER_DIR = $(top_srcdir)/inc# ----------------------------------------------------------------# Header to be install in the stagingdir (make install)# gm_os is the prefix in <statingdir_path>/usr/include/gm_os/<headers># ----------------------------------------------------------------lib_includedir = $(includedir)/gm_os/lib_include_HEADERS = $(HEADER_DIR)/gm_os_types.h $(HEADER_DIR)/gm_os_trace.h $(HEADER_DIR)/gm_os.h# ----------------------------------------------------------------# Use for the installation in the stagingdirThe Makefile.am templatesmakefile.am# Use for the installation in the stagingdir# ----------------------------------------------------------------pkgconfigdir = $(libdir)/pkgconfigpkgconfig_DATA = gm_os.pc# ----------------------------------------------------------------# Compilation and generation of the gm_os library# ----------------------------------------------------------------lib_LTLIBRARIES = libgm_os.lalibgm_os_la_SOURCES = src/gm_os_misc.c src/gm_os_heap.c src/gm_os_message.clibgm_os_la_CFLAGS = -I$(HEADER_DIR) $(GLIB2_CFLAGS) $(MY_DEBUG_CFLAG)libgm_os_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -lpthread $(MY_DEBUG_LDFLAGS)libgm_os_la_LIBADD = $(GLIB2_LIBS)
  • bin_PROGRAMS = gtest_etpl_oss_posixgtest_etpl_oss_posix_SOURCES = src/gtest_unit_os.cppgtest_etpl_oss_posix_CPPFLAGS = $(GTEST_CFLAGS) $(UNO_CFLAGS) -I$(top_srcdir)/include -I./include -I$(top_srcddir)/src/os -I$(top_srcdir)/includeName of the final binarySource code to compile{C/CPP}FLAGSfor the compilationThe Makefile.am templatesAnother example of a Makefile template used for generating a binary:-I$(top_srcddir)/src/os -I$(top_srcdir)/includegtest_etpl_oss_posix_LDFLAGS = $(top_builddir)/src/.libs/libetpl_oss_posix.agtest_etpl_oss_posix_LDADD = $(ETPL_OSS_POSIX_LIBS) $(GTEST_LIBS) $(UNO_LIBS) Provided by the configure.acLDFLAGSfor the linknb: *_LDFLAGS defines internal dependencies to the component and *_LDADD defines externaldependencies. So if we compile internaly a library, then a binary that will link with, it will failledif we launch a parallel build (eg: make –j7).The paralel build can also be solved by adding this line in the Makefile.am :.NOTPARALLEL:
  • The Makefile.am templatesObject Descriptionfoo_SOURCES his variable, if it exists, lists all the source files which are compiled to build the program. These filesare added to the distribution by default. When building the program, Automake will cause each sourcefile to be compiled to a single `.o file (or `.lo when using libtool). Normally these object files arenamed after the source file, but other factors can change this. If a file in the `_SOURCES variable hasan unrecognized extension, Automake will do one of two things with it. If a suffix rule exists forturning files with the unrecognized extension into `.o files, then automake will treat this file as it willany other source file. Otherwise, the file will be ignored as though it were a header file. Theprefixes `dist_ and `nodist_ can be used to control whether files listed in a `_SOURCES variable aredistributed.`dist_ is redundant, as sources are distributed by default, but it can be specified forclarity if desired. It is possible to have both `dist_ and `nodist_ variants of agiven `_SOURCES variable at once; this lets you easily distribute some files and not others, forTemplate definition for binaries and libraries :given `_SOURCES variable at once; this lets you easily distribute some files and not others, forinstance:nodist_maude_SOURCES = nodist.cdist_maude_SOURCES = dist-me.cBy default the output file (on Unix systems, the `.o file) will be put into the current build directory.However, if the option subdir-objects is in effect in the current directory then the `.o file will be putinto the subdirectory named after the source file. For instance, with subdir-objects enabled, `sub/dir/file.c will be compiled to `sub/dir/file.o. Some people prefer this mode ofoperation. You can specify subdir-objects in AUTOMAKE_OPTIONS .EXTRA_foo_SOURCES Automake needs to know the list of files you intend to compile statically. For one thing, this is theonly way Automake has of knowing what sort of language support a given `Makefile.in requires. Thismeans that, for example, you cant put a configure substitution like `@my_sources@ intoa `_SOURCES variable. If you intend to conditionally compile source files and use `configure tosubstitute the appropriate object names into, e.g., `_LDADD (see below), then you should list thecorresponding source files in the `EXTRA_ variable. This variable alsosupports `dist_ and `nodist_ prefixes, e.g., `foo_EXTRA_maude_SOURCES.
  • The Makefile.am templatesObject Descriptionfoo_AR A static library is created by default by invoking $(AR) cru followed by the name of the library andthen the objects being put into the library. You can override this by setting the `_AR variable. Thisis usually used with C++; some C++ compilers require a special invocation in order to instantiate allthe templates which should go into a library. For instance, the SGI C++ compiler likes this macro setlike so:libfoo_a_AR = $(CXX) -ar -ofoo_LIBADD Extra objects can be added to a static library using the `_LIBADD variable. This should be used forobjects determined by configure. Note that `_LIBADD is not used for shared libraries; there youmust use`_LDADD‘.foo_LDADD Extra objects can be added to a shared library or a program by listing them in the `_LDADD variable.foo_LDADD Extra objects can be added to a shared library or a program by listing them in the `_LDADD variable.This should be used for objects determined by configure. `_LDADD is inappropriate for passingprogram-specific linker flags (except for `-l, `-L, `-dlopen and `-dlpreopen). Usethe `_LDFLAGS variable for this purpose. For instance, if your `configure.in uses AC_PATH_XTRA,you could link your program against the X libraries like so:foo_LDADD = $(X_PRE_LIBS) $(X_LIBS) $(X_EXTRA_LIBS)foo_LDFLAGS This variable is used to pass extra flags to the link step of a program or a shared library.foo_LINK You can override the linker on a per-program basis. By default the linker is chosen according to thelanguages used by the program. For instance, a program that includes C++ source code would usethe C++ compiler to link. The `_LINK variable must hold the name of a command which can bepassed all the `.o file names as arguments. Note that the name of the underlying programis not passed to `_LINK; typically one uses`$@:foo_LINK = $(CCLD) -magic -o $@
  • Object Descriptionfoo_CFLAGS Automake allows you to set compilation flags on a per-program (or per-library) basis. A single sourcefile can be included in several programs, and it will potentially be compiled with different flags foreach program. This works for any language directly supported by Automake. The flagsare `_CFLAGS, `_CXXFLAGS, `_OBJCFLAGS, `_YFLAGS, `_ASFLAGS, `_FFLAGS, `_RFLAGS,and `_GCJFLAGS. When using a per-program compilation flag, Automake will choose a differentname for the intermediate object files. Ordinarily a file like `sample.c will be compiled toproduce `sample.o. However, if the programs `_CFLAGS variable is set, then the object file will benamed, for instance, `maude-sample.o. In compilations with per-program flags, theordinary `AM_ form of the flags variable is not automatically included in the compilation (however,the user form of the variable is included). So for instance, if you want thehypothetical `maude compilations to also use the value of `AM_CFLAGS, you would need to write:foo_CFLAGS = ... your flags ... $(AM_CFLAGS)The Makefile.am templatesfoo_CFLAGS = ... your flags ... $(AM_CFLAGS)foo_DEPENDENCIES It is also occasionally useful to have a program depend on some other target which is not actuallypart of that program. This can be done using the `_DEPENDENCIES variable. Each program dependson the contents of such a variable, but no further interpretation is done. If `_DEPENDENCIES is notsupplied, it is computed by Automake. The automatically-assigned value is the contentsof `_LDADD, with most configure substitutions, `-l, `-L, `-dlopen and `-dlpreopen optionsremoved. The configure substitutions that are left in are only `@LIBOBJS@ and `@ALLOCA@; theseare left because it is known that they will not cause an invalid value for `_DEPENDENCIES to begenerated.foo_SHORTNAME On some platforms the allowable file names are very short. In order to support these systems andper-program compilation flags at the same time, Automake allows you to set a "short name" whichwill influence how intermediate object files are named. For instance, if youset `maude_SHORTNAME to `m, then in the above per-program compilation flag example the objectfile would be named `m-sample.o rather than `maude-sample.o. This facility is rarely needed inpractice, and we recommend avoiding it until you find it is required.
  • A Makefile can just call other sub-makefile:These few lines are enough for calling sub-modules. We can imagine that we have tocompile a library, then link with itSUBDIRS = src unit_test html html-privateCompilationUnitary testGenerate a doxygen documentation from the public APIGenerate a full doxygen documentation of the completesource codeThe Makefile.am templates
  • The Makefile.am templatesVariables used when building a program :Occasionally it is useful to know which `Makefile variables Automake uses for compilations; for instance youmight need to do your own compilation in some special cases. Some variables are inherited from Autoconf; theseare CC, CFLAGS, CPPFLAGS, DEFS, LDFLAGS, and LIBS.There are some global additional variables which Automake itself defines:Additional variable’snameDescriptionAM_CPPFLAGS The contents of this macro are passed to every compilation which invokes the Cpreprocessor; it is a list of arguments to the preprocessor. For instance, `-I and `-D options should be listed here. Automake already provides some `-I optionsautomatically. In particular it generates `-I$(srcdir), `-I., and a `-I pointing to theautomatically. In particular it generates `-I$(srcdir), `-I., and a `-I pointing to thedirectory holding `config.h (if youveused AC_CONFIG_HEADER or AM_CONFIG_HEADER). You can disable the default `-I options using the `nostdinc option.INCLUDES This does the same job as `AM_CPPFLAGS. It is an older name for the samefunctionality. This macro is deprecated; we suggest using `AM_CPPFLAGS instead.AM_CFLAGS This is the variable which the `Makefile.am author can use to pass in additional Ccompiler flags. It is more fully documented elsewhere. In some situations, this is notused, in preference to the per-executable (or per-library) CFLAGS.COMPILE This is the command used to actually compile a C source file. The filename isappended to form the complete command line.LINK This is the command used to actually link a C program. It already includes `-o $@ andthe usual variable references (for instance, CFLAGS); it takes as "arguments" the namesof the object files and libraries to link in.This impact all components from the Makefile.am (binary, libarry, … )
  • MAKEFILE.AM LABThe Makefile.am templatesMAKEFILE.AM LAB
  • The Makefile.am templatesThe main goal for this lab is to :1. Write a Makefile.am that will call another Makefile locatedinto a src directory2. In this second Makefile.am, just generate a binary from2. In this second Makefile.am, just generate a binary froma helloworld.c.2. Managed them using a single configure.ac
  • Using the library templateThe goal of this topic is to know how to generate static/dynamic libraries.
  • Using the library templateAutotools 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>/include/prefix/ metadata (.pc files)<STAGINGDIR>/<PREFIX>/lib/ static and/or libraryBy 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 templateStatic libraries:Integrates all symbols in onebinary.The nm command displaysinternal only built-in functions.Dynamic libraries :Uses external symbols throughdynamic libraries.The nm command shows theinternal (T) or external (U)symbols.The ldd command displays thelibraries dependencies of thebinary.binary.BINARYSTATICLIB BINARYDYNAMICLIB
  • Creating a static library is an easy task thanks to the ar tool from the Binutils:$ ar –rv mystaticlibrary.a file1.o file2.o file3.oor$ ar –rv mystaticlibrary.a *.oThe previous command merges the three objects (test1.o, test2.o et test3.o) into onearchive.A static library is:• a tank for ELF objectsUsing the library template• a tank for ELF objects• similar to an archive such as zip or tar• have a .a extensionA static library is not linked but is an archive made by the ar Binutil. Hence, it is possibleextract it the built-in objects.Extracting the content of a static library uses the same tool: $ ar x mystaticlibrary.aSome tools such as Midnight commanger (mc) can browse into these archives.For more information: man ar
  • It is also possible to list the contentof files included in a static library:$ ar –t mystaticlibrarycominter.ocom_util.ofiloint er.omiscell.oparal.opilot.osimul_api.ospyinter.oUsing the library templateThe following command is used to get thesymbols list per object:$ nm mystaticlibrary.aad_server.o:00000099 T affichage_etat_client00000004 C bDebugAd00000004 C bDebugSuU bTrace00000390 T close_socketcominter.o:00000004 d bComInitspyinter.ouserint.o00000004 d bComInit00000000 d bNoInitWarn00000010 b bTrComInterSymbol Type DescriptionA The symbols value is absolute, and will not be changed by further linking.B Un-initialized data sectionD Initialized data sectionT Normal code sectionU Undefined symbol used but not defined. Dependency on another library.W Doubly defined symbol. If found, allow definition in another library to resolve dependency
  • A link with a static library will bring all the functions used within the source code inside thefinal library.The final symbol table will be a merge of the functions used inside the source code and thefunctions from the static library:$ gcc test.o mystaticlibrary.a –o testtest.o libtest.aUsing the library templateBecause a static library is like an archive that contain ELF objects, a link with a static libraryis similar to a link with other ELF objects:$ gcc –c file.o mystaticlibrary.a –o testor$ gcc –c file.o file1.o file2.o –o testA static link can be also used in order to reduce the size of the final ELF Object. Indeed, onlyThe functions used in the code will be add (not the whole library) during the link step.
  • To creating a dynamic library, we need to link all the objects into one ELF object. Wedon’t need any other Binutils, but the ld linker itself through gcc:$ gcc -Wall -fPIC -c test1.c –o test1.o$ gcc -Wall -fPIC -c test2.c -0 test2.o$ gcc -shared -Wl,-soname,libtest.so.1 -o libtest.so.1.0 test1.o test2.oListing of parameters that can be given to the compiler:Compiler options Definitions-Wall include all warnings. See man page for warnings specified.Using the library templateThose libraries have a .so extension but they are associated with a version (Minor andMajor). For more information: man ld-fPIC Compiler directive to output position independent code, acharacteristic required by shared libraries. Also see -fpic.-shared Produce a shared object which can then be linked with other objectsto form an executable.-W1 Pass options to linker. In this example the options to be passed on tothe linker are: ”-soname libctest.so.1”. The name passed with the”-o” option is passed to gcc.-o Output of operation. In this case the name of the shared object tobe output will be libctest.so.1.0
  • Once a binary is built, it is possible to get a listing of its dynamic dependencies:$ ldd mybinarylibanasm7.so => /home/tgayet/vittam2/lib.i386_linux/libanasm7.so (0x40017000)libc.so.6 => /lib/tls/libc.so.6 (0x42000000)/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)This command outputs with which libraries the binary is linked ; it also gives the path ofthe libraries.The nm tools can also be used in order to have the symbols (functions built inside). TheUsing the library templateThe nm tools can also be used in order to have the symbols (functions built inside). Thelibrary shouldn’t not be stripped.At runtime, for a binary linked with a dynamic library, the loader will check the local cachethrough the ldconfig tool. Previously the configuration was made with the /etc/ld.so.conf butnow has been replaced by the /etc/ld.so.conf.d/ (or /etc/ld.conf.d/).Regenerating the cache : $ sudo ldconfigDumping the cache : $ sudo ldconfig -pA dynamic library is linked with a binary only during runtime, so we can override whichlibrary is loaded through the LD_LIBRARY_PATH environment variable:$ export LD_LIBRARY_PATH=./my_lib_path$ ./mybinary
  • In order to link a dynamic library with a binary we can specify some information to theld linker:$ gcc -fPIC test.o –L./libpath –ltestThis command specifies that the test.o source code that will make the final binary willbe dynamically linked with the libtest.so library. The « lib » prefix should not be specifiedbecause it is automatically added (For libtest.so, only test should be specified to the –lparameter).Using the library templateThe –l<libname> parameter tells the linker to search a library called libname. Bydefault, a dynamic (libname.so) one is used except if the –static parameter is provided.Linker option Description-l Provide a libname (eg: for libtest, only –ltest is specify)-L Provide a path or a set for the librariesDYNAMICLIBBINARY
  • Using the library templateLinking with a mix of shared and static librariesBy default, the linker will link against the shared libraries if they are available. If the -static flag isgiven, the linker will try to use static libraries instead of dynamic one. But -Bdynamic and -Bstaticprovides finer control of which library, shared or static should searched for each library specified forthe 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 forlibbar and any libraries after it until a -Bstatic is seen.http://gcc.gnu.org/onlinedocs/gcc/Link-Options.htmlhttp://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.htmllibbar and any libraries after it until a -Bstatic is seen.To pass the -Bdynamic and -Bstatic options to the linker, one needs to dogcc -o main main.o -Wl,-Bstatic -lfoo -Wl,-Bdynamic –lbarSince the gcc driver calls the linker with some default libraries,gcc -o main main.o -Wl,-Bstatictells the linker to use the static versions for all default libraries like libc and etc.
  • cc$ pmap -x 2238822388: bashAddress Kbytes RSS Anon Locked Mode Mapping08048000 780 - - - r-x-- bash0810b000 4 - - - r---- bash0810c000 20 - - - rw--- bash0021f000 1356 - - - r-x-- libc-2.11.1.so00372000 4 - - - ----- libc-2.11.1.so00373000 8 - - - r---- libc-2.11.1.so00375000 4 - - - rw--- libc-2.11.1.so009a9000 108 - - - r-x-- ld-2.11.1.so009c4000 4 - - - r---- ld-2.11.1.so009c5000 4 - - - rw--- ld-2.11.1.soExample of the memory dump for thebash binary.The dynamic libraries are loaded in memoryonly one time even if used by severalbinaries.Using the library template009c5000 4 - - - rw--- ld-2.11.1.so00cc4000 24 - - - r-x-- libnss_compat-2.11.1.so00cca000 4 - - - r---- libnss_compat-2.11.1.so00ccb000 4 - - - rw--- libnss_compat-2.11.1.so00e17000 8 - - - r-x-- libdl-2.11.1.so00e19000 4 - - - r---- libdl-2.11.1.so00e1a000 4 - - - rw--- libdl-2.11.1.so00f99000 76 - - - r-x-- libnsl-2.11.1.so00fac000 4 - - - r---- libnsl-2.11.1.so00fad000 4 - - - rw--- libnsl-2.11.1.sobffbe000 84 - - - rw--- [ stack ]-------- ------- ------- ------- -------total kB 9748 - - -binaries.They are very useful in order to know howmany memory is used by a binary.Another similar command is exmap.
  • Using the library templateCODEBSSHEAPCODEDATACODELIB 1LIB 2Dynamic libraries are mapped by the dynamic linker in theprocess address space,All processes share the same dynamic library code segment,Each dynamic library data segment is of course per process,Each dynamic library data size must be counted in the process memoryMemory slicing with dynamic libraries :StackDATALIB 2Each dynamic library data size must be counted in the process memoryconsumption.
  • Now with the autotools ☺☺☺☺Using the library template
  • Using the library templatelib_LTLIBRARIES = libfoo.lalibfoo_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.hlibfoo_la_CFLAGS = -I$(HEADER_DIR) Example of template :Name of the librarySource code associatedlibfoo_la_CFLAGS = -I$(HEADER_DIR) $(LIBCONFIG_CFLAGS) $(LIBLOG_CFLAGS) -DLOG_NAME=TOE -DLOG_MASK_PRIO=LOG_PRIO_ALLlibfoo_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -lpthread -lrtlibfoo_la_LIBADD = $(LIBCONFIG_LIBS) $(LIBLOG_LIBS) $(EFENCE_LIBS)Compilation flagsInternal link flagsExternal link flags (eg: dependencies)
  • Using the library templateThis is possible to force the generation of a static library in case of a Makefile that generatea static one before to link with :noinst_lib_LTLIBRARIES = libfoo.laThe 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 :The following prefix are accepted :check_LTLIBRARIES : generate a library for unitary testsnoinst_LTLIBRARIES : generate a library for local usage (won’t be installed)
  • GNU/MAKE LABUsing the library templateGNU/MAKE LAB
  • Using the library templateThe main goal of this lab is to generate a library.The library have two source code lib01.c and lib02.c located intoa src directory.The configure script should managed the version.The configure script should managed the version.A single Makefile should be able to compile either a static or adynamic one.
  • Using the application templateThe goal of this topic is to know how to generate binaries.
  • check_PROGRAM : generate a binary for the unitary testsnoinst_PROGRAM : generate a binary for local usage (won’t be installed)Using the application templateAs well as for the library, binaries can accept some prefix :Internal link flags should be given to the LDFLAGS one. That’s include internalstatic library.External link flags should be given to the LDADD one. That’s include all dependencieschecked by the PKG_CHECK_MODULE M4 macrochecked by the PKG_CHECK_MODULE M4 macro
  • Using the application templatebin_PROGRAMS = foofoo_SOURCES = main.cfoo_SOURCES = main.cfoo_LDADD = libfoo.la @FLIBS@Example of template used for a binary template :pkglib_LTLIBRARIES = libfoo.lalibfoo_la_SOURCES = bar.f baz.c zardoz.cclibfoo_la_LIBADD = $(FLIBS)
  • 0x0 Elf HeaderCodePadding0x400000Code0x10000000InitializedData (not 0)Data SizeElf HeaderCodePaddingElf HeaderElf HeaderCodeCodePaddingPadding0x400000Code0x10000000InitializedData (not 0)Data Size0x400000Code0x10000000InitializedData (not 0)Data Size0x400000Code0x10000000InitializedData (not 0)Data SizeCodeCode0x10000000InitializedData (not 0)Data Size0x10000000InitializedData (not 0)InitializedData (not 0)InitializedData (not 0)Data SizeData SizeCode sizeCode sizeCode sizeFrom Executable Binary to Process Memory Map :Using the application templateNot loadedin memoryExecutable fileEOFInitializedDataDyn Lib infoDWARFDebug InfoData set to0 (BSS)HeapProcessStackMemory MapInitializedDataDyn Lib infoDWARFDebug InfoInitializedDataInitializedDataDyn Lib infoDWARFDebug InfoDyn Lib infoDWARFDebug InfoData set to0 (BSS)HeapProcessStackMemory MapData set to0 (BSS)HeapProcessStackData set to0 (BSS)HeapProcessStackData set to0 (BSS)Data set to0 (BSS)Data set to0 (BSS)Data set to0 (BSS)HeapHeapProcessStackProcessStackMemory MapStatically LinkedMono-threadSimple CaseThe 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.
  • CODEDATABSSHEAPThread #1Stack..Multiple threads share the entire process address spaceEach thread has its own user space stack that is allocated when doingpthread_create system call. If stack size is not given, a default value is used.Be Careful: on x86 and NPTL POSIX thread implementation this means 8 Mb. This isthe same value for default process stack size.Always specify the stack size,Try to kill the system created initial thread after creating your own init thread,The multi-threaded case :Using the application templateThread #1Stack.
  • ---------------------------------------------------------Process : /usr/livep/bin/dispatcherPID : 962---------------------------------------------------------code (bin) - 00400000 (32 KB) r-xp (1f:01 5148248) /usr/livep/bin/dispatcherdata (bin) - 10000000 (4 KB) rw-p (1f:01 5148248) /usr/livep/bin/dispatcherBSS (bin) - 10001000 (256 KB) rwxp (00:00 0)---------------------------------------------------------code (lib) - 2aaa8000 (24 KB) r-xp (1f:01 1954952) /lib/ld-uClibc.so.0bss (lib) - 2aaae000 (4 KB) rw-p (00:00 0)data (lib) - 2aaed000 (4 KB) rw-p (1f:01 1954952) /lib/ld-uClibc.so.0---------------------------------------------------------code (lib) - 2aaee000 (60 KB) r-xp (1f:01 2203060) /lib/libpthread.so.0bss (lib) - 2aafd000 (252 KB) ---p (00:00 0)data (lib) - 2ab3c000 (28 KB) rw-p (1f:01 2203060) /lib/libpthread.so.0---------------------------------------------------------code (lib) - 2ab43000 (28 KB) r-xp (1f:01 1990056) /lib/libbluetooth.sobss (lib) - 2ab4a000 (252 KB) ---p (00:00 0)data (lib) - 2ab89000 (4 KB) rw-p (1f:01 1990056) /lib/libbluetooth.so---------------------------------------------------------code (lib) - 2ab8a000 (4 KB) r-xp (1f:01 2248520) /lib/libsysutil.so.1bss (lib) - 2ab8b000 (252 KB) ---p (00:00 0)data (lib) - 2abca000 (4 KB) rw-p (1f:01 2248520) /lib/libsysutil.so.1---------------------------------------------------------code (lib) - 2abcb000 (8 KB) r-xp (1f:01 2166444) /lib/libgeneric_socket.so.1bss (lib) - 2abcd000 (256 KB) ---p (00:00 0)data (lib) - 2ac0d000 (4 KB) rw-p (1f:01 2166444) /lib/libgeneric_socket.so.1---------------------------------------------------------code (lib) - 2ac0e000 (48 KB) r-xp (1f:01 2133348) /lib/libdbbh.so.1bss (lib) - 2ac1a000 (252 KB) ---p (00:00 0)Example of result for a processwith threadsUsing the application templatebss (lib) - 2ac1a000 (252 KB) ---p (00:00 0)data (lib) - 2ac59000 (4 KB) rw-p (1f:01 2133348) /lib/libdbbh.so.1---------------------------------------------------------code (lib) - 2ac5a000 (24 KB) r-xp (1f:01 2155132) /lib/libgdbm.so.3.0.0bss (lib) - 2ac60000 (252 KB) ---p (00:00 0)data (lib) - 2ac9f000 (4 KB) rw-p (1f:01 2155132) /lib/libgdbm.so.3.0.0---------------------------------------------------------code (lib) - 2aca0000 (12 KB) r-xp (1f:01 1966356) /lib/libapi_dispatcher.so.1bss (lib) - 2aca3000 (252 KB) ---p (00:00 0)data (lib) - 2ace2000 (4 KB) rw-p (1f:01 1966356) /lib/libapi_dispatcher.so.1---------------------------------------------------------code (lib) - 2ace3000 (248 KB) r-xp (1f:01 2005176) /lib/libc.so.0bss (lib) - 2ad21000 (252 KB) ---p (00:00 0)data (lib) - 2ad60000 (12 KB) rw-p (1f:01 2005176) /lib/libc.so.0Stack per thread--------------------------------------------------------- - 2ad63000 (8 KB) rw-p (00:00 0)- 7e7ef000 (68 KB) rwxp (00:00 0)- 7e9ef000 (68 KB) rwxp (00:00 0)- 7ebef000 (68 KB) rwxp (00:00 0)- 7edef000 (68 KB) rwxp (00:00 0)- 7efef000 (68 KB) rwxp (00:00 0)- 7f1ef000 (68 KB) rwxp (00:00 0)- 7f3ef000 (68 KB) rwxp (00:00 0)- 7f5ef000 (68 KB) rwxp (00:00 0)- 7f7fc000 (16 KB) rwxp (00:00 0)- 7fff5000 (12 KB) rwxp (00:00 0)---------------------------------------------------------Mapped: 3420 KBMinimum of memory required: 2964 KBStack : 12 KB--------------------------------------------------------- Stack per thread.
  • APPLICATION LABUsing the application templateAPPLICATION LAB
  • Using the application templateThe 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.2. Second, generate a library foolib from a foolib.c source code.2. Second, generate a library foolib from a foolib.c source code.You will have to write a configure.ac and a Makefile.am3. Third, merge the two configure.ac and Makefile.amThe library should compile first as a static library then link withthe binary.
  • The config.h supportThe goal of this topic is to know how works the global config.h configuration header
  • The config.h headerConfig.h are headers used to centralize the autotools setting. This will be like theID card of the build.The default name of this header is config.h but it can be customized by thedeveloper. The target patch when the header will be generated can be also updated(default’s one is the current path of the configure script).The autoconf tool will then generate an intermediate config.h.in file through theautogen.sh script, which will be processed to create the config.h file afterwardsthrough the configure script:through the configure script:The flags will impact the build like this :Thus, using a config.h header will remove those flags from the build command line.That’s mean this header must be include by the source code for the same purpose.$ gcc –c –o test.o –DCONDITION=1 test.c#ifdef CONDITIONprintf(“message enabled.”);#endifconfig.h.in config.h./autogen.sh ./configure …Used by abuild
  • The config.h header/* inc/internal_config.h. Generated from internal_config.h.in by configure. *//* inc/internal_config.h.in. Generated from configure.ac by autoheader. *//* Define to enable debug mode */#define DEBUG 1/* Specify if we are in dev mode or not *//* #undef DEV_CONF *//* Define to 1 if you have the <dlfcn.h> header file. */#define HAVE_DLFCN_H 1/* Define to 1 if you have the <inttypes.h> header file. */#define HAVE_INTTYPES_H 1Example of a config.h :/* inc/internal_config.h. Generated from internal_config.h.in by configure. *//* inc/internal_config.h.in. Generated from configure.ac by autoheader. *//* Define to enable debug mode */#define DEBUG 1/* Define to the full name of this package. */#define PACKAGE_NAME "toe"/* Define to the full name and version of this package. */#define PACKAGE_STRING "toe 1.0.0"/* Define to the one symbol short name of this package. */#define PACKAGE_TARNAME "toe"/* Define to the home page for this package. */#define PACKAGE_URL ""#define HAVE_INTTYPES_H 1/* Define to 1 if you have the <memory.h> header file. */#define HAVE_MEMORY_H 1/* Define to 1 if you have the <stdint.h> header file. */#define HAVE_STDINT_H 1/* Name of package */#define PACKAGE "toe“(…)The difference between a config.h.in and a config.h are de dynamic tests made by the configure script. Theintermediate file will just include all the static variables. That will be merge by all the dynamic test that check theenvironment, the toolchain, the dependencies, …)/* Define to the version of this package. */#define PACKAGE_VERSION "1.0.0"/* Define to 1 if you have the ANSI C header files. */#define STDC_HEADERS 1/* Version number of package */#define VERSION "1.0.0"/* Define to empty if `const does not conform to ANSI C. *//* #undef const */(…)config.h.in config.h.in
  • The config.h headerThe 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 configurationtests in the form of C preprocessor macro definitions. Every variable exported by the configure scriptthrough M4 macro (PKG_CHECK_MODULES(), AC_DEFINE(), AC_SUBST(), … ) will be set inside.The template file config.h.in can also be generated automatically bythe autoheader tool. autoreconf will invoke autoheader when AC_CONFIG_HEADERS is usedin configure.ac. If multiple configuration headers are used, autoheader will always only generate thetemplate for the first one in the list.Impact on the configure.ac template :template for the first one in the list.Example of usage in a configure.ac template(…)dnl ---------------------------------------dnl Specify the internal toe_config.hdnl ---------------------------------------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 byComponent itself.
  • The config.h headerImpact on the Makefile.am template :lib_LTLIBRARIES = libtoe.lalibtoe_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.hlibtoe_la_CFLAGS = -I$(HEADER_DIR) = -I$(HEADER_DIR) $(LIBCONFIG_CFLAGS) $(LIBLOG_CFLAGS) -DLOG_NAME=TOE -DLOG_MASK_PRIO=LOG_PRIO_ALLlibtoe_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -lpthread -lrtlibtoe_la_LIBADD = $(LIBCONFIG_LIBS) $(LIBLOG_LIBS) $(EFENCE_LIBS)Even if the config.h (here internal_config.h) is well include by the source code, this is importantto specify it in the Makefile in order to include this dynamic file in the tarball generated by a make dist.
  • The config.h headerConfig.h or not config.h that is the question…With config.h :The command line is more silent.The config.h is the ID card of the build becauseit defines all the activator, values, used during theWithout config.h :Every flags will be provided to the compilerover the command line (can be quite huge)Easy to manage with existent component it defines all the activator, values, used during thecompilation.That need to import this header in all sourcecode (.c, .cpp, .cxx, …) or within a top header. Theinclusion should be secured like this :#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */Easy to manage with existent component(don’t need any modification for the headerImport).The development process can check thevariables either in this config.h header orthrough the command line.
  • GNU/MAKE LABThe config.h headerGNU/MAKE LAB
  • The config.h headerThe main goal of this lab is to write one autotool projectwithout any config.h and another with that support.Compare the command line for the two build using « make v=1»
  • The config.h headerhttp://www.gnu.org/software/automake/manual/html_node/Optional.html#index-AC_005fCONFIG_005fHEADERS-219More help about :
  • The silent/verbose supportThe goal of this topic is to know how works to manage the silent/verbose support
  • Managing silent/verbose supportWhen a big build is launch it can be nice to do not have too much tracesIn 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 tostdio (err/out).Only errors will be displayed in detail and will stop the build process.
  • Managing silent/verbose supportImpact on the configure.ac template :The silent mode can be enable by default and let the output like the silent gnu/linux kernel makefile.Here is an example that allow to switch from the default silent mode to the verbose one :AC_ARG_ENABLE(verbose,AS_HELP_STRING([--enable-verbose], [Enable the verbose support [default=no]]),[case "${enableval}" inyes) have_verbose=true ;;no) have_verbose=false ;;*) AC_MSG_ERROR(bad value ${enableval} for --enable-verbose) ;;esac],[have_verbose=false]) Default’s value[have_verbose=false])dnl --------------------------------------------dnl Export the conditional HAVE_VERBOSE variable to the Makefilesdnl --------------------------------------------AM_CONDITIONAL(HAVE_VERBOSE, $have_verbose)dnl --------------------------------------------dnl Test the have_verbose variable and if equal to truednl --------------------------------------------AC_MSG_CHECKING([Checking the verbose support])if test "$have_verbose" = "true" ; thendnl --------------------------------------------dnl Display the result of the test ... verbosednl --------------------------------------------AC_MSG_RESULT([verbose])( … )Default’s value
  • Managing silent/verbose support( … )dnl ---------------------------------------dnl Enable the verbose modednl ---------------------------------------m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([no])])elsednl ---------------------------------------dnl Disable the silent modednl ---------------------------------------m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])dnl --------------------------------------------dnl Display the result of the test ... silentdnl --------------------------------------------Disable the silent mode,so enable the verbosemode.Enable the silent mode,so disable the verbosemode.dnl --------------------------------------------AC_MSG_RESULT([silent])fiControl the silent/verbose mode can be done by the confgure script :Silent mode : ./configure --prefix=/usrVerbose mode : ./configure --prefix=/usr --enable-verbose
  • Managing silent/verbose supportOnce the silent/verbose mode have been choosen by the configure script, thisIs possible to override it thanks to the « V » parameter:Silent mode selected by the configure script:o Silent mode : makeo Verbose mode : make V=1$ export LIBTOOLFLAGS "--silent“$ make –sVerbose mode selected by the configure script:o Silent mode : make V=0o Verbose mode : makeThis is possible to tune more the silent/verbose mode:
  • SILENT/VERBOSE LABManaging silent/verbose supportSILENT/VERBOSE LAB
  • Managing silent/verbose supportThe main goal of this lab is to add a verbosesupport by adding the –enable-verbose.The default state must be silent.
  • Managing dependencies with the pkg-config toolThe goal of this topic is to know how a pkgconfig file (.pc) are managed and how to usethe pkg-config tool.
  • The pkg-config toolThe PKG-CONFIG tool(aka PaCKage CONFIGgurator)
  • The pkg-config toolThe 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 findglib (or other libraries). It is language-agnostic, so it can be used for defining the location ofdocumentation 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 OSX and Windows. It does not require anything but a reasonably well working C compiler and a Clibrary, but can use an installed glib if that is present. (A copy of glib 1.2.10 is shipped togetherwith 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 Cby Havoc Pennington. It also grew an autoconf macro written by Tim Janik, later rewritten byScott 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 toolPKG_CONFIG_PATHSTAGING_DIRECTORYPKG_CONFIG_SYSROOT_DIRincludepkgconfigRoot of the filesystemThe variable say where the pkgconfigThe variable is useful in order to update both libdirAnd includedir in a cross-compilation mode.The variable say where the pkgconfigshould find the the pkg-config metadata.The staging directory uses :LIBDIR: /<PREFIX>/lib(path used to save the pkgconfig in <LIBDIR>/pkgconfig)INCLUDEDIR: /<PREFIX>/includeFor instance, here is the result with several prefix :PREFIX LIBDIR INCLUDEDIR PKGCONFIGPATH/. /lib /include /lib/pkgconfig/usr /usr/lib /usr/include /usr/lib/pkgconfig/usr/local /usr/local/lib /usr/local/include /usr/local/lib/pkgconfig
  • The pkg-config toolName Descriptionprefix A prefix used in constructing the default values of the variables listed below. If you are using Autoconf, write it as@prefix@.exec_prefix The default value of exec_prefix should be $(prefix). If you are using Autoconf, write it as ‘@exec_prefix@’.Generally, $(exec_prefix) is used for directories that contain machine-specific files (such as executables and subroutinelibraries), while $(prefix) is used directly for other directories.bindir The directory for installing executable programs that users can run. This should normally be written it as$(exec_prefix)/bin or @bindir@.sbindir The directory for installing executable programs that can be run from the shell, but are only generally useful to systemadministrators. This should normally be /usr/local/sbin, but write it as $(exec_prefix)/sbin or @sbindir@.Variables for Installation Directories :libdir The directory for object files and libraries of object code. Do not install executables here, they probably ought to go in$(libexecdir) instead. The value of libdir should normally be $(exec_prefix)/lib or @libdir@.includedir The directory for installing header files to be included by user programs with the C ‘#include’ preprocessor directive.This should normally be $(prefix)/include or @includedir@.srcdir The directory for the sources being compiled. If you are using Autoconf, use srcdir = @srcdir@.sysconfdir The directory for installing read-only data files that pertain to a single machine–that is to say, files for configuring ahost. All the files in this directory should be ordinary ASCII text files. This directory should normally be @sysconfdir@.For more information : http://www.gnu.org/prep/standards/standards.pdf
  • The pkg-config toolThe 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]--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 toolRecent pkg-config tool version use several environment variables:Name Description SincePKG_CONFIG_PATH A colon-separated (on Windows, semicolon-separated) list of directories tosearch for .pc files. The default directory will always besearched after searching the path; the default islibdir/pkgconfig:datadir/pkgconfig where libdir is the libdir for pkg-configand datadir is the datadir for pkg-config when it was installed.PKG_CONFIG_DEBUG_SPEW If set, causes pkg-config to print all kinds of debugging information andreport all errors.PKG_CONFIG_TOP_BUILD_DIR A value to set for the magic variable pc_top_builddir which may appear in.pc files. If the environment variable is not set, the defaultvalue $(top_builddir) will be used. This variable should refer to the topbuilddir of the Makefile where the compile/link flags reported by pkg-config will be used. This only matters when compiling/linking against aconfig will be used. This only matters when compiling/linking against apackage that hasnt yet been installed.PKG_CONFIG_DISABLE_UNINSTALLED Normally if you request the package "foo" and the package "foo-uninstalled"exists, pkg-config will prefer the "-uninstalled" variant. This allowscompilation/linking against uninstalled packages. If this environmentvariable is set, it disables said behavior.PKG_CONFIG_ALLOW_SYSTEM_CFLAGS Dont strip -I/usr/include out of cflags.PKG_CONFIG_ALLOW_SYSTEM_LIBS Dont strip -L/usr/lib out of libsPKG_CONFIG_SYSROOT_DIR Modify -I and -L to use the directories located in target sysroot. this optionis useful when crosscompiling package that use pkg-config to determineCFLAGS anf LDFLAGS. -I and -L are modified to point to the new systemroot. this means that a -I/usr/include/libfoo will become-I/var/target/usr/include/libfoo with a PKG_CONFIG_SYSROOT_DIR equalto /var/target (same rule apply to -L)0.24PKG_CONFIG_LIBDIR Replaces the default pkg-config search directory, usually/usr/lib/pkgconfig
  • The pkg-config tool$ pkg-config –helpUsage: 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 Usage provided by pkg-config--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 --libsgiven 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--print-provides print which packages the package provides--print-requires print which packages the package requires--print-requires-private print which packages the package requires for static linking
  • The pkg-config toolAsk for the LDFLAGS for a static link :$ pkg-config --libs bar–lbarAsk for the LDFLAGS for a dynamic link:$ pkg-config --libs --static bar-lbarask for the LDFLAGS following a specific version :$ pkg-config --libs "bar >= 2.7“Requested bar >= 2.7 but version of bar is 2.1.2Example of metadata for bar.pc :prefix=/usrexec_prefix=${prefix}includedir=${prefix}/includelibdir=${exec_prefix}/libfooname= Autotools are great :-)Name: barDescription: The bar libraryVersion: 2.1.2Requires.private: foo >= 0.7Ask for the CFLAGS :$ pkg-config --cflags bar-I/usr/include/fooAsk for the value of a specific name :$ pkg-config –variable=fooname barAutotools are great :-)Multiple request for the CFLAGS & LDFLAGS :$ pkg-config --cflags --libs bar-I/usr/include/foo -lbarRequires.private: foo >= 0.7Cflags: -I${includedir}Libs: -L${libdir} –lbarCheck the component exists :$ pkg-config --exists --print-errors bar$ echo $?0Check the version :$ pkg-config --modversion bar2.1.2
  • The pkg-config toolListing of the packages installed :$ pkg-config --list-alllibbsd libbsd - Utility functions from BSD systemsxtrans XTrans - Abstract network code for Xm17n-db m17n-db - The m17n database used by the m17n library.autoopts AutoOpts - A semi-automated generated/library option parserxcb XCB - X-protocol C Bindinggtest gtest - Google test framework for the C/C++ languagelibdrm_nouveau libdrm_nouveau - Userspace interface to nouveau kernel DRM servicesnautilus-sendto nautilus-sendto - Extend nautilus-sendto through pluginsgnome-screensaver gnome-screensaver - gnome screensaverxrandr Xrandr - X RandR Library(...)Increase the trace during the pkg-config runtime :Increase the trace during the pkg-config runtime :$ pkg-config --debug --libs testParsing package file /home/gayetth/Desktop/autotools-tests/pkg-config/001/test.pcline>prefix=/usrVariable declaration, prefix has value /usrline>exec_prefix=${prefix}Variable declaration, exec_prefix has value /usrline>libdir=${exec_prefix}/lib( … )line>line>Name: testline>Description: testline>Requires:line>Version: 1.0.0line>Libs: -L${libdir} -ltestline>Cflags: -I${includedir}/testline>Path position of test is 1Package test has -L/usr/lib in Libs
  • The pkg-config toolThe PKG-CONFIG metadata files
  • The pkg-config toolPkgconfig files are metadata provided by a specific component (eg: static/dynamic libray) for othercomponent 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 toolExample of a pkg-config file used for the libglib-2.0:# This is a commentprefix=/home/hp/unst # this defines a variableexec_prefix=${prefix} # defining another variable in terms of the firstlibdir=${exec_prefix}/libincludedir=${prefix}/includePartie hauteInvariante« NAME »Name: Gobject # human-readable nameDescription: Object/type system for GLib # human-readable descriptionVersion: 1.3.1URL: http://www.gtk.orgRequires: glib-2.0 = 1.3.1Conflicts: foobar <= 4.5 Libs: -L${libdir} -lgobject-1.3Libs.private: -lm Cflags: -I${includedir}/glib-2.0 -I${libdir}/glib/includePartie bassecustomisable
  • The pkg-config toolDescription of a pkg-config generic pattern that contain the metadata :Nom DescriptionName This field should be a human-readable name for the package. Note that it is not the name passed asan argument to pkg-config.Description This should be a brief description of the packageURL An URL where people can get more information about and download the packageVersion This should be the most-specific-possible package version string.Requires This is a comma-separated list of packages that are required by your package. Flags from dependentpackages will be merged in to the flags reported for your package. Optionally, you can specify thepackages will be merged in to the flags reported for your package. Optionally, you can specify theversion of the required package (using the operators =, <, >, >=, <=); specifying a version allows pkg-config to perform extra sanity checks. You may only mention the same package one time onthe Requires: line. If the version of a package is unspecified, any version will be used with nochecking.Conflicts This optional line allows pkg-config to perform additional sanity checks, primarily to detect brokenuser installations. The syntax is the same as Requires: except that you can list the same packagemore than once here, for example "foobar = 1.2.3, foobar = 1.2.5, foobar >= 1.3", if you have reasonto do so. If a version isnt specified, then your package conflicts with all versions of the mentionedpackage. If a user tries to use your package and a conflicting package at the same time, then pkg-config will complain.Libs This line should give the link flags specific to your package. Dont add any flags for requiredpackages; pkg-config will add those automatically.Libs.private This line should list any private libraries in use. Private libraries are libraries which are not exposedthrough your library, but are needed in the case of static linking.Cflags his line should list the compile flags specific to your package. Dont add any flags for requiredpackages; pkg-config will add those automatically.
  • The pkg-config toolAutotools template : Pkgconfig after update by the configure file :toe.pc.in :prefix=@prefix@exec_prefix=@exec_prefix@libdir=@libdir@includedir=@includedir@Name: @PACKAGE_NAME@Description: Thin OS Extension for nativedevelopmentsRequires: libconfig log• toe.pc :prefix=/usrexec_prefix=${prefix}libdir=${exec_prefix}/libincludedir=${prefix}/includeName: toeDescription: Thin OS Extension for nativedevelopmentsRequires: libconfig logRequires: libconfig logVersion: @VERSION@Libs: -L${libdir} -ltoeCflags: -I${includedir}/toe/Requires: libconfig logVersion: 1.0.0Libs: -L${libdir} -ltoeCflags: -I${includedir}/toe/All the variable between @, will be replaced by the correct value.In other words, when the end user will set a prefix to a configure file, it will replace all the @prefix@ values insidethe pc.in file and update all the orther variables link with.Beware, that if the « Require: » field is used, pkg-config will check first all the dependencies. If one of dependencyis not found, any pkg-config –flags or pkg-config –libs will failled. In the above example, pkg-config will check boththe libconfig.pc and log.pc before.The transformation will be done following the configure parameters : ./configure --prefix=/usr …
  • The pkg-config toolThis is possible to manage all the metadata within the configure.ac template :dnl Variables declarationPKG_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.amAC_SUBST(PCK_DEFINITION)AC_SUBST(PKG_DEPEND)Thus we can obtain the following toe.pc.in :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 toolThe autotools bring some M4 macros that can be used in order to work with the pkg-config’smetadata :configure.acPKG_PROG_PKG_CONFIG([MIN-VERSION])PKG_CHECK_EXISTS(MODULES, [ACTION-IF-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 toolPKG_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 --version0.25Example of checking from a configure.ac file: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. Sobeware is the result of this macro !!
  • As well as with the which command tool, you can check first if this tools is available on thecurrent gnu/linux system, then where the command is located in the filesystem:$ which pkg-config/usr/bin/pkg-configThe autotools can do the same within the configure.ac :AC_PATH_PROG([PKG_CONFIG],[pkg-config])if test -z "$PKG_CONFIG" ; thenAC_MSG_ERROR([pkg-config tool not found])The pkg-config toolAC_MSG_ERROR([pkg-config tool not found])fi
  • The pkg-config toolPKG_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 toPKG_CHECK_MODULES(), but does not set variables or print errors.Example:(…)POLKIT_REQUIRED=3.2.1PKG_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 toolPKG_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.0PKG_CHECK_MODULES([GTEST],[gtest >=$LIBGTEST_REQUIRED_VERSION],[have_libgtest=yes],[have_libgtest=no])if test "$have_libgtest" = no ; thenAC_MSG_ERROR([Missing the libgtest library!!])fiChecking 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 theAC_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 cflagsfor the given module list. If a module is missing or has the wrong version, by default configure will abort with amessage. To replace the default action, specify an ACTION-IF-NOT-FOUND. PKG_CHECK_MODULES will notprint any error messages if you specify your own ACTION-IF-NOT-FOUND. However, it will set the variableMYSTUFF_PKG_ERRORS, which you can use to display what went wrong.
  • The pkg-config toolThe two M4 macros PKG_CHECK_EXISTS and PKG_CHECK_MODULES can check morethan 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 toolImpact 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 insidePKG_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_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.6PKG_CHECK_MODULES([LIBCONFIG],[libconfig>=$LIBCONFIG_REQUIRED_VERSION],[have_libconfig=yes],[have_libconfig=no])if test "$have_libconfig" = no ; thenAC_MSG_ERROR([Missing the libconfig library 1.4.6 !!])fiAC_OUTPUT(Makefilefoo.pc)# EOF
  • The pkg-config toolEXTRA_DIST = $(top_srcdir)/autogen.shHEADER_DIR = $(top_srcdir)/inclib_includedir = $(includedir)/foolib_include_HEADERS = $(HEADER_DIR)/foo/foo.hpkgconfigdir = $(libdir)/pkgconfigpkgconfig_DATA = foo.pclib_LTLIBRARIES = libfoo.laImpact on the Makefile.am template :libfoo_la_SOURCES = src/foo.c inc/config.hlibfoo_la_CFLAGS = -I$(HEADER_DIR) $(LIBCONFIG_CFLAGS)libfoo_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -lpthread -lrtlibfoo_la_LIBADD = $(LIBCONFIG_LIBS)# EOFNote: external dependencies must be set to the _LIBADD variable. Internal/local one, should beassociated to _LDFLAGS.
  • The pkg-config toolPKG-CONFIG LABPKG-CONFIG LAB
  • The pkg-config toolThe goal of this lab is to manageFOODEPFOO12.5.6DEPFOO31.3DEPFOO21.4.2TP_PKG_CONFIGThe foo component will have two direct dependencies depfoo1 et depfoo2 and another onedepfoo3 pushed by depfoo1.Workflow :1. Fill the content of the files from the depfoo3 component2. Fill the content of the files from the depfoo1 component3. Fill the content of the files from the depfoo2 component4. Fill the content of the files from the foo componentIn order to launch your TP, run the ./run_tp.sh script.
  • The pkg-config tool/sdk/x86/ (STAGING_DIRECTORY)/depfoo1Standard roofs used for developementdepfoo1.pc.indepfoo1.cMakefile.amconfigure.acdepfoo2.pc.inTP_PKG_CONFIGdepfoo1.h/depfoo2/foodepfoo2.pc.indepfoo2.cMakefile.amconfigure.acdepfoo3.pc.indepfoo3.cMakefile.amconfigure.acfoo.cMakefile.am/depfoo3configure.acdepfoo2.hfoo.hdepfoo3.h
  • The pkg-config tool TP_PKG_CONFIGYou should have after the installation :/sdk/x86/lib/libdepfoo1.so + libdepfoo1.alibdepfoo2.so + libdepfoo2.alibdepfoo3.so + libdepfoo3.apkgconfig/depfoo1.pcdepfoo1.pcdepfoo2.pcdepfoo3.pcinclude/depfoo1/depfoo1.hdepfoo2/depfoo2.hdepfoo3/depfoo3.hbin/fooMore help: http://linux.die.net/man/1/pkg-config OR man pkgconfig
  • Generating a documentationThe goal of this topic is to know how to generate automatically a doxygendocumentation in a html format
  • Doxygen documentation in html formatGenerating a default doxygendocumentation
  • Doxygen documentation in html formatThis feature will impact the two autotools templates :configure.acThis script will simply check that we have the doxygen filein the current path.Makefile.amThis file will manage the documentation generation using theThis file will manage the documentation generation using thedoxygen tool.
  • Doxygen documentation in html formatdnl ---------------------------------------------------dnl Check for doxygen supportdnl ---------------------------------------------------AC_PATH_PROG([DOXYGEN], [doxygen])dnl Export the boolean value of the doxygen checkAM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN)Impact of the configure.ac template :dnl Display a warning in case the doxygen tool is not founddnl If not found, it will just display a warning.if test –z “$DOXYGEN” thenAC_MSG_WARN([doxygen tool not found])fiThis script will first test if the doxygen, then will export the result of this test to the othermakefile templates.
  • # Extra files to add in the archiveEXTRA_DIST = $(top_builddir)/autogen.sh $(top_builddir)/default-DoxyfileDoxygen documentation in html formatImpact on the Makefile.am template :In order to add the doxygen setting file in the tarball generated with make dist, we mustspecify it explicitely:DOXYFILE ?= $(top_builddir)/default-DoxyfileThe doxyfile should be define :Then for the two targets we will :Make a directory that will be used for the html extractionMake a local copy of the default-DoxyfileUpgrade of the Doxyfile with data from the composant :o Extraction directory (HTML_OUTPUT)o Its name (PROJECT_NAME)o Its version (PROJECT_NUMBER)o The path of the source code to parse (INPUT)Launch of the documentation by invoquing the doxygen toolRemove the temporarily DoxyfileDOXYFILE ?= $(top_builddir)/
  • Doxygen documentation in html format# Automatic generation of the documentation for the public APIif HAVE_DOXYGENhtml-local:@echo -n "Removing the previous documentation : "@rm -fR ./html_public_api@echo "OK"@echo -n "Preparing the documentation requirement : "@cp $(DOXYFILE) Doxyfile@chmod +w Doxyfile@echo "HTML_OUTPUT=./html_public_api” >> DoxyfileOfficial target launched by make html :This target will generate a documentation of the public API :Create a directoryMake a local copy@echo "HTML_OUTPUT=./html_public_api” >> Doxyfile@echo "PROJECT_NAME=@PACKAGE_NAME@” >> Doxyfile@echo "PROJECT_NUMBER=@PACKAGE_VERSION@” >> Doxyfile@echo "INPUT=$(srcdir)/inc/toe” >> Doxyfile@echo "OK"@echo -n "Generating the documentation in doxygen format : "@doxygen > /dev/null 2>&1@echo "OK"@echo "--> You can now browse the html generated documentation using the html_public_api/index.html file."@echo " firefox html_public_api/index.html & “@rm –f DoxyfileendifIt will first generate an instant version of a Doxyfile file, then upgrade it with a set of data beforeto launch the generation of the html documentation.The html target is standard to the autotools.Path of the headers todocument in HTML formatLaunch the generationRemove the lcoal copy
  • Doxygen documentation in html format# Automatic generation of the full documentation for the source code (internal and public API)if HAVE_DOXYGENfullhtml:@echo -n "Removing the previous documentation : "@rm -fR ./html_full@echo "OK"@echo -n "Preparing the documentation requirement : "@cp $(DOXYFILE) Doxyfile@chmod +w Doxyfile@echo "HTML_OUTPUT=./html_full” >> Doxyfile@echo "PROJECT_NAME=@PACKAGE_NAME@” >> DoxyfileOfficial target launched by make html :This target will generate a documentation of the full source code :@echo "PROJECT_NAME=@PACKAGE_NAME@” >> Doxyfile@echo "PROJECT_NUMBER=@PACKAGE_VERSION@“ >> Doxyfile@echo "INPUT=$(srcdir)/“ >> Doxyfile@echo "OK"@echo -n "Generating the documentation in doxygen format : "@doxygen > /dev/null 2>&1@echo "OK"@echo "--> You can now browse the html generated documentation using the html_full/index.html file."@echo " firefox html_full/index.html & “@rm –f DoxyfileendifThe differenc with the html target is INTPUT path that defines the path to the source code toParse with the doxygen tool.The fullhtml target is standard to the autotools.root path to the component’ssource code used todocument in HTML format
  • Editing a default doxygenDoxygen documentation in html formatconfiguration
  • Doxygen documentation in html formatDoxywizard is a GUI front-end used for configuring and running doxygen. In our case we will just use itfor 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 formatThe doxywizard tool (also known as doxygen-gui) can be used in order to generate a default doxygenconfiguration. 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.
  • DOCUMENTATION LABDoxygen documentation in html formatDOCUMENTATION LAB
  • Doxygen documentation in html formatThe goal of this lab is to add two target to your makefile used to generate a documention :make htmlshould generate a documentation of the public API (headers thats should be installedinto <STAGING_PATH>/<PREFIX_PATH>/include/<COMPOSANT_NAME>/).Local directory : ./html_public_apimake fullhtmlshould generate a complete documentation of the implementation of the whole component.Local directory : ./html_fullLocal directory : ./html_fullProjet’s files:The two targets will have to use the same doxygen file called: default-Doxyfile/tp-docscrc / foo.cMakefile.amconfigure.acinc / foo / foo_public.hDefault-Doxyfilehtml_public_api /html_full /inc / foo_private.hPublic APIfoo.pc.inDocumentation on the public APIDocumentation on the source code
  • Launching unitary test with covering supportThe goal of this topic is to know how to automaticaly launch unitary tests with coveringsupport using gcov for PKI data.
  • gcov is a test coverage program. Use it in concert with GCC to analyze your programs tohelp create more efficient, faster running code and to discover untested parts of yourprogram. You can use gcov as a profiling tool to help discover where your optimizationefforts will best affect your code. You can also use gcov along with the other profiling tool,gprof, to assess which parts of your code use the greatest amount of computing time.Profiling tools help you analyze your codes performance. Using a profiler such as gcovor gprof, you can find out some basic performance statistics, such as:• how often each line of code executesLaunching a unitary test with covering support• how often each line of code executes• what lines of code are actually executed• how much computing time each section of code uses$ gcc -fprofile-arcs -ftest-coverage -g tableau.c -o tableau$ gcov tableau.c92.31% of 26 source lines executed in file tableau.cCreating tableau.c.gcov.$ more tableau.c.gcovvoid permuter_cases (char *tableau, int i1, int i2, int taille)20 {20 char inter;20 if( (i1 < 0) || (i2 < 0) || (i1 >= taille) || (i2 >= taille))
  • ./autogen.sh./configure --prefix=/usr --enable-test --enable-covering make coveringtmake checkWill compile and launch the unit test[ with gcov data at the runtime ]makeIt will generate:- Makefile.in- configure script- config.h.in if usedIt will generate:- Makefile- config.h header- .pc fileIt will generate theexpected ELF objects(binaries, libraries, … )including gcov support. Analyze thedatageneratedby gcov andmake htmloutputLaunching a unitary test with covering support--enable-test :- Enable the unitary tests- If the Google tests are used the libgtest is checked- Same for the libgmock--enable-covering :- Add the gcov flags to gccStep #1 Step #2 Step #3tIt will generate an htmlreport that includes asynthesis of the gcovdata generated at theruntime. Thus, there is acorrelation between theunit tests and the lcovresults !!Step #4
  • Makefile dependencies./autogen.sh./configure –prefix …make or make –j7Generates the final files (Makefile, config.h, … )Launching a unitary test with covering supportmake coveringmake DESTDIR=<PATH> install make checkThis target generates html output from the lcovanalysis and provides human readable data about thesource code covering by the unitary tests.--enable-covering should be set to the configure scriptThis target launches the unitary tests using the Googletest/mock and provides junit.xml report per unit test.If gcov has been set, it will generate some informationthat will be analysed by lcov.--enable-test should be set to the configure scriptThis target generates the (cross)compilationand the link of the component.This target intalls the files generatedduring the build process.
  • Adaptations needed :configure.ac :Add the --enable-test support that will exports HAVE_TEST to theMakefiles.Add the --enable-covering support for adding the gcov flagsLaunching a unitary test with covering supportAdd the --enable-covering support for adding the gcov flagsto the build process.Makefile.am :Add the make check support to make the unit tests automaticAdd the make covering support to make the lcov analysis automatic.
  • 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 supportcommand doesn’t do anything at all.
  • dnl ---------------------------------------------------dnl Check for lcov supportdnl ---------------------------------------------------AC_PATH_PROG([LCOV], [lcov])AC_PATH_PROG([GENHTML], [genhtml])dnl Export the boolean value of the lcov checkAM_CONDITIONAL(HAVE_LCOV, test $LCOV)configure.ac(first part)Adaptations needed :Launching a unitary test with covering supportdnl Display a warning in case the lcov tool is not founddnl If not found, it will just display a warning.if test –z “$LCOV” thenAC_MSG_WARN([lcov/genhtml tools not found])fiThis 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 testdnl Mandatory : nodnl Values : none (just enable the tests if set)dnl Defaults value : disablednl --------------------------------------------AC_ARG_ENABLE(test,AS_HELP_STRING([--enable-test], [Enable the test unitary support [default=no]]),[case "${enableval}" inyes) have_test=true ;;no) have_test=false ;;*) AC_MSG_ERROR(bad value ${enableval} for --enable-test) ;;esac],[have_test=false])dnl --------------------------------------------dnl Export the conditional HAVE_TEST variable to the Makefilesdnl --------------------------------------------AM_CONDITIONAL(HAVE_TEST, $have_test)dnl --------------------------------------------dnl Test the have_test variable and if equal to truednl --------------------------------------------AC_MSG_CHECKING(Checking the test support)if test "$have_test" != "false" ; thendnl --------------------------------------------dnl Display the result of the test ... yesconfigure.ac(second part)dnl Display the result of the test ... yesdnl --------------------------------------------AC_MSG_RESULT([yes])LIBGTEST_REQUIRED_VERSION=1.5.0PKG_CHECK_MODULES([GTEST],[gtest >= $LIBGTEST_REQUIRED_VERSION],[have_libgtest=yes],[have_libgtest=no])if test "$have_libgtest" = no ; thenAC_MSG_ERROR([Missing libgtest library (http://code.google.com/p/googletest/) !!])fiLIBGMOCK_REQUIRED_VERSION=1.5.0PKG_CHECK_MODULES([GMOCK],[gmock >=$LIBGMOCK_REQUIRED_VERSION],[have_libgmock=yes],[have_libgmock=no])if test "$have_libgmock" = no ; thenAC_MSG_ERROR([Missing libgmock library !!])fielsednl --------------------------------------------dnl Display the result of the test ... nodnl --------------------------------------------AC_MSG_RESULT([no])fiIf you are not using the Google test/mock you can avoid this step. If you need to check both the gtest and gmockdependencies.
  • dnl --------------------------------------------dnl Test if the libgtest is well available in the stagingdirdnl If so get the cflags and ldflag from the .pc filednl --------------------------------------------LIBGTEST_REQUIRED_VERSION=1.5.0PKG_CHECK_MODULES([GTEST],[gtest >= $LIBGTEST_REQUIRED_VERSION],[have_libgtest=yes],[have_libgtest=no])if test "$have_libgtest" = no ; thenAC_MSG_ERROR([Missing libgtest library (http://code.google.com/p/googletest/) !!])fiCheck the Google test library : configure.acChecking the dependencies :Launching a unitary test with covering supportdnl --------------------------------------------dnl Test if the libgmock is well available in the stagingdirdnl If so get the cflags and ldflag from the .pc filednl --------------------------------------------LIBGMOCK_REQUIRED_VERSION=1.5.0PKG_CHECK_MODULES([GMOCK],[gmock >= $LIBGMOCK_REQUIRED_VERSION],[have_libgmock=yes],[have_libgmock=no])if test "$have_libgmock" = no ; thenAC_MSG_ERROR([Missing libgmock (http://code.google.com/p/googlemock/) library !!])fiCheck the Google mock library : configure.acDependencies are not mandatory. Indeed this is possible to use a single main in order to test ourdevelopment.
  • Unit test definition :TESTS = myUnitTestExecutable# Definition of the unit test :check_PROGRAMS = myUnitTestExecutablemyUnitTestExecutable_SOURCES = test1.cppmyUnitTestExecutable_CPPFLAGS =myUnitTestExecutable_LDFLAGS =Launching a unitary test with covering supportmyUnitTestExecutable_LDFLAGS =myUnitTestExecutable_LDADD =By specifying the unit test executable as check_PROGRAMS instead of usingsomething like bin_PROGRAMS or noinst_PROGRAMS, it generates themakefiles 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_LIBRARIESinstead of lib_LIBRARIES to specify libraries that should only be built for unittests.
  • Calling an unit tests directly :# ----------------------------------------------------------------# Unit Tests# ----------------------------------------------------------------# Listing of the program to launch# Those programs should not be installed# ----------------------------------------------------------------if HAVE_TESTTESTS = toe_gtest_assertcheck_PROGRAMS = $(TESTS)toe_gtest_assert_SOURCES = $(top_srcdir)/test/src/toe_gtest_assert.cpptoe_gtest_assert_CPPFLAGS = -I$(HEADER_DIR) $(GTEST_CFLAGS) $(LIBCONFIG_CFLAGS)  Makefile.ammake checkLaunching a unitary test with covering support$(LIBCONFIG_CFLAGS) $(LIBLOG_CFLAGS) -DLOG_NAME=TOE_ASSERT -DLOG_MASK_PRIO=255toe_gtest_assert_LDFLAGS = $(top_builddir)/.libs/libtoe.a -lpthread -lrttoe_gtest_assert_LDADD = $(GTEST_LIBS) $(LIBCONFIG_LIBS) $(LIBLOG_LIBS) $(EFENCE_LIBS)elseTESTS =endifThe Makefile will call the toe_gtest_assert binary directly.TEST is a common autotool variable.
  • Calling an unit test over a script :# ----------------------------------------------------------------# - Listing of the program to launch# - Those programs should not be installed# ----------------------------------------------------------------if HAVE_TESTcheck_SCRIPTS = unitary_test.shTESTS = $(check_SCRIPTS)unitary_test.sh:@rm -f test/pasi_gtest@cp ./pasi_gtest test/pasi_gtest@echo "cd test" >> ./unitary_test.sh@echo "./pasi_gtest " >> ./unitary_test.sh@chmod +x ./unitary_test.shnoinst_PROGRAMS = pasi_gtestpasi_gtest_SOURCES = test/pasi_test.cpp test/pasi_handle.cpp  Makefile.ammake checkLaunching a unitary test with covering supporttest/pasi_handle.cpp test/pasi_atsc_handle.cpp test/pasi_mpeg_parsing.cpp test/pasi_dvb_parsing.cpp test/pasi_atsc_parsing.cpp test/pasi_string_converter.cpppasi_gtest_CPPFLAGS = -I$(HEADER_DIR) -g -Wall -Wextrapasi_gtest_LDFLAGS = -lrt -lstdc++pasi_gtest_LDADD = $(GTEST_LIBS) $(EFENCE_LIBS)elseTESTS =endifThis Makefile first generates a shell script called unitary_test.sh, then the binary, then launch it.
  • Code covering :• Name : --enable-covering• Mandatory flag : no• If this flag is set, the ELF objects will be compiled and linked with the following options:CFLAGS/CXXFLAGS : --fprofile-arcs -ftest-coverage.LDFLAGS : --fprofile-arcs• If this flag is not set, it wont add all the covering flags needed.Launching a unitary test with covering support• This creates an instrumented executable which contains additional instructions that record thenumber of times each line of the program is executed. The option -ftest-coverage adds instructionsfor counting the number of times individual lines are executed, while -fprofile-arcs incorporatesinstrumentation code for each branch of the program. Branch instrumentation records howfrequently different paths are taken through ‘if’ statements and other conditionals. The executablemust then be run to create the coverage data.
  • Impact for the covering target in the configure.ac template :dnl --------------------------------------------dnl Brief : enable or disable the buildin covering modednl Mandatory : nodnl 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}" inyes) have_covering=true ;;no) have_covering=false ;;*) AC_MSG_ERROR(bad value ${enableval} for --enable-covering) ;;esac],[have_covering=false])dnl --------------------------------------------Launching a unitary test with covering supportdnl --------------------------------------------dnl Test the have_covering variable and if equal to truednl --------------------------------------------AC_MSG_CHECKING([Checking the covering support])if test "$have_covering" = "true" ; thendnl --------------------------------------------dnl Display the result of the test ... yesdnl --------------------------------------------AC_MSG_RESULT([yes])dnl --------------------------------------------dnl Update the CFLAGS and CPPFLAGS with gcov options for gccdnl --------------------------------------------CFLAGS=" $CFLAGS -fprofile-arcs -ftest-coverage "CPPFLAGS=" $CPPFLAGS -fprofile-arcs -ftest-coverage "LDFLAGS=" $LDFLAGS -fprofile-arcs "elsednl --------------------------------------------dnl Display the result of the test ... nodnl --------------------------------------------AC_MSG_RESULT([no])fi configure.ac
  • The .gcno file is generated when the source file is compiled with the GCC -ftest-coverage option. It contains informationto reconstruct the basic block graphs and assign source line numbers to blocks.The .gcda file is generated when a program containing object files built with the GCC -fprofile-arcs option is executed. Aseparate .gcda file is created for each object file compiled with this option. It contains arc transition counts, and somesummary information.$ gcov -b tmp.c90.00% of 10 source lines executed in file tmp.c80.00% of 5 branches executed in file tmp.c80.00% of 5 branches taken at least once in file tmp.c50.00% of 2 calls executed in file tmp.cCreating tmp.c.gcov.Here is a sample of a resulting tmp.c.gcov file:-: 0:Source:tmp.c-: 0:Graph:tmp.gcno-: 0:Data:tmp.gcda-: 0:Runs:1-: 0:Programs:1-: 1:#include <stdio.h>-: 2:-: 3:int main (void)Launching a unitary test with covering support-: 3:int main (void)function main called 1 returned 1 blocks executed 75%1: 4:{1: 5: int i, total;-: 6:1: 7: total = 0;-: 8:11: 9: for (i = 0; i < 10; i++)branch 0 taken 91% (fallthrough)branch 1 taken 9%10: 10: total += i;-: 11:1: 12: if (total != 45)branch 0 taken 0% (fallthrough)branch 1 taken 100%#####: 13: printf ("Failuren");call 0 never executed-: 14: else1: 15: printf ("Successn");call 0 called 1 returned 100%1: 16: return 0;-: 17:}
  • make covering : launch the kpi• Analyse the data generated by the unit tests compiled with the gcov support. Itmakes an html report in the output directory.• The lcov host tool (lcov and genhtml) must be available in the server.# ----------------------------------------------------------------# Automatic LCOV analyzing# ----------------------------------------------------------------covering: all check@echo -n "Removing the previous html generation : "@rm -fR ./outputBefore to launch the analysis through lcov,the package (aka system under test or SUT)should be already compiled (all). Then, theLaunching a unitary test with covering support• The result available will be saved into the output directory.@rm -fR ./output@echo "OK"@echo -n "Analyzing the covering : "@lcov -c -d . -b . -o toe.log@echo "OK"@echo -n "Generating the html report : "@genhtml -o output toe.log@echo "OK"@echo "--> You can now browse the html generated covering using the output/index.html file."@echo " firefox output/index.html & "@rm -f *.gcno *.gcdaMakefile.amshould be already compiled (all). Then, theunit test should be also compiled andlaunched (check).
  • Using lcov can be made in two steps:lcov -c -d . -b . -o toe.log : parse all the data generated during the runtime(thanks to the gcov feature) and make a synthesys logfile.genhtml -o output toe.log : use the previous aggregation logfile andgenerate an html report with log of detail with the source code reallyexecuted and how many times.Launching a unitary test with covering supportlcov [-h|--help] [-v|--version][-q|--quiet] [-z|--zerocounters] [-c|--capture][-f|--follow][-t|--test-name testname][-o|--output-file filename][-d|--directory directory][-k|--kernel-directory directory][-a|--add-tracefile tracefile][-e|--extract tracefile][-r|--remove tracefile][-l|--list tracefile][--diff tracefile diff][--no-checksum]lcov usage :genhtml [-h|--help] [-v|--version][-q|--quiet] [-s|--show-details] [-f|--frames][-b|--baseline-file] baseline-file[-o|--output-directory output-directory][-t|--title title][-d|--description-file description-file][-k|--keep-descriptions] [-c|--css-file css-file][-p|--prefix prefix] [--no-prefix][--no-source] [--num-spaces num] [--highlight]tracefile(s)genhtml usage :
  • Example of html export :Launching a unitary test with covering supportOnly the first line is interesting !! See details on the next slide…All the other lines are unused.48.5 % 59.6 % 26.6 %Data to return to theProject manager
  • 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 testfunctions, the more the KPI will give good data.The main goal is to target 100% but because some tests canbe difficult to check (exception, interraction with the system, … )The tests should be runable on Hudson.Launching a unitary test with covering supportThe tests should be runable on Hudson.Actually each component provides the following data:o Number of lines (wc –l sloccount)o % of lines testedo % of functions testedo % of branches tested
  • UNIT TEST & COVERING LABLaunching a unitary test with covering supportUNIT TEST & COVERING LAB
  • 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 downloadthe runtime package here: http://downloads.sourceforge.net/ltp/lcov-1.9.tar.gzImmagine 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.gzLaunching a unitary test with covering support• 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 !
  • More help about :http://www.gnu.org/software/automake/http://www.gnu.org/software/autoconf/http://www.gnu.org/software/hello/manual/automake/Tests.htmlhttp://www.crsr.net/Notes/CheckAndAutotools.htmlhttp://gcc.gnu.org/onlinedocs/gcc/Gcov.htmlhttp://ltp.sourceforge.net/coverage/lcov.phpLaunching a unitary test with covering supporthttp://ltp.sourceforge.net/coverage/lcov.phphttp://codingfreak.blogspot.com/2009/02/gcov-analyzing-code-produced-with-gcc.htmlhttp://www.cmi.univ-mrs.fr/~contensi/coursC/index.php?section=env&page=test
  • Managing the debug modeThe goal of this topic is to know how to select a debug/release mode relative to a build
  • Managing the debug modeThe main goal is to provide parameters to the GCC compiler and to the LD linker in order tohave a build usable with a debug mode.Gcc have a set of parameters that can be used for customizing the debug mode :Parameters Description-g Produces debugging information in the operating systems native format(stabs, COFF, XCOFF, or DWARF 2). GDB can work with this debugginginformation.-ggdb Produces debugging information for use by GDB. This means to use themost expressive format available (DWARF 2, stabs, or the native format ifFor more detail : http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.htmlmost expressive format available (DWARF 2, stabs, or the native format ifneither of those are supported), including GDB extensions if at allpossible.-Werror All warning become errors-Wall Enable all warning
  • Managing the debug modeAC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [Enable the debug support [default=no]]),[case "${enableval}" inyes) have_debug=true ;;no) have_debug=false ;;*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;esac],[have_debug=false])AM_CONDITIONAL(HAVE_DEBUG, $have_debug)AC_MSG_CHECKING([Checking the debug support])if test "$have_debug" = "true" ; thenAC_MSG_RESULT([yes])AC_DEFINE(DEBUG, 1, [Define to enable debug mode])CFLAGS=" $CFLAGS –ggdb "Impact to the configure.ac template :Update of the flags245 06/17/10CFLAGS=" $CFLAGS –ggdb "CPPFLAGS=" $CPPFLAGS -ggdb "LDFLAGS= " $LDFLAGS «m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([no])])ElseAC_MSG_RESULT([no])m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])fiUsage: ./configure –enable-debugIf set, it will set all the flags needed in debug mode ; it will disable the silent mode.To control the verbose/silent mode, you can specify it to the makefile using the V parameter:Verbose mode : make V=1Silent mode : make V=0Enable the verbose modeDisable the verbose modeUpdate of the flags
  • DEBUG MODE LABManaging the debug modeDEBUG MODE LAB
  • Managing the debug modeThe goal of this lab is to add a debug support to yourAutotools projet.Test a build using this one and another build without and checkthe debug flags are well provided to gcc through the CFLAGS.Check the final ELF library have well the debug symbols :file ELFfilenm -gC ELFLib.soobjdump -h ELFfileobjdump -TC ELFLibreadelf -Ws /usr/lib/libexample.soreadelf -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 levelThe goal of this topic is to know how to select an optimization level relative to a build
  • Manage the optimization levelParameters Description-O-O1Optimize. Optimizing compilation takes somewhat more time, and a lot more memory for alarge function.-O2 Optimize even more. GCC performs nearly all supported optimizations that do not involve aspace-speed gcc-3.3.2 Last change: 2003-10-16 57 GNU GCC(1) tradeoff. The compiler doesnot perform loop unrolling or function inlining when you specify -O2. As compared to -O, thisoption increases both compilation time and the performance of the generated code.As well as for the debug support, this is possible to provide to gcc parameters that canbe used for specify an optimization level :-O3 Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions and -frename-registers options.-O0 Do not optimize. This is the default.-Os Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size.It also performs further optimizations designed to reduce code size. -Os disables thefollowing optimization flags: -falign-functions -falign-jumps -falign-loops -falign-labels -freorder-blocks -fprefetch-loop-arraysIf multiple -O options, with or without level numbers, the last of them is the one thatis effective.By definition, no optimization should be set (-O0) if the debug mode is used.
  • AC_MSG_CHECKING([Optimization level])AC_ARG_WITH(optim-level,AS_HELP_STRING([--with-optim-level=<0,1,2,3>],[Provide the optim level to give to gcc as -O<level>]),[current_optim_level=$withval],[current_optim_level=0])if test "$current_optim_level" != "0" ; thendnl override the default optim levelcase "$current_optim_level" in"1" | "2" | "3" ) ;;*) AC_MSG_ERROR(bad value ${withval} for the optim-level parameter. It must be anumber between 1 and 3.);;Impact on the configure.ac template :Manage the optimization levelDefault optim level !250 06/17/10;;esacFiif test "$have_debug" = "true" ; thencurrent_optim_level="0"AC_MSG_RESULT([-O$current_optim_level!! Remove all optimization in debug mode.])elseAC_MSG_RESULT([-O$current_optim_level])fiCFLAGS=" $CFLAGS –O$current_optim_level "Usage : ./configure –with-optim-level=3By default, no optimization is set; in debug mode, none is required.
  • OPTIMIZATION LABManage the optimization levelOPTIMIZATION LAB
  • Manage the optimization levelThe goal of this lab is to update an autotools componentwith an optimization level support by adding a--with-optim-level=3 parameter.Test a build using this one and another build without andcheck the flags -Ox is well provided to gcc according to thecheck the flags -Ox is well provided to gcc according to thelevel expected.
  • Manage the profiling modeThe goal of this topic is to know how to select a debug/release mode relative to a build
  • Manage the profiling modeThe first step in generating profile information for your program is to compile and link it with profiling enabled. To compile a source filefor profiling, specify the `-pg option when you run the compiler. (This is in addition to the options you normally use.)To link the program for profiling, if you use a compiler such as cc to do the linking, simply specify `-pg in addition to your usual options.The same option, `-pg, alters either compilation or linking to do what is necessary for profiling. Here are examples:$ gcc -g -c myprog.c utils.c -pg compilation$ gcc -o myprog myprog.o utils.o –pg linkThe `-pg option also works with a command that both compiles and links:$ gcc -o myprog myprog.c utils.c -g -pgNote: The `-pg option must be part of your compilation options as well as your link options. If it is not thenno call-graph data will be gathered and when you run gprof you will get an error message like this:no call-graph data will be gathered and when you run gprof you will get an error message like this:gprof: gmon.out file is missing call-graph dataIf you add the `-Q switch to suppress the printing of the call graph data you will still be able to see thetime samples:Flat profile:Each sample counts as 0.01 seconds.% cumulative self self totaltime seconds seconds calls ms/call ms/call name33.34 0.02 0.02 7208 0.00 0.00 open16.67 0.03 0.01 244 0.04 0.12 offtime16.67 0.04 0.01 8 1.25 1.25 memccpy16.67 0.05 0.01 7 1.43 1.43 write
  • Gprof profiling is similar in some ways to prof profiling. Instead of profs option -p, the usual option to enable gprof profiling is -pg. Thelinker links against a different mcount() function which maintains exact counts of entries into each function by individual call sites,probably by walking the stack at run-time to find the address the called function will return to.The gprof post-processor then constructs the call graph for the program, and propagates function execution time (obtained from the PCsampling) through the call graph, proportionally to the number of calls from each call site for the function. The resulting weighted callgraph gives a more thorough picture of inefficiencies in the program; however the call graph may be substantially inaccurate when:• Propagating execution time meaningfully is difficult when there is recursion (i.e., the call graph is not a tree).• The heuristic of allocating execution time of a function to its call sites proportionally to the number of calls from each call site failsbecause different call sites made substantially different demands on the function. E.g., a function might be called equal number of timesfrom location A and B, but the average latency for calls from A might be 100 times longer than the average latency for calls from B;Manage the profiling modefrom location A and B, but the average latency for calls from A might be 100 times longer than the average latency for calls from B;nevertheless, gprof would assign equal amounts of time to be propagated up the call graph to locations A and B.Sample of results :nb : gprof with pthread requires some adaptation of the code!!
  • Manage the profiling modeCohabitation 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, youshould 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 multithreadedapplications. It actually only profiles the main thread, which is quite useless.WorkaroundThere is an easy, but surprisingly not very widespread fix for this annoying gprof behaviour. Basically, gprof uses theinternalITIMER_PROF timer which makes the kernel deliver a signal to the application whenever it expires. So we justneed to pass this timer data to all spawned threads.need to pass this timer data to all spawned threads.ExampleIt wouldn’t be too hard to put a call to setitimer in each function spawned by a thread, but I thought it would be moreelegant 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. Itcan 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.cmore detail: http://sam.zoy.org/writings/programming/gprof.html
  • The remaining functions in the listing (those whose self seconds field is 0.00) didnt appear in the histogram samples at all. However, thecall graph indicated that they were called, so therefore they are listed, sorted in decreasing order by the calls field. Clearly some time wasspent executing these functions, but the paucity of histogram samples prevents any determination of how much time each took.Here is what the fields in each line means:% time This is the percentage of the total execution time your program spent in this function.These should all add up to 100%.cumulative seconds This is the cumulative total number of seconds the computer spent executing thisfunctions, plus the time spent in all the functions above this one in this table.self seconds This is the number of seconds accounted for by this function alone. The flat profile listingis sorted first by this number.Manage the profiling modeis sorted first by this number.calls This is the total number of times the function was called. If the function was nevercalled, or the number of times it was called cannot be determined (probably because thefunction was not compiled with profiling enabled), the calls field is blank.self ms/call This represents the average number of milliseconds spent in this function per call, if thisfunction is profiled. Otherwise, this field is blank for this function.total ms/call This represents the average number of milliseconds spent in this function and itsdescendants per call, if this function is profiled. Otherwise, this field is blank for thisfunction. This is the only field in the flat profile that uses call graph analysis.Name This is the name of the function. The flat profile is sorted by this field alphabeticallyafter the self seconds and calls fields are sorted.
  • AC_ARG_ENABLE(profiling,AS_HELP_STRING([--enable-profiling], [Enable the buildin profiling (gnu/gprof) support[default=no]]),[case "${enableval}" inyes) have_profiling=true ;;no) have_profiling=false ;;*) AC_MSG_ERROR(bad value ${enableval} for --enable-profiling) ;;esac],[have_profiling=false])dnl --------------------------------------------dnl Test the have_profiling variable and if equal to truednl --------------------------------------------AC_MSG_CHECKING([Checking the profiling support])if test "$have_profiling" = "true" ; thendnl --------------------------------------------Manage the profiling modeImpact on the configure.ac template :258 06/17/10Usage: ./configure --enable-profiling/--disable-profilingdnl --------------------------------------------dnl Display the result of the test ... yesdnl --------------------------------------------AC_MSG_RESULT([yes])dnl --------------------------------------------dnl Update the CFLAGS, CPPFLAGS and LDFLAGS with gprof options for gccdnl --------------------------------------------CFLAGS=" $CFLAGS –pg "CPPFLAGS=" $CPPFLAGS –pg "LDFLAGS=" $LDFLAGS –pg "elsednl --------------------------------------------dnl Display the result of the test ... nodnl --------------------------------------------AC_MSG_RESULT([no])fiIf set, it will give –pg to both the CFLAGS and the LDFLAGS.
  • PROFILING LABManage the profiling modePROFILING LAB
  • Manage the profiling modeThe goal of this lab is to update an autotools componentwith the profiling support by adding a –enable-profilingparameter.Test a build using this one and another build withoutand check the flags -pg is well provided to gcc.and check the flags -pg is well provided to gcc.
  • The cross-compilationThe goal of this topic is to know how cross-compile.
  • ./configure --build i686-pc-linux-gnu --host i586-mingw32msvcchecking for a BSD-compatible install... /usr/bin/install -cchecking whether build environment is sane... yeschecking for gawk... gawkchecking whether make sets $(MAKE)... yeschecking for i586-mingw32msvc-strip... i586-mingw32msvc-stripThe cross-compilationExample of cross-compilation in action :checking for i586-mingw32msvc-strip... i586-mingw32msvc-stripchecking for i586-mingw32msvc-gcc... i586-mingw32msvc-gccchecking for C compiler default output file name... a.exechecking whether the C compiler works... yeschecking whether we are cross compiling... yeschecking for suffix of executables... .exechecking for suffix of object files... ochecking whether we are using the GNU C compiler... yeschecking whether i586-mingw32msvc-gcc accepts -g... yeschecking for i586-mingw32msvc-gcc option to accept ANSI Cetc ...
  • The cross-compilationOne 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 :Paramaters Description M4 Macro--host=host-type The system where built programs and libraries will run. The type of system onwhich the package runs. By default it is the same as the build machine.Specifying it enables the cross-compilation mode.AC_CANONICAL_HOST--target=target-typeWhen building compiler tools: the system for which the tools will create output.The type of system for which any compiler tools in the package produce code(rarely needed). By default, it is the same as host.--build=build-typeThe system on which the package is built. The type of system on which thepackage is being configured and compiled. It defaults to the result ofrunning config.guess.AC_CANONICAL_SYSTEMBy 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 packagebeing 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-compilationUsing the Host type :In almost all cases the host system is the system on which you run the `configure script, and on whichyou 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 nota 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.hostThe canonical configuration name of the host. This will normally be determined by running theThe 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_aliasIn 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_cpuhost_vendorhost_osThe first three parts of the canonical configuration name.
  • The cross-compilationUsing 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. Seesection 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 willalso run `AC_CANONICAL_HOST (see section Using the Host Type).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 bedefined by `AC_CANONICAL_HOST.targetThe canonical configuration name of the target.target_aliasThe argument to the `--target option. If the user did not specify a `--target option, this will be the same as host_aliastarget_cputarget_vendortarget_osThe first three parts of the canonical target configuration name.
  • The cross-compilationThis is a string of the form cpu-manufacturer-operating_system. In some cases, this is extended to a four partform: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. Inparticular, the manufacturer field is often omitted, leading to strings such as `i386-linux or `sparc-sunos. The shellscript `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.Field Descriptioncpu The type of processor. This is typically something like `i386 or `sparc. More specific variants areused as well, such as `mipsel to indicate a little endian MIPS processor.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 normallydetermine the configuration name for a machine, it is normally only necessary to specify a configuration name whenbuilding a cross-compiler or when building using a cross-compiler.This should be synchronize with the toolchain’s prefix.used as well, such as `mipsel to indicate a little endian MIPS processor.manufacturer A somewhat freeform field which indicates the manufacturer of the system. This is oftensimply `unknown. Other common strings are `pc for an IBM PC compatible system, or the nameof a workstation vendor, such as `sun.operating_system The name of the operating system which is run on the system. This will be somethinglike `solaris2.5 or `irix6.3. There is no particular restriction on the version number, and stringslike`aix4.1.4.0 are seen. For an embedded system, which has no operating system, this fieldnormally indicates the type of object file format, such as `elf or `coff.kernel This is used mainly for GNU/Linux. A typical GNU/Linux configuration name is `i586-pc-linux-gnulibc1. In this case the kernel, `linux, is separated from the operating system, `gnulibc1
  • The cross-compilationAC_CANONICAL_HOSTcase "${host}" ini[3456]86-*-linux-gnu*) do something ;;sparc*-sun-solaris2.[56789]*) do something ;;sparc*-sun-solaris*) do something ;;mips*-*-elf*) do something ;;The configure script can detect the host system thanks to the“AC_CANONICAL_HOST” or ”AC_CANONICAL_SYSTEM” m4 macros:Example of action that dependon the host type.mips*-*-elf*) do something ;;esac
  • The cross-compilationIn cross-compilation mode, binaries will be generate with a prefix that will follow the oneprovide to the target argument.In other word, native build will generate : mybinaryAnd with a target equal to i686-cm-linux prefix the binary will become : i686-cm-linux-mybinaryThis is possible to do not add the prefix in cross-compilation mode if the following parameter is setto the configure script:./configure --prefix=/usr --program-transform-name=""Thus the final name won’t have any impact and won’t change.
  • CROSS-COMPILATIONLABThe cross-compilationCROSS-COMPILATIONLAB
  • The cross-compilationThe main goal of this lab is to compile a helloworld binary inthree times:For the host: ./configure --prefix=/usrFor a target: ./configure --prefix=/usr --host=i386-linux-gnu --host=i386-linux-gnu --build=mips-elfFor a target: ./configure --prefix=/usr --host=i386-linux-gnu --build=mips-elf --program-transform-name=""Check for the name of the final binaries.
  • Check the autotools for hudsonSPECIFIC TECHNICOLORThe goal of this topic is to be sure the autotools will work with hudson.
  • Check the autotools for hudsonHudson make the autotools usage more difficult to use.Objets are not generated in the top_srcdir path but in top_builddirSo because top_srcdir != top_builddir, developers should valide theirautotools template before to apply a baseline on clearcase.
  • HudsonServerSet the environmentmkdir tmp_srcdir./autogen.sh./configure --prefix=/usr --srcdir=`pwd`/tmp_srcdir …Make the latest stable archive, extract it in a specificdirectory, then launch the configure script beforebuilding the componentmake disttar zxvf composant-version.tar.gz -C <BUILD_PATH>cd <BUILD_PATH>/composant-version/./autogen.shCheck the autotools for hudson273 06/17/10Code covering for KPI project needs using lcov byanalyzing the gcov data and generate an html reportLatest doxygen documentation of thepublic API in html formatLaunch the unit tests with Google{test/gmock}(generate junit xml files as a report)Autotools targetsavailable on Hudsonmake coveringmake check./autogen.sh./configure --prefix=/usr –enable-covering –enable-testmake –j7make DESTDIR=<STAGINGDIR> installmake htmlDeliver to default CI stream+ Baseline+ Recommended baseline
  • Check the autotools for hudson# Export some variablesexport COMP_NAME=my_compexport COMP_VERSION=1.0.1export COMP_FULLNAME=$COMP_NAME-$COMP_VERSIONexport BUILD_DIR=/tmp/$COMP_FULLNAMEexport STAGING_DIR=/local/work/$USER/staging# Fist stage need for the archive generationMY_TMP_DIR=`pwd`/output-distmkdir -p ${MY_TMP_DIR}./autogen.shcd ${MY_TMP_DIR}../configure --prefix=/usr --srcdir=${MY_TMP_DIR} …make distcd ..Overload of the srcdir need byconfigure scriptcd ..# Extract the archive into the /tmp/my_build directory :tar zxvf ${MY_TMP_DIR}/$COMP_FULLNAME.tar.gzmv $COMP_FULLNAME dist-sourcecd dist-source./autogen.shcd ..MY_TARGET_DIR= pwd`/output-targetcd ${ MY_TARGET_DIR}../dist-source/configure --prefix=/usr –enable-covering –enable-test --srcdir=${MY_TARGET_DIR}make –j17make DESTDIR=<STAGING_DIR> installCreate the archive
  • HUDSON LABCheck the autotools for hudsonHUDSON LAB
  • Check the autotools for hudsonThe main goal of this lab if to valid your autotools byFollowing the previous steps.After the « make dist », the extraction, and the configuring,we should be able to compile and link.we should be able to compile and link.If you have time, you can write a bash script for automatingThis checking.
  • The M4 macrosThe goal of this topic is to know how M4 macros are written.
  • The M4 macrosAutoconf modifies the M4 environment in a few ways. First, as mentioned earlier, it changes thedefault quote characters from the backtick and single quote characters to the open and close squarebracket 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_DEFUNinstead of m4_define because it ensures that certain environmental constraints important to Autoconfare in place when your macro is called!!The AC_DEFUN macro supports a prerequisite framework, so you can specify which macros arerequired to have been called before your macro may be called.This framework is accessed by using the AC_REQUIRE macro to indicate your macro’srequirements at the beginning of your macro definition, like so:# Test for option AAC_DEFUN([TEST_A],[AC_REQUIRE([TEST_B])dnltest " $A" = "yes" && options=" $options A"])
  • The M4 macrosThis 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 filewill be included in aclocal.m4 when you run aclocal, and its macro(s) will henceforth bevisible toautoconf. However if it contains numerous macros, it will rapidly become difficult tomaintain, 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 andgather all these files in a directory. This directory is usually called m4/. To build aclocal.m4,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 m4ACLOCAL_AMFLAGS contains options to pass to aclocal when aclocal.m4 is to be rebuiltby make.This line is also used by autoreconf.
  • The M4 macrosAC_DEFUN([TRAVOLTA],[test "$body_temperature_in_celsius" -gt "38" &&dance_floor=occupied])AC_DEFUN([NEWTON_JOHN],[test "$hair_style" = "curly" && dance_floor=occupied])AC_DEFUN([RESERVE_DANCE_FLOOR],[if date | grep ^Sat.*pm >/dev/null 2>&1; thenAC_REQUIRE([TRAVOLTA])Example:my_macros.m4AC_REQUIRE([TRAVOLTA])AC_REQUIRE([NEWTON_JOHN])fi])With this configure.ac :configure.acAC_INITsinclude(my_macro.m4)RESERVE_DANCE_FLOORif test "$dance_floor" = occupied; thenAC_MSG_ERROR([cannot pick up here, lets move])fi
  • The M4 macrosIf you have somme command you often use in your configure.ac :make_command="“for a in "$MAKE" make gmake gnumakedo test -z "$a" && continueif ( sh -c "$a --version" 2>/dev/null | grep GNU >/dev/null )then make_command=$a ; break;fidoneif test -z $make_commandthen ifGNUmake="“else ifGNUmake="#“fiAC_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: We suppose you have written a smallcheck already used in your "configure" script- which is actually a bourne shell script thatcalls other tools and possibly sets anAC_SUBST variable to be replaced in yourMakefile.in. It may look like the followingcheck for a "gnu make" in the buildenvironment.now you have an extra file "acinclude.m4" reading:and in its place in the original "configure.in" you write that name as:AC_DEFUN(CHECK_GNU,[make_command=""for a in "$MAKE" make gmake gnumakedo test -z "$a" && continueif ( sh -c "$a --version" 2>/dev/null | grep GNU >/dev/null )then make_command=$a ; break;fidoneif test -n $make_commandthen ifGNUmake=""else ifGNUmake="#"fiAC_SUBST(ifGNUmake)])....CHECK_GNU...
  • The M4 macrosNow you are already done with having your own autoconf macro. And you can be quite sure that it will work inyour project - and probably you have tested it on the platforms you do usually build for. Believe it or not, this is arather "controlled" environment - if you push the macro to the AC Macro Archive then your macro might make itinto other projects where they will meet lots of other macros, lots of other shell code, lots of different platforms. Andpossibly, 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 ifAC_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 redefineproblem 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 areFor the same reason, you should put m4-quotes in any other places where actually an m4-macro is being created - or possibly you aregoing to use a symbol that might be a complex macro. As a rule of thumb, all uppercase-symbols might be defined as a macrosomewhere 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 willbe 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 everexecuted 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 shellyou happen to have your configure script get executed with. While "-z" is seen often, even "-n" is rarely implemented. Even more, thereare some buggy shells which remove an empty "" string completely instead of providing an empty argument to the "test" command, sothat "test" would see a test "$var" = "" as a real test = - and ask for a syntax error.
  • The M4 macrosUse cache variables - _cv_make_commandYour macro might be used by other macros which get each expanded into the final "configure" script. That will make yourcheck 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 handleproblems 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_CHECKInform the user when the "configure" script enters your macro and when it leaves your macro. If there are problems, they canbe 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 itsdefinition. At best, inform the user of the result - and try to avoid terminology that is not helpful to a non-coder.Dont be afraid of long names - use AS_VAR_PUSHDEF / POPDEFYou should avoid to destroy shell variable values possibly used somewhere else - or the ones of the other macro calling yourmacro. As for short-lived variables that do not span over other macros, just use very short names - for the other ones use a longprefix 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 doubledefines, i.e. MYPROJECT_CHECK_GNU. Do never use AC_CHECK_GNU since all AC_ names are reserved - even if youknow there is no such macro in the "autoconf" package then it might still be added later. If you intend to submit your macro theAC Macro Archive then you can use the AX_ prefix - we take all macros and we will ensure all macros in the archive areunique. Always and forever.
  • The M4 macrosAC_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 gnumakedo test "x$a" = "x" && continueif ( sh -c "$a --version" 2>/dev/null | grep GNU >/dev/null )then _make_command="$a" ; break;fidoneAfter applying all these guideline, the macro might now look like this:doneif test "x$_make_command" != "x"then ifGNUmake=""AC_MSG_RESULT([$_make_command])else ifGNUmake="#"AC_MSG_RESULT([nothing found])fiAC_SUBST([ifGNUmake])AS_VAR_POPDEF([_make_command])dnl]])
  • The M4 macrosAdding some action : ACTION-IF-TRUE / ACTION-IF-FALSEIf 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 (oradditionally 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 fordnl -------------------------------------------------------------------------------------------------------------------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 gnumakefor a in "$MAKE" $1 make gmake gnumakedo test "x$a" = "x" && continueif ( sh -c "$a --version" 2>/dev/null | grep GNU >/dev/null )then _make_command="$a" ; break;fidoneif test "x$_make_command" != "x"then ifGNUmake=""AC_MSG_RESULT([$_make_command])$2else ifGNUmake="#"AC_MSG_RESULT([nothing found])$3fiAC_SUBST([ifGNUmake])AS_VAR_POPDEF([_make_command])]])
  • Using a custom m4 functions is done by includingAutomake supports an include directive which can be used to include other `Makefile fragments when automake isrun. Note that these fragments are read and interpreted by automake, not by make. As with conditionals,make has noidea that include is in use.There are two forms of include:include $(srcdir)/fileinclude a fragment which is found relative to the current source directory.include $(top_srcdir)/fileThe M4 macrosinclude $(top_srcdir)/fileinclude a fragment which is found relative to the top source directory. Note that if a fragment is includedinside a conditional, then the condition applies to the entire contents of that fragment.Example of m4 macro include:include(pkg.m4)sinclude(pkg.m4)
  • M4 MACROS LABThe M4 macrosM4 MACROS LAB
  • The M4 macrosThe main goal for this lab is to create a file called mymacros.m4that 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 thegnu/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 –rcat /proc/versionLinux version 2.6.35-28-generic (buildd@rothera) (gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) ) #50-UbuntuSMP Fri Mar 18 19:00:26 UTC 2011cat /proc/sys/kernel/osrelease2.6.35-28-genericThen, 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.htmlGNU 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.htmlSome 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.docxhttp://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20-%20integration%20of%20the%20debug%20mode%20in%20autotools.docxhttp://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20-%20int%C3%A9gration%20of%20the%20tests%20in%20autotools.docxhttp://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20-%20pkgconfig%20with%20the%20autotools.docxhttp://systems.thomnet.com/km/STB/HybridSTB/Revolution/ProjectDocuments/application%20note%20-%20version%20management%20in%20autotools.docx
  • http://www.murrayc.com/learning/linux/automake/automake.shtmlhttp://www.murrayc.com/learning/linux/using_libraries/using_libraries.shtmlhttp://www.murrayc.com/learning/linux/building_libraries/building_libraries.shtmlhttp://www.gnu.org/software/libtool/http://www.gnu.org/software/make/http://www.gnu.org/software/m4/m4.htmlhttp://www.gnu.org/software/m4/manual/m4.htmlhttp://www.developingprogrammers.com/index.php/2006/01/05/autotools-tutorial/http://www.cppfrance.com/tutoriaux/AUTOTOOLS-AUTOCONF-AUTOMAKE-LIBTOOL_876.aspxhttp://www.lrde.epita.fr/~adl/autotools.htmlhttp://inti.sourceforge.net/tutorial/libinti/autotoolsproject.htmlhttp://www.cs.wmich.edu/~kkaugars/projects/Automake.htmlhttp://www.st-andrews.ac.uk/~iam/docs/tutorial.htmlLinks 2/2 : other useful linkshttp://www.st-andrews.ac.uk/~iam/docs/tutorial.htmlhttp://autotoolset.sourceforge.net/tutorial.htmlhttp://www.linuxselfhelp.com/gnu/autoconf/html_chapter/autoconf_toc.htmlhttp://media.vodka-pomme.net/autotools/autotools.pdfhttp://www-igm.univ-mlv.fr/~dr/XPOSE/Breugnot/http://irt.enseeiht.fr/boyer/Automake-Autoconf/Automake.htmhttp://ymettier.free.fr/articles_lmag/lmag75/lmag75.htmlhttp://sourceware.org/autobook/autobook/autobook_toc.html#SEC_Contentshttp://developer.kde.org/documentation/other/makefile_am_howto/en/index.htmlhttp://git.ademar.org/gitweb.cgi?p=autotools.git;a=summaryhttp://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.htmlhttp://www.seul.org/docs/autotut/http://www-lil.univ-littoral.fr/~quesnel/download/autotools.pdf
  • Books that can help
  • Thanks for your attention06/17/10