Auto Tools
Auto Tools
Foreword (1/2)
This presentation targets developers familiar with Unix development tools (shell, make, compiler) that want to learn Autotools. The latest version of this document can be retrieved from
http://www.lrde.epita.fr/~adl/autotools.html
Please mail me corrections and suggestions about this document at [email protected]. Do not send me any general question about the Autotools. Use the appropriate mailing list instead ([email protected], or [email protected]).
A. Duret-Lutz
1 / 162
Tool Versions
Foreword (2/2)
This document was updated for the following releases of the Autotools: GNU GNU GNU GNU Autoconf Automake Libtool Gettext 2.65 1.11.1 2.2.6b 0.17 (November (December (November (November 2009) 2009) 2009) 2007)
These were the last releases at the time of writing. The usage of these tools has improved a lot over the last years. Some syntaxes used here will not work with older tools. This a deliberate choice:
New users should learn todays recommended usages. Make sure you have up-to-date tools and do not bother with old releases.
A. Duret-Lutz Using GNU Autotools May 16, 2010 2 / 162
Title Page
Goals Portable Packages Uniform Builds Package Use Cases The User Point of View The Power User Point of View The Packager Point of View The Maintainer Point of View The congure Process Why We Need Tools
A. Duret-Lutz Using GNU Autotools May 16, 2010 4 / 162
3 4
Goals
Portable Packages
Portable Packages
1
Goals Portable Packages Uniform Builds Package Use Cases The User Point of View The Power User Point of View The Packager Point of View The Maintainer Point of View The congure Process Why We Need Tools
3 4
A. Duret-Lutz
5 / 162
Goals
Portable Packages
Sources of Non-Portability in C
Consider C functions... that do not exist everywhere (e.g., strtod()) that have dierent names (e.g., strchr() vs. index()) that have varying prototypes (e.g., int setpgrp(void); vs. int setpgrp(int, int);) that can behave dierently (e.g., malloc(0);) that might require other libraries (is pow() in libm.so or in libc.so?) that can be dened in dierent headers (string.h vs. strings.h vs. memory.h) How should a package deal with those?
A. Duret-Lutz
6 / 162
Goals
Portable Packages
Possible Solutions
Slice the code with lots of #if/#else Create substitution macros Create substitution functions
A. Duret-Lutz
7 / 162
Goals
Portable Packages
Possible Solutions
Slice the code with lots of #if/#else Create substitution macros Create substitution functions The latter two are to be preferred.
A. Duret-Lutz
7 / 162
Goals
Portable Packages
Goals
Portable Packages
Substitution macros
A. Duret-Lutz
9 / 162
Goals
Portable Packages
Substitution functions
If strdup() does not exist, link your program with a replacement denition such as
A. Duret-Lutz
10 / 162
Goals
Uniform Builds
Uniform Builds
1
Goals Portable Packages Uniform Builds Package Use Cases The User Point of View The Power User Point of View The Packager Point of View The Maintainer Point of View The congure Process Why We Need Tools
3 4
A. Duret-Lutz
11 / 162
Goals
Uniform Builds
Maintaining a collection of #define for each system by hand is cumbersome. Requiring users to add the necessary -D, -I, and -l compilation options to Makele is burdensome. Complicated builds hinder the acceptance of free software.
A. Duret-Lutz
12 / 162
Goals
Uniform Builds
Maintaining a collection of #define for each system by hand is cumbersome. Requiring users to add the necessary -D, -I, and -l compilation options to Makele is burdensome. Complicated builds hinder the acceptance of free software.
In 1991 people started to write shell scripts to guess these settings for some GNU packages. Since then the congure script is mandatory in any package of the GNU project.
A. Duret-Lutz
12 / 162
Goals
Uniform Builds
congures Purpose
congure
congure probes the systems for required functions, libraries, and tools
A. Duret-Lutz
13 / 162
Goals
Uniform Builds
congures Purpose
congure
cong.h
congure probes the systems for required functions, libraries, and tools then it generates a cong.h le with all #defines
A. Duret-Lutz
13 / 162
Goals
Uniform Builds
congures Purpose
congure
Makele
src/ Makele
cong.h
congure probes the systems for required functions, libraries, and tools then it generates a cong.h le with all #defines as well as Makeles to build the package
A. Duret-Lutz
13 / 162
Goals
Uniform Builds
A. Duret-Lutz
14 / 162
Goals
Uniform Builds
http://www.gnu.org/prep/standards/ Practices that packages of the GNU project should follow: program behavior
how to report errors, standard command line options, etc.
A. Duret-Lutz
14 / 162
Goals
Uniform Builds
http://www.gnu.org/prep/standards/ Practices that packages of the GNU project should follow: program behavior
how to report errors, standard command line options, etc.
coding style
A. Duret-Lutz
14 / 162
Goals
Uniform Builds
http://www.gnu.org/prep/standards/ Practices that packages of the GNU project should follow: program behavior
how to report errors, standard command line options, etc.
A. Duret-Lutz
14 / 162
Goals
Uniform Builds
http://www.gnu.org/prep/standards/ Practices that packages of the GNU project should follow: program behavior
how to report errors, standard command line options, etc.
A. Duret-Lutz
14 / 162
Goals Portable Packages Uniform Builds Package Use Cases The User Point of View The Power User Point of View The Packager Point of View The Maintainer Point of View The congure Process Why We Need Tools
3 4
A. Duret-Lutz
15 / 162
A. Duret-Lutz
16 / 162
A. Duret-Lutz
16 / 162
A. Duret-Lutz
16 / 162
A. Duret-Lutz
16 / 162
A. Duret-Lutz
16 / 162
A. Duret-Lutz
16 / 162
A. Duret-Lutz
16 / 162
A. Duret-Lutz
16 / 162
A. Duret-Lutz
18 / 162
A. Duret-Lutz
18 / 162
A. Duret-Lutz
19 / 162
Goals Portable Packages Uniform Builds Package Use Cases The User Point of View The Power User Point of View The Packager Point of View The Maintainer Point of View The congure Process Why We Need Tools
3 4
A. Duret-Lutz
20 / 162
A. Duret-Lutz
21 / 162
A. Duret-Lutz
21 / 162
Objects les, programs, and libraries are built where congure was run.
A. Duret-Lutz
22 / 162
Objects les, programs, and libraries are built where congure was run. ~ % tar zxf ~/amhello-1.0.tar.gz ~ % cd amhello-1.0
A. Duret-Lutz
22 / 162
Objects les, programs, and libraries are built where congure was run. ~ % tar zxf ~/amhello-1.0.tar.gz ~ % cd amhello-1.0 ~/amhello-1.0 % mkdir build && cd build
A. Duret-Lutz
22 / 162
Objects les, programs, and libraries are built where congure was run. ~ % tar zxf ~/amhello-1.0.tar.gz ~ % cd amhello-1.0 ~/amhello-1.0 % mkdir build && cd build ~/amhello-1.0/build % ../configure
A. Duret-Lutz
22 / 162
Objects les, programs, and libraries are built where congure was run. ~ % tar zxf ~/amhello-1.0.tar.gz ~ % cd amhello-1.0 ~/amhello-1.0 % mkdir build && cd build ~/amhello-1.0/build % ../configure ~/amhello-1.0/build % make ...
A. Duret-Lutz
22 / 162
Objects les, programs, and libraries are built where congure was run. ~ % tar zxf ~/amhello-1.0.tar.gz ~ % cd amhello-1.0 ~/amhello-1.0 % mkdir build && cd build ~/amhello-1.0/build % ../configure ~/amhello-1.0/build % make ... Sources les are in / amhello-1.0/ , built les are all in / amhello-1.0/ build/ .
A. Duret-Lutz
22 / 162
A. Duret-Lutz
23 / 162
A. Duret-Lutz
23 / 162
A. Duret-Lutz
23 / 162
A. Duret-Lutz
24 / 162
A. Duret-Lutz
24 / 162
install platform-dependent les install platform-independent les (can be shared among multiple machines)
A. Duret-Lutz
24 / 162
Cross-Compilation
~/amhello-1.0 % ./configure
checking checking checking checking checking checking checking checking checking checking checking checking checking ... for a BSD-compatible install... /usr/bin/install -c whether build environment is sane... yes for gawk... gawk whether make sets $(MAKE)... yes for gcc... gcc for C compiler default output file name... a.out whether the C compiler works... yes whether we are cross compiling... no for suffix of executables... for suffix of object files... o whether we are using the GNU C compiler... yes whether gcc accepts -g... yes for gcc option to accept ANSI C...
A. Duret-Lutz
25 / 162
Cross-Compilation
~/amhello-1.0 % ./configure
checking checking checking checking checking checking checking checking checking checking checking checking checking ... for a BSD-compatible install... /usr/bin/install -c whether build environment is sane... yes for gawk... gawk whether make sets $(MAKE)... yes for gcc... gcc for C compiler default output file name... a.out whether the C compiler works... yes whether we are cross compiling... no for suffix of executables... for suffix of object files... o whether we are using the GNU C compiler... yes whether gcc accepts -g... yes for gcc option to accept ANSI C...
A. Duret-Lutz
25 / 162
Cross-Compilation
~/amhello-1.0 % ./configure --build i686-pc-linux-gnu \ --host i586-mingw32msvc
checking checking checking checking checking checking checking checking checking checking checking checking checking checking ... for a BSD-compatible install... /usr/bin/install -c whether build environment is sane... yes for gawk... gawk whether make sets $(MAKE)... yes for i586-mingw32msvc-strip... i586-mingw32msvc-strip for i586-mingw32msvc-gcc... i586-mingw32msvc-gcc for C compiler default output file name... a.exe whether the C compiler works... yes whether we are cross compiling... yes for suffix of executables... .exe for suffix of object files... o whether we are using the GNU C compiler... yes whether i586-mingw32msvc-gcc accepts -g... yes for i586-mingw32msvc-gcc option to accept ANSI C...
Using GNU Autotools May 16, 2010 25 / 162
A. Duret-Lutz
Cross-Compilation
~/amhello-1.0 % ./configure --build i686-pc-linux-gnu \ --host i586-mingw32msvc ... ~/amhello-1.0 % make ...
A. Duret-Lutz
25 / 162
Cross-Compilation
~/amhello-1.0 % ./configure --build i686-pc-linux-gnu \ --host i586-mingw32msvc ... ~/amhello-1.0 % make ... ~/amhello-1.0 % cd src; file hello.exe
hello.exe: MS Windows PE 32-bit Intel 80386 console executable not relocatable
A. Duret-Lutz
25 / 162
Cross-Compilation
~/amhello-1.0 % ./configure --build i686-pc-linux-gnu \ --host i586-mingw32msvc ... ~/amhello-1.0 % make ... ~/amhello-1.0 % cd src; file hello.exe
hello.exe: MS Windows PE 32-bit Intel 80386 console executable not relocatable
Of course you need a cross-compiler installed rst. Cross-compilation congure options: --build=BUILD The system on which the package is built. --host=HOST The system where built programs & libraries will run. --target=TARGET Only when building compiler tools: the system for which the tools will create output. For simple cross-compilation, only --host=HOST is needed.
A. Duret-Lutz Using GNU Autotools May 16, 2010 25 / 162
.
A. Duret-Lutz Using GNU Autotools May 16, 2010 26 / 162
.
A. Duret-Lutz Using GNU Autotools May 16, 2010 26 / 162
Goals Portable Packages Uniform Builds Package Use Cases The User Point of View The Power User Point of View The Packager Point of View The Maintainer Point of View The congure Process Why We Need Tools
3 4
A. Duret-Lutz
27 / 162
A. Duret-Lutz
28 / 162
A. Duret-Lutz
28 / 162
A. Duret-Lutz
28 / 162
Goals Portable Packages Uniform Builds Package Use Cases The User Point of View The Power User Point of View The Packager Point of View The Maintainer Point of View The congure Process Why We Need Tools
3 4
A. Duret-Lutz
29 / 162
Preparing Distributions
make dist Create PACKAGE-VERSION.tar.gz. make distcheck Likewise, with many sanity checks. Prefer this one!
A. Duret-Lutz
30 / 162
Preparing Distributions
make dist Create PACKAGE-VERSION.tar.gz. make distcheck Likewise, with many sanity checks. Prefer this one! make distcheck ensures most of the use cases presented so far work. It tests VPATH builds (with read-only source tree) It ensures make clean, make distclean, and make uninstall do not omit les, It checks that DESTDIR installations work, It runs the test suite (both make check and make installcheck). Releasing a package that fails make distcheck means releasing a package that will disappoint many users.
A. Duret-Lutz Using GNU Autotools May 16, 2010 30 / 162
A. Duret-Lutz
31 / 162
Nested Packages
A. Duret-Lutz
32 / 162
Nested Packages
For installers:
A single package to congure, build, and install. configure options are passed recursively to sub-packages. configure --help=recursive shows the help of all sub-packages.
A. Duret-Lutz
32 / 162
Nested Packages
For installers:
A single package to congure, build, and install. configure options are passed recursively to sub-packages. configure --help=recursive shows the help of all sub-packages.
For maintainers:
Easier integration. The sub-package is autonomous.
A. Duret-Lutz
32 / 162
Goals Portable Packages Uniform Builds Package Use Cases The User Point of View The Power User Point of View The Packager Point of View The Maintainer Point of View The congure Process Why We Need Tools
3 4
A. Duret-Lutz
33 / 162
Makele.in
src/ Makele.in
cong.h.in
congure
A. Duret-Lutz
34 / 162
Makele.in
src/ Makele.in
cong.h.in
congure
Makele
src/ Makele
cong.h
*.in les are conguration templates from which congure generates the conguration les to use for building
A. Duret-Lutz Using GNU Autotools May 16, 2010 34 / 162
Makele.in congure
src/ Makele.in
cong.h.in
cong reconguration
A. Duret-Lutz Using GNU Autotools May 16, 2010 35 / 162
Makele.in congure
src/ Makele.in
cong.h.in
cong.log
Makele.in congure
src/ Makele.in
cong.h.in
cong.status cong.log
Makele.in congure
src/ Makele.in
cong.h.in
Makele.in congure
src/ Makele.in
cong.h.in
Goals Portable Packages Uniform Builds Package Use Cases The User Point of View The Power User Point of View The Packager Point of View The Maintainer Point of View The congure Process Why We Need Tools
3 4
A. Duret-Lutz
36 / 162
A. Duret-Lutz
37 / 162
A. Duret-Lutz
37 / 162
A. Duret-Lutz
37 / 162
A. Duret-Lutz
37 / 162
A. Duret-Lutz
37 / 162
Hello World Introducing Core Autotools Hello World Explained Using Autoconf Using Automake
A. Duret-Lutz
38 / 162
Hello World
Hello World
Hello World Introducing Core Autotools Hello World Explained Using Autoconf Using Automake
A. Duret-Lutz
39 / 162
Hello World
A. Duret-Lutz
40 / 162
Hello World
Makele.in congure
src/ Makele.in
cong.h.in
A. Duret-Lutz
41 / 162
Hello World
Makele.in congure
src/ Makele.in
cong.h.in
A. Duret-Lutz
41 / 162
Hello World
Makele.in congure
src/ Makele.in
cong.h.in
A. Duret-Lutz
41 / 162
Hello World
congure.ac
autoreconf
Makele.in congure
src/ Makele.in
cong.h.in
A. Duret-Lutz
41 / 162
Hello World
congure.ac
Makele.am
src/ Makele.am
autoreconf
Makele.in congure
src/ Makele.in
cong.h.in
A. Duret-Lutz
41 / 162
Hello World
Autotools Inputs
congure.ac
AC_INIT([amhello], [1.0], [bug-report@address]) AM_INIT_AUTOMAKE([foreign -Wall -Werror]) AC_PROG_CC AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT
Makele.am
SUBDIRS = src
src/ Makele.am
bin_PROGRAMS = hello hello_SOURCES = main.c
A. Duret-Lutz
42 / 162
Hello World
src/
main.c
A. Duret-Lutz
43 / 162
Hello World
src/
./src: Makefile.am main.c ~/amhello % autoreconf --install configure.ac:2: installing ./install-sh configure.ac:2: installing ./missing src/Makefile.am: installing ./depcomp ~/amhello %
A. Duret-Lutz
43 / 162
Hello World
src/
./src: Makefile.am main.c ~/amhello % autoreconf --install configure.ac:2: installing ./install-sh configure.ac:2: installing ./missing src/Makefile.am: installing ./depcomp ~/amhello % ls -R .: Makefile.am configure.ac Makefile.in depcomp* aclocal.m4 install-sh* autom4te.cache/ missing* A. Duret-Lutz Using GNU Autotools config.h.in src/
43 / 162
Hello World
traces.1
Makefile.in
main.c
Using GNU Autotools May 16, 2010 43 / 162
Hello World
traces.1
Makefile.in
main.c
Using GNU Autotools May 16, 2010 43 / 162
Hello World
traces.1
Makefile.in
main.c
Using GNU Autotools May 16, 2010 43 / 162
Hello World
traces.1
Makefile.in
main.c
Using GNU Autotools May 16, 2010 43 / 162
Hello World
traces.1
Makefile.in
main.c
Using GNU Autotools May 16, 2010 43 / 162
Hello World
A. Duret-Lutz
43 / 162
Hello World
A. Duret-Lutz
43 / 162
Hello World
Hello World
A. Duret-Lutz
43 / 162
Hello World
A. Duret-Lutz
43 / 162
Hello World
Hello World Introducing Core Autotools Hello World Explained Using Autoconf Using Automake
A. Duret-Lutz
44 / 162
GNU Automake
A. Duret-Lutz
45 / 162
GNU Automake
A. Duret-Lutz
45 / 162
GNU Automake
A. Duret-Lutz
45 / 162
GNU Automake
A. Duret-Lutz
45 / 162
GNU Automake
A. Duret-Lutz
45 / 162
GNU Automake
A. Duret-Lutz
45 / 162
GNU Automake
A. Duret-Lutz
45 / 162
A. Duret-Lutz
45 / 162
A. Duret-Lutz
45 / 162
Behind autoreconf
congure.ac Makele.am src/ Makele.am
autoreconf
congure
A. Duret-Lutz
cong.h.in
Makele.in
src/ Makele.in
May 16, 2010 46 / 162
Behind autoreconf
congure.ac Makele.am src/ Makele.am
congure
A. Duret-Lutz
cong.h.in
Makele.in
src/ Makele.in
May 16, 2010 46 / 162
Behind autoreconf
congure.ac Makele.am src/ Makele.am
aclocal
congure
A. Duret-Lutz
cong.h.in
Makele.in
src/ Makele.in
May 16, 2010 46 / 162
Behind autoreconf
congure.ac aclocal.m4 Makele.am src/ Makele.am
aclocal
congure
A. Duret-Lutz
cong.h.in
Makele.in
src/ Makele.in
May 16, 2010 46 / 162
Behind autoreconf
congure.ac aclocal.m4 Makele.am src/ Makele.am
aclocal
autoconf
congure
A. Duret-Lutz
cong.h.in
Makele.in
src/ Makele.in
May 16, 2010 46 / 162
Behind autoreconf
congure.ac aclocal.m4 Makele.am src/ Makele.am
aclocal
autoconf
congure
A. Duret-Lutz
cong.h.in
Makele.in
src/ Makele.in
May 16, 2010 46 / 162
Behind autoreconf
congure.ac aclocal.m4 Makele.am src/ Makele.am
congure
A. Duret-Lutz
cong.h.in
Makele.in
src/ Makele.in
May 16, 2010 46 / 162
Behind autoreconf
congure.ac aclocal.m4 Makele.am src/ Makele.am
congure
A. Duret-Lutz
cong.h.in
Makele.in
src/ Makele.in
May 16, 2010 46 / 162
Behind autoreconf
congure.ac aclocal.m4 Makele.am src/ Makele.am
congure
A. Duret-Lutz
cong.h.in
Makele.in
src/ Makele.in
May 16, 2010 46 / 162
Behind autoreconf
congure.ac aclocal.m4 Makele.am src/ Makele.am
congure
A. Duret-Lutz
cong.h.in
Makele.in
src/ Makele.in
May 16, 2010 46 / 162
A. Duret-Lutz
47 / 162
Hello World Introducing Core Autotools Hello World Explained Using Autoconf Using Automake
A. Duret-Lutz
48 / 162
A. Duret-Lutz
49 / 162
A. Duret-Lutz
49 / 162
A. Duret-Lutz
49 / 162
A. Duret-Lutz
50 / 162
A. Duret-Lutz
51 / 162
A. Duret-Lutz
51 / 162
A. Duret-Lutz
51 / 162
Makele.am
SUBDIRS = src Build recursively in src/ .
A. Duret-Lutz
52 / 162
Makele.am
SUBDIRS = src Build recursively in src/ . Nothing else is declared for the current directory. (The top-level Makele.am is usually short.)
A. Duret-Lutz
52 / 162
src/ Makele.am
bin_PROGRAMS = hello hello_SOURCES = main.c We are building some programs.
A. Duret-Lutz
53 / 162
src/ Makele.am
bin_PROGRAMS = hello hello_SOURCES = main.c We are building some programs. These programs will be installed in bindir.
A. Duret-Lutz
53 / 162
A. Duret-Lutz
54 / 162
src/ Makele.am
bin_PROGRAMS = hello hello_SOURCES = main.c We are building some programs. These programs will be installed in bindir.
A. Duret-Lutz
55 / 162
src/ Makele.am
bin_PROGRAMS = hello hello_SOURCES = main.c We are building some programs. These programs will be installed in bindir. There is only one program to build: hello.
A. Duret-Lutz
55 / 162
src/ Makele.am
bin_PROGRAMS = hello hello_SOURCES = main.c We are building some programs. These programs will be installed in bindir. There is only one program to build: hello. To create hello, just compile main.c.
A. Duret-Lutz
55 / 162
Using Autoconf
Using Autoconf
Hello World Introducing Core Autotools Hello World Explained Using Autoconf Using Automake
A. Duret-Lutz
56 / 162
Using Autoconf
A. Duret-Lutz
57 / 162
Using Autoconf
A. Duret-Lutz
57 / 162
Using Autoconf
A. Duret-Lutz
57 / 162
Using Autoconf
Using Autoconf
Discovering M4
example.m4
m4_define(NAME1, Harry) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) ~ %
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
m4_define(NAME1, Harry) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) ~ % m4 -P example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
m4_define(NAME1, Harry) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) ~ % m4 -P example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
m4_define(NAME1, Harry) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) ~ % m4 -P example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
m4_define(NAME1, Harry) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) ~ % m4 -P example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) ~ % m4 -P example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) ~ % m4 -P example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) ~ % m4 -P example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
Discovering M4
example.m4
A. Duret-Lutz
58 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too
A. Duret-Lutz
59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2)
A. Duret-Lutz
59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2)
A. Duret-Lutz
59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
m4_define(MET, $1 met $2) MET(NAME1, NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
MET(Harry, Jr., NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
MET(Harry, Jr., NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
MET(Harry, Jr., NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
MET(Harry, Jr., NAME2) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
MET(Harry, Jr., Sally) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
MET(Harry, Jr., Sally) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
MET(Harry, Jr., Sally) Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
Harry met Jr. Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
Harry met Jr. Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
Harry met Jr. Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
Harry met Jr. Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
M4 Quoting
The macros arguments are processed Then the macro is expanded Finally the output of the macro is processed too A string can be protected from processing using quotes. This is a source of many mistakes for the unwary.
example.m4
Harry met Jr. Can you guess the output of the above?
A. Duret-Lutz Using GNU Autotools May 16, 2010 59 / 162
Using Autoconf
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2)
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2)
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2)
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2)
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2)
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2)
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2)
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
MET(NAME1, NAME2)
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
MET(NAME1, NAME2)
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
MET(NAME1, NAME2)
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
A. Duret-Lutz
60 / 162
Using Autoconf
Quote each macro argument once. So it is processed only after it has been output.
example.m4
A. Duret-Lutz
60 / 162
Using Autoconf
Spacing Matters
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET(NAME1, NAME2) ~ % m4 -P example.m4
Using Autoconf
Spacing Matters
The parenthesis must stick to the macro name.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET (NAME1, NAME2) ~ % m4 -P example.m4
Using Autoconf
Spacing Matters
The parenthesis must stick to the macro name. Spaces after or inside quotes are part of the arguments.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET( NAME1 , NAME2) ~ % m4 -P example.m4
Harry, Jr.
A. Duret-Lutz
met Sally
Using GNU Autotools May 16, 2010 61 / 162
Using Autoconf
Spacing Matters
The parenthesis must stick to the macro name. Spaces after or inside quotes are part of the arguments. Spaces before quotes are ignored.
example.m4
m4_define(NAME1, Harry, Jr.) m4_define(NAME2, Sally) m4_define(MET, $1 met $2) MET( NAME1, NAME2) ~ % m4 -P example.m4
Using Autoconf
Autoconf on Top of M4
Autoconf = M4 with more machinery, and many predened macros.
A. Duret-Lutz
62 / 162
Using Autoconf
Autoconf on Top of M4
Autoconf = M4 with more machinery, and many predened macros. The quotes are [ and ] (instead of and ).
A. Duret-Lutz
62 / 162
Using Autoconf
Autoconf on Top of M4
Autoconf = M4 with more machinery, and many predened macros. The quotes are [ and ] (instead of and ). For this reason we use the test command instead of [ in shell fragments: if [ "$x" = "$y" ]; then ...
A. Duret-Lutz
62 / 162
Using Autoconf
Autoconf on Top of M4
Autoconf = M4 with more machinery, and many predened macros. The quotes are [ and ] (instead of and ). For this reason we use the test command instead of [ in shell fragments: if test "$x" = "$y"; then ...
A. Duret-Lutz
62 / 162
Using Autoconf
Autoconf on Top of M4
Autoconf = M4 with more machinery, and many predened macros. The quotes are [ and ] (instead of and ). For this reason we use the test command instead of [ in shell fragments: if test "$x" = "$y"; then ... Macros are dened with AC DEFUN. AC_DEFUN([NAME1], [Harry, Jr.]) AC_DEFUN([NAME2], [Sally]) AC_DEFUN([MET], [$1 met $2]) MET([NAME1], [NAME2])
A. Duret-Lutz
62 / 162
Using Autoconf
AC_CONFIG_FILES([FILES]) AC_OUTPUT
A. Duret-Lutz Using GNU Autotools May 16, 2010 63 / 162
Using Autoconf
AC_CONFIG_FILES([FILES]) AC_OUTPUT
A. Duret-Lutz Using GNU Autotools May 16, 2010 63 / 162
Using Autoconf
AC_CONFIG_FILES([FILES]) AC_OUTPUT
A. Duret-Lutz Using GNU Autotools May 16, 2010 63 / 162
Using Autoconf
Using Autoconf
Using Autoconf
Using Autoconf
A. Duret-Lutz
64 / 162
Using Autoconf
AC INIT(PACKAGE, VERSION, BUG-REPORT-ADDRESS) Mandatory Autoconf initialization. AC PREREQ(VERSION) Require a minimum Autoconf version. E.g. AC PREREQ([2.65])
A. Duret-Lutz
64 / 162
Using Autoconf
AC INIT(PACKAGE, VERSION, BUG-REPORT-ADDRESS) Mandatory Autoconf initialization. AC PREREQ(VERSION) Require a minimum Autoconf version. E.g. AC PREREQ([2.65]) AC CONFIG SRCDIR(FILE) A safety check. FILE should be a distributed source le, and this makes sure that configure is not run from outer space. E.g. AC CONFIG SRCDIR([src/main.c]).
A. Duret-Lutz
64 / 162
Using Autoconf
AC INIT(PACKAGE, VERSION, BUG-REPORT-ADDRESS) Mandatory Autoconf initialization. AC PREREQ(VERSION) Require a minimum Autoconf version. E.g. AC PREREQ([2.65]) AC CONFIG SRCDIR(FILE) A safety check. FILE should be a distributed source le, and this makes sure that configure is not run from outer space. E.g. AC CONFIG SRCDIR([src/main.c]). AC CONFIG AUX DIR(DIRECTORY) Auxiliary scripts such as install-sh and depcomp should be in DIRECTORY. E.g. AC CONFIG AUX DIR([build-aux]).
A. Duret-Lutz
64 / 162
Using Autoconf
~/amhello % ls -R .: Makefile.am configure.ac Makefile.in depcomp* aclocal.m4 install-sh* autom4te.cache/ missing* config.h.in src/ auxiliary tools configure* used during the build ./autom4te.cache: output.0 requests output.1 traces.0
A. ./src: Duret-Lutz
traces.1
65 / 162
Using Autoconf
A. Duret-Lutz
66 / 162
Using Autoconf
A. Duret-Lutz
66 / 162
Using Autoconf
A. Duret-Lutz
67 / 162
Using Autoconf
A. Duret-Lutz
67 / 162
Using Autoconf
Using Autoconf
Using Autoconf
A. Duret-Lutz
68 / 162
Using Autoconf
A. Duret-Lutz
68 / 162
Using Autoconf
FOO=foo AC_SUBST([FOO])
AC_SUBST([FOO]) FOO=foo
Using Autoconf
A. Duret-Lutz
69 / 162
Using Autoconf
A. Duret-Lutz
69 / 162
Using Autoconf
A. Duret-Lutz
69 / 162
Using Autoconf
A. Duret-Lutz
70 / 162
Using Autoconf
A. Duret-Lutz
70 / 162
Using Autoconf
A. Duret-Lutz
70 / 162
Using Autoconf
Using Autoconf
Output Commands
AC CONFIG HEADERS(HEADERS...) Create HEADER for all HEADER.in. Use only one such header unless you know what you are doing (autoheader creates HEADER.in only for the rst HEADER). HEADERS contain denitions made with AC DEFINE.
A. Duret-Lutz
71 / 162
Using Autoconf
Output Commands
AC CONFIG HEADERS(HEADERS...) Create HEADER for all HEADER.in. Use only one such header unless you know what you are doing (autoheader creates HEADER.in only for the rst HEADER). HEADERS contain denitions made with AC DEFINE. AC_CONFIG_HEADERS([config.h]) Will create cong.h from cong.h.in
A. Duret-Lutz
71 / 162
Using Autoconf
Output Commands
AC CONFIG HEADERS(HEADERS...) Create HEADER for all HEADER.in. Use only one such header unless you know what you are doing (autoheader creates HEADER.in only for the rst HEADER). HEADERS contain denitions made with AC DEFINE. AC_CONFIG_HEADERS([config.h:config.hin]) Will create cong.h from cong.hin (DJGPP supports only 1 dot).
A. Duret-Lutz
71 / 162
Using Autoconf
Output Commands
AC CONFIG HEADERS(HEADERS...) Create HEADER for all HEADER.in. Use only one such header unless you know what you are doing (autoheader creates HEADER.in only for the rst HEADER). HEADERS contain denitions made with AC DEFINE. AC_CONFIG_HEADERS([config.h:config.hin]) Will create cong.h from cong.hin (DJGPP supports only 1 dot). AC CONFIG FILES(FILES...) Create FILE for all FILE.in. FILES contain denitions made with AC SUBST.
A. Duret-Lutz
71 / 162
Using Autoconf
Output Commands
AC CONFIG HEADERS(HEADERS...) Create HEADER for all HEADER.in. Use only one such header unless you know what you are doing (autoheader creates HEADER.in only for the rst HEADER). HEADERS contain denitions made with AC DEFINE. AC_CONFIG_HEADERS([config.h:config.hin]) Will create cong.h from cong.hin (DJGPP supports only 1 dot). AC CONFIG FILES(FILES...) Create FILE for all FILE.in. FILES contain denitions made with AC SUBST. AC_CONFIG_FILES([Makefile sub/Makefile script.sh:script.in])
A. Duret-Lutz
71 / 162
Using Autoconf
Output Commands
AC CONFIG HEADERS(HEADERS...) Create HEADER for all HEADER.in. Use only one such header unless you know what you are doing (autoheader creates HEADER.in only for the rst HEADER). HEADERS contain denitions made with AC DEFINE. AC_CONFIG_HEADERS([config.h:config.hin]) Will create cong.h from cong.hin (DJGPP supports only 1 dot). AC CONFIG FILES(FILES...) Create FILE for all FILE.in. FILES contain denitions made with AC SUBST. AC_CONFIG_FILES([Makefile sub/Makefile script.sh:script.in]) Automake creates FILE.in for each FILE that has a FILE.am.
A. Duret-Lutz Using GNU Autotools May 16, 2010 71 / 162
Using Autoconf
Output Commands
AC CONFIG HEADERS(HEADERS...) Create HEADER for all HEADER.in. Use only one such header unless you know what you are doing (autoheader creates HEADER.in only for the rst HEADER). HEADERS contain denitions made with AC DEFINE. AC_CONFIG_HEADERS([config.h:config.hin]) Will create cong.h from cong.hin (DJGPP supports only 1 dot). AC CONFIG FILES(FILES...) Create FILE for all FILE.in. FILES contain denitions made with AC SUBST. AC_CONFIG_FILES([Makefile sub/Makefile script.sh:script.in]) Automake creates FILE.in for each FILE that has a FILE.am. Its legitimate to process non-Makeles too.
A. Duret-Lutz Using GNU Autotools May 16, 2010 71 / 162
Using Autoconf
A. Duret-Lutz
72 / 162
Using Autoconf
A. Duret-Lutz
72 / 162
Using Autoconf
script.sh
#!/bin/sh SED=/usr/xpg4/bin/sed TAR=/usr/bin/tar d=$1; shift; mkdir "$d" for f; do "$SED" s/#.*// "$f" \ >"$d/$f" done "$TAR" cf "$d.tar" "$d"
.in les are templates where @XYZ@ are placeholders for AC SUBST([XYZ]) denitions. config.status substitutes them.
A. Duret-Lutz
72 / 162
Using Autoconf
script.sh
#!/bin/sh SED=/usr/xpg4/bin/sed TAR=/usr/bin/tar d=$1; shift; mkdir "$d" for f; do "$SED" s/#.*// "$f" \ >"$d/$f" done "$TAR" cf "$d.tar" "$d"
.in les are templates where @XYZ@ are placeholders for AC SUBST([XYZ]) denitions. config.status substitutes them. Makele.ins also use @XYZ@ as placeholders but Automake makes all XYZ=@XYZ@ denitions and you may simply use $(XYZ) as needed.
A. Duret-Lutz Using GNU Autotools May 16, 2010 72 / 162
Using Automake
Using Automake
Hello World Introducing Core Autotools Hello World Explained Using Autoconf Using Automake
A. Duret-Lutz
73 / 162
Using Automake
Automake Principles
Automake helps creating portable and GNU-standard compliant Makeles.
A. Duret-Lutz
74 / 162
Using Automake
Automake Principles
Automake helps creating portable and GNU-standard compliant Makeles.
You may be used to other kinds of build systems. (E.g., no VPATH builds, but all objects go into obj/ .)
A. Duret-Lutz
74 / 162
Using Automake
Automake Principles
Automake helps creating portable and GNU-standard compliant Makeles.
You may be used to other kinds of build systems. (E.g., no VPATH builds, but all objects go into obj/ .) Do not use Automake if you do not like the GNU Build System: Automake will get in your way if you dont t the mold.
A. Duret-Lutz
74 / 162
Using Automake
Automake Principles
Automake helps creating portable and GNU-standard compliant Makeles.
You may be used to other kinds of build systems. (E.g., no VPATH builds, but all objects go into obj/ .) Do not use Automake if you do not like the GNU Build System: Automake will get in your way if you dont t the mold.
A. Duret-Lutz
74 / 162
Using Automake
Automake Principles
Automake helps creating portable and GNU-standard compliant Makeles.
You may be used to other kinds of build systems. (E.g., no VPATH builds, but all objects go into obj/ .) Do not use Automake if you do not like the GNU Build System: Automake will get in your way if you dont t the mold.
A. Duret-Lutz
74 / 162
Using Automake
Automake Principles
Automake helps creating portable and GNU-standard compliant Makeles.
You may be used to other kinds of build systems. (E.g., no VPATH builds, but all objects go into obj/ .) Do not use Automake if you do not like the GNU Build System: Automake will get in your way if you dont t the mold.
Makele.ams follow roughly the same syntax as Makeles however they usually contains only variable denitions.
A. Duret-Lutz
74 / 162
Using Automake
Automake Principles
Automake helps creating portable and GNU-standard compliant Makeles.
You may be used to other kinds of build systems. (E.g., no VPATH builds, but all objects go into obj/ .) Do not use Automake if you do not like the GNU Build System: Automake will get in your way if you dont t the mold.
Makele.ams follow roughly the same syntax as Makeles however they usually contains only variable denitions.
automake creates build rules from these denitions.
A. Duret-Lutz
74 / 162
Using Automake
Automake Principles
Automake helps creating portable and GNU-standard compliant Makeles.
You may be used to other kinds of build systems. (E.g., no VPATH builds, but all objects go into obj/ .) Do not use Automake if you do not like the GNU Build System: Automake will get in your way if you dont t the mold.
Makele.ams follow roughly the same syntax as Makeles however they usually contains only variable denitions.
automake creates build rules from these denitions. Its OK to add extra Makele rules in Makele.am: automake will preserve them in the output.
A. Duret-Lutz
74 / 162
Using Automake
A. Duret-Lutz
75 / 162
Using Automake
AC_CONFIG_FILES([FILES]) AC_OUTPUT
A. Duret-Lutz Using GNU Autotools May 16, 2010 76 / 162
Using Automake
A. Duret-Lutz
77 / 162
Using Automake
Using Automake
A. Duret-Lutz
78 / 162
Using Automake
A. Duret-Lutz
78 / 162
Using Automake
A. Duret-Lutz
78 / 162
Using Automake
A. Duret-Lutz
79 / 162
Using Automake
A. Duret-Lutz
80 / 162
Using Automake
A. Duret-Lutz
80 / 162
Using Automake
A. Duret-Lutz
80 / 162
Using Automake
A. Duret-Lutz
80 / 162
Using Automake
Using Automake
Declaring Sources
Makele.am
bin_PROGRAMS = foo run-me foo_SOURCES = foo.c foo.h print.c print.h run_me_SOURCES = run.c run.h print.c These programs will be installed in $(bindir).
A. Duret-Lutz
81 / 162
Using Automake
Declaring Sources
Makele.am
bin_PROGRAMS = foo run-me foo_SOURCES = foo.c foo.h print.c print.h run_me_SOURCES = run.c run.h print.c These programs will be installed in $(bindir). The sources of each program go into program SOURCES.
A. Duret-Lutz
81 / 162
Using Automake
Declaring Sources
Makele.am
bin_PROGRAMS = foo run-me foo_SOURCES = foo.c foo.h print.c print.h run_me_SOURCES = run.c run.h print.c These programs will be installed in $(bindir). The sources of each program go into program SOURCES. Non-alphanumeric characters are mapped to .
A. Duret-Lutz
81 / 162
Using Automake
Declaring Sources
Makele.am
bin_PROGRAMS = foo run-me foo_SOURCES = foo.c foo.h print.c print.h run_me_SOURCES = run.c run.h print.c These programs will be installed in $(bindir). The sources of each program go into program SOURCES. Non-alphanumeric characters are mapped to . Automake automatically computes the list of objects to build and link from these les.
A. Duret-Lutz
81 / 162
Using Automake
Declaring Sources
Makele.am
bin_PROGRAMS = foo run-me foo_SOURCES = foo.c foo.h print.c print.h run_me_SOURCES = run.c run.h print.c These programs will be installed in $(bindir). The sources of each program go into program SOURCES. Non-alphanumeric characters are mapped to . Automake automatically computes the list of objects to build and link from these les. Header les are not compiled. We list them only so they get distributed (Automake does not distribute les it does not know about).
A. Duret-Lutz
81 / 162
Using Automake
Declaring Sources
Makele.am
bin_PROGRAMS = foo run-me foo_SOURCES = foo.c foo.h print.c print.h run_me_SOURCES = run.c run.h print.c These programs will be installed in $(bindir). The sources of each program go into program SOURCES. Non-alphanumeric characters are mapped to . Automake automatically computes the list of objects to build and link from these les. Header les are not compiled. We list them only so they get distributed (Automake does not distribute les it does not know about). Its OK to use the same source for two programs.
A. Duret-Lutz Using GNU Autotools May 16, 2010 81 / 162
Using Automake
Declaring Sources
Makele.am
bin_PROGRAMS = foo run-me foo_SOURCES = foo.c foo.h print.c print.h run_me_SOURCES = run.c run.h print.c These programs will be installed in $(bindir). The sources of each program go into program SOURCES. Non-alphanumeric characters are mapped to . Automake automatically computes the list of objects to build and link from these les. Header les are not compiled. We list them only so they get distributed (Automake does not distribute les it does not know about). Its OK to use the same source for two programs. Compiler and linker are inferred from the extensions.
A. Duret-Lutz Using GNU Autotools May 16, 2010 81 / 162
Using Automake
(Static) Libraries
A. Duret-Lutz
82 / 162
Using Automake
(Static) Libraries
Makele.am
lib_LIBRARIES = libfoo.a libbar.a libfoo_a_SOURCES = foo.c privfoo.h libbar_a_SOURCES = bar.c privbar.h include_HEADERS = foo.h bar.h
A. Duret-Lutz
82 / 162
Using Automake
(Static) Libraries
Makele.am
lib_LIBRARIES = libfoo.a libbar.a libfoo_a_SOURCES = foo.c privfoo.h libbar_a_SOURCES = bar.c privbar.h include_HEADERS = foo.h bar.h These libraries will be installed in $(libdir).
A. Duret-Lutz
82 / 162
Using Automake
(Static) Libraries
Makele.am
lib_LIBRARIES = libfoo.a libbar.a libfoo_a_SOURCES = foo.c privfoo.h libbar_a_SOURCES = bar.c privbar.h include_HEADERS = foo.h bar.h These libraries will be installed in $(libdir). Library names must match lib*.a.
A. Duret-Lutz
82 / 162
Using Automake
(Static) Libraries
Makele.am
lib_LIBRARIES = libfoo.a libbar.a libfoo_a_SOURCES = foo.c privfoo.h libbar_a_SOURCES = bar.c privbar.h include_HEADERS = foo.h bar.h These libraries will be installed in $(libdir). Library names must match lib*.a. Public headers will be installed in $(includedir).
A. Duret-Lutz
82 / 162
Using Automake
(Static) Libraries
Makele.am
lib_LIBRARIES = libfoo.a libbar.a libfoo_a_SOURCES = foo.c privfoo.h libbar_a_SOURCES = bar.c privbar.h include_HEADERS = foo.h bar.h These libraries will be installed in $(libdir). Library names must match lib*.a. Public headers will be installed in $(includedir). Private headers are not installed, like ordinary source les.
A. Duret-Lutz
82 / 162
Using Automake
Directory Layout
You may have one Makele (hence one Makele.am) per directory.
A. Duret-Lutz
83 / 162
Using Automake
Directory Layout
You may have one Makele (hence one Makele.am) per directory. They must all be declared in congure.ac.
congure.ac
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile src/dira/Makefile src/dirb/Makefile])
A. Duret-Lutz
83 / 162
Using Automake
Directory Layout
You may have one Makele (hence one Makele.am) per directory. They must all be declared in congure.ac.
congure.ac
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile src/dira/Makefile src/dirb/Makefile]) make is run at the top-level. Makele.ams should x the order in which to recurse directories using the SUBDIRS variable.
A. Duret-Lutz
83 / 162
Using Automake
Directory Layout
You may have one Makele (hence one Makele.am) per directory. They must all be declared in congure.ac.
congure.ac
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile src/dira/Makefile src/dirb/Makefile]) make is run at the top-level. Makele.ams should x the order in which to recurse directories using the SUBDIRS variable.
Makele.am
SUBDIRS = lib src
src/ Makele.am
SUBDIRS = dira dirb
A. Duret-Lutz
83 / 162
Using Automake
Directory Layout
You may have one Makele (hence one Makele.am) per directory. They must all be declared in congure.ac.
congure.ac
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile src/dira/Makefile src/dirb/Makefile]) make is run at the top-level. Makele.ams should x the order in which to recurse directories using the SUBDIRS variable.
Makele.am
SUBDIRS = lib src
src/ Makele.am
SUBDIRS = dira dirb The current directory is implicitly built after subdirectories.
A. Duret-Lutz
83 / 162
Using Automake
Directory Layout
You may have one Makele (hence one Makele.am) per directory. They must all be declared in congure.ac.
congure.ac
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile src/dira/Makefile src/dirb/Makefile]) make is run at the top-level. Makele.ams should x the order in which to recurse directories using the SUBDIRS variable.
Makele.am
SUBDIRS = lib src
src/ Makele.am
SUBDIRS = dira dirb . The current directory is implicitly built after subdirectories. You can put . where you want to override this.
A. Duret-Lutz Using GNU Autotools May 16, 2010 83 / 162
Using Automake
Directory Layout
You may have one Makele (hence one Makele.am) per directory. They must all be declared in congure.ac.
congure.ac
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile src/dira/Makefile src/dirb/Makefile]) make is run at the top-level. Makele.ams should x the order in which to recurse directories using the SUBDIRS variable.
Makele.am
SUBDIRS = lib src
src/ Makele.am
SUBDIRS = dira . dirb The current directory is implicitly built after subdirectories. You can put . where you want to override this.
A. Duret-Lutz Using GNU Autotools May 16, 2010 83 / 162
Using Automake
Directory Layout
You may have one Makele (hence one Makele.am) per directory. They must all be declared in congure.ac.
congure.ac
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile src/dira/Makefile src/dirb/Makefile]) make is run at the top-level. Makele.ams should x the order in which to recurse directories using the SUBDIRS variable.
Makele.am
SUBDIRS = lib src
src/ Makele.am
SUBDIRS = . dira dirb The current directory is implicitly built after subdirectories. You can put . where you want to override this.
A. Duret-Lutz Using GNU Autotools May 16, 2010 83 / 162
Using Automake
A. Duret-Lutz
84 / 162
Using Automake
Objects les, programs, and libraries are built where congure was run. ~ % tar zxf ~/amhello-1.0.tar.gz ~ % cd amhello-1.0 ~/amhello-1.0 % mkdir build && cd build ~/amhello-1.0/build % ../configure ~/amhello-1.0/build % make ... Sources les are in / amhello-1.0/ , built les are all in / amhello-1.0/ build/ .
A. Duret-Lutz
85 / 162
Using Automake
A. Duret-Lutz
86 / 162
Using Automake
In each Makele, config.status will dene $(srcdir): the path to the matching source directory.
A. Duret-Lutz
86 / 162
Using Automake
In each Makele, config.status will dene $(srcdir): the path to the matching source directory. When referring to sources les or targets in Automake variables, you do not have to worry about source vs. build, because make will check both directories.
A. Duret-Lutz
86 / 162
Using Automake
In each Makele, config.status will dene $(srcdir): the path to the matching source directory. When referring to sources les or targets in Automake variables, you do not have to worry about source vs. build, because make will check both directories. You may need $(srcdir) when specifying ags for tools, or writing custom commands. E.g., to tell the compiler to include headers from dir/ , you should write -I$(srcdir)/dir, not -Idir. (-Idir would fetch headers from the build tree.)
A. Duret-Lutz Using GNU Autotools May 16, 2010 86 / 162
Using Automake
Convenience Libraries
lib/ Makele.am
noinst_LIBRARIES = libcompat.a libcompat_a_SOURCES = xalloc.c xalloc.h
A. Duret-Lutz
87 / 162
Using Automake
Convenience Libraries
lib/ Makele.am
noinst_LIBRARIES = libcompat.a libcompat_a_SOURCES = xalloc.c xalloc.h This is a convenience library, used only when building the package.
A. Duret-Lutz
87 / 162
Using Automake
Convenience Libraries
lib/ Makele.am
noinst_LIBRARIES = libcompat.a libcompat_a_SOURCES = xalloc.c xalloc.h This is a convenience library, used only when building the package.
src/ Makele.am
LDADD = ../lib/libcompat.a AM_CPPFLAGS = -I$(srcdir)/../lib bin_PROGRAMS = foo run-me foo_SOURCES = foo.c foo.h print.c print.h run_me_SOURCES = run.c run.h print.c
A. Duret-Lutz
87 / 162
Using Automake
Convenience Libraries
lib/ Makele.am
noinst_LIBRARIES = libcompat.a libcompat_a_SOURCES = xalloc.c xalloc.h This is a convenience library, used only when building the package.
src/ Makele.am
LDADD = ../lib/libcompat.a AM_CPPFLAGS = -I$(srcdir)/../lib bin_PROGRAMS = foo run-me foo_SOURCES = foo.c foo.h print.c print.h run_me_SOURCES = run.c run.h print.c LDADD is added when linking all programs.
A. Duret-Lutz
87 / 162
Using Automake
Convenience Libraries
lib/ Makele.am
noinst_LIBRARIES = libcompat.a libcompat_a_SOURCES = xalloc.c xalloc.h This is a convenience library, used only when building the package.
src/ Makele.am
LDADD = ../lib/libcompat.a AM_CPPFLAGS = -I$(srcdir)/../lib bin_PROGRAMS = foo run-me foo_SOURCES = foo.c foo.h print.c print.h run_me_SOURCES = run.c run.h print.c LDADD is added when linking all programs. AM CPPFLAGS contains additional preprocessor ags.
A. Duret-Lutz Using GNU Autotools May 16, 2010 87 / 162
Using Automake
Convenience Libraries
lib/ Makele.am
noinst_LIBRARIES = libcompat.a libcompat_a_SOURCES = xalloc.c xalloc.h This is a convenience library, used only when building the package.
src/ Makele.am
bin_PROGRAMS = foo run-me foo_SOURCES = foo.c foo.h print.c print.h run_me_SOURCES = run.c run.h print.c run_me_LDADD = ../lib/libcompat.a run_me_CPPFLAGS = -I$(srcdir)/../lib LDADD is added when linking all programs. AM CPPFLAGS contains additional preprocessor ags. You can use per-target variables: they apply to a single program.
A. Duret-Lutz Using GNU Autotools May 16, 2010 87 / 162
Using Automake
Per-Target Flags
Assuming foo is a program or library: foo CFLAGS Additional C compiler ags foo CPPFLAGS Additional preprocessor ags (-Is and -Ds)
A. Duret-Lutz
88 / 162
Using Automake
Per-Target Flags
Assuming foo is a program or library: foo CFLAGS Additional C compiler ags foo CPPFLAGS Additional preprocessor ags (-Is and -Ds) foo LDADD Additional link objects, -ls and -Ls (if foo is a program) foo LIBADD Additional link objects, -ls and -Ls (if foo is a library) foo LDFLAGS Additional linker ags The default value for foo XXXFLAGS is $(AM XXXFLAGS).
A. Duret-Lutz
88 / 162
Using Automake
Per-Target Flags
Assuming foo is a program or library: foo CFLAGS Additional C compiler ags foo CPPFLAGS Additional preprocessor ags (-Is and -Ds) foo LDADD Additional link objects, -ls and -Ls (if foo is a program) foo LIBADD Additional link objects, -ls and -Ls (if foo is a library) foo LDFLAGS Additional linker ags The default value for foo XXXFLAGS is $(AM XXXFLAGS). Use plain le names to refer to libraries inside your package (keep -ls and -Ls for external libraries only).
src/ Makele.am
bin_PROGRAMS = foo run-me foo_SOURCES = foo.c foo.h print.c print.h run_me_SOURCES = run.c run.h print.c run_me_CPPFLAGS = -I$(srcdir)/../lib run_me_LDADD = ../lib/libcompat.a
A. Duret-Lutz Using GNU Autotools May 16, 2010 88 / 162
Using Automake
A. Duret-Lutz
89 / 162
Using Automake
Per-Target Flags
Assuming foo is a program or library: foo CFLAGS Additional C compiler ags foo CPPFLAGS Additional preprocessor ags (-Is and -Ds) foo LDADD Additional link objects, -ls and -Ls (if foo is a program) foo LIBADD Additional link objects, -ls and -Ls (if foo is a library) foo LDFLAGS Additional linker ags The default value for foo XXXFLAGS is $(AM XXXFLAGS). Use plain le names to refer to libraries inside your package (keep -ls and -Ls for external libraries only).
src/ Makele.am
bin_PROGRAMS = foo run-me foo_SOURCES = foo.c foo.h print.c print.h run_me_SOURCES = run.c run.h print.c run_me_CPPFLAGS = -I$(srcdir)/../lib run_me_LDADD = ../lib/libcompat.a $(EFENCELIB)
A. Duret-Lutz Using GNU Autotools May 16, 2010 90 / 162
Using Automake
A. Duret-Lutz
91 / 162
Using Automake
A. Duret-Lutz
91 / 162
Using Automake
A. Duret-Lutz
91 / 162
Using Automake
A. Duret-Lutz
91 / 162
Using Automake
Makele.am
SUBDIRS = lib src EXTRA_DIST = HACKING ... will additionally distribute HACKING .
A. Duret-Lutz Using GNU Autotools May 16, 2010 91 / 162
Using Automake
Conditionals: Usage
Conditionals allow for conditional builds and unconditional distribution.
A. Duret-Lutz
92 / 162
Using Automake
Conditionals: Usage
Conditionals allow for conditional builds and unconditional distribution.
Conditional Programs
bin_PROGRAMS = foo if WANT_BAR bin_PROGRAMS += bar endif foo_SOURCES = foo.c bar_SOURCES = bar.c
A. Duret-Lutz
92 / 162
Using Automake
Conditionals: Usage
Conditionals allow for conditional builds and unconditional distribution.
Conditional Programs
bin_PROGRAMS = foo if WANT_BAR bin_PROGRAMS += bar endif foo_SOURCES = foo.c bar_SOURCES = bar.c
Conditional Sources
bin_PROGRAMS = foo foo_SOURCES = foo.c if WANT_BAR foo_SOURCES += bar.c endif
A. Duret-Lutz
92 / 162
Using Automake
Conditionals: Usage
Conditionals allow for conditional builds and unconditional distribution.
Conditional Programs
bin_PROGRAMS = foo bin_PROGRAMS = foo if WANT_BAR foo_SOURCES = foo.c bin_PROGRAMS += bar if WANT_BAR endif foo_SOURCES += bar.c foo_SOURCES = foo.c endif bar_SOURCES = bar.c bar is built i WANT BAR is true.
Conditional Sources
A. Duret-Lutz
92 / 162
Using Automake
Conditionals: Usage
Conditionals allow for conditional builds and unconditional distribution.
Conditional Programs
bin_PROGRAMS = foo bin_PROGRAMS = foo if WANT_BAR foo_SOURCES = foo.c bin_PROGRAMS += bar if WANT_BAR endif foo_SOURCES += bar.c foo_SOURCES = foo.c endif bar_SOURCES = bar.c bar is built i WANT BAR is true. bar.o is linked in foo i WANT BAR is true.
Conditional Sources
A. Duret-Lutz
92 / 162
Using Automake
Conditionals: Usage
Conditionals allow for conditional builds and unconditional distribution.
Conditional Programs
bin_PROGRAMS = foo bin_PROGRAMS = foo if WANT_BAR foo_SOURCES = foo.c bin_PROGRAMS += bar if WANT_BAR endif foo_SOURCES += bar.c foo_SOURCES = foo.c endif bar_SOURCES = bar.c bar is built i WANT BAR is true. bar.o is linked in foo i WANT BAR is true. In all cases foo.c and bar.c are distributed regardless of WANT BAR.
Conditional Sources
A. Duret-Lutz
92 / 162
Using Automake
Conditionals: Usage
Conditionals allow for conditional builds and unconditional distribution.
Conditional Programs
bin_PROGRAMS = foo bin_PROGRAMS = foo if WANT_BAR foo_SOURCES = foo.c bin_PROGRAMS += bar if WANT_BAR endif foo_SOURCES += bar.c foo_SOURCES = foo.c endif bar_SOURCES = bar.c bar is built i WANT BAR is true. bar.o is linked in foo i WANT BAR is true. In all cases foo.c and bar.c are distributed regardless of WANT BAR. This is portable. config.status will comment rules of Makele.in that must be disabled.
A. Duret-Lutz Using GNU Autotools May 16, 2010 92 / 162
Conditional Sources
Using Automake
Conditionals: Usage
Conditionals allow for conditional builds and unconditional distribution.
Conditional Programs
bin_PROGRAMS = foo bin_PROGRAMS = foo if WANT_BAR foo_SOURCES = foo.c bin_PROGRAMS += bar if WANT_BAR endif foo_SOURCES += bar.c foo_SOURCES = foo.c endif bar_SOURCES = bar.c bar is built i WANT BAR is true. bar.o is linked in foo i WANT BAR is true. In all cases foo.c and bar.c are distributed regardless of WANT BAR. This is portable. config.status will comment rules of Makele.in that must be disabled. WANT BAR must be declared and valued in congure.ac.
A. Duret-Lutz Using GNU Autotools May 16, 2010 92 / 162
Conditional Sources
Using Automake
Conditionals: Declaration
AM CONDITIONAL(NAME, CONDITION) Declare conditional NAME. CONDITION should be a shell instruction that succeeds i NAME should be enabled.
A. Duret-Lutz
93 / 162
Using Automake
Conditionals: Declaration
AM CONDITIONAL(NAME, CONDITION) Declare conditional NAME. CONDITION should be a shell instruction that succeeds i NAME should be enabled.
congure.ac
AC_CHECK_HEADER([bar.h], [use_bar=yes]) AM_CONDITIONAL([WANT_BAR], [test "$use_bar" = yes]) Will enable WANT BAR only if bar.h is present on the system.
A. Duret-Lutz
93 / 162
Using Automake
A. Duret-Lutz
94 / 162
Using Automake
A. Duret-Lutz
94 / 162
Using Automake
A. Duret-Lutz
94 / 162
Using Automake
A. Duret-Lutz
94 / 162
Using Automake
Beware of conicts: your denitions (of variables or rules) will override those of Automake.
-Wall will diagnose these.
A. Duret-Lutz Using GNU Autotools May 16, 2010 94 / 162
Using Automake
Recommendations
A. Duret-Lutz
95 / 162
Using Automake
Recommendations
A. Duret-Lutz
95 / 162
Using Automake
Recommendations
A. Duret-Lutz
95 / 162
Using Automake
A. Duret-Lutz
96 / 162
Using Automake
A. Duret-Lutz
96 / 162
Using Automake
Writing and Managing Custom Macros Writing Autoconf Macros Managing Custom Macros with aclocal Libtool Gettext Introducing Gettext Internationalizing a Package, Start to Finish Localizing a Package Nested Packages The End
A. Duret-Lutz Using GNU Autotools May 16, 2010 97 / 162
11 12
13 14
Writing and Managing Custom Macros Writing Autoconf Macros Managing Custom Macros with aclocal Libtool Gettext Introducing Gettext Internationalizing a Package, Start to Finish Localizing a Package Nested Packages The End
11 12
13 14
A. Duret-Lutz
98 / 162
Two fundamentally dierent types of new macros: Macros that factor related tests in a single reusable entity.
A. Duret-Lutz
99 / 162
Two fundamentally dierent types of new macros: Macros that factor related tests in a single reusable entity.
High-level. Combination of existing lower-level macros. May not use shell code at all.
A. Duret-Lutz
99 / 162
Two fundamentally dierent types of new macros: Macros that factor related tests in a single reusable entity.
High-level. Combination of existing lower-level macros. May not use shell code at all.
A. Duret-Lutz
99 / 162
Dening Macros
AC DEFUN(MACRO-NAME, MACRO-BODY) Dene MACRO-NAME as MACRO-BODY. Avoid names that may conict.
A. Duret-Lutz
100 / 162
Dening Macros
AC DEFUN(MACRO-NAME, MACRO-BODY) Dene MACRO-NAME as MACRO-BODY. Avoid names that may conict. Macro name spaces: m4 Original M4 macros, plus M4sugar macros. AS M4sh macros (macroized shell constructs) AH Autoheader macros AC Autoconf macros (written on top of the above layers)
Dening Macros
AC DEFUN(MACRO-NAME, MACRO-BODY) Dene MACRO-NAME as MACRO-BODY. Avoid names that may conict. Macro name spaces: m4 Original M4 macros, plus M4sugar macros. AS M4sh macros (macroized shell constructs) AH Autoheader macros AC Autoconf macros (written on top of the above layers) AC CHECK Generic checks. AC FUNC Specic function checks. AC HEADER Specic header checks. AC PROG Specic program checks. ... AM Automake macros AT Autotest macros
A. Duret-Lutz Using GNU Autotools May 16, 2010 100 / 162
mkdir() Example
POSIX systems dene mkdir() with two arguments. On Mingw32 (at least), mkdir() takes only one argument. On Win32 (at least), the name is mkdir() with one argument.
A. Duret-Lutz
101 / 162
mkdir() Example
POSIX systems dene mkdir() with two arguments. On Mingw32 (at least), mkdir() takes only one argument. On Win32 (at least), the name is mkdir() with one argument. #if HAVE_MKDIR # if MKDIR_ONE_ARG # define mkdir(a,b) mkdir(a) # endif #else # if HAVE__MKDIR # define mkdir(a,b) _mkdir(a) # else # error "Dont know how to create a directory." # endif #endif
A. Duret-Lutz Using GNU Autotools May 16, 2010 101 / 162
mkdir() Example
POSIX systems dene mkdir() with two arguments. On Mingw32 (at least), mkdir() takes only one argument. On Win32 (at least), the name is mkdir() with one argument. #if HAVE_MKDIR # if MKDIR_ONE_ARG # define mkdir(a,b) mkdir(a) # endif #else # if HAVE__MKDIR # define mkdir(a,b) _mkdir(a) # else # error "Dont know how to create a directory." # endif #endif Lets write an Autoconf macro to dene these C macros.
A. Duret-Lutz Using GNU Autotools May 16, 2010 101 / 162
A. Duret-Lutz
102 / 162
A. Duret-Lutz
102 / 162
A. Duret-Lutz
102 / 162
A. Duret-Lutz
102 / 162
A. Duret-Lutz
102 / 162
A. Duret-Lutz
103 / 162
A. Duret-Lutz
103 / 162
A. Duret-Lutz
103 / 162
Wait! Thats not enough for an Autoconf check: we should also add some checking whether... message on top of this.
A. Duret-Lutz Using GNU Autotools May 16, 2010 103 / 162
Wait! Thats not enough for an Autoconf check: we should also add some checking whether... message on top of this. We use the AX prex for helper macros not meant to be used directly.
A. Duret-Lutz Using GNU Autotools May 16, 2010 103 / 162
A. Duret-Lutz
104 / 162
Makele.in congure
src/ Makele.in
cong.h.in
A. Duret-Lutz
106 / 162
A. Duret-Lutz
106 / 162
A. Duret-Lutz
106 / 162
A. Duret-Lutz
107 / 162
A. Duret-Lutz
107 / 162
Keep conguration actions outside AC CACHE CHECK: they have to be executed whether the check is run or cached.
A. Duret-Lutz Using GNU Autotools May 16, 2010 107 / 162
A. Duret-Lutz
108 / 162
A. Duret-Lutz
108 / 162
A. Duret-Lutz
108 / 162
Remember to [quote]. Read the Portable Shell section of the Autoconf manual, before writing shell code.
A. Duret-Lutz
108 / 162
Remember to [quote]. Read the Portable Shell section of the Autoconf manual, before writing shell code. Test your macros on dierent systems.
Check test results in cong.log . Get accounts on foreign systems (Google for free shell account).
A. Duret-Lutz Using GNU Autotools May 16, 2010 108 / 162
Writing and Managing Custom Macros Writing Autoconf Macros Managing Custom Macros with aclocal Libtool Gettext Introducing Gettext Internationalizing a Package, Start to Finish Localizing a Package Nested Packages The End
11 12
13 14
A. Duret-Lutz
109 / 162
A. Duret-Lutz
110 / 162
A. Duret-Lutz
110 / 162
A. Duret-Lutz
110 / 162
Behind autoreconf
congure.ac aclocal.m4 Makele.am src/ Makele.am
congure
A. Duret-Lutz
cong.h.in
Makele.in
src/ Makele.in
May 16, 2010 111 / 162
A. Duret-Lutz
113 / 162
A. Duret-Lutz
113 / 162
A. Duret-Lutz
113 / 162
Libtool
Libtool
10
Writing and Managing Custom Macros Writing Autoconf Macros Managing Custom Macros with aclocal Libtool Gettext Introducing Gettext Internationalizing a Package, Start to Finish Localizing a Package Nested Packages The End
11 12
13 14
A. Duret-Lutz
114 / 162
Libtool
A. Duret-Lutz
115 / 162
Libtool
A. Duret-Lutz
115 / 162
Libtool
A. Duret-Lutz
115 / 162
Libtool
Linking against the library may also require specic ags. There is no way for a developer to keep track of all these details.
Quiz: match each of the above example with its OS.
A. Duret-Lutz
115 / 162
Libtool
Linking against the library may also require specic ags. There is no way for a developer to keep track of all these details.
Quiz: match each of the above example with its OS.
Libtool
A. Duret-Lutz
116 / 162
Libtool
A. Duret-Lutz
116 / 162
Libtool
In a Makele.am, you simply create and link against *.la les. These operations are translated appropriately.
A. Duret-Lutz
116 / 162
Libtool
A. Duret-Lutz
117 / 162
Libtool
A. Duret-Lutz
117 / 162
Libtool
Makele.am
lib_LTLIBRARIES = libfoo.la libfoo_la_SOURCES = foo.c foo.h etc.c
A. Duret-Lutz
117 / 162
Libtool
Makele.am
lib_LTLIBRARIES = libfoo.la libfoo_la_SOURCES = foo.c foo.h etc.c bin_PROGRAMS = runme runme_SOURCES = main.c runme_LDADD = libfoo.la
A. Duret-Lutz Using GNU Autotools May 16, 2010 117 / 162
Libtool
src/ main.c
#include "say.h" int main (void) { say_hello (); return 0; }
lib/ say.h
void say_hello (void);
A. Duret-Lutz
118 / 162
Libtool
src/ Makele.am
AM_CPPFLAGS = -I$(srcdir)/../lib bin_PROGRAMS = hello hello_SOURCES = main.c hello_LDADD = ../lib/libhello.la
Makele.am
SUBDIRS = lib src ACLOCAL_AMFLAGS = -I m4
A. Duret-Lutz Using GNU Autotools May 16, 2010 119 / 162
Libtool
congure.ac
AC_INIT([amhello], [2.0], [bug-report@address]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign -Wall -Werror]) LT_INIT AC_PROG_CC AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile]) AC_OUTPUT
A. Duret-Lutz
120 / 162
Libtool
~/amhello % ls -R
A. Duret-Lutz
121 / 162
Libtool
lib/
src/
say.c
say.h
main.c
A. Duret-Lutz
121 / 162
Libtool
A. Duret-Lutz
121 / 162
Libtool
~/amhello % mkdir m4 ~/amhello % autoreconf --install libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, bui libtoolize: copying file build-aux/ltmain.sh libtoolize: putting macros in AC_CONFIG_MACRO_DIR, m4. libtoolize: copying file m4/libtool.m4 libtoolize: copying file m4/ltoptions.m4 libtoolize: copying file m4/ltsugar.m4 libtoolize: copying file m4/ltversion.m4 libtoolize: copying file m4/lt~obsolete.m4 configure.ac:5: installing build-aux/config.guess configure.ac:5: installing build-aux/config.sub configure.ac:4: installing build-aux/install-sh configure.ac:4: installing build-aux/missing lib/Makefile.am: installing build-aux/depcomp ~/amhello %
A. Duret-Lutz Using GNU Autotools May 16, 2010 121 / 162
Libtool
A. Duret-Lutz
121 / 162
Libtool
% mkdir m4 % autoreconf --install % ./configure --prefix ~/test % make && make install %
A. Duret-Lutz
121 / 162
Libtool
~/amhello % mkdir m4 ~/amhello % autoreconf --install ... ~/amhello % ./configure --prefix ~/test ... ~/amhello % make && make install ... ~/amhello % ~/test/bin/hello Hello World! This is amhello 2.0. ~/amhello %
A. Duret-Lutz
121 / 162
Libtool
libhello.so.0.0.0*
A. Duret-Lutz
122 / 162
Libtool
~/amhello % ls -R ~/test /home/adl/test: bin/ lib/ /home/adl/test/bin: hello* /home/adl/test/lib: libhello.a libhello.so@ libhello.so.0.0.0* libhello.la* libhello.so.0@ ~/amhello % ldd ~/test/bin/hello libhello.so.0 => /home/adl/test/lib/libhello.so.0 (0xb7fe7000) libc.so.6 => /lib/tls/libc.so.6 (0xb7e9c000) lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0xb7fea000) ~/amhello %
A. Duret-Lutz
122 / 162
Libtool
~/amhello % ls -R ~/test /home/adl/test: bin/ lib/ /home/adl/test/bin: hello* /home/adl/test/lib: libhello.a libhello.so@ libhello.so.0.0.0* libhello.la* libhello.so.0@ ~/amhello % ldd ~/test/bin/hello libhello.so.0 => /home/adl/test/lib/libhello.so.0 (0xb7fe7000) libc.so.6 => /lib/tls/libc.so.6 (0xb7e9c000) lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0xb7fea000) ~/amhello % ldd src/hello not a dynamic executable ~/amhello %
A. Duret-Lutz Using GNU Autotools May 16, 2010 122 / 162
Libtool
~/amhello % ls -R ~/test /home/adl/test: bin/ lib/ /home/adl/test/bin: hello* /home/adl/test/lib: libhello.a libhello.so@ libhello.so.0.0.0* libhello.la* libhello.so.0@ ~/amhello % ldd ~/test/bin/hello libhello.so.0 => /home/adl/test/lib/libhello.so.0 (0xb7fe7000) libc.so.6 => /lib/tls/libc.so.6 (0xb7e9c000) lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0xb7fea000) ~/amhello % ldd src/hello not a dynamic executable ~/amhello % file src/hello src/hello: Bourne shell script text executable
A. Duret-Lutz Using GNU Autotools May 16, 2010 122 / 162
Libtool
A. Duret-Lutz
123 / 162
Libtool
A. Duret-Lutz
123 / 162
Libtool
A. Duret-Lutz
123 / 162
Libtool
A. Duret-Lutz
124 / 162
Libtool
A. Duret-Lutz
124 / 162
Libtool
This wrapper script runs the real binary, and arranges so it nds the not-yet-installed libraries
This way src/ hello can be run, for instance in a test suite
A. Duret-Lutz
124 / 162
Libtool
This wrapper script runs the real binary, and arranges so it nds the not-yet-installed libraries
This way src/ hello can be run, for instance in a test suite
(gdb)
A. Duret-Lutz
124 / 162
Libtool
This wrapper script runs the real binary, and arranges so it nds the not-yet-installed libraries
This way src/ hello can be run, for instance in a test suite
(gdb)
Libtool
A. Duret-Lutz
125 / 162
Libtool
A. Duret-Lutz
125 / 162
Libtool
A. Duret-Lutz
125 / 162
Libtool
Hence libtools versioning format encodes a range of supported interfaces. Interface numbers are not release numbers.
A. Duret-Lutz Using GNU Autotools May 16, 2010 125 / 162
Libtool
A. Duret-Lutz
126 / 162
Libtool
lib/Makele.am
lib_LTLIBRARIES = libhello.la libhello_la_SOURCES = say.c say.h libhello_la_LDFLAGS = -version-info CURRENT:REVISION:AGE
A. Duret-Lutz
126 / 162
Libtool
lib/Makele.am
lib_LTLIBRARIES = libhello.la libhello_la_SOURCES = say.c say.h libhello_la_LDFLAGS = -version-info 0:0:0 The default version is 0:0:0. Its also a good initial version.
A. Duret-Lutz Using GNU Autotools May 16, 2010 126 / 162
Libtool
Remember to bump library versions before a release. Suppose the old version was CURRENT:REVISION:AGE. If you have not changed the interface (bug xes) augmented the interface (new functions) broken old interface (e.g. removed functions) bump the version to CURRENT : REVISION+1 : AGE CURRENT+1 : 0 : AGE+1 CURRENT+1 : 0 : 0
A. Duret-Lutz
127 / 162
Gettext
Introducing Gettext
Introducing Gettext
10
Writing and Managing Custom Macros Writing Autoconf Macros Managing Custom Macros with aclocal Libtool Gettext Introducing Gettext Internationalizing a Package, Start to Finish Localizing a Package Nested Packages The End
11 12
13 14
A. Duret-Lutz
128 / 162
Gettext
Introducing Gettext
Introducing Gettext
Internationalization
Localization
A. Duret-Lutz
129 / 162
Gettext
Introducing Gettext
Introducing Gettext
Internationalization Changing a program to support for multiple languages and cultural habits.
Localization
A. Duret-Lutz
129 / 162
Gettext
Introducing Gettext
Introducing Gettext
Internationalization Changing a program to support for multiple languages and cultural habits.
Localization Providing an internationalized package the necessary bits to support ones native language and cultural habits.
A. Duret-Lutz
129 / 162
Gettext
Introducing Gettext
Introducing Gettext
Internationalization = I18n Changing a program to support for multiple languages and cultural habits.
Localization = L10n Providing an internationalized package the necessary bits to support ones native language and cultural habits.
A. Duret-Lutz
129 / 162
Gettext
Introducing Gettext
Introducing Gettext
Internationalization = I18n Changing a program to support for multiple languages and cultural habits.
Character handling (unicode...) Locale awareness (date formats, currencies, numbers, time zones, etc.) Localizability
Isolate localizable items (messages, pictures, etc.) Implement infrastructure necessary for localizing above items.
Localization = L10n Providing an internationalized package the necessary bits to support ones native language and cultural habits.
A. Duret-Lutz
129 / 162
Gettext
Introducing Gettext
Introducing Gettext
Internationalization = I18n Changing a program to support for multiple languages and cultural habits.
Character handling (unicode...) Locale awareness (date formats, currencies, numbers, time zones, etc.) Localizability
Isolate localizable items (messages, pictures, etc.) Implement infrastructure necessary for localizing above items.
Localization = L10n Providing an internationalized package the necessary bits to support ones native language and cultural habits.
Translate localizable items (messages, pictures, etc.) for one language.
A. Duret-Lutz
129 / 162
Gettext
Introducing Gettext
Introducing Gettext
Internationalization = I18n Changing a program to support for multiple languages and cultural habits.
Character handling (unicode...) Locale awareness (date formats, currencies, numbers, time zones, etc.) Localizability
Isolate localizable items (messages, pictures, etc.) Implement infrastructure necessary for localizing above items.
The programmers work. Localization = L10n Providing an internationalized package the necessary bits to support ones native language and cultural habits.
Translate localizable items (messages, pictures, etc.) for one language.
Gettext
Introducing Gettext
Introducing Gettext
Internationalization = I18n Changing a program to support for multiple languages and cultural habits.
Character handling (unicode...) Locale awareness (date formats, currencies, numbers, time zones, etc.) Localizability
Isolate localizable items (messages, pictures, etc.) Implement infrastructure necessary for localizing above items.
The programmers work. Localization = L10n Providing an internationalized package the necessary bits to support ones native language and cultural habits.
Translate localizable items (messages, pictures, etc.) for one language.
The translators work. Gettext = complete toolset for translating messages output by programs.
A. Duret-Lutz Using GNU Autotools May 16, 2010 129 / 162
Gettext
Introducing Gettext
void say_hello (void) { puts ("Hello World!"); puts ("This is " PACKAGE_STRING "."); } The program is written in English.
A. Duret-Lutz
130 / 162
Gettext
Introducing Gettext
A. Duret-Lutz
130 / 162
Gettext
Introducing Gettext
gettext looks up the translation of the English message in the current locales catalog.
A. Duret-Lutz Using GNU Autotools May 16, 2010 130 / 162
Gettext
Writing and Managing Custom Macros Writing Autoconf Macros Managing Custom Macros with aclocal Libtool Gettext Introducing Gettext Internationalizing a Package, Start to Finish Localizing a Package Nested Packages The End
11 12
13 14
A. Duret-Lutz
131 / 162
Gettext
Start with a non-internationalized Hello World. Invoke AM GNU GETTEXT from congure.ac Run gettextize to provide the basic infrastructure. Fill in the conguration les left by gettextize. Update src/ Makele.am to link hello with the necessary library. Update the code:
Initialize Gettext in main() Mark translatable strings.
A. Duret-Lutz
132 / 162
Gettext
src/ main.c
#include "say.h" int main (void) { say_hello (); return 0; }
src/ say.c
#include <config.h> #include <stdio.h> void say_hello (void) { puts ("Hello World!"); puts ("This is " PACKAGE_STRING "."); }
Using GNU Autotools May 16, 2010 133 / 162
A. Duret-Lutz
Gettext
Makele.am
SUBDIRS = src
src/ Makele.am
bin_PROGRAMS = hello hello_SOURCES = main.c say.c say.h
A. Duret-Lutz
134 / 162
Gettext
A. Duret-Lutz
135 / 162
Gettext
A. Duret-Lutz
135 / 162
Gettext
Gettext
Running gettextize
You should run gettextize: A rst time, to install the Gettext infrastructure in your package. Each time you upgrade Gettext to a new version. ~/amhello %
A. Duret-Lutz
136 / 162
Gettext
Running gettextize
You should run gettextize: A rst time, to install the Gettext infrastructure in your package. Each time you upgrade Gettext to a new version. ~/amhello % gettextize --copy --no-changelog [...] ~/amhello % Install most of the Gettext infrastructure.
A. Duret-Lutz
136 / 162
Gettext
Running gettextize
You should run gettextize: A rst time, to install the Gettext infrastructure in your package. Each time you upgrade Gettext to a new version. ~/amhello % gettextize --copy --no-changelog [...] ~/amhello % cp /usr/share/gettext/gettext.h src Install most of the Gettext infrastructure. Copy gettext.h in the source tree, it will be distributed.
A. Duret-Lutz
136 / 162
Gettext
Makele.am
SUBDIRS = po src bin_PROGRAMS = hello ACLOCAL_AMFLAGS = -I m4 hello_SOURCES = main.c say.c say.h EXTRA_DIST = ...
A. Duret-Lutz Using GNU Autotools May 16, 2010 137 / 162
src/ Makele.am
Gettext
po/ Makevars
DOMAIN = $(PACKAGE) subdir = po top_builddir = .. XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ COPYRIGHT_HOLDER = Your Name or Your Employer MSGID_BUGS_ADDRESS = $(PACKAGE BUGREPORT) EXTRA_LOCALE_CATEGORIES =
A. Duret-Lutz
138 / 162
Gettext
A. Duret-Lutz
138 / 162
Gettext
po/ Makevars
DOMAIN = $(PACKAGE) subdir = po top_builddir = .. XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ COPYRIGHT_HOLDER = Your Name or Your Employer MSGID_BUGS_ADDRESS = $(PACKAGE BUGREPORT) EXTRA_LOCALE_CATEGORIES = List sources les that (may) contain translatable strings in POTFILES.in.
po/ POTFILES.in
src/main.c src/say.c
A. Duret-Lutz Using GNU Autotools May 16, 2010 138 / 162
Gettext
Whats Next?
Done:
1 2 3 4
Start with a non-internationalized Hello World. Invoke AM GNU GETTEXT from congure.ac Run gettextize to provide the basic infrastructure. Fill in the conguration les left by gettextize.
A. Duret-Lutz
139 / 162
Gettext
Whats Next?
Done:
1 2 3 4
Start with a non-internationalized Hello World. Invoke AM GNU GETTEXT from congure.ac Run gettextize to provide the basic infrastructure. Fill in the conguration les left by gettextize.
Update src/ Makele.am to link hello with the necessary library. Update the code:
Initialize Gettext in main() Mark translatable strings.
Gettext
A. Duret-Lutz
140 / 162
Gettext
A. Duret-Lutz
140 / 162
Gettext
A. Duret-Lutz
140 / 162
Gettext
A. Duret-Lutz
140 / 162
Gettext
A. Duret-Lutz
140 / 162
Gettext
Initializing Gettext
src/ main.c
say_hello(); return 0; }
A. Duret-Lutz Using GNU Autotools May 16, 2010 141 / 162
Gettext
Initializing Gettext
src/ main.c
#include <locale.h> #include "say.h" int main (void) { setlocale (LC_ALL, ""); Initialize the locale as specied in the environment. (E.g., the user sets LANG=fr FR in the environment to get French messages.)
say_hello(); return 0; }
A. Duret-Lutz Using GNU Autotools May 16, 2010 141 / 162
Gettext
Initializing Gettext
src/ main.c
#include <config.h> #include <locale.h> #include "gettext.h" #include "say.h" int main (void) { setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); say_hello(); return 0; }
A. Duret-Lutz Using GNU Autotools
Initialize the locale as specied in the environment. (E.g., the user sets LANG=fr FR in the environment to get French messages.) Tell Gettext where to nd message catalogs for this program. (All programs in the same package usually share the same message catalog.)
May 16, 2010 141 / 162
Gettext
void say_hello (void) { puts ("Hello World!"); puts ("This is " PACKAGE_STRING "."); }
A. Duret-Lutz
142 / 162
Gettext
A. Duret-Lutz
142 / 162
Gettext
Gettext
A. Duret-Lutz
143 / 162
Gettext
Gettext
Localizing a Package
Localizing a Package
10
Writing and Managing Custom Macros Writing Autoconf Macros Managing Custom Macros with aclocal Libtool Gettext Introducing Gettext Internationalizing a Package, Start to Finish Localizing a Package Nested Packages The End
11 12
13 14
A. Duret-Lutz
144 / 162
Gettext
Localizing a Package
Gettext
Localizing a Package
Gettext
Localizing a Package
A. Duret-Lutz
146 / 162
Gettext
Localizing a Package
A. Duret-Lutz
146 / 162
Gettext
Localizing a Package
A. Duret-Lutz
146 / 162
Gettext
Localizing a Package
A. Duret-Lutz
146 / 162
Gettext
Localizing a Package
Gettext
Localizing a Package
Gettext
Localizing a Package
Gettext
Localizing a Package
Gettext
Localizing a Package
Initialize po/ LL.po or po/ LL CC.po from po/ amhello.pot, using msginit. LL is your language code, and CC is your country code pt is Portuguese pt BR is Brazilian Portuguese (The annexes of the Gettext manual show lists of LLs and CCs.) Fill in po/ LL.po (or po/ LL CC.po) List the new translation in po/ LINGUAS
2 3
A. Duret-Lutz
149 / 162
Gettext
Localizing a Package
Initialize po/ LL.po or po/ LL CC.po from po/ amhello.pot, using msginit. LL is your language code, and CC is your country code pt is Portuguese pt BR is Brazilian Portuguese (The annexes of the Gettext manual show lists of LLs and CCs.) Fill in po/ LL.po (or po/ LL CC.po) List the new translation in po/ LINGUAS
2 3
A. Duret-Lutz
149 / 162
Gettext
Localizing a Package
A. Duret-Lutz
150 / 162
Gettext
Localizing a Package
po-mode):
Use C-c C-c after you have completed the translation, to get back to the updated amhello.pot buer. Once all strings are translated, use Use
Tab V
A. Duret-Lutz
150 / 162
Gettext
Localizing a Package
#: src/say.c:9 msgid "Hello World!" msgstr "" #: src/say.c:10 #, c-format msgid "This is %s.\n" msgstr ""
A. Duret-Lutz
151 / 162
Gettext
Localizing a Package
#: src/say.c:9 msgid "Hello World!" msgstr "Bonjour Monde !" #: src/say.c:10 #, c-format msgid "This is %s.\n" msgstr "Ceci est %s.\n"
A. Duret-Lutz
151 / 162
Gettext
Localizing a Package
A. Duret-Lutz
152 / 162
Gettext
Localizing a Package
A. Duret-Lutz
152 / 162
Gettext
Localizing a Package
Gettext
Localizing a Package
Gettext
Localizing a Package
. This will:
Update the revision date Save the le Run msgfmt --statistics --check on po/ fr.po, to validate it.
A. Duret-Lutz
153 / 162
Gettext
Localizing a Package
. This will:
Update the revision date Save the le Run msgfmt --statistics --check on po/ fr.po, to validate it.
A. Duret-Lutz
153 / 162
Gettext
Localizing a Package
A. Duret-Lutz
154 / 162
Gettext
Localizing a Package
A. Duret-Lutz
154 / 162
Gettext
Localizing a Package
A. Duret-Lutz
154 / 162
Gettext
Localizing a Package
A. Duret-Lutz
154 / 162
Gettext
Localizing a Package
A. Duret-Lutz
154 / 162
Gettext
Localizing a Package
A. Duret-Lutz
154 / 162
Gettext
Localizing a Package
A. Duret-Lutz
154 / 162
Gettext
Localizing a Package
A. Duret-Lutz
154 / 162
Gettext
Localizing a Package
A. Duret-Lutz
155 / 162
Gettext
Localizing a Package
A. Duret-Lutz
155 / 162
Gettext
Localizing a Package
A. Duret-Lutz
155 / 162
Gettext
Localizing a Package
Gettext
Localizing a Package
http://www.iro.umontreal.ca/translation/ The Translation Project provides an infrastructure for package maintainers and translators to exchange messages catalogs.
A. Duret-Lutz
156 / 162
Gettext
Localizing a Package
http://www.iro.umontreal.ca/translation/ The Translation Project provides an infrastructure for package maintainers and translators to exchange messages catalogs. Translators gather in Language Teams (consider joining the team of your own language) to discuss issues. Maintainer submit *.pot les and are notied when *.po les are updated. Pages in The Translation Project will show where work is needed (consider adopting an orphan *.po le.)
A. Duret-Lutz
156 / 162
Gettext
Localizing a Package
http://www.iro.umontreal.ca/translation/ The Translation Project provides an infrastructure for package maintainers and translators to exchange messages catalogs. Translators gather in Language Teams (consider joining the team of your own language) to discuss issues. Maintainer submit *.pot les and are notied when *.po les are updated. Pages in The Translation Project will show where work is needed (consider adopting an orphan *.po le.) This is only one way of getting a project translated. A lot of packages have dedicated translators and deal with them directly.
A. Duret-Lutz Using GNU Autotools May 16, 2010 156 / 162
Nested Packages
Nested Packages
10
Writing and Managing Custom Macros Writing Autoconf Macros Managing Custom Macros with aclocal Libtool Gettext Introducing Gettext Internationalizing a Package, Start to Finish Localizing a Package Nested Packages The End
11 12
13 14
A. Duret-Lutz
157 / 162
Nested Packages
Nested Packages
For installers:
A single package to congure, build, and install. configure options are passed recursively to sub-packages. configure --help=recursive shows the help of all sub-packages.
For maintainers:
Easier integration. The sub-package is autonomous.
A. Duret-Lutz
158 / 162
Nested Packages
A. Duret-Lutz
159 / 162
Nested Packages
A sub-package should appear as an ordinary directory. In Makele.am, this directory must appear in SUBDIRS so make recurses into it.
A. Duret-Lutz
159 / 162
Nested Packages
A sub-package should appear as an ordinary directory. In Makele.am, this directory must appear in SUBDIRS so make recurses into it. congure.ac should also declare this directory AC_CONFIG_SUBDIRS([subdir]) so configure calls subdir/ congure recursively.
A. Duret-Lutz
159 / 162
Nested Packages
arms congure.ac
AC_INIT([arm], [1.0]) AM_INIT_AUTOMAKE([foreign -Wall -Werror]) arms Makele.am AC_PROG_CC SUBDIRS = hand src AC_CONFIG_FILES([Makefile src/Makefile]) AC_CONFIG_SUBDIRS([hand]) AC_OUTPUT
The End
The End
10
Writing and Managing Custom Macros Writing Autoconf Macros Managing Custom Macros with aclocal Libtool Gettext Introducing Gettext Internationalizing a Package, Start to Finish Localizing a Package Nested Packages The End
11 12
13 14
A. Duret-Lutz
161 / 162
The End
Where to go Now?
A. Duret-Lutz
162 / 162
The End
Where to go Now?
Subscribe to these tools mailing lists, to see other peoples uses of the tools.
A. Duret-Lutz
162 / 162
The End
Where to go Now?
Subscribe to these tools mailing lists, to see other peoples uses of the tools. Pick a package that uses these tools and dissect its setup.
Try picking something written by somebody who isnt just another neophyte! I recommend looking at GNU Coreutils.
A. Duret-Lutz
162 / 162