Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Autotools pratical training
1.
2.
3. Autotools introduction
The goal of this topic is to know how to well works with the autotools in a cross-
compilation environement
4. The autotools process
History :
Historically, a shell configure script transformed a Makefile.in into a
Makefile
Autoconf 1 (1992): autoconf transformed a configure.in into a configure file
Autoconf 2 (1994): added cross-compilation support, sub-directories, hidden
results, more tests, …
Automake (1994): automake transformed a Makefile.am into a Makefile
Libtool (1996): changed the Automake behavior
7. Autotools introduction
Autotools is a collection of OSS tools :
GNU Automake is a tool for automatically generating `Makefile.in' files compliant
with the GNU Coding Standards.
http://www.gnu.org/software/automake/
GNU Autoconf is an extensible package of M4 macros that produce shell scripts to automatically configure software source code packages. These scripts
can adapt the packages to many kinds of UNIX-like systems without manual user intervention. Autoconf creates a configuration script for a package from a
template file that lists the operating system features that the package can use, in the form of M4 macro calls.
Producing configuration scripts using Autoconf requires GNU M4. You should install GNU M4 (at least version 1.4.6, although 1.4.13 or
later is
recommended) before configuring Autoconf, so that Autoconf's configure script can find it. The configuration scripts produced by Autoconf are self-
contained, so their users do not need to have Autoconf (or GNU M4).
http://www.gnu.org/software/autoconf/
GNU libtool is a generic library support script. Libtool hides the complexity of using shared libraries behind a consistent, portable interface.
http://www.gnu.org/software/libtool/
pkg-config is a helper tool used when compiling applications and libraries. It helps you insert the correct compiler options on the command line so an
application can use gcc -o test test.c `pkg-config --libs --cflags glib-2.0` for instance, rather than hard-coding values on where to find glib (or other
libraries). It is language-agnostic, so it can be used for defining the location of documentation tools, for instance.
http://www.freedesktop.org/wiki/Software/pkg-config
GNU M4 is an implementation of the traditional Unix macro processor. It is mostly SVR4 compatible although it has some extensions (for example,
handling more than 9 positional parameters to macros). GNU M4 also has built-in functions for including files, running shell commands, doing arithmetic,
etc.
GNU M4 is a macro processor in the sense that it copies its input to the output expanding macros as it goes. Macros are either builtin or user-
defined and can take any number of arguments. Besides just doing macro expansion, m4 has builtin functions for including named files, running
UNIX commands, doing integer arithmetic, manipulating text in various ways, recursion etc... m4 can be used either as a front-end
to a compiler or as a macro processor in its own right.
http://www.gnu.org/software/m4/
Autogen.sh (a.k.a. buildconf) provides automatic build system preparation and is generally very useful to projects that use the GNU build system (i.e. the
GNU autotools: autoconf, automake, and libtool).
http://buildconf.brlcad.org/
A toolchain (GNU or other) that include binutils.
14. Mastering the build process
The goal of this topic is to know how the build process works.
15. Mastering the build process
The GNU Compiler Collection (GCC) :
is a compiler system produced by the GNU Project
is supporting various programming languages
is a key component of the GNU toolchain
has been adopted as the standard compiler by most other modern Unix-like computer operating
systems, including Linux, the BSD family and Mac OS X
has been ported to a wide variety of processor architectures
is widely deployed as a tool in commercial, proprietary and closed source software
development environments
is also available for most embedded platforms, for example Symbian (called gcce), AMCC and
Freescale Power Architecture-based chips
can target a wide variety of platforms, including videogame consoles such as the PlayStation 2
and Dreamcast. Several companies make a business out of supplying and supporting GCC ports
to various platforms, and chip manufacturers today consider a GCC port almost essential to the
success of an architecture.
Originally named the GNU C Compiler, because it only handled the C programming language,
GCC 1.0 was released in 1987, and the compiler was extended to compile C++ in December of that
year. Front ends were later developed for Fortran, Pascal, Objective-C, Java, and Ada, among others.
The Free Software Foundation (FSF) distributes GCC under the GNU General Public License
(GNU GPL). GCC has played an important role in the growth of free software, as both a tool and an
example.
http://gcc.gnu.org
16.
17.
18.
19.
20. Mastering the build process
Linking : the compiler’s backend
•Generates assembly code for the final output.
•Generates ELF object (replace the old a.out one).
•Uses ld through the gcc.
•Can make:
Binary: adds a main entry to the intermediate code.
Dynamic library: if the -shared parameter has been given (cannot be
runable except for the libc).
Direct usage with the ld linker : $ ld -o mybinary /lib/crt0.o file.o –lc
crt0 (or crt0.o, gcrt0.o, mcrt0.o) is a set of execution start-up routines (usually part of
the C standard library) that are platform dependent, and is required in order to compile
using GCC and other GNU tools. crt stands for "C runtime".
-e entry
Use entry as the explicit symbol for beginning execution of the program, rather than the
default entry point (main). If there is no symbol named entry, the linker will try to parse
entry as a number, and use that as the entry address (the number will be interpreted in base
10; you may use a leading 0x for base 16, or a leading 0 for base 8).
21. Mastering the build process
GNU tools from the toolchain are set for an embedded usage :
--sysroot=staging directory
Use dir as the logical root directory for headers and libraries. For example, if the compiler would normally search for headers in
/usr/include and libraries in /usr/lib, it will instead search dir/usr/include and dir/usr/lib.
If you use both this option and the -isysroot option, then the --sysroot option will apply to libraries, but the -isysroot option will apply to
header files.
The GNU linker (beginning with version 2.16) has the necessary support for this option. If your linker does not support this option, the
header file aspect of --sysroot will still work, but the library aspect will not.
Usually te environment is defined like this :
export STAGING_DIR=<PATH TO THE STAGING DIRECTORY>
export PREFIX=«i686-cm-linux-»
export TOOLCHAIN_DIR=<PATH TO THE TOOLCHAIN>
export CC=$(PREFIX)gcc --sysroot=$(STAGING_DIR)
export LD=$(PREFIX)ls --sysroot=$(STAGING_DIR)
export GCC=$(PREFIX)gcc --sysroot=$(STAGING_DIR)
export CXX=$(PREFIX)gcc --sysroot=$(STAGING_DIR)
export GDB="$(STAGING_DIR)/bin/$(PREFIX)gdb"
export RANLIB="$(TOOLCHAIN_DIR)/bin/$(PREFIX)ranlib"
export STRIP="$(TOOLCHAIN_DIR)/bin/$(PREFIX)strip"
export OBJCOPY="$(TOOLCHAIN_DIR)/bin/$(PREFIX)objcopy"
export AR="$(TOOLCHAIN_DIR)/bin/$(PREFIX)ar"
export AS="$(TOOLCHAIN_DIR)/bin/$(PREFIX)as"
export LD="$(TOOLCHAIN_DIR)/bin/$(PREFIX)ld"
23. Mastering the build process
The main goal of this lab is to know how is working the
GNU/
Using the helloworld.c source code try several parameters
{--verbose/-E/-S}:
gcc --verbose
gcc -c helloworld.c
gcc -c helloworld.c -o helloworld.o
gcc -E helloworld.c
gcc -S helloworld.c
…
25. Quick GNU/make reminder
The final files generated are gnu/make based.
Most Makefile.am can be extend with gnu/make features that‘s why this is
important to know how makefiles are made.
We will remain some basic makefile usage.
26.
27.
28.
29.
30.
31. Quick GNU/make reminder
With GNU/Makefiles :
No target is buildin ; everything should be written from scratch
each time ;
Doesn‘t use generic templates for binaries, libraries, … ;
Cross-compilation support should be manualy specified ;
Pkg-config can be used (not by M4 macros) ;
Can make ugly Makefile ;
Makefile are often more static than dynamic
Everything done by gnu Makefile is automatically
natively supported by the Autotools !
32. Quick GNU/make reminder
Other make engine exists:
ocmake (http://www.cmake.org/)
oqmake (http://doc.qt.nokia.com/4.4/qmake-manual.html)
oand so on…
For more information about the GNU/make:
http://oreilly.com/catalog/make3/book/index.csp
http://www.wanderinghorse.net/computing/make/book/ManagingProjectsWithG
NUMake-3.1.3.pdf
http://notendur.hi.is/~jonasson/software/make-book/
http://www.gnu.org/software/make/manual/make.pdf
http://en.wikipedia.org/wiki/Make_(software)#Modern_versions
http://ecee.colorado.edu/~mcclurel/gnu_make_overview.pdf
http://static.maemo.org/static/d/dcacc028fda611dd9062b3dd54505f765f76_gnu_
make_and_makefiles.pdf
34. Quick GNU/make reminder
The main goal of the lab is to write a makefile with several targets:
The project have three source code: data.c, main.c and io.c
The make file should support the following targets:
Compilation: make (aka make all)
Cleaning old objects:make clean
Create tarball: make dist
Create an installer: make DESTDIR=«PATH» install
Create an uninstaller:make DESTDIR=«PATH» uninstall
35. Quick GNU/make reminder
So, if we check the several Makefiles written,
no one will be identical,
that’s mean there is no uniformisation/no standard.
That what the autotools provide.
39. The autotools process
working with the autotools means for a developer to manage templates and
potfiles :
Makefile.am : used to define what should be build
and how
using generic templates.
configure.ac : used to define an autotools project.
It can include
<component>.*.in : used to associate some metadata
(this is used by *.pc.in used for managing
dependencies or config files).
Only those files have to be managed by the developers.
No more files need to be stored in repository except if there are filled
(README, LICENCE, … ).
40. The autotools process
STEP #1 : autogen.sh
The autogen.sh is a generic script used to prepare an autotool project for end users.
Its goal is to check the environment need for the autotools scripts and binaries.
This script need to be launched each time a template have been modified.
It will generate several files:
oa configure script from the configure.ac
oa Makefile.in form the Makefile.am
oa config.h.in if expected
configure.ac ---
Roadmap : |
| ------> autoconf* -----> configure
[aclocal.m4] --+--- |
| -----> autoheader* --> [config.h.in]
|
[acsite.m4] -----
Makefile.am -------------------------------> Makefile.in
41. The autotools process
STEP #2 : configuration, compilation and installation
This is the end user view.
This step must start by the launch of the configure script in order to generate a final
Makefile:
./configure --prefix=/usr …
Then, this is possible to use the several target from the Makefile:
and so on…
42.
43.
44. The autotools process
Debugging via autom4te:
At times, it is desirable to see what was happening inside m4, to see why output was not matching expectations. However, post-
processing done by autom4te means that directly using the m4 builtin m4_traceon is likely to interfere with operation. Also, frequent
diversion changes and the concept of forbidden tokens make it difficult to use m4_defn to generate inline comments in the final output.
There are a couple of tools to help with this. One is the use of the --trace option provided by autom4te (as well as each of the programs
that wrap autom4te, such as autoconf), in order to inspect when a macro is called and with which arguments. For example, when this
paragraph was written, the autoconf version could be found by:
$ autoconf --trace=AC_INIT
configure.ac:23:AC_INIT:GNU Autoconf:2.63b.95-3963:bug-autoconf@gnu.org
$ autoconf --trace='AC_INIT:version is $2‗
version is 2.63b.95-3963
Another trick is to print out the expansion of various m4 expressions to standard error or to an independent file, with no further m4
expansion, and without interfering with diversion changes or the post-processing done to standard output. m4_errprintn shows a given
expression on standard error. For example, if you want to see the expansion of an autoconf primitive or of one of your autoconf macros,
you can do it like this:
$ cat <<EOF > configure.ac
AC_INIT
m4_errprintn([The definition of AC_DEFINE_UNQUOTED:])
m4_errprintn(m4_defn([AC_DEFINE_UNQUOTED]))
AC_OUTPUT
EOF
$ autoconf
error-->The definition of AC_DEFINE_UNQUOTED:
error-->_AC_DEFINE_Q([], $@)
45.
46.
47. The autotools process
• The essential files:
The smallest project requires you provide only two files:
CONFIGURE.AC : an input file to autoconf that provides the macro invocations and shell code fragments
autoconf uses to build a configure script.
MAKEFILE.AM: an input file to automake that specifies a projects build requirements: what needs to be built,
and where it goes when installed.
The GNU Autotools will generate the rest of the files needed to build the project.
• The Directory Structure:
Before writing any code for a new project you need to decide on the directory structure the project will use ;
The top-level directory is used for configuration files, such as configure.in, and other sundry files like ChangeLog,
COPY (a copy of the project license) and README ;
Any unique library should have its own subdirectory containing all headers and sources, a Makefile.am, and any other
library specific files ;
The headers and sources for the main application should be in another subdirectory, typically called src ;
Other directories can include: config for intermediate files, doc for the project documentation and test for the project
self-test suite ;
The following steps will take you through creating and building the HelloWorld project. The top-level directory for
HelloWorld is <tests/project>. You will find the project's headers and sources in the src subdirectory. There are three
files: helloworld.cc, helloworld.h and main.cc ;
50. The autotools process
The goal of this lab if to use an hello world autotools project.
Experiment the several steps :
Preparation: ./autogen.sh
See the files before and after.
Configuration: ./configure –prefix=/usr
Read the config.log that detail the configuration step ; this is a good way to
debug a configure script.
Compilation: make
Installation: make DESTDIR=pwd install
Delivery: make dist
51. Using the autoscan tool
The goal of this topic is to know how to use the autoscan tool
52. Using the autoscan tool
STEP #0 : autoscan
The easiest way to create a (mostly) complete configure.ac file is to run the
autoscan utility, which is part of the autoconf package.
This utility examines the contents of a project directory and generates the basis for a
configure.ac file (which autoscan names configure.scan) using existing makefiles and
source files.
The autoscan utility examines the project directory hierarchy and creates two files
called configure.scan and autoscan.log.
The project may or may not already be instrumented for Autotools ; it doesn’t really
matter, because autoscan is decidedly non-destructive. It will never alter any existing
files in a project.
your source files autoscan* configure.scan configure.ac
53. Using the autoscan tool
First exampleof the autoscan tool, two files should appear in the current directory:
After the launch with an empty directory:
autoscan.log
configure.scan should be renamed into a configure.ac file afterward
As we see, the contents of the generated configure.scan is similar to our hand-crafted
template:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.56)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
# Checks for programs.
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT
As the name autoscan implies, you can guess that it can do other things as well, not only
54. Using the autoscan tool
Second example with two existing files in the project:
A header sleep.h :
#include <stdio.h>
#include <unistd.h> /* Needed for sleep() */
A source code sleep.c :
#include "sleep.h"
#define SECONDS_TO_SLEEP 3
int
main()
{
unsigned int sleep_left = 0;
/* sleep() for SECONDS_TO_SLEEP seconds, then print a message. */
sleep(SECONDS_TO_SLEEP);
printf("I woke up after %d seconds.n", SECONDS_TO_SLEEP);
return 0;
}
55. Using the autoscan tool
That will automaticaly generate the following configure.scan script:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.56)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_CONFIG_SRCDIR([sleep.c]) some file that is in the package's source directory.
AC_CONFIG_HEADER([config.h]) containing C preprocessor #define statements.
# Checks for programs.
AC_PROG_CC determine the C compiler to use.
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([unistd.h]) check for existing header file(s) (in our case only one, unistd.h).
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
To get a very basic, but working input file to autoconf, rename configure.scan to
AC_OUTPUT
configure.ac: mv configure.scan configure.ac
Then update the AC_INIT macro, and add the AC_COPYRIGHT macro.
57. Using the autoscan tool
The main goal for this lab is to go into a directory where is
existing source code ;
Launch the autoscan command: ./autoscan
View the configure.scan generated.
59. The autogen.sh script
The autogen.sh script is used for converting all the templates (configure.ac, Makefile.am, …) in
final files (Makefile, configure, …) needed for a common Autotools usage.
Thus, The autogen.sh script (a.k.a. buildconf) provides automatic build system preparation and is
generally very useful to projects that use the GNU build system (i.e. the GNU Autotools: autoconf,
automake, and libtool). It is a POSIX shell script that is used for preparing a build system for
compilation, verifying versions, ensuring necessary functionality, and overcoming many common
build preparation issues.
Official web site : http://buildconf.brlcad.org/
Licence : BSD
Latest stable release : 23.12.2009
http://downloads.sourceforge.net/project/buildconf/autogen/2009.12.23/buildconf.2009.12.23.tar.gz?u
se_mirror=freefr&ts=1278845776
This script is standalone, its usage is mainly limited to a call in the autotools directory :
$ ./autogen.sh
Another way is to use the following command: autoreconf -i –force
(This is what the script do in background)
60. The autogen.sh script
Before the autoconf script some bootstrap command was used:
first, we need to generate the required output files from the two input files configure.in and Makefile.am. First we need to
collect all the macro invocations in configure.in that Autoconf will need to build the configure script. This is done with the
following command:
$ aclocal
This generates the file aclocal.m4 and adds it to the current directory. Next, run autoconf:
$ autoconf
After running autoconf you will find the configure script in the current directory. It's important to run aclocal first because
automake relies on the contents on configure.in and aclocal.m4.
There are a few files that the GNU standard says must be present in the top-level directory, and if not found Automake will
report an error. Enter the following command to create these files:
$ touch AUTHORS NEWS README ChangeLog
Now we can run automake to create Makefile.in. The –add-missing argument copies some boilerplate files from your
Automake installation into the current directory.
$ automake --add-missing
By now, the contents of the directory should be looking a lot like the top-level directory of a GNU package you may have
installed before:
61. The autogen.sh script
What the autogen.sh really do :
It tranforms the template into intermediate files:
Those files will complete the other files (component.pc.in), in order to be
ready for the configure script.
Note : configure.ac is by far the preferred naming for autoconf >= 2.50 while
configure.in is what was used by autoconf ⇐ 2.13 and was kept for *cough*
backward compatibility *cough*…
62. The autogen.sh script
Parameters used to control the autogen.sh script :
There is two controversal parameters with the --quiet and --verbose that can be set in the same
time!! Indeed, the autogen.sh script will follow the last one provided at the launch.
Check of the autotools components version:
$ ./autogen.sh –version
Identical as :
Preparing the toe build system...please wait ./autoconf --version
Found GNU Autoconf version 2.67
Found GNU Automake version 1.11.1 ./automake –version
Found GNU Libtool version 2.2.6b ./libtool --version
autogen.sh build preparation script by Christopher Sean Morrison
+ config.guess download patch by Sebastian Pipping (2008-12-03)
revised 3-clause BSD-style license, copyright (c) 2005-2009
script version 20090301, ISO/IEC 9945 POSIX shell script
---
Version requested. No preparation or configuration will be performed.
63. The autogen.sh script
Autogen.sh usage can be obtain with the command line:
$ ./autogen.sh –help
Usage: ./autogen.sh [-h|--help] [-v|--verbose] [-q|--quiet] [-d|--download] [--version]
--help Help on autogen.sh usage
--verbose Verbose progress output
--quiet Quiet suppressed progress output
--download Download the latest config.guess from gnulib
--version Only perform GNU Build System version checks
Description: This script will validate that minimum versions of the
GNU Build System tools are installed and then run autoreconf for you.
Should autoreconf fail, manual preparation steps will be run
potentially accounting for several common preparation issues. The
AUTORECONF, AUTOCONF, AUTOMAKE, LIBTOOLIZE, ACLOCAL, AUTOHEADER,
PROJECT, & CONFIGURE environment variables and corresponding _OPTIONS
variables (e.g. AUTORECONF_OPTIONS) may be used to override the
default automatic detection behavior.
autogen.sh build preparation script by Christopher Sean Morrison
+ config.guess download patch by Sebastian Pipping (2008-12-03)
revised 3-clause BSD-style license, copyright (c) 2005-2009
script version 20090301, ISO/IEC 9945 POSIX shell script
---
Help was requested. No preparation or configuration will be performed.
64. The autogen.sh script $ ./autogen.sh –verbose
Silent launch (default): Verbose output enabled
Found a configure template: ./configure.ac
Preparing the toe build system...please wait
Checking autoreconf version: autoreconf --version
$ ./autogen.sh Checking autoconf version: autoconf --version
Preparing the toe build system...please wait
Found GNU Autoconf version 2.67
Checking if 2.67.0 is greater than 2.52.0
Checking automake version: automake --version
Verbose launch
Found GNU Automake version 1.11.1
Checking if 1.11.1 is greater than 1.6.0
Found GNU Autoconf version 2.67 Checking libtoolize version: libtoolize --version
Found GNU Libtool version 2.2.6b
Found GNU Automake version 1.11.1 Checking if 2.2.6 is greater than 1.4.2
Found GNU Libtool version 2.2.6b Checking aclocal version: aclocal --version
Checking autoheader version: autoheader --version
Checking whether to only output version information
Automatically preparing build ... done Backing up COPYING in /home/gayetth/workspace/TOE
cp -p COPYING COPYING.25605.protect_from_automake.backup
Backing up INSTALL in /home/gayetth/workspace/TOE
cp -p INSTALL INSTALL.25605.protect_from_automake.backup
The toe build system is now prepared. To build here, run: Found an autom4te.cache directory, deleting it
./configure rm -rf autom4te.cache
make mv -f "./config.guess" "./config.guess.backup"
mv -f "./config.sub" "./config.sub.backup"
mv -f "./ltmain.sh" "./ltmain.sh.backup"
Automatically preparing build ... autoreconf -i -f
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./config.guess'
libtoolize: copying file `./config.sub'
libtoolize: copying file `./install-sh'
libtoolize: copying file `./ltmain.sh'
libtoolize: Consider adding `AC_CONFIG_MACRO_DIR([m4])' to configure.ac and
libtoolize: rerunning libtoolize, to keep the correct libtool macros in-tree.
libtoolize: Consider adding `-I m4' to ACLOCAL_AMFLAGS in Makefile.am.
rm -f COPYING.25605.protect_from_automake.backup
Restoring INSTALL from backup (automake -f likely clobbered it)
rm -f INSTALL
mv INSTALL.25605.protect_from_automake.backup INSTALL
rm -f INSTALL.25605.protect_from_automake.backup
rm -f "./config.guess.backup"
rm -f "./config.sub.backup"
rm -f "./ltmain.sh.backup"
done
The toe build system is now prepared. To build here, run:
./configure
make
rm -f "./config.guess.backup"
rm -f "./config.sub.backup"
rm -f "./ltmain.sh.backup"
65. The autogen.sh script
Useful variables used to control the autogen.sh script :
To skip autoreconf and prepare manually: AUTORECONF=false
./autogen.sh
To verbosely try running with an older (unsupported) autoconf: AUTOCONF_VERSION=2.50 ./autogen.sh
--verbose
66. The autogen.sh script
Impact on the autotools templates:
If we take the decision to use the autogen.sh script instead of the single autoreconf
command, this file is mandatorary to include in the tarball generated by the « make
dist » command.
EXTRA_DIST = $(top_builddir)/autogen.sh
The autogen.sh script should be within the files of the project.
If this file is not added the tarball will miss this file and won‘t be standalone!
68. The autogen.sh script
Take an autotools project and check the differential before
and after the launch of the autogen.sh script.
Check with: autoreconf –i –force
Check with the autotools hierarchy poster provided.
70. Using libtool
What libtool can do :
GNU Libtool simplifies your job by encapsulating both the platform-specific dependencies, and the user interface, in
a single script. GNU Libtool is designed so that the complete functionality of each host type is available via a generic
interface, but nasty quirks are hidden from the programmer.
GNU Libtool's consistent interface is reassuring... users don't need to read obscure documentation in order to have
their favorite source package build shared libraries. They just run your package configure script (or equivalent), and
libtool does all the dirty work.
71. Using libtool
Libtool is a tool used:
The following issues need to be addressed in any reusable shared library system, specifically libtool:
The package installer should be able to control what sort of libraries are built.
It can be tricky to run dynamically linked programs whose libraries have not yet been installed. LD_LIBRARY_PATH must be set properly (if it is supported), or
programs fail to run.
The system must operate consistently even on hosts that don't support shared libraries.
The commands required to build shared libraries may differ wildly from host to host. These need to be determined at configure time in a consistent way. It is not
always obvious with what prefix or suffix a shared library should be installed. This makes it difficult for Makefile rules, since they generally assume that file names
are the same from host to host.
Motivation for writing libtool :
The system needs a simple library version number abstraction, so that shared libraries can be upgraded in place. The programmer should be informed how to design
the interfaces to the library to maximize binary compatibility. The install Makefile target should warn the package installer to set the proper environment variables
(LD_LIBRARY_PATH or equivalent), or run ldconfig.
Since early 1995, several different GNU developers have recognized the importance of having shared library support for their packages. The primary motivation for
such a change is to encourage modularity and reuse of code (both conceptually and physically) in GNU programs.
Such a demand means that the way libraries are built in GNU packages needs to be general, to allow for any library type the package installer might want. The
problem is compounded by the absence of a standard procedure for creating shared libraries on different platforms.
The following sections outline the major issues facing shared library support in GNU, and how shared library support could be standardized with libtool.
The following specifications were used in developing and evaluating this system:
The system must be as elegant as possible.
The system must be fully integrated with the GNU Autoconf and Automake utilities, so that it will be easy for GNU maintainers to use. However, the system must not
require these tools, so that it can be used by non-GNU packages.
72.
73. Using libtool
Libtool is a tool used: libtool [OPTION]... [MODE-ARG]...
Listing of the several modes available:
74. Using libtool
TAGs available :
The same tags can be overwritten in the autotool context (this often do in a
cross-compilation mode):
CC=sh4-linux-gcc CXX=sh4-linux-g++ ./configure --prefix=/usr …
76. Using libtool
Link mode :
Link mode links together object files (including library objects) to form another library or to create an executable program.
mode-args consist of a command using the C compiler to create an output file (with the -o flag) from several object files. The following
components of mode-args are treated specially:
79. Using libtool
Link mode (cont)
If the output-file ends in .la, then a libtool library is created, which must be built only from library
objects (.lo files). The -rpath option is required. In the current implementation, libtool libraries may
not depend on other uninstalled libtool libraries.
If the output-file ends in .a, then a standard library is created using ar and possibly ranlib.
If output-file ends in .o or .lo, then a reloadable object file is created from the input files (generally
using ‗ld -r‘). This method is often called partial linking.
Otherwise, an executable program is created.
80. Using libtool
Execution mode :
For execute mode, the library path is automatically set, then a program is executed.
The first of the mode-args is treated as a program name, with the rest as arguments to that
program.
The following components of mode-args are treated specially:
If any of the args are libtool executable wrappers, then they are translated into the name of their
corresponding uninstalled binary, and any of their required library directories are added to the
library path.
81. Using libtool
Installation mode :
In install mode, libtool interprets most of the elements of mode-args as an installation command beginning with cp, or a BSD-compatible install
program.
The following components of mode-args are treated specially:
-inst-prefix-dir inst-prefix-dir
When installing into a temporary staging area, rather than the final prefix, this argument is used to reflect the temporary path, in
much the same way automake uses DESTDIR. For instance, if prefix is /usr/local, but inst-prefix-dir is /tmp, then the object will
be installed under /tmp/usr/local/. If the installed object is a libtool library, then the internal fields of that library will
reflect only prefix, not inst-prefix-dir:
# Directory that this library needs to be installed in:
libdir='/usr/local/lib'
not
# Directory that this library needs to be installed in:
libdir='/tmp/usr/local/lib‗
inst-prefix is also used to insure that if the installed object must be relinked upon installation, that it is relinked against the libraries in inst-prefix-
dir/prefix, not prefix.
In truth, this option is not really intended for use when calling libtool directly; it is automatically used when libtool --mode=install calls libtool --
mode=relink. Libtool does this by analyzing the destination path given in the original libtool --mode=install command and comparing it to the
expected installation path established during libtool --mode=link.
Thus, end-users need change nothing, and automake-style make install DESTDIR=/tmp will Just Work(tm) most of the time. For systems where fast
installation can not be turned on, relinking may be needed. In this case, a ‗DESTDIR‘ install will fail.
Currently it is not generally possible to install into a temporary staging area that contains needed third-party libraries which are not yet visible at their
final location.
The rest of the mode-args are interpreted as arguments to the cp or install command.
82. Using libtool
Finish mode :
Finish mode has two functions. One is to help system administrators install libtool libraries so that
they can be located and linked into user programs.
To invoke this functionality, pass the name of a library directory as mode-arg:
The second is to facilitate transferring libtool libraries to a native compilation environment after
they were built in a cross-compilation environment. Cross-compilation environments may rely on
recent libtool features, and running libtool in finish mode will make it easier to work with older
versions of libtool. This task is performed whenever the mode-arg is a .la file.
83. Using libtool
Uninstall mode :
Uninstall mode deletes installed libraries, executables and objects.
The first mode-arg is the name of the program to use to delete files (typically /bin/rm).
The remaining mode-args are either flags for the deletion program (beginning with a ‗-‘), or the
names of files to delete.
84. Using libtool
Clean mode :
Clean mode deletes uninstalled libraries, executables, objects and libtool's temporary files associated
with them.
The first mode-arg is the name of the program to use to delete files (typically /bin/rm).
The remaining mode-args are either flags for the deletion program (beginning with a ‗-‘), or the
names of files to delete.
86. Using libtool
The goal of this lab is to understand what libtool is really working.
Try to compile a helloworld.c source code by the two way:
gcc –c helloworld.c –o helloworld.o
Libtool --mode=compile gcc -c helloworld.c
Same for the link step (should create a helloworld binary):
gcc helloworld.o –o helloworld
libtool --mode=link gcc –o helloworld helloworld.o
88. The configure.{in/ac} template
A configure.ac is the template of the configure script that will be used by
the end user.
A configure.ac is written using M4 macros while a configure script is a
shell script.
The main goal of a configure script is to lead the configuration of a
component. The several flags provided to the configure script is like the ID
card of the build.
The configure.ac teamplate is equal to the configure.in that is the old
notation.
Those script are executed like shell script at the runtime (no compiled).
Can build libraries, binaries, … in the same files, by managing
dependencies.
89.
90. The configure.{in/ac} template
Preset Output Variables :
Beware about all directories, because they can be override by configure options: ./configure –
prefix=/usr –srcdir=/tmp_srcdir …
If so, top_builddir can be different to top_srcdir and bring link problems, so be carefull !!
91. The configure.{in/ac} template
Flags overriding :
http://www.gnu.org/software/hello/manual/autoconf/Preset-Output-Variables.html
92. The configure.{in/ac} template
Tools overriding :
Examples:
./configure –prefix=/usrCC=gcc CFLAGS=-O3 LIBS=―-lposix‖ …
or
CC=sh4-linux-gcc AR=sha-linux-g++ ./configure –prefix=/usr …
93. The configure.{in/ac} template
Special Characters in Output Variables :
Many output variables are intended to be evaluated both by make and by the shell. Some
characters are expanded differently in these two contexts, so to avoid confusion these
variables' values should not contain any of the following characters: " # $ & ' ( ) * ; < > ? [
^`|
Also, these variables' values should neither contain newlines, nor start with ‗~‘, nor contain
white space or ‗:‘ immediately followed by ‗~‘. The values can contain nonempty
sequences of white space characters like tabs and spaces, but each such sequence might
arbitrarily be replaced by a single space during substitution.
These restrictions apply both to the values that configure computes, and to the values set
directly by the user. For example, the following invocations of configure are problematic,
since they attempt to use special characters within CPPFLAGS and white space
within $(srcdir):
CPPFLAGS='-DOUCH="&"#$*?"' '../My Source/ouch-1.0/configure'
'../My Source/ouch-1.0/configure' CPPFLAGS='-DOUCH="&"#$*?"'
94. The configure.{in/ac} template
Some of the useful built-in M4 macros:
There are many others ; check the gnu/autoconf manual for more
Information (http://www.gnu.org/software/autoconf/manual/autoconf.pdf).
95.
96.
97. The configure.{in/ac} template
Printing messages :
Configure scripts need to give users running them several kinds of information. The following macros print messages
in ways appropriate for each kind. The arguments to all of them get enclosed in shell double quotes, so the shell
performs variable and back-quote substitution on them. These macros are all wrappers around the echo shell command.
They direct output to the appropriate file descriptor:
Macro: AC_MSG_CHECKING (feature-description)
Notify the user that configure is checking for a particular feature. This macro prints a message that starts with
‗checking ‘ and ends with ‗...‘ and no newline. It must be followed by a call to AC_MSG_RESULT to print the result of
the check and the newline. The feature-descriptionshould be something like „whether the Fortran compiler accepts
C++ comments‟ or „for c89‟. This macro prints nothing if configure is run with the --quiet or --silent option. This is
quite similar to a echo -n.
Macro: AC_MSG_RESULT (result-description)
Notify the user of the results of a check. result-description is almost always the value of the cache variable for the
check, typically „yes‟, „no‟, or a file name. This macro should follow a call to AC_MSG_CHECKING, and the result-
description should be the completion of the message printed by the call to AC_MSG_CHECKING. This macro prints
nothing if configure is run with the --quiet or --silent option. This is quite similar to an echo after an echo -n, so it will
be in the same line.
Example:
AC_MSG_CHECKING(“Checking something”)
(…)
Something tested here…The result is a boolean variable such as « bchkSomething »
(…)
AC_MSG_RESULT(bchkSomething)
98. The configure.{in/ac} template
Macros used for traces :
Macro: AC_MSG_NOTICE (message)
Deliver the message to the user. It is useful mainly to print a general description of the overall purpose of a group
of feature checks, e.g., AC_MSG_NOTICE([checking if stack overflow is detectable]). This macro prints nothing
if configure is run with the --quiet or --silent option.
Macro: AC_MSG_ERROR (error-description, [exit-status = „$?/1‟])
Notify the user of an error that prevents configure from completing. This macro prints an error message to the
standard error output and exits configure with exit-status („$?‟ by default, except that „0‟ is converted to „1‟). error-
description should be something like „invalid value $HOME for $HOME‟. The error-description should start with
a lower-case letter, and “cannot” is preferred to “can't”.
Macro: AC_MSG_FAILURE (error-description, [exit-status])
This AC_MSG_ERROR wrapper notifies the user of an error that prevents configure from completing and that
additional details are provided in config.log. This is typically used when abnormal results are found during a
compilation.
Examples:
AC_MSG_NOTICE(“this is just a message”)
99. The configure.{in/ac} template
Initialisation of the configure script (including the requirements) :
The Autoconf language differs from many other computer languages because it treats actual code the same as plain text. Whereas in C,
for instance, data and instructions have different syntactic status, in Autoconf their status is rigorously the same. Therefore, we need a
means to distinguish literal strings from text to be expanded: quotation.
When calling macros that take arguments, there must not be any white space between the macro name and the open parenthesis.
AC_INIT([hello], [1.0]) # good
Arguments should be enclosed within the quote characters ‗[‘ and ‗]‘, and be separated by commas. Any leading blanks or newlines in
arguments are ignored, unless they are quoted. You should always quote an argument that might contain a macro name, comma,
parenthesis, or a leading blank or newline. This rule applies recursively for every macro call, including macros called from other
macros.
AC_COPYRIGHT (copyright-notice)
State that, in addition to the Free Software Foundation's copyright on the Autoconf macros, parts of your configure are covered by the
copyright-notice. The copyright-notice shows up in both the head of configure and in ‗configure --version‘.
Some are mandatory :
o AC_INIT([pyPackage], [myPackageVersion], [thierry.gayet2@technicolor.com]) initializes autoconf with information
about your project, including the project name, version number, bug-reporting address, tarball name and the project homepage.
o AC_PREREQ(2.59) specify the autoconf version
Others are not :
o AC_AUTOMAKE() adds several standard checks and initializes automake.
• AM_INIT_AUTOMAKE([1.10 no-define])
•AM_INIT_AUTOMAKE([1.10 no-define foreign]) specify that the component won‘t use the GNU file (NEWS
100. The configure.{in/ac} template
PATH and source code definition :
AC_CONFIG_SRCDIR(unique-file-in-source-dir)
unique-file-in-source-dir is some file that is in the package's source directory; configure checks for this file's existence to make sure that
the directory that it is told contains the source code in fact does. Occasionally people accidentally specify the wrong directory with --
srcdir; this is a safety check. Packages that do manual configuration or use the install program might need to tell configure where to find
some other shell scripts by calling AC_CONFIG_AUX_DIR, though the default places it looks are correct for most cases.
AC_CONFIG_AUX_DIR(dir)
Use the auxiliary build tools (e.g., install-sh, config.sub, config.guess, Cygnus configure, Automake and Libtool scripts, etc.) that are in
directory dir. These are auxiliary files used in configuration. dir can be either absolute or relative to srcdir. The default is srcdir or srcdir/..
or srcdir/../.., whichever is the first that contains install-sh. The other files are not checked for, so that using AC_PROG_INSTALL does
not automatically require distributing the other auxiliary files. It checks for install.sh also, but that name is obsolete because some make
have a rule that creates install from it if there is no makefile. The auxiliary directory is commonly named build-aux. If you need
portability to DOS variants, do not name the auxiliary directory aux.
AC_REQUIRE_AUX_FILE(file)
Declares that file is expected in the directory defined above. In Autoconf proper, this macro does nothing: its sole purpose is to be traced
by third-party tools to produce a list of expected auxiliary files. For instance it is called by macros like AC_PROG_INSTALL (see
Particular Programs) or AC_CANONICAL_BUILD (see Canonicalizing) to register the auxiliary files they need. Similarly, packages that
use aclocal should declare where local macros can be found using AC_CONFIG_MACRO_DIR.
AC_CONFIG_MACRO_DIR(dir)
Specify dir as the location of additional local Autoconf macros. This macro is intended for use by future versions of commands like
autoreconf that trace macro calls. It should be called directly from configure.ac so that tools that install macros for aclocal can find the
macros' declarations. Note that if you use aclocal from Automake to generate aclocal.m4, you must also set ACLOCAL_AMFLAGS = -I
dir in your top-level Makefile.am. Due to a limitation in the Autoconf implementation of autoreconf, these include directives currently
must be set on a single line in Makefile.am, without any backslash-newlines.
101. The configure.{in/ac} template
Checking for specific headers:
AC_CHECK_HEADERS([unistd.h])
Then you could have code like the following in conf.h.in. The conf.h created by configure defines ‗HAVE_UNISTD_H‘ to 1, if and
only if the system has unistd.h.
/* Define as 1 if you have unistd.h. */ #undef HAVE_UNISTD_H
The format of the template file is stricter than what the C preprocessor is required to accept. A directive line should contain only
whitespace, ‗#undef‘, and ‗HAVE_UNISTD_H‘. The use of ‗#define‘ instead of ‗#undef‘, or of comments on the same line as
‗#undef‘, is strongly discouraged. Each hook should only be listed once. Other preprocessor lines, such as ‗#ifdef‘ or ‗#include‘, are
copied verbatim from the template into the generated header.
102. The configure.{in/ac} template
Default prefix :
By default, configure sets the prefix for files it installs to /usr/local. The user of configure can select a different prefix using the --
prefix and --exec-prefix options. There are two ways to change the default: when creating configure, and when running it. Some software
packages might want to install in a directory other than /usr/local by default. To accomplish that, use the AC_PREFIX_DEFAULT macro.
AC_PREFIX_DEFAULT(prefix)
Set the default installation prefix to prefix instead of /usr/local.
It may be convenient for users to have configure guess the installation prefix from the location of a related program that they have
already installed. If you wish to do that, you can call AC_PREFIX_PROGRAM.
AC_PREFIX_PROGRAM(program)
If the user did not specify an installation prefix (using the --prefix option), guess a value for it by looking for program in PATH, the way
the shell does. If program is found, set the prefix to the parent of the directory containing program, else default the prefix as described
above (/usr/local or AC_PREFIX_DEFAULT). For example, if program is gcc and the PATH contains /usr/local/gnu/bin/gcc, set the
prefix to /usr/local/gnu.
For example, if the AC_PREFIX_DEFAULT(/usr) is defined within a configure.ac, it won‘t be mandatory to specify the prefix at the
configure launch.
If not we should mantadory specify the prefix: ./configure --prefix=/usr
103. The configure.{in/ac} template
In order to prevent autotools re-generating configure script automatically this is possible to
specify that we are in maintainer mode :
Sometimes due to the SCM not strictly remembering the timestamp of files the generated Makefile will think that it
needs to re-run "autoreconf -i" or equivalent to re-generate Makefile.in from Makefile.am, configure from
configure.ac, etc.
You need to look into maintainer mode - that should prevent the autoreconf step, which will fix the end-users'
problems.
In order to proceed, the following line should be add to the configure.ac:
AM_MAINTAINER_MODE
Or provide set the --enable-maintainer-mode parameter to the configure script :
./configure --prefix=/usr
--enable-maintainer-mode
104.
105. The configure.{in/ac} template
The version scheme used by Libtool tracks interfaces, where an interface is the set of exported entry
points into the library.
All Libtool libraries start with `-version-info' set to `0:0:0' -- this will be the default version number if
you don't explicitly set it on the Libtool link command line.
The meaning of these numbers (from left to right) is as follows:
Beware, this can generate a warning if you want to generate a static library.
106.
107. The configure.{in/ac} template
Example of Makefile.am template that use the version:
lib_LTLIBRARIES = libtoe.la
libtoe_la_SOURCES = src/toe_assert.c
src/toe_memory.c
src/toe_thread.c
src/toe_messageQueue.c
inc/utlist.h
inc/internal_api.h
inc/internal_config.h
libtoe_la_CFLAGS = -I$(HEADER_DIR)
Makefile.am
$(LIBCONFIG_CFLAGS)
$(LIBLOG_CFLAGS)
-DLOG_NAME=TOE
-DLOG_MASK_PRIO=LOG_PRIO_ALL
libtoe_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
-lpthread
-lrt
108.
109.
110. The configure.{in/ac} template
Managing subdirs using AC_CONFIG_SUBDIRS (dir ...)
Make AC_OUTPUT run configure in each subdirectory dir in the given blank-or-newline-separated list. Each dir should be a literal, i.e.,
please do not use:
if test "x$package_foo_enabled" = xyes; then
my_subdirs="$my_subdirs foo"
fi
AC_CONFIG_SUBDIRS([$my_subdirs])
because this prevents ‗./configure --help=recursive‘ from displaying the options of the package foo. Instead, you should write:
if test "x$package_foo_enabled" = xyes; then
AC_CONFIG_SUBDIRS([foo])
fi
If a given dir is not found at configure run time, a warning is reported; if the subdirectory is optional, write:
if test -d "$srcdir/foo"; then
AC_CONFIG_SUBDIRS([foo])
fi
If a given dir contains configure.gnu, it is run instead of configure. This is for packages that might use a non-Autoconf script
Configure, which can't be called through a configure wrapper since it would be the same file on case-insensitive file systems.
Likewise, if a dir contains configure.in but no configure, the Cygnus configure script found by AC_CONFIG_AUX_DIR is used.
111. The configure.{in/ac} template
Some operations are accomplished in several possible ways, depending on the OS variant. Checking for them essentially requires a
―case statement‖. Autoconf does not directly provide one; however, it is easy to simulate by using a shell variable to keep track of
whether a way to perform the operation has been found yet.
Here is an example that uses the shell variable fstype to keep track of whether the remaining cases need to be checked. Note that
since the value of fstype is under our control, we don't have to use the longer ‗test "x$fstype" = xno‘.
AC_MSG_CHECKING([how to get file system type])
fstype=no
# The order of these tests is important.
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/statvfs.h>
#include <sys/fstyp.h>]])],
[AC_DEFINE([FSTYPE_STATVFS], [1],
[Define if statvfs exists.])
fstype=SVR4])
if test $fstype = no; then
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/statfs.h>
#include <sys/fstyp.h>]])],
[AC_DEFINE([FSTYPE_USG_STATFS], [1],
[Define if USG statfs.])
fstype=SVR3])
fi
if test $fstype = no; then
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/statfs.h>
#include <sys/vmount.h>]])]),
[AC_DEFINE([FSTYPE_AIX_STATFS], [1],
[Define if AIX statfs.])
fstype=AIX])
fi
# (more cases omitted here)
AC_MSG_RESULT([$fstype])
112. The configure.{in/ac} template
Creating variables exported to the Makefiles :
AC_DEFINE (variable, value, [description])
AC_DEFINE (variable)
Define variable to value (verbatim), by defining a C preprocessor macro for variable. variable should be a C identifier, optionally suffixed
by a parenthesized argument list to define a C preprocessor macro with arguments. The macro argument list, if present, should be a
comma-separated list of C identifiers, possibly terminated by an ellipsis ‗...‘ if C99 syntax is employed. variable should not contain
comments, white space, trigraphs, backslash-newlines, universal character names, or non-ASCII characters.
value may contain backslash-escaped newlines, which will be preserved if you use AC_CONFIG_HEADERS but flattened if passed via
@DEFS@ (with no effect on the compilation, since the preprocessor sees only one line in the first place). value should not contain raw
newlines. If you are not using AC_CONFIG_HEADERS, value should not contain any ‗#‘ characters, as make tends to eat them. To use a
shell variable, use AC_DEFINE_UNQUOTED instead.
description is only useful if you are using AC_CONFIG_HEADERS. In this case, description is put into the generated config.h.in as the
comment before the macro define. The following example defines the C preprocessor variable EQUATION to be the string constant ‗"$a
> $b"‘:
AC_DEFINE([EQUATION], ["$a > $b"], [Equation string.])
If neither value nor description are given, then value defaults to 1 instead of to the empty string. This is for backwards compatibility with
older versions of Autoconf, but this usage is obsolescent and may be withdrawn in future versions of Autoconf.
If the variable is a literal string, it is passed to m4_pattern_allow.
If multiple AC_DEFINE statements are executed for the same variable name (not counting any parenthesized argument list), the last one
wins.
113. The configure.{in/ac} template
AC_DEFINE_UNQUOTED (variable, value, [description])
AC_DEFINE_UNQUOTED (variable)
Like AC_DEFINE, but three shell expansions are performed—once—on variable and value: variable expansion (‗$‘), command
substitution (‗`‘), and backslash escaping (‗‘), as if in an unquoted here-document. Single and double quote characters in the value have
no special meaning. Use this macro instead of AC_DEFINE when variable or value is a shell variable. Examples:
AC_DEFINE_UNQUOTED([config_machfile], ["$machfile"],
[Configuration machine file.])
AC_DEFINE_UNQUOTED([GETGROUPS_T], [$ac_cv_type_getgroups],
[getgroups return type.])
AC_DEFINE_UNQUOTED([$ac_tr_hdr], [1],
[Translated header name.])
Due to a syntactical bizarreness of the Bourne shell, do not use semicolons to separate AC_DEFINE or AC_DEFINE_UNQUOTED
calls from other macro calls or shell code; that can cause syntax errors in the resulting configure script. Use either blanks or newlines.
That is, do this:
AC_CHECK_HEADER([elf.h],
[AC_DEFINE([SVR4], [1], [System V Release 4]) LIBS="-lelf $LIBS"])
or this:
AC_CHECK_HEADER([elf.h],
[AC_DEFINE([SVR4], [1], [System V Release 4])
LIBS="-lelf $LIBS"])
instead of this:
114. The configure.{in/ac} template
AC_SUBST (variable, [value])
Create an output variable from a shell variable. Make AC_OUTPUT substitute the variable variable into output files (typically one or
more makefiles). This means that AC_OUTPUT replaces instances of ‗@variable@‘ in input files with the value that the shell variable
has when AC_OUTPUT is called.
The value can contain any non-NUL character, including newline. If you are using automake 1.11 or newer, for newlines in values you
might want to consider using AM_SUBST_NOTMAKE to prevent automake from adding a line variable = @variable@ to the
Makefile.in files (see automake).
Variable occurrences should not overlap: e.g., an input file should not contain ‗@var1@var2@‘ if var1 and var2 are variable names.
The substituted value is not rescanned for more output variables; occurrences of ‗@variable@‘ in the value are inserted literally into the
output file. (The algorithm uses the special marker |#_!!_#| internally, so neither the substituted value nor the output file may contain
|#_!!_#|.)
If value is given, in addition assign it to variable.
All the variables defined by :
•AC_SUBST()
•AC_DEFINED_*()
•AM_CONDITIONAL()
•…
can be used in the Makefile.am.
115. The configure.{in/ac} template
AM_CONDITIONAL (conditional, condition):
The conditional name, conditional, should be a simple string starting with a letter and containing only letters, digits, and underscores. It
must be different from ‗TRUE‘ and ‗FALSE‘ that are reserved by automake.
The shell condition (suitable for use in a shell if statement) is evaluated when configure is run. Note that you must arrange for every
AM_CONDITIONAL to be invoked every time configure is run. If AM_CONDITIONAL is run conditionally (e.g., in a shell if
statement), then the result will confuse automake.
Conditionals typically depend upon options that the user provides to the configure script. Here is an example of how to write a
conditional that is true if the user uses the --enable-debug option.
AC_ARG_ENABLE([debug],
[ --enable-debug Turn on debugging],
[case "${enableval}" in
yes) debug=true ;;
no) debug=false ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
esac],[debug=false])
AM_CONDITIONAL([DEBUG], [test x$debug = xtrue])
Here is an example of how to use that conditional in Makefile.am:
if DEBUG
DBG = debug_program
else
DBG =
endif
noinst_PROGRAMS = $(DBG)
116. The configure.{in/ac} template
AM_COND_IF (conditional, [if-true], [if-false])
If conditional is fulfilled, execute if-true, otherwise execute if-false. If either branch contains AC_CONFIG_FILES, it will cause
automake to output the rules for the respective files only for the given condition.
AM_COND_IF macros may be nested when m4 quotation is used properly (see M4 Quotation).
Here is an example of how to define a conditional config file:
AM_CONDITIONAL([SHELL_WRAPPER], [test "x$with_wrapper" = xtrue])
AM_COND_IF([SHELL_WRAPPER],
[AC_CONFIG_FILES([wrapper:wrapper.in])])
117.
118. The configure.{in/ac} template
AC_ARG_WITH (package, help-string, [action-if-given], [action-if-not-given])
If the user gave configure the option --with-package or --without-package, run shell commands action-if-given. If neither option was
given, run shell commands action-if-not-given. The name package indicates another software package that this program should work
with. It should consist only of alphanumeric characters, dashes, plus signs, and dots.
The option's argument is available to the shell commands action-if-given in the shell variable with val, which is actually just the value
of the shell variable named with_package, with any non-alphanumeric characters in package changed into ‗_‘. You may use that
variable instead, if you wish.
The argument help-string is a description of the option that looks like this:
--with-readline support fancy command line editing
AC_ARG_WITH([readline],
help-string may be more than one line long, if more detail is needed. Just make sure the columns line up in ‗configure --help‘. Avoid
[AS_HELP_STRING([--without-readline],
tabs in the help string [disable support for readline])],
[],
[with_readline=yes])
LIBREADLINE=
AS_IF([test "x$with_readline" != xno],
[AC_CHECK_LIB([readline], [main],
[AC_SUBST([LIBREADLINE], ["-lreadline -lncurses"])
AC_DEFINE([HAVE_LIBREADLINE], [1],
[Define if you have libreadline])
],
[AC_MSG_FAILURE(
[readline test failed (--without-readline to disable)])],
[-lncurses])])
119.
120.
121. The configure.{in/ac} template
Configuring Other Packages in Subdirectories
In most situations, calling AC_OUTPUT is sufficient to produce makefiles in subdirectories. However, configure scripts that control more than one
independent package can use AC_CONFIG_SUBDIRS to run configure scripts for other packages in subdirectories.
AC_CONFIG_SUBDIRS(dir ...)
Make AC_OUTPUT run configure in each subdirectory dir in the given blank-or-newline-separated list. Each dir should be a literal, i.e., please do not
use:
if test "x$package_foo_enabled" = xyes; then
my_subdirs="$my_subdirs foo"
fi
AC_CONFIG_SUBDIRS([$my_subdirs])
because this prevents ‗./configure --help=recursive‘ from displaying the options of the package foo. Instead, you should write:
if test "x$package_foo_enabled" = xyes; then
AC_CONFIG_SUBDIRS([foo])
fi
If a given dir is not found at configure run time, a warning is reported; if the subdirectory is optional, write:
if test -d "$srcdir/foo"; then
AC_CONFIG_SUBDIRS([foo])
fi
If a given dir contains configure.gnu, it is run instead of configure. This is for packages that might use a non-Autoconf script Configure, which can't be
called through a wrapper configure since it would be the same file on case-insensitive file systems. Likewise, if a dir containsconfigure.in but
no configure, the Cygnus configure script found by AC_CONFIG_AUX_DIR is used.The subdirectory configure scripts are given the same command line
options that were given to this configure script, with minor changes if needed, which include:
· adjusting a relative name for the cache file;
· adjusting a relative name for the source directory;
· propagating the current value of $prefix, including if it was defaulted, and if the default values of the top level and of the
subdirectory configure differ.This macro also sets the output variable subdirs to the list of directories ‗dir ...‟. Make rules can use this variable to
determine which subdirectories to recurse into.This macro may be called multiple times.
122. The configure.{in/ac} template
Generating final files :
It can be Makefiles, .pc files, config.h headers and so on :
AC_CONFIG_FILES([
Makefile
src/Makefile New format
foo.pc
])
AC_OUTPUT
It can be Makefiles, .pc files, config.h headers and so on :
AC_OUTPUT([
Makefile
src/Makefile Old deprecated format
foo.pc
])
Both format are functional.
The first one is the best format. It is the new one with new being relative because it has been that way for a while.
The last one is the old format from way long ago.
124. The configure.{in/ac} template
The main goal for this lab is to write a basic configure that :
Check the C compiler
Check Some standard headers
Generate a Makefile in output
In case of problems with configure, you can consult the
―config.log‖ file that may provide more information about an
Autotools problem.
Read the ./configure --help to know all the parameters that
can be used by this script.
126. The Makefile.am templates
A makefile.am template will use a context prepared by the configure script.
This is the second most important template after the configure.ac.
A GNU/Makefile can support more than one target.
According to the final binary to build (binary, library, … ), the Makefile will run
them one by one in the same order than written in the template.
As seen before, Makefile.am are generic template ready for a conversion into a
Makefile.in
The Makefile.in, contains variables between arobases in order to make the update by
the configure script easy to do.
134. The Makefile.am templates
Variables used when building a program :
Occasionally it is useful to know which `Makefile' variables Automake uses for compilations; for instance you
might need to do your own compilation in some special cases. Some variables are inherited from Autoconf; these
are CC, CFLAGS, CPPFLAGS, DEFS, LDFLAGS, and LIBS.
There are some global additional variables which Automake itself defines:
This impact all components from the Makefile.am (binary, libarry, … )
136. The Makefile.am templates
The main goal for this lab is to :
1.Write a Makefile.am that will call another Makefile located
into a src directory
1.In this second Makefile.am, just generate a binary from
a helloworld.c.
1.Managed them using a single configure.ac
137. Using the library template
The goal of this topic is to know how to generate static/dynamic libraries.
138. Using the library template
Autotools template make the makefile standard and portable.
Writting a library is quite identical as a binary.
A library either static or dynamic should also export its public api:
<STAGINGDIR>/<PREFIX>/include/ public headers
<STAGINGDIR>/<PREFIX>/include/prefix/ metadata (.pc files)
<STAGINGDIR>/<PREFIX>/lib/ static and/o
By default, the configure script generate both a static and dynamic library:
This is possible so specify just one type:
./configure --disable-static : generate only a dynamic one
./configure –disable-dynamic : force to generate only a static one
139.
140.
141.
142.
143.
144.
145.
146. Using the library template
Linking with a mix of shared and static libraries
By default, the linker will link against the shared libraries if they are available. If the -static flag is
given, the linker will try to use static libraries instead of dynamic one. But -Bdynamic and -Bstatic
provides finer control of which library, shared or static should searched for each library specified for
the linker. The library search option is toggled by each -Bdynamic or -Bstatic:
ld ... -Bstatic -lfoo -Bdynamic -lbar ....
This command tells the linker to search the static library for libfoo, and search the shared version for
libbar and any libraries after it until a -Bstatic is seen.
To pass the -Bdynamic and -Bstatic options to the linker, one needs to do
gcc -o main main.o -Wl,-Bstatic -lfoo -Wl,-Bdynamic –lbar
Since the gcc driver calls the linker with some default libraries,
gcc -o main main.o -Wl,-Bstatic
tells the linker to use the static versions for all default libraries like libc and etc.
http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
147.
148. Using the library template
Memory slicing with dynamic libraries :
Dynamic libraries are mapped by the dynamic linker in the process address
space, CODE
BSS
All processes share the same dynamic library code segment, HEAP
CODE
LIB 1
Each dynamic library data segment is of course per process, DATA
CODE
Each dynamic library data size must be counted in the process memory LIB 2
consumption. DATA
Stack
151. Using the library template
This is possible to force the generation of a static library in case of a Makefile that generate
a static one before to link with :
noinst_lib_LTLIBRARIES = libfoo.la
The binary will be link using the internal LDFALGS.
Nb : the noinst prefix say that the library won‘t be install by the make install command.
The following prefix are accepted :
check_LTLIBRARIES : generate a library for unitary tests
noinst_LTLIBRARIES : generate a library for local usage (won‘t be installed)
153. Using the library template
The main goal of this lab is to generate a library.
The library have two source code lib01.c and lib02.c located into
a src directory.
The configure script should managed the version.
A single Makefile should be able to compile either a static or a
dynamic one.
154. Using the application template
The goal of this topic is to know how to generate binaries.
155. Using the application template
As well as for the library, binaries can accept some prefix :
check_PROGRAM : generate a binary for the unitary tests
noinst_PROGRAM : generate a binary for local usage (won‘t be installed)
Internal link flags should be given to the LDFLAGS one. That‘s include internal
static library.
External link flags should be given to the LDADD one. That‘s include all dependencies
checked by the PKG_CHECK_MODULE M4 macro
156. Using the application template
Example of template used for a binary template :
bin_PROGRAMS = foo
foo_SOURCES = main.c
foo_SOURCES = main.c
foo_LDADD = libfoo.la @FLIBS@
pkglib_LTLIBRARIES = libfoo.la
libfoo_la_SOURCES = bar.f baz.c zardoz.cc
libfoo_la_LIBADD = $(FLIBS)
157. Using the application template
From Executable Binary to Process Memory Map :
0x0 Elf Header
0x400000
Code
Code size
Code
0x10000000
Padding
Initialized
Data Size Data (not 0)
Initialized
Data Data set to
0 (BSS)
Statically Linked
Heap
Dyn Lib info Mono-thread
DWARF
EOF Debug Info Simple Case Process
Stack
Executable file Not loaded
Memory Map
in memory
The header is not load in memory as defined in this picture because it gives information about the binary format;
for instance it say at which memory address the code must be loaded.
158. Using the application template
The multi-threaded case :
Multiple threads share the entire process address space CODE
Each thread has its own user space stack that is allocated when doing DATA
pthread_create system call. If stack size is not given, a default value is used.
BSS
Be Careful: on x86 and NPTL POSIX thread implementation this means 8 Mb. This is the HEAP
same value for default process stack size. Thread #1
Stack
Always specify the stack size, .
.
.
Try to kill the system created initial thread after creating your own init thread,
Thread #1
Stack
159. Using the application template
Example of result for a process
with threads
Stack per thread.
161. Using the application template
The main goal for this lab is to:
1.First, generate a foobin binary from a foobin.c source code.
You will have to write a configure.ac and a Makefile.am.
1.Second, generate a library foolib from a foolib.c source code.
You will have to write a configure.ac and a Makefile.am
1.Third, merge the two configure.ac and Makefile.am
The library should compile first as a static library then link with
the binary.
162. The config.h support
The goal of this topic is to know how works the global config.h configuration header
163.
164.
165. The config.h header
Impact on the configure.ac template :
The AC_CONFIG_HEADERS([config.h]) M4 macro indicates that we will use a config.h header file.
The generated header is included by your source code to pick up the results of the various configuration
tests in the form of C preprocessor macro definitions. Every variable exported by the configure script
through M4 macro (PKG_CHECK_MODULES(), AC_DEFINE(), AC_SUBST(), … ) will be set inside.
The template file config.h.in can also be generated automatically by
the autoheader tool. autoreconf will invoke autoheader when AC_CONFIG_HEADERS is used
in configure.ac. If multiple configuration headers are used, autoheader will always only generate the
template for the first one in the list.
Example of usage in a configure.ac template
(…)
dnl ---------------------------------------
dnl Specify the internal toe_config.h
dnl ---------------------------------------
AC_CONFIG_HEADERS([inc/internal_config.h])
(..)
That will generate a header called « internal_config.h » in the « inc » directory.
Its content will include both all the boolean result of the internal check and also the custom checks made by
Component itself.
166. The config.h header
Impact on the Makefile.am template :
lib_LTLIBRARIES = libtoe.la
libtoe_la_SOURCES = src/toe_assert.c
src/toe_memory.c
src/toe_thread.c
src/toe_messageQueue.c
inc/utlist.h
inc/internal_api.h
inc/internal_config.h
libtoe_la_CFLAGS = -I$(HEADER_DIR)
$(LIBCONFIG_CFLAGS)
$(LIBLOG_CFLAGS)
-DLOG_NAME=TOE
Even if the config.h (here internal_config.h) is well include by the source code, this is important
-DLOG_MASK_PRIO=LOG_PRIO_ALL
libtoe_la_LDFLAGS the Makefile in = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
to specify it in order to include this dynamic file in the tarball generated by a make dist.
-lpthread
167. The config.h header
Config.h or not config.h that is the question…
Without config.h : With config.h :
Every flags will be provided to the compiler The command line is more silent.
over the command line (can be quite huge)
The config.h is the ID card of the build because
Easy to manage with existent component it defines all the activator, values, used during the
(don‘t need any modification for the header compilation.
Import).
That need to import this header in all source
The development process can check the code (.c, .cpp, .cxx, …) or within a top header. The
variables either in this config.h header or inclusion should be secured like this :
through the command line.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
169. The config.h header
The main goal of this lab is to write one autotool project
without any config.h and another with that support.
Compare the command line for the two build using « make v=1»
170. The config.h header
More help about :
http://www.gnu.org/software/automake/manual/html_node/Optional.ht
ml#index-AC_005fCONFIG_005fHEADERS-219
172. Managing silent/verbose support
When a big build is launch it can be nice to do not have too much traces
In the console screen.
The autotools can control the silent/verbose mode.
If the silent mode is selected, no build or warning traces won‘t be written to
stdio (err/out).
Only errors will be displayed in detail and will stop the build process.
173.
174.
175. Managing silent/verbose support
Once the silent/verbose mode have been choosen by the configure script, this
Is possible to override it thanks to the « V » parameter:
Silent mode selected by the configure script:
o Silent mode : make
o Verbose mode : make V=1
Verbose mode selected by the configure script:
o Silent mode : make V=0
o Verbose mode : make
This is possible to tune more the silent/verbose mode:
$ export LIBTOOLFLAGS "--silent“
$ make –s
177. Managing silent/verbose support
The main goal of this lab is to add a verbose
support by adding the –enable-verbose.
The default state must be silent.
178. Managing dependencies with the pkg-config tool
The goal of this topic is to know how a pkgconfig file (.pc) are managed and how to use
the pkg-config tool.
180. The pkg-config tool
The pkg-config is a helper tool used when compiling applications and libraries.
It helps you insert the correct compiler options rather than hard-coding values on where to find
glib (or other libraries). It is language-agnostic, so it can be used for defining the location of
documentation tools, for instance.
It works fine both with native and cross-compile environnement.
The program is free software and licensed under the GPL version 2 or any later.
pkg-config works on multiple platforms: Linux and other UNIX-like operating systems, Mac OS
X and Windows. It does not require anything but a reasonably well working C compiler and a C
library, but can use an installed glib if that is present. (A copy of glib 1.2.10 is shipped together
with pkg-config and this is sufficient for pkg-config to compile and work properly.)
The first implementation was written in shell, by James Henstridge. Later, it was rewritten in C
by Havoc Pennington. It also grew an autoconf macro written by Tim Janik, later rewritten by
Scott James Remnant. The current maintainer is Tollef Fog Heen <tfheen@err.no>.
The current release of pkg-config is version 0.25 (March 2011).
181.
182. The pkg-config tool
Variables for Installation Directories :
For more information : http://www.gnu.org/prep/standards/standards.pdf
183. The pkg-config tool
The autootols can make a fine tuning of the installation directories :
--bindir=DIR user executables [EPREFIX/bin]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--libexecdir=DIR program executables [EPREFIX/libexec]
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
--datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
--datadir=DIR read-only architecture-independent data [DATAROOTDIR]
--infodir=DIR info documentation [DATAROOTDIR/info]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
--mandir=DIR man documentation [DATAROOTDIR/man]
--docdir=DIR documentation root [DATAROOTDIR/doc/toe]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
--psdir=DIR ps documentation [DOCDIR]
--srcdir=DIR find the sources in DIR [configure dir or `..']
Example : ./configure --prefix=/usr
--srcdir=/tmp/tmp232123
184. The pkg-config tool
Recent pkg-config tool version use several environment variables:
185. The pkg-config tool
$ pkg-config –help Usage provided by pkg-config
Usage: pkg-config [OPTION...]
--version output version of pkg-config
--modversion output version for package
--atleast-pkgconfig-version=VERSION require given version of pkg-config
--libs output all linker flags
--static output linker flags for static linking
--short-errors print short errors
--libs-only-l output -l flags
--libs-only-other output other libs (e.g. -pthread)
--libs-only-L output -L flags
--cflags output all pre-processor and compiler flags
--cflags-only-I output -I flags
--cflags-only-other output cflags not covered by the cflags-only-I option
--variable=NAME get the value of variable named NAME
--define-variable=NAME=VALUE set variable NAME to VALUE
--exists return 0 if the module(s) exist
--print-variables output list of variables defined by the module
--uninstalled return 0 if the uninstalled version of one or more module(s) or their
dependencies will be used
--atleast-version=VERSION return 0 if the module is at least version VERSION
--exact-version=VERSION return 0 if the module is at exactly version VERSION
--max-version=VERSION return 0 if the module is at no newer than version VERSION
--list-all list all known packages
--debug show verbose debug information
--print-errors show verbose information about missing or conflicting packages,default if --
cflags or --libs
given on the command line
--silence-errors be silent about errors (default unless --cflags or --libsgiven on the command
line)
--errors-to-stdout print errors from --print-errors to stdout not stderr