% Copyright (C) 2005, 2006, 2008  Alexandre Duret-Lutz.
% Permission is granted to use, modify, and redistribute under the terms
% of the Creative Commons Attribution-ShareAlike 2.0 license.
% http://creativecommons.org/licenses/by-sa/2.0/
% Trivial source code examples displayed in this tutorial (such as the
% C files, `Makefile.am's, and `configure.ac's of all the `amhello'
% projects) can be reused as if they were in the public domain.

\documentclass{beamer}

\usepackage{pgf,tikz}
\usepackage{url}
\usepackage{listings}

\def\cret{\tikz{
  \draw[->,rounded corners=2pt,thick,color=blue]
       (1.25ex,.75em) -- (1.25ex,0pt) -- (0pt,0pt);}}


\usetheme[secheader]{Madrid}
\lstset{language=sh}
\setbeamertemplate{navigation symbols}{}
\defbeamertemplate*{footline}{infolines theme without institution}
{
  \leavevmode%
  \hbox{%
  \begin{beamercolorbox}[wd=.333333\paperwidth,ht=2.25ex,dp=1ex,center]{author in head/foot}%
    \usebeamerfont{author in head/foot}\insertshortauthor
  \end{beamercolorbox}%
  \begin{beamercolorbox}[wd=.333333\paperwidth,ht=2.25ex,dp=1ex,center]{title in head/foot}%
    \usebeamerfont{title in head/foot}\insertshorttitle
  \end{beamercolorbox}%
  \begin{beamercolorbox}[wd=.333333\paperwidth,ht=2.25ex,dp=1ex,right]{date in head/foot}%
    \usebeamerfont{date in head/foot}\insertshortdate{}\hspace*{2em}
    \insertframenumber{} / \inserttotalframenumber\hspace*{2ex}
  \end{beamercolorbox}}%
  \vskip0pt%
}

\newcommand{\variable}[1]{{\color{violet}{\textsf{#1}}}}
\newcommand{\variablew}[1]{{{\textsf{#1}}}}
\newcommand{\filename}[1]{{\color{blue}{\textit{\begingroup \urlstyle{sf}\Url{#1}}}}}
\newcommand{\filenamew}[1]{{{\textit{\begingroup \urlstyle{sf}\Url{#1}}}}}
\newcommand{\command}[1]{`\texttt{#1}'}

% built files
\definecolor{bfile}{rgb}{.9,0.9,0.9}
% distributed generated files
\colorlet{dgfile}{yellow}
% auto* input file
\colorlet{afile}{green!33}
% tools
\definecolor{tfile}{rgb}{1.0,0.5,0.5}

\tikzstyle{afile}=[draw,fill=afile,shape=document,inner sep=1ex]
\tikzstyle{bfile}=[draw,fill=bfile,shape=document,inner sep=1ex]
\tikzstyle{dgfile}=[draw,fill=dgfile,shape=document,inner sep=1ex]
\tikzstyle{tfile}=[draw,fill=tfile,shape=rectangle,inner sep=1ex]

\newcommand\arr[1][]{\draw[thick,->,#1]}
\def\afile{\node[style=afile]}
\def\bfile{\node[style=bfile]}
\def\dgfile{\node[style=dgfile]}
\def\tfile{\node[style=tfile]}


\makeatletter

% Verbatim from the pgf manual:
\pgfdeclareshape{document}{
   \inheritsavedanchors[from=rectangle] % this is nearly a rectangle
   \inheritanchorborder[from=rectangle]
   \inheritanchor[from=rectangle]{center}
   \inheritanchor[from=rectangle]{north}
   \inheritanchor[from=rectangle]{south}
   \inheritanchor[from=rectangle]{west}
   \inheritanchor[from=rectangle]{east}
   % ... and possibly more
   \backgroundpath{% this is new
     % store lower right in xa/ya and upper right in xb/yb
     \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
     \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
     % compute corner of ``flipped page''
     \pgf@xc=\pgf@xb \advance\pgf@xc by-5pt % this should be a parameter
     \pgf@yc=\pgf@yb \advance\pgf@yc by-5pt
     % construct main path
     \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
     \pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
     \pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yb}}
     \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
     \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
     \pgfpathclose
     % add little corner
     \pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@yb}}
     \pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
     \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
     \pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
 }
}

\makeatother

% Adapted from texinfo.tex
\font\keyrm=cmtt8 scaled 1000
\font\keysy=cmsy9
\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
  \raise0.4pt\hbox{$\langle$}\kern-.08em\vtop{%
    \vbox{\hrule\kern-0.4pt
     \hbox{\raise0.4pt\hbox{\vphantom{$\langle$}}#1}}%
    \kern-0.4pt\hrule}%
  \kern-.06em\raise0.4pt\hbox{$\rangle$}}}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\title{Using GNU Autotools}
\author[A. Duret-Lutz]{Alexandre Duret-Lutz\\\url{adl@gnu.org}}
\date{\today}
\subject{Introduction to the GNU Build System and GNU Autotools}
\keywords{autoconf, automake, build system, tutorial, introduction, presentation}

\newcommand{\mypart}[1]{\part{#1}\frame{\partpage \tableofcontents}}
\newcommand{\mysection}[1]{\section{#1}\frame{\frametitle{#1}\tableofcontents[sectionstyle=show/shaded,subsectionstyle=show/shaded/shaded]}}
\newcommand{\mysubsection}[1]{\subsection{#1}\frame{\frametitle{#1}\tableofcontents[sectionstyle=show/shaded,subsectionstyle=show/shaded/shaded]}}

\begin{document}

\section*{Foreword}
\begin{frame}
\frametitle{Foreword (1/2)}

This presentation targets developers familiar with Unix development
tools (shell, make, compiler) that want to learn Autotools.

\bigskip

The latest version of this document can be retrieved from\\
{\small \url{http://www.lrde.epita.fr/~adl/autotools.html}}

\bigskip

Please mail me corrections and suggestions \textbf{about this
  document} at \url{adl@gnu.org}.

\medskip

Do not send me any general question about the Autotools.  Use the
appropriate mailing list instead (\url{autoconf@gnu.org}, or
\url{automake@gnu.org}).

\end{frame}

\section*{Tool Versions}
\begin{frame}
\frametitle{Foreword (2/2)}

This document was updated for the following releases of the
Autotools:

\gdef\gettextver{0.17}
\gdef\automakever{1.10.1}
\gdef\autoconfver{2.61}
\begin{center}
\begin{tabular}{lcr}
GNU Autoconf & \autoconfver & (November 2006) \\
GNU Automake & \automakever & (January 2008) \\
GNU Libtool  & 1.5.26       & (February 2008) \\
GNU Gettext  & \gettextver  & (November 2007) \\
\end{tabular}
\end{center}

These were the last releases at the time of writing.

\begin{itemize}
\item The usage of these tools has improved a lot over
  the last years.
\item Some syntaxes used here will not work with older tools.
\item This a deliberate choice:
\begin{itemize}
\item New users should learn today's recommended usages.
\item Make sure you have up-to-date tools and do not bother with old releases.
\end{itemize}
\end{itemize}

\end{frame}

\section*{Title Page}
\begin{frame}
  \titlepage

\centering
\fbox{\begin{minipage}{0.8\textwidth}
Copyright \copyright{} 2008  Alexandre Duret-Lutz\\
\url{http://creativecommons.org/licenses/by-sa/2.0/} \\

\small
Trivial source code examples displayed in this tutorial (such as the C
files, \filename{Makefile.am}s, and \filename{configure.ac}s of all
the \command{amhello} projects) can be reused as if they were in the
public domain.
\end{minipage}}

\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\mypart{The GNU Build System}

\section{Goals}

\mysubsection{Portable Packages}

\begin{frame}
\frametitle{Sources of Non-Portability in C}

Consider C functions...
\begin{itemize}
\item that do not exist everywhere (e.g., \texttt{strtod()})
\item that have different names (e.g., \texttt{strchr()} vs. \texttt{index()})
\item that have varying prototypes\\
      (e.g., \texttt{int setpgrp(void);} vs.  \texttt{int setpgrp(int, int);})
\item that can behave differently (e.g., \texttt{malloc(0);})
\item that might require other libraries\\
      (is \texttt{pow() in \filename{libm.so} or in \filename{libc.so}?)}
\item that can be defined in different headers\\
      (\filename{string.h} vs. \filename{strings.h} vs. \filename{memory.h})
\end{itemize}

\medskip

How should a package deal with those?

\end{frame}

\begin{frame}
\frametitle{Possible Solutions}
\begin{itemize}
\item Slice the code with lots of \texttt{\#if}/\texttt{\#else}
\item Create substitution macros
\item Create substitution functions
\end{itemize}

\uncover<2>{The latter two are to be preferred.}

\end{frame}

\begin{frame}[fragile]
\frametitle{Code Cluttered with \texttt{\#if}/\texttt{\#else}}

\begin{block}{Excerpt of ffcall-1.10's \texttt{alloc\_trampoline()}}
\scriptsize
\begin{lstlisting}[language=C]
#if !defined(CODE_EXECUTABLE)
  static long pagesize = 0;
#if defined(EXECUTABLE_VIA_MMAP_DEVZERO)
  static int zero_fd;
#endif
  if (!pagesize) {
#if defined(HAVE_MACH_VM)
      pagesize = vm_page_size;
#else
      pagesize = getpagesize();
#endif
#if defined(EXECUTABLE_VIA_MMAP_DEVZERO)
      zero_fd = open("/dev/zero", O_RDONLY,0644);
      if (zero_fd < 0) {
        fprintf(stderr, "trampoline: Cannot open /dev/zero!\n");
        abort();
      }
#endif
  }
#endif
\end{lstlisting}
\end{block}

\end{frame}

\begin{frame}[fragile]
\frametitle{Substitution macros}

\begin{block}{Excerpt of coreutils-5.2.1's \filenamew{system.h}}
\begin{lstlisting}[language=C]
#if ! HAVE_FSEEKO && ! defined fseeko
# define fseeko(s, o, w) ((o) == (long) (o) \
                          ? fseek (s, o, w) \
                          : (errno = EOVERFLOW, -1))
#endif
\end{lstlisting}
\end{block}

Then use \texttt{fseeko()} whether it exists or not.
\end{frame}


\begin{frame}[fragile]
\frametitle{Substitution functions}

If \texttt{strdup()} does not exist, link your
program with a replacement definition such as

\begin{block}{\filenamew{strdup.c} (from the GNU C library)}
\begin{lstlisting}[language=C]
char *
strdup (const char *s)
{
  size_t len = strlen (s) + 1;
  void *new = malloc (len);
  if (new == NULL)
    return NULL;
  return (char *) memcpy (new, s, len);
}
\end{lstlisting}
\end{block}

\end{frame}

\mysubsection{Uniform Builds}

\begin{frame}
\frametitle{Need for Automatic Configuration}

\begin{itemize}
\item Maintaining a collection of \texttt{\#define} for each system
      by hand is cumbersome.
\item Requiring users to add the necessary \texttt{-D}, \texttt{-I},
      and \texttt{-l} compilation options to \filename{Makefile} is
      burdensome.
\item Complicated builds hinder the acceptance of free software.
\end{itemize}
\bigskip
\begin{itemize}[<2>]
\item In 1991 people started to write shell scripts to \textbf{guess}
  these settings for some GNU packages.
\item Since then the \filename{configure} script is mandatory in any
  package of the GNU project.
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{\filenamew{configure}'s Purpose}

\begin{center}
\begin{tikzpicture}
\dgfile (configure)    at (4,3) {\filenamew{configure}};
\uncover<2->{
\bfile  (configh)      at (7,1) {\filenamew{config.h}};}
\uncover<3->{
\bfile  (Makefile)     at (1,1) {\filenamew{Makefile}};
\bfile  (src/Makefile) at (4,1) {\filenamew{src/Makefile}};}

\uncover<2->{
\arr (configure) .. controls +(0:2.5cm) and +(90:1cm) .. (configh);
}
\uncover<3->{
\arr (configure) .. controls +(-10:2.5cm) and +(85:1cm) .. (Makefile);
\arr (configure) .. controls +(-5:2.5cm) and +(80:1cm) .. (src/Makefile);
}

\end{tikzpicture}
\end{center}

\begin{itemize}
\item<1-> \filename{configure} probes the systems for required functions,
          libraries, and tools
\item<2-> then it generates a \filename{config.h} file with all
          \texttt{\#define}s
\item<3-> as well as \filename{Makefile}s to build the package
\end{itemize}

\end{frame}


\begin{frame}
\frametitle{GNU Coding Standards}

\begin{center}
\url{http://www.gnu.org/prep/standards/}
\end{center}

Practices that packages of the GNU project should follow:
\begin{itemize}
\item<2-> program behavior
\begin{itemize}
\item how to report errors,
\item standard command line options,
\item etc.
\end{itemize}
\item<3-> coding style
\item<4-> \alert{configuration}
\item<5-> \alert{\filenamew{Makefile} conventions}
\item<5-> etc.
\end{itemize}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Package Use Cases}
\mysubsection{The User Point of View}

\begin{frame}[fragile]
\frametitle{Standard Installation Procedure}
\begin{block}{}
\begin{semiverbatim}
~ % \alert<1>{\textit{tar zxf amhello-1.0.tar.gz}}
\uncover<2->{~ % \alert<2>{\textit{cd amhello-1.0}}}
\uncover<3->{~/amhello-1.0 % \alert<3>{\textit{./configure}}
...}
\uncover<4->{~/amhello-1.0 % \alert<4>{\textit{make}}
...}
\uncover<5->{~/amhello-1.0 % \alert<5>{\textit{make check}}
...}
\uncover<6->{~/amhello-1.0 % \alert<6>{\textit{su}}
Password:}
\uncover<7->{/home/adl/amhello-1.0 # \alert<7>{\textit{make install}}
...}
\uncover<8->{/home/adl/amhello-1.0 # \alert<8>{\textit{exit}}}
\uncover<9->{~/amhello-1.0 % \alert<9->{\textit{make installcheck}}
...}
\end{semiverbatim}
\end{block}
\end{frame}

\begin{frame}
\frametitle{Standard Makefile Targets}

\begin{description}[\command{make install-strip}]
\item[\command{make all}]
  Build programs, libraries, documentation, etc.  (Same as \command{make}.)
\item[\command{make install}]
  Install what needs to be installed.
\item[\command{make install-strip}]
  Same as \command{make install}, then strip debugging symbols.
\item[\command{make uninstall}]
  The opposite of \command{make install}.
\item[\command{make clean}]
  Erase what has been built (the opposite of \command{make all}).
\item[\command{make distclean}]
  Additionally erase anything \command{./configure} created.
\item[\command{make check}]
  Run the test suite, if any.
\item[\command{make installcheck}]
  Check the installed programs or libraries, if supported.
\item[\command{make dist}]
  Create \filename{PACKAGE-VERSION.tar.gz}.
\end{description}

\end{frame}

\begin{frame}<1-4>[fragile,label=standard-dirs]
\frametitle{Standard File System Hierarchy}

\begin{center}
\begin{tabular}{ll}
Directory variable & Default value \\
\variable{prefix}                   & \filename{/usr/local} \\
\hspace{1cm}\variable{exec-prefix} & \variable{prefix} \\
\hspace{2cm}\variable{bindir}       & \variable{exec-prefix}\filename{/bin} \\
\hspace{2cm}\variable{libdir}       & \variable{exec-prefix}\filename{/lib} \\
\hspace{2cm}... & \\
\hspace{1cm}\variable{includedir}   & \variable{prefix}\filename{/include} \\
\hspace{1cm}\variable{datarootdir}  & \variable{prefix}\filename{/share} \\
\hspace{2cm}\variable{datadir}      & \variable{datarootdir} \\
\hspace{2cm}\variable{mandir}       & \variable{datarootdir}\filename{/man} \\
\hspace{2cm}\variable{infodir}      & \variable{datarootdir}\filename{/info} \\
\hspace{1cm}... & \\
\end{tabular}
\end{center}

\begin{block}<-4>{}
\begin{semiverbatim}
~/amhello-1.0 % \uncover<2->{\alert<2>{\textit{./configure --prefix ~/usr}}}
\uncover<3->{~/amhello-1.0 % \alert<3>{\textit{make}}}
\uncover<4->{~/amhello-1.0 % \alert<4>{\textit{make install}}}
\end{semiverbatim}
\end{block}
\only<5>{}% So I can replay this frame later without the above block.
\end{frame}

\begin{frame}[fragile]
\frametitle{Standard Configuration Variables}

\command{./configure} automatically detects many settings.\\
You can force some of them using configuration variables.

\begin{description}[\variable{CXXFLAGS}]
\item[\variable{CC}] C compiler command
\item[\variable{CFLAGS}] C compiler flags
\item[\variable{CXX}] C++ compiler command
\item[\variable{CXXFLAGS}] C++ compiler flags
\item[\variable{LDFLAGS}] linker flags
\item[\variable{CPPFLAGS}] C/C++ preprocessor flags
\item[\variable{...}] See \command{./configure --help} for a full list.
\end{description}

\begin{block}{}
\begin{semiverbatim}
~/amhello-1.0 % \uncover<2->{\alert<2>{\textit{./configure --prefix ~/usr CC=gcc-3 \textbackslash
CPPFLAGS=-I\$HOME/usr/include LDFLAGS=-L\$HOME/usr/lib}}}
\end{semiverbatim}
\end{block}
\end{frame}

\mysubsection{The Power User Point of View}

\begin{frame}[fragile]
\frametitle{Overriding Default Configuration Settings with \filenamew{config.site}}

\begin{block}<1->{Recall that old command}
\begin{semiverbatim}
~/amhello-1.0 % \alert<1>{\textit{./configure --prefix ~/usr CC=gcc-3 \textbackslash
CPPFLAGS=-I\$HOME/usr/include LDFLAGS=-L\$HOME/usr/lib}}
\end{semiverbatim}
\end{block}

\begin{block}<2->{Common configuration settings can be put in \variablew{prefix}\filenamew{/share/config.site}}
\begin{semiverbatim}
~/amhello-1.0 % \alert<2>{\textit{cat ~/usr/share/config.site}}
test -z "\$CC" && CC=gcc-3
test -z "\$CPPFLAGS" && CPPFLAGS=-I\$HOME/usr/include
test -z "\$LDFLAGS" && LDFLAGS=-L\$HOME/usr/lib
\end{semiverbatim}
\end{block}

\begin{block}<3->{Reducing the command to...}
\begin{semiverbatim}
~/amhello-1.0 % \alert<3>{\textit{./configure --prefix ~/usr}}
\small{}configure: loading site script /home/adl/usr/share/config.site
...
\end{semiverbatim}
\end{block}
\end{frame}

\begin{frame}[fragile,label=VPATH]
\frametitle{Parallel Build Trees (a.k.a. VPATH Builds)}

Objects files, programs, and libraries are built where
\filename{configure} was run.

\begin{block}<2->{}
\begin{semiverbatim}
~ % \alert<2>{\textit{tar zxf ~/amhello-1.0.tar.gz}}
~ % \alert<2>{\textit{cd amhello-1.0}}
\uncover<3->{~/amhello-1.0 % \alert<3>{\textit{mkdir build && cd build}}}
\uncover<4->{~/amhello-1.0/build % \alert<4>{\textit{../configure}}}
\uncover<5->{~/amhello-1.0/build % \alert<5>{\textit{make}}
...}
\end{semiverbatim}
\end{block}

\uncover<6->{Sources files are in \filename{~/amhello-1.0/}, \\
built files are all in \filename{~/amhello-1.0/build/}.}
\end{frame}

\begin{frame}[fragile]
\frametitle{Parallel Build Trees for Multiple Architectures}

Builds for multiple architectures can share the same source tree.

\begin{block}<2->{Have the source on a (possibly read-only) shared directory}
\begin{semiverbatim}
~ % \alert<2>{\textit{cd /nfs/src}}
/nfs/src % \alert<2>{\textit{tar zxf ~/amhello-1.0.tar.gz}}
\end{semiverbatim}
\end{block}

\begin{block}<3->{Compilation on first host}
\begin{semiverbatim}
~ % \textit{mkdir /tmp/amh && cd /tmp/amh}
/tmp/amh % \alert<3>{\textit{/nfs/src/amhello-1.0/configure}}
/tmp/amh % \textit{make && sudo make install}
\end{semiverbatim}
\end{block}

\begin{block}<4->{Compilation on second host\uncover<5->{, \alert{assuming shared data}}}
\begin{semiverbatim}
~ % \textit{mkdir /tmp/amh && cd /tmp/amh}
/tmp/amh % \alert<4>{\textit{/nfs/src/amhello-1.0/configure}}
/tmp/amh % \textit{make && sudo \alert<5->{make} \alert<5->{install\only<5->{-exec}}}
\end{semiverbatim}
\end{block}

\end{frame}

\begin{frame}
\frametitle{Two Part Installation}

\centering
\begin{tabular}{cl}
\command{make install} & \\
= & \\
\command{make install-exec} &
\uncover<2->{install platform-dependent files} \\
+ & \\
\command{make install-data} &
\uncover<3->{install platform-independent files} \\
& \uncover<3->{(can be shared among multiple machines)} \\
\end{tabular}

\end{frame}

\begin{frame}<handout:3,6>[fragile,t]
\frametitle{Cross-Compilation}

\vspace{-0.5em}

\begin{block}{}
\begin{semiverbatim}
~/amhello-1.0 % \alert<1,3>{\textit{./configure \only<3->{--build i686-pc-linux-gnu \\
                            --host i586-mingw32msvc}}}
\only<all:-3>{\small{}checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets \$(MAKE)... yes
\only<all:3>{\alert{checking for i586-mingw32msvc-strip... i586-mingw32msvc-strip}
}checking for \alert<2->{\only<all:-2>{gcc}\only<all:3>{i586-mingw32msvc-gcc}}... \alert<2->{\only<all:-2>{gcc}\only<all:3>{i586-mingw32msvc-gcc}
}checking for C compiler default output file name... \alert<2->{\only<all:-2>{a.out}\only<all:3>{a.exe}}
checking whether the C compiler works... yes
checking whether we are cross compiling... \alert<2->{\only<all:-2>{no}\only<all:3>{yes}}
checking for suffix of executables... \only<all:3>{\alert{.exe}}
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether \alert<2->{\only<all:-2>{gcc}\only<all:3>{i586-mingw32msvc-gcc}} accepts -g... yes
checking for \alert<2->{\only<all:-2>{gcc}\only<all:3>{i586-mingw32msvc-gcc}} option to accept ANSI C...
}...\only<all:4->{
~/amhello-1.0 % \alert<4>{\textit{make}}
...
\uncover<all:5->{~/amhello-1.0 % \alert<5>{\textit{cd src; file hello.exe}}\scriptsize
hello.exe: MS Windows PE 32-bit Intel 80386 console executable not relocatable}}
\end{semiverbatim}
\end{block}

\uncover<all:5->{Of course you need a cross-compiler installed first.}

\medskip
\uncover<all:6->{Cross-compilation \filename{configure} options:}

\begin{description}[<all:6->][\command{--target=\variable{TARGET}}]
\item[\command{--build=\variable{BUILD}}] The system on which the package is built.
\item[\command{--host=\variable{HOST}}] The system where built programs \& libraries will run.
\item[\command{--target=\variable{TARGET}}] Only when building compiler tools: the system
for which the tools will create output.
\end{description}

\uncover<all:6->{For simple cross-compilation, only \command{--host=\variable{HOST}} is needed.}
\end{frame}

\begin{frame}[fragile]
\frametitle{Renaming Programs at Install Time}

Maybe \filename{hello} is already a command on this host?

\begin{description}[<2->]
\item[\command{--program-prefix=\variable{PREFIX}}]~\\
prepend \variable{PREFIX} to installed program names,
\item[\command{--program-suffix=\variable{SUFFIX}}]~\\
append \variable{SUFFIX} to installed program names,
\item[\command{--program-transform-name=\variable{PROGRAM}}]~\\
run \command{sed \variable{PROGRAM}} on installed program names.
\end{description}

\begin{block}<3->{}
\begin{semiverbatim}
~/amhello-1.0 % \textit{./configure \alert{--program-prefix test-}}
~/amhello-1.0 % \textit{make}
~/amhello-1.0 % \textit{sudo make install}
\end{semiverbatim}
\end{block}

\uncover<3->{Will install \filename{hello} as
  \filename{/usr/local/bin/test-hello}}.

\end{frame}

\mysubsection{The Packager Point of View}

\begin{frame}[fragile]
\frametitle{Building Binary Packages Using \variablew{DESTDIR}}

\variable{DESTDIR} is used to relocate a package at install time.

\begin{block}{}
\begin{semiverbatim}
~/amhello-1.0 % \alert<1>{\textit{./configure --prefix /usr}}
...
\uncover<2->{~/amhello-1.0 % \alert<2>{\textit{make}}
...}
\uncover<3->{~/amhello-1.0 % \alert<3>{\textit{make DESTDIR=\$HOME/inst install}}
...}
\uncover<4->{~/amhello-1.0 % \alert<4>{\textit{cd ~/inst}}
~/inst % \alert<4>{\textit{tar zcvf ~/amhello-1.0-i686.tar.gz .}}
./
./usr/
./usr/bin/
./usr/bin/hello}
\end{semiverbatim}
\end{block}

\uncover<4->{... and \filename{~/amhello-1.0-i686.tar.gz} is ready to
  be uncompressed in \filename{/} on many hosts.}


\end{frame}

\mysubsection{The Maintainer Point of View}

\begin{frame}
\frametitle{Preparing Distributions}

\begin{description}[\command{make distcheck}]
\item[\command{make dist}] Create \filename{PACKAGE-VERSION.tar.gz}.
\item[\command{make distcheck}] Likewise, with many sanity checks. \alert{Prefer this one!}
\end{description}

\uncover<2->{\command{make distcheck} ensures most of the use cases
  presented so far work.

\begin{itemize}
\item It tests VPATH builds (with read-only source tree)
\item It ensures \command{make clean}, \command{make distclean},
      and \command{make uninstall} do not omit files,
\item It checks that \variable{DESTDIR} installations work,
\item It runs the test suite (both \command{make check} and
      \command{make installcheck}).
\end{itemize}

Releasing a package that fails \command{make distcheck} means releasing
a package that will disappoint many users.}
\end{frame}

\begin{frame}[fragile]
\frametitle{Automatic Dependency Tracking}

\begin{block}{}
\begin{semiverbatim}
~/amhello-1.0 % \textit{./configure --prefix /usr}
...
\alert{checking dependency style of gcc... gcc3}
...
\end{semiverbatim}
\end{block}

Dependency tracking is performed as a side-effect of compilation.\\
Several methods are supported, and checked for by \filename{configure}.\\
(The \texttt{gcc3} method above is the fastest.)

\medskip

\uncover<2->{
Dependency tracking is only needed when the source files change;\\
it can be safely disabled for throw-away installation builds.\\
Slow methods must be enabled explicitly.

\begin{description}[\command{--disable-dependency-tracking}]
\item[\command{--disable-dependency-tracking}]
speed up one-time builds
\item[\command{--enable-dependency-tracking}]
do not reject slow dependency extractors
\end{description}}

\end{frame}

\begin{frame}[label=nested-packages]
\frametitle{Nested Packages}

\begin{itemize}
\item<1-> \emph{Autoconfiscated} packages can be nested to arbitrary depth.
  \begin{itemize}
  \item A package can distribute a third-party library it uses in a
    subdirectory.
  \item It's possible to gather many packages this way to distribute a
    set of tools.
  \end{itemize}
\item<2-> For installers:
  \begin{itemize}
  \item A single package to configure, build, and install.
  \item \command{configure} options are passed recursively to sub-packages.
  \item \command{configure --help=recursive} shows the help of all sub-packages.
  \end{itemize}
\item<3-> For maintainers:
  \begin{itemize}
  \item Easier integration.
  \item The sub-package is autonomous.
  \end{itemize}
\end{itemize}

\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\mysection{The configure Process}

\begin{frame}
\frametitle{The (simplified) \filenamew{configure} process}

\begin{center}
\begin{tikzpicture}

\dgfile (Makefilein) at (1,5) {\filenamew{Makefile.in}};
\dgfile (src/Makefilein) at (4,5) {\filenamew{src/Makefile.in}};
\dgfile (confighin) at (7,5) {\filenamew{config.h.in}};
\dgfile (configure) at (4,3) {\filenamew{configure}};
\uncover<2->{
\bfile (Makefile) at (1,1) {\filenamew{Makefile}};
\bfile (src/Makefile) at (4,1) {\filenamew{src/Makefile}};
\bfile (configh) at (7,1) {\filenamew{config.h}};

\arr (Makefilein) .. controls +(-90:1cm) and +(180:3cm) .. (configure);
\arr (src/Makefilein) .. controls +(-90:1cm) and +(175:3cm) .. (configure);
\arr (confighin) .. controls +(-90:1cm) and +(170:3cm) .. (configure);

\arr (configure) .. controls +(-10:2.5cm) and +(80:1cm) .. (Makefile);
\arr (configure) .. controls +(-5:2.2cm) and +(85:1cm) .. (src/Makefile);
\arr (configure) .. controls +(0:2cm) and +(90:1cm) .. (configh);
}
\end{tikzpicture}
\end{center}

\filename{*.in} files are configuration templates\\
\uncover<2->{from which \filename{configure} generates the configuration files
to use for building}

\end{frame}

\begin{frame}<handout:2,4-5>[label=real-configure]
\frametitle{The (real) \filenamew{configure} process}


\begin{center}
\begin{tikzpicture}

\dgfile (Makefilein) at (1,5) {\filenamew{Makefile.in}};
\dgfile (src/Makefilein) at (4,5) {\filenamew{src/Makefile.in}};
\dgfile (confighin) at (7,5) {\filenamew{config.h.in}};
\dgfile (configure) at (-.7,4) {\filenamew{configure}};
\uncover<all:2->{\bfile (configlog) at (5.5,2) {\filenamew{config.log}};}
\uncover<all:3->{\bfile (configstatus) at (2.5,3) {\filenamew{config.status}};}

\uncover<all:4->{\bfile (Makefile) at (1,1) {\filenamew{Makefile}};
\bfile (src/Makefile) at (4,1) {\filenamew{src/Makefile}};
\bfile (configh) at (7,1) {\filenamew{config.h}};}
\uncover<all:5->{\bfile (configcache) at (0,2) {\filenamew{config.cache}};}

\uncover<all:2>{\arr[color=red] (configure) .. controls +(10:2cm) and +(80:2cm) .. (configlog);}
\uncover<all:3->{\arr (configure) .. controls +(10:2cm) and +(80:2cm) .. (configlog);}
\uncover<all:3>{\arr[color=red] (configure) .. controls +(0:1cm) and +(90:1cm) .. (configstatus);}
\uncover<all:4->{\arr (configure) .. controls +(0:1cm) and +(90:1cm) .. (configstatus);}
\uncover<all:5>{\arr[color=red] (configure) .. controls +(-10:1.5cm) and +(80:1cm) .. (configcache);
              \arr[color=red] (configcache) .. controls +(-140:2cm) and +(-170:2cm) .. (configure);}
\uncover<all:4>{\arr[color=red] (Makefilein) .. controls +(-90:1cm) and +(180:2.8cm) .. (configstatus);
\arr[color=red] (src/Makefilein) .. controls +(-90:1cm) and +(170:3cm) .. (configstatus);
\arr[color=red] (confighin) .. controls +(-90:1cm) and +(170:3cm) .. (configstatus);

\arr[color=red] (configstatus) .. controls +(-10:3cm) and +(70:1cm) .. (Makefile);
\arr[color=red] (configstatus) .. controls +(-5:2.5cm) and +(90:2cm) .. (src/Makefile);
\arr[color=red] (configstatus) .. controls +(5:2cm) and +(90:2cm) .. (configh);
\arr[color=red] (configstatus) .. controls +(0:2cm) and +(100:.5cm) .. (configlog);
}
\uncover<all:5->{\arr (Makefilein) .. controls +(-90:1cm) and +(180:2.8cm) .. (configstatus);
\arr (src/Makefilein) .. controls +(-90:1cm) and +(170:3cm) .. (configstatus);
\arr (confighin) .. controls +(-90:1cm) and +(170:3cm) .. (configstatus);

\arr (configstatus) .. controls +(-10:3cm) and +(70:1cm) .. (Makefile);
\arr (configstatus) .. controls +(-5:2.5cm) and +(90:2cm) .. (src/Makefile);
\arr (configstatus) .. controls +(5:2cm) and +(90:2cm) .. (configh);
\arr (configstatus) .. controls +(0:2cm) and +(100:.5cm) .. (configlog);
}
\end{tikzpicture}
\end{center}

\only<all:1>{\textcolor{white}{config}}
\only<all:2>{\filename{config.log} contains a trace of the configuration}
\only<all:3-4>{\filename{config.status} will actually process the templates}
\only<all:5>{\command{configure -C} caches results in \filename{config.cache} to speed up reconfigurations}
\only<all:-4>{\\
\textcolor{white}{reconfiguration}}

\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\mysection{Why We Need Tools}
\begin{frame}
\frametitle{Why We Need Tools}

If you try to mimic this build system by hand, you'll discover that
\begin{itemize}[<+->]
\item The GNU Build System has a lot of features.  \\
      Some users may expect features you do not use.
\item Implementing them portably is difficult, and exhausting. \\
      (Think portable shell scripts, portable \filename{Makefile}s,
      on systems you may not have handy.)
\item You will have to upgrade your setup to follow changes of
      the GNU Coding Standards.
\end{itemize}

\medskip
\uncover<+->{GNU Autotools provide:}

\begin{itemize}[<+->]
\item Tools to create the GNU Build System from simple instructions.
\item A central place where fixes and improvements are made.\\
      (A bug-fix for a portability issue benefits every package.)
\end{itemize}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\mypart{GNU Autotools}

\mysection{Hello World}

\begin{frame}[fragile]
\frametitle{\filenamew{src/main.c} for Hello World}

\begin{block}{\filenamew{src/main.c}}
\begin{lstlisting}[language=C]
#include <config.h>
#include <stdio.h>

int
main (void)
{
  puts ("Hello World!");
  puts ("This is " PACKAGE_STRING ".");
  return 0;
}
\end{lstlisting}
\end{block}

\end{frame}

\begin{frame}<handout:5>
\frametitle{Generating All Template Files}

\only<all:1-2>{\begin{center}
\begin{tikzpicture}

\dgfile (Makefilein) at (1,5) {\filenamew{Makefile.in}};
\dgfile (src/Makefilein) at (4,5) {\filenamew{src/Makefile.in}};
\dgfile (confighin) at (7,5) {\filenamew{config.h.in}};
\dgfile (configure) at (-.7,4) {\filenamew{configure}};
\uncover<all:1>{\bfile (config.log) at (5.5,2) {\filenamew{config.log}};
\bfile (configstatus) at (2.5,3) {\filenamew{config.status}};

\bfile (Makefile) at (1,1) {\filenamew{Makefile}};
\bfile (src/Makefile) at (4,1) {\filenamew{src/Makefile}};
\bfile (configh) at (7,1) {\filenamew{config.h}};
\bfile (configcache) at (0,2) {\filenamew{config.cache}};

\arr (configure) .. controls +(10:2cm) and +(80:2cm) .. (configlog);
\arr (configure) .. controls +(0:1cm) and +(90:1cm) .. (configstatus);
\arr (configure) .. controls +(-10:1.5cm) and +(80:1cm) .. (configcache);
\arr (configcache) .. controls +(-140:2cm) and +(-170:2cm) .. (configure);

\arr (Makefilein) .. controls +(-90:1cm) and +(180:2.8cm) .. (configstatus);
\arr (src/Makefilein) .. controls +(-90:1cm) and +(175:3.2cm) .. (configstatus);
\arr (confighin) .. controls +(-90:1cm) and +(170:3cm) .. (configstatus);

\arr (configstatus) .. controls +(-10:3cm) and +(70:1cm) .. (Makefile);
\arr (configstatus) .. controls +(-5:2.5cm) and +(90:1cm) .. (src/Makefile);
\arr (configstatus) .. controls +(5:2cm) and +(90:2cm) .. (configh);
\arr (configstatus) .. controls +(0:2cm) and +(100:.5cm) .. (configlog);
}
\end{tikzpicture}
\end{center}}
\only<all:3->{\begin{center}
\begin{tikzpicture}{-3.5cm}{3cm}{8cm}{9cm}
\dgfile (Makefilein) at (1,5) {\filenamew{Makefile.in}};
\dgfile (src/Makefilein) at (4,5) {\filenamew{src/Makefile.in}};
\dgfile (confighin) at (7,5) {\filenamew{config.h.in}};
\dgfile (configure) at (-.5,4) {\filenamew{configure}};
\uncover<all:4->{
\tfile (autoreconf) at (2.5,6.5) {\command{autoreconf}};
\afile (configureac) at (-2,8) {\filenamew{configure.ac}};
}
\uncover<all:5->{
\afile (Makefileam) at (1,8) {\filenamew{Makefile.am}};
\afile (src/Makefileam) at (4,8) {\filenamew{src/Makefile.am}};
}
\uncover<all:4->{
\arr (configureac) .. controls +(-90:2cm) and +(185:4cm) .. (autoreconf);
\arr (autoreconf) .. controls +(-10:4cm) and +(100:2.7cm) .. (configure);
\arr (autoreconf) .. controls +(5:4cm) and +(90:1cm) .. (confighin);
}
\uncover<all:5->{
\arr (Makefileam) .. controls +(-90:.8cm) and +(178:3cm) .. (autoreconf);
\arr (src/Makefileam) .. controls +(-90:.6cm) and +(170:3cm) .. (autoreconf);
\arr (autoreconf) .. controls +(-5:4cm) and +(55:.5cm) .. (Makefilein);
\arr (autoreconf) .. controls +(0:3cm) and +(70:.5cm) .. (src/Makefilein);
}
\end{tikzpicture}
\end{center}}
\end{frame}

\begin{frame}[fragile]
\frametitle{Autotools Inputs}

\begin{columns}
\column{0.54\textwidth}
\begin{block}{\filenamew{configure.ac}}
\begin{lstlisting}[language=sh]
AC_INIT([amhello], [1.0],
        [bug-report@address])
AM_INIT_AUTOMAKE([
  -Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
  Makefile
  src/Makefile
])
AC_OUTPUT
\end{lstlisting}
\end{block}
\column{0.42\textwidth}
\begin{block}<2->{\filenamew{Makefile.am}}
\begin{lstlisting}[language=make]
SUBDIRS = src
\end{lstlisting}
\end{block}

\begin{block}<3->{\filenamew{src/Makefile.am}}
\begin{lstlisting}[language=make]
bin_PROGRAMS = hello
hello_SOURCES = main.c
\end{lstlisting}
\end{block}

\end{columns}
\end{frame}

\begin{frame}<handout:2,5-8,11,13,14>[fragile,t,label=amhello-example-first]
\frametitle{Preparing the Package}

\vspace*{-1em}
\begin{block}{}
\begin{semiverbatim}
\only<all:-3>{~/amhello % \alert<1>{\textit{ls -R}}
.:
Makefile.am  configure.ac  src/

./src:
Makefile.am  main.c
~/amhello % \uncover<2->{\alert<2>{\textit{autoreconf --install}}
configure.ac:4: installing `./install-sh'
configure.ac:4: installing `./missing'
src/Makefile.am: installing `./depcomp'
}}\only<all:-8>{\uncover<2->{~/amhello % }\uncover<all:3->{\alert<3>{\textit{ls -R}}
.:
Makefile.am      configure.ac
\alert<all:5>{Makefile.in}      \alert<all:7>{depcomp}*
\alert<all:6>{aclocal.m4}       \alert<all:7>{install-sh}*
\alert<all:8>{autom4te.cache/}  \alert<all:7>{missing}*
\alert<all:5>{config.h.in}      src/
\alert<all:5>{configure}*

./autom4te.cache:
\alert<all:8>{output.0  requests  traces.1
output.1  traces.0}

./src:
Makefile.am  \alert<5>{Makefile.in}  main.c}
}\only<all:9-11>{~/amhello % \alert<9>{\textit{./configure}}
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets \$(MAKE)... yes
checking for gcc... gcc
...
checking dependency style of gcc... gcc3
\alert<10>{configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: executing depfiles commands}
~/amhello % \uncover<11>{\alert{\textit{make}}
...}}\only<all:12-13>{~/amhello % \alert<12>{\textit{src/hello}}
Hello World!
This is amhello 1.0.
~/amhello % \uncover<13->{\alert<13>{\textit{make distcheck}}
...
========================================
amhello archives ready for distribution:
amhello-1.0.tar.gz
========================================
~/amhello % }}\only<all:14->{~/amhello % \alert<14>{\textit{tar ztf amhello-1.0.tar.gz}}
amhello-1.0/
amhello-1.0/Makefile.am
amhello-1.0/Makefile.in
amhello-1.0/aclocal.m4
amhello-1.0/config.h.in
amhello-1.0/configure
amhello-1.0/configure.ac
amhello-1.0/depcomp
amhello-1.0/install-sh
amhello-1.0/missing
amhello-1.0/src/
amhello-1.0/src/Makefile.am
amhello-1.0/src/Makefile.in
amhello-1.0/src/main.c
~/amhello %}
\end{semiverbatim}
\end{block}
{\vspace*{-5cm}\hspace*{6cm}\alert{%
\only<all:5>{expected configuration templates}%
\only<all:6>{definitions for third-party macros\\%
         \hspace*{6cm}used in \filenamew{configure.ac}}%
\only<all:7>{auxiliary tools\\%
         \hspace*{6cm}used during the build}%
\only<all:8>{Autotools cache files}}}%
\end{frame}



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\mysection{Introducing Core Autotools}

\begin{frame}
\frametitle{Two Core Packages}

\begin{description}[\command{autoreconf}]
\item<1->[GNU Autoconf]~\\
\item<2->[\command{autoconf}]
  Create \filename{configure} from \filename{configure.ac}.
\item<3->[\command{autoheader}]
  Create \filename{config.h.in} from \filename{configure.ac}.
\item<4->[\command{autoreconf}]
  \alert<11>{Run all tools in the right order.}
\item<5->[\command{autoscan}] Scan sources for common portability
  problems,\\ and related macros missing from \filename{configure.ac}.
\item<6->[\command{autoupdate}]
  Update obsolete macros in \filename{configure.ac}.
\item<7->[\command{ifnames}]
  Gather identifiers from all \texttt{\#if}/\texttt{\#ifdef}/... directives.
\item<8->[\command{autom4te}]
  The heart of Autoconf.  It drives M4 and implements the features used by
  most of the above tools.  Useful for creating more than just
  \filename{configure} files.
\item<1->[GNU Automake]~\\
  \item<9->[\command{automake}]
    Create \filename{Makefile.in}s from \filename{Makefile.am}s and
    \filename{configure.ac}.
  \item<10->[\command{aclocal}]
    Scan \filename{configure.ac} for uses of third-party macros, and
    gather definitions in \filename{aclocal.m4}.
\end{description}
\end{frame}

\begin{frame}<handout:10>[label=behind-autoreconf]
\frametitle{Behind \command{autoreconf}}

\begin{tikzpicture}
\dgfile (configure) at (-2,3) {\filenamew{configure}};
\dgfile (confighin) at (.8,3) {\filenamew{config.h.in}};
\dgfile (Makefilein) at (3.6,3) {\filenamew{Makefile.in}};
\dgfile (src/Makefilein) at (6.4,3) {\filenamew{src/Makefile.in}};
\uncover<all:1>{
\tfile (autoreconf) at (2.5,6.5) {\command{autoreconf}};
}

\uncover<all:3->{
\tfile (aclocal) at (-2,7) {\command{aclocal}};
}
\uncover<all:5->{
\tfile (autoconf) at (-2,5) {\command{autoconf}};
}
\uncover<all:7->{
\tfile (autoheader) at (1.75,5.75) {\command{autoheader}};
}
\uncover<all:9->{
\tfile (automake) at (5.5,6.5) {\command{automake}};
}


\afile (configureac) at (-2,9) {\filenamew{configure.ac}};
\uncover<all:4->{\dgfile (aclocalm4) at (1,8.5) {\filenamew{aclocal.m4}};}
\afile (Makefileam) at (3.5,9) {\filenamew{Makefile.am}};
\afile (src/Makefileam) at (6.5,9) {\filenamew{src/Makefile.am}};


\uncover<all:1>{
\arr (autoreconf) .. controls +(-10:4cm) and +(40:2cm) .. (configure);
\arr (autoreconf) .. controls +(-5:4cm) and +(55:2cm) .. (confighin);
\arr (autoreconf) .. controls +(0:4cm) and +(70:2cm) .. (Makefilein);
\arr (autoreconf) .. controls +(5:4cm) and +(90:2cm) .. (src/Makefilein);

\arr (configureac) .. controls +(-90:2cm) and +(180:4cm) .. (autoreconf);
\arr (Makefileam) .. controls +(-120:2cm) and +(175:4cm) .. (autoreconf);
\arr (src/Makefileam) .. controls +(-130:2cm) and +(170:4cm) .. (autoreconf);
}
\uncover<all:4->{
\arr (configureac) .. controls +(-90:.5cm) and +(170:1.7cm) .. (aclocal);
\arr (aclocal) .. controls +(10:2cm) and +(150:2cm) .. (aclocalm4);
}
\uncover<all:6->{
\arr (configureac) .. controls +(-140:2cm) and +(175:2cm) .. (autoconf);
\arr (aclocalm4) .. controls +(-120:2cm) and +(170:2cm) .. (autoconf);
\arr (autoconf) .. controls +(-10:2cm) and +(90:1cm) .. (configure);
}
\uncover<all:8->{
\arr (configureac) .. controls +(-50:2cm) and +(175:2.5cm) .. (autoheader);
\arr (aclocalm4) .. controls +(-110:2cm) and +(170:2cm) .. (autoheader);
\arr (autoheader) .. controls +(-10:2.5cm) and +(90:1cm) .. (confighin);
}
\uncover<all:10->{
\arr (configureac) .. controls +(-40:3cm) and +(180:4cm) .. (automake);
\arr (aclocalm4) .. controls +(-50:2cm) and +(176:2cm) .. (automake);
\arr (Makefileam) .. controls +(-90:2cm) and +(173:2cm) .. (automake);
\arr (src/Makefileam) .. controls +(-110:2cm) and +(170:2cm) .. (automake);
\arr (automake) .. controls +(-10:2cm) and +(80:1cm) .. (Makefilein);
\arr (automake) .. controls +(-5:2cm) and +(90:1cm) .. (src/Makefilein);
}
\end{tikzpicture}
\end{frame}


\begin{frame}
\frametitle{\command{autoreconf} is Your Friend}

In practice,
\begin{itemize}
\item You do not have to remember the interaction of all tools.
\item Use \command{autoreconf --install} to setup the package initially.
\item Rely on the rebuild rules (output in \filename{Makefile}s) to
      rerun the right autotool when you change some input file.
\item You only need a rough idea of the purpose of each
      tool to understand errors.  (What tool complains and about what?)
\end{itemize}

\begin{description}[<2>][\command{autoheader}]
\item[\command{autoconf}]
  Creates \filename{configure} from \filename{configure.ac}.
\item[\command{autoheader}]
  Creates \filename{config.h.in} from \filename{configure.ac}.
\item[\command{automake}]
  Creates \filename{Makefile.in}s from \filename{Makefile.am}s and
  \filename{configure.ac}.
\item[\command{aclocal}]
  Scans \filename{configure.ac} for uses of third-party macros, and
  gather definitions in \filename{aclocal.m4}.
\item[\command{autom4te}]
  Autoconf driver for M4.  All tools that process
  \filename{configure.ac} do so through \command{autom4te}.
\end{description}

\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\mysection{Hello World Explained}

\begin{frame}<1-3| handout:8>[fragile,label=configure-ac-explained]
\frametitle{\texttt{amhello}'s \filenamew{configure.ac} explained}

\begin{block}{\filenamew{configure.ac}}
\begin{semiverbatim}
\alert<all:2>{AC_INIT([amhello], [1.0], [bug-report@address])}
\alert<all:3>{AM_INIT_AUTOMAKE([-Wall -Werror foreign])}
\alert<all:4>{AC_PROG_CC}
\alert<all:5>{AC_CONFIG_HEADERS([config.h])}
\alert<all:6>{AC_CONFIG_FILES([Makefile src/Makefile])}
\alert<all:7>{AC_OUTPUT}
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<2->Initialize Autoconf.  Specify package's name, version number, and
         bug-report address.
\item<3->Initialize Automake.  Turn on all Automake warnings and
  report them as errors.  This is a \alert<3>{foreign} package.
\item<4->Check for a C compiler.
\item<5->Declare \filenamew{config.h} as output header.
\item<6->Declare \filenamew{Makefile} and
         \filenamew{src/Makefile} as output files.
\item<7->Actually output all declared files.\only<8>{}
\end{itemize}

\end{frame}

\begin{frame}[fragile]
\frametitle{\texttt{foreign} Ignores some GNU Coding Standards}

\begin{block}{\filenamew{configure.ac}\only<all:2->{ without the \texttt{foreign} option}}
\begin{semiverbatim}
...
AM_INIT_AUTOMAKE([-Wall -Werror\only<all:1>{ \alert{foreign}}])
...
\end{semiverbatim}
\end{block}
\begin{block}{}
\begin{semiverbatim}
~/amhello % \textit{autoreconf --install}
configure.ac:2: installing `./install-sh'
configure.ac:2: installing `./missing'
src/Makefile.am: installing `./depcomp'
\uncover<all:2>{\alert{Makefile.am: installing `./INSTALL'
Makefile.am: required file `./NEWS' not found
Makefile.am: required file `./README' not found
Makefile.am: required file `./AUTHORS' not found
Makefile.am: required file `./ChangeLog' not found
Makefile.am: installing `./COPYING'
autoreconf: automake failed with exit status: 1}}
\end{semiverbatim}
\end{block}

\end{frame}

\againframe<3-7| handout:0>{configure-ac-explained}

\begin{frame}<handout:2>[fragile]
\frametitle{\texttt{amhello}'s \filenamew{Makefile.am} explained}

\begin{block}{\filenamew{Makefile.am}}
\begin{semiverbatim}
\alert<all:1>{SUBDIRS = src}
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<1-> Build recursively in \filename{src/}.
\item<2-> Nothing else is declared for the current directory.\\
          (The top-level \filename{Makefile.am} is usually short.)
\end{itemize}
\end{frame}

\begin{frame}<1-2| handout:5>[fragile,label=src-Makefile-am-explained]
\frametitle{\texttt{amhello}'s \filenamew{src/Makefile.am} explained}

\begin{block}{\filenamew{src/Makefile.am}}
\begin{semiverbatim}
\alert<all:2>{bin}_\alert<all:1>{PROGRAMS} = \alert<all:3>{hello}
\alert<all:4>{hello_SOURCES = main.c}
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<1-> We are building some programs.
\item<2-> These programs will be installed in \variable{bindir}.
\item<3-> There is only one program to build: \filename{hello}.
\item<4-> To create \filename{hello}, just compile \filename{main.c}.\only<5>{}
\end{itemize}
\end{frame}

\againframe<5| handout:0>{standard-dirs}

\againframe<2-4| handout:0>{src-Makefile-am-explained}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\mysection{Using Autoconf}

\begin{frame}
\frametitle{From \filenamew{configure.ac} to \filenamew{configure} and \filenamew{config.h.in}}

\begin{itemize}
\item<1-> \command{autoconf} is a macro processor.
\item<1-> It converts \filename{configure.ac}, which is a shell script
  using macro instructions, into \filename{configure}, a full-fledged
  shell script.
\item<2-> Autoconf offers many macros to perform common configuration checks.
\item<2-> It is not uncommon to have a \filename{configure.ac} without
  shell constructs, using only macros.
\item<3-> While processing \filename{configure.ac} it is also possible
  to trace the occurrences of macros.  This is how
  \command{autoheader} creates \filename{config.h.in}.  It just looks
  for the macros that \#define symbols.
\end{itemize}

\begin{itemize}
\item<4-> The real macro processor actually is GNU M4.  Autoconf offers
  some infrastructure on top of that, plus the pool of macros.
\end{itemize}
\end{frame}

\begin{frame}<handout:2>[fragile]
\frametitle{Discovering M4}

\begin{block}{\filenamew{example.m4}}
\begin{semiverbatim}
\only<all:6->{\cret}\uncover<-5>{\alert<5>{m4_define(}\alert<3>{NAME1}\alert<5>, \alert<4>{Harry}\alert<5>)\cret}
\only<all:9->{\cret}\uncover<-8>{\alert<8>{m4_define(}\alert<6>{NAME2}\alert<8>, \alert<7>{Sally}\alert<8>)\cret}
\only<all:14->{\cret}\uncover<-13>{\alert<13>{m4_define(}\alert<9>{MET}\alert<13>, \alert<10>{$1} \alert<11>{met} \alert<12>{$2}\alert<13>)\cret}
\only<all:-20>{\alert<20>{MET(}\alert<14,16>{\only<all:-14>{NAME1}\only<all:15->{Harry}}\alert<20>, \alert<17,19>{\only<all:-17>{NAME2}\only<all:18->{Sally}}\alert<20>)}\only<all:21->{\alert<22>{Harry} \alert<23>{met} \alert<24>{Sally}}\cret
\end{semiverbatim}
\end{block}

\uncover<25>{}

\begin{block}{}
\begin{semiverbatim}
~ % \uncover<2->{\alert<2>{m4 -P example.m4}
\cret
\cret
\cret
Harry met Sally\cret}
\end{semiverbatim}
\end{block}
\end{frame}

\begin{frame}<handout:4>[fragile]
\frametitle{M4 Quoting}

\begin{itemize}
\item \alert<1>{The macro's arguments are processed}
\item Then the macro is expanded
\item Finally \alert<1>{the output of the macro is processed too}
\item<2-> A string can be protected from processing using \alert<2>{quotes}.
\end{itemize}

\uncover<3->{This is a source of many mistakes for the unwary.}

\begin{block}<2->{\filenamew{example.m4}}
\begin{semiverbatim}
\only<all:9->{\cret}\uncover<-8>{\alert<8>{m4_define(}\alert<5>{NAME1}\alert<8>, \alert<6>{\only<all:-6>{\alert<2>`}Harry, Jr.\only<all:-6>{\alert<2>'}}\alert<8>)\cret}
\only<all:13->{\cret}\uncover<-12>{\alert<12>{m4_define(}\alert<10>{NAME2}\alert<12>, \alert<11>{Sally}\alert<12>)\cret}
\only<all:18->{\cret}\uncover<-17>{\alert<17>{m4_define(}\alert<13>{MET}\alert<17>, \alert<14>{$1} \alert<15>{met} \alert<16>{$2}\alert<17>)\cret}
\only<all:-25>{\alert<25>{MET(}\only<all:-18>{\alert<18>{NAME1}}\only<all:19->{\alert<20>{Harry}\alert<25>, \alert<21>{Jr}.}\alert<25>, \alert<22,24>{\only<all:-22>{NAME2}\only<all:23->{Sally}}\alert<25>)}\only<all:26->{\alert<27>{Harry} \alert<28>{met} \alert<29>{Jr}.}\cret
\end{semiverbatim}
\end{block}

\uncover<4->{Can you guess the output of the above?}\uncover<30>{}

\end{frame}

\begin{frame}<handout:3>[fragile]
\frametitle{M4 Quoting Rule of the Thumb}

\begin{itemize}
\item<1-> Quote each macro argument once.
\item<2-> So it is processed only after it has been output.
\end{itemize}

\begin{block}<3->{\filenamew{example.m4}}
\begin{semiverbatim}
\only<all:7->{\cret}\uncover<-6>{\alert<6>{m4_define(}\alert<4>{\only<all:-4>`NAME1\only<all:-4>'}\alert<6>, \alert<5>{\only<all:-5>`Harry, Jr.\only<all:-5>'}\alert<6>)\cret}
\only<all:10->{\cret}\uncover<-9>{\alert<9>{m4_define(}\alert<7>{\only<all:-7>`NAME2\only<all:-7>'}\alert<9>, \alert<8>{\only<all:-8>`Sally\only<all:-8>'}\alert<9>)\cret}
\only<all:13->{\cret}\uncover<-12>{\alert<12>{m4_define(}\alert<10>{\only<all:-10>`MET\only<all:-10>'}\alert<12>, \alert<11>{\only<all:-11>`$1 met $2\only<all:-11>'}\alert<12>)\cret}
\only<all:-15>{\alert<15>{MET(}\alert<13>{\only<all:-13>`NAME1\only<all:-13>'}\alert<15>, \alert<14>{\only<all:-14>`NAME2\only<all:-14>'}\alert<15>)}\only<all:16->{\alert<17>{\only<all:-17>{NAME1}}\only<all:18->{\alert<19>{Harry}, \alert<20>{Jr}.} \alert<21>{met} \only<all:-22>{\alert<22>{NAME2}}\only<all:23->{\alert<24>{Sally}}}\cret
\end{semiverbatim}
\end{block}

\uncover<25>{}
\end{frame}

\begin{frame}<handout:2->[fragile]
\frametitle{Spacing Matters}

\begin{itemize}
\item<2-|handout:2> The parenthesis must stick to the macro name.
\item<3-|handout:3> Spaces after or inside quotes are part of the arguments.
\item<4-|handout:4> Spaces before quotes are ignored.
\end{itemize}

\begin{block}{\filenamew{example.m4}}
\begin{semiverbatim}
m4_define(`NAME1',\alert<all:4>{\only<all:4>{\textvisiblespace}}\only<all:-3>{ }`Harry, Jr.')\cret
m4_define(`NAME2',\alert<all:4>{\only<all:4>{\textvisiblespace}}\only<all:-3>{ }`Sally')\cret
m4_define(`MET',\alert<all:4>{\only<all:4>{\textvisiblespace}}\only<all:-3>{ }`$1 met $2')\cret
MET\alert<all:2>{\only<all:2>{\textvisiblespace}}(\alert<all:4>{\only<all:4>{\textvisiblespace}}`\alert<all:3>{\only<all:3>{\textvisiblespace}}NAME1\only<all:3>{\alert<all:3>{\textvisiblespace}}'\alert<all:3>{\only<all:3>{\textvisiblespace}},\alert<all:4>{\only<all:4>{\textvisiblespace}}\only<all:-3>{ }`NAME2')\cret
\end{semiverbatim}
\end{block}

\begin{block}{}
\begin{semiverbatim}
~ % m4 -P example.m4
\cret
\cret
\cret
\only<all:2>{ met \alert<all:2>{\textvisiblespace}(NAME1, NAME2)\cret}\uncover<all:1,3->{{\only<all:3>{\alert<all:3>{\textvisiblespace}}}Harry, Jr.\alert<all:3>{\only<all:3>{\textvisiblespace\textvisiblespace}} met Sally\cret}
\end{semiverbatim}
\end{block}
\end{frame}

\begin{frame}<handout:5>[fragile]
\frametitle{Autoconf on Top of M4}

\begin{itemize}
\item<1-> Autoconf = M4 with more machinery, and many predefined macros.
\item<2-> The quotes are \texttt{[} and \texttt{]} (instead of \texttt{`} and \texttt{'}).
\item<3-> For this reason we use the \texttt{test} command instead of \texttt{[}
 in shell fragments:
\begin{block}<3->{}
\begin{semiverbatim}
if \only<all:4->{\alert<4>{test}}\only<all:-3>{\alert<3>{[}} "$x" = "$y"\only<all:-3>{ \alert<3>{]}}; then ...
\end{semiverbatim}
\end{block}
\item<5-> Macros are defined with \texttt{AC\_DEFUN}.
\begin{block}<5->{}
\begin{semiverbatim}
AC_DEFUN([NAME1], [Harry, Jr.])
AC_DEFUN([NAME2], [Sally])
AC_DEFUN([MET], [$1 met $2])
MET([NAME1], [NAME2])
\end{semiverbatim}
\end{block}
\end{itemize}
\end{frame}

\begin{frame}<handout:1,6>[fragile,label=structure]
\frametitle{The Structure of a \filenamew{configure.ac}}

\begin{block}{\filenamew{configure.ac}}
\begin{semiverbatim}
# Prelude.
AC_INIT([\only<all:1>{\variable{PACKAGE}}\only<all:2->{\alert<2>{amhello}}], [\only<all:1>{\variable{VERSION}}\only<all:2->{\alert<2>{1.0}}], [\only<all:1>{\variable{BUG-REPORT-ADDRESS}}\only<all:2->{\alert<2>{bug-report@address}}])
\uncover<3->{\alert<3>{AM_INIT_AUTOMAKE([-Wall -Werror foreign])}}
# \textsf{Checks for programs.}
\uncover<4->{\alert<4>{AC_PROG_CC}}
# \textsf{Checks for libraries.}
# \textsf{Checks for header files.}
# \textsf{Checks for typedefs, structures, and compiler characteristics.}
# \textsf{Checks for library functions.}
# \textsf{Output files.}
\uncover<6->{\alert<6>{AC_CONFIG_HEADERS([config.h])}}
AC_CONFIG_FILES([\only<all:-4>{\variable{FILES}}\only<all:5->{\alert<5>{Makefile src/Makefile}}])
AC_OUTPUT
\end{semiverbatim}
\end{block}

\end{frame}

\begin{frame}
\frametitle{Useful Autoconf Macros for Prelude}

\begin{description}[<+->][xx]
\item[\texttt{AC\_INIT(\variable{PACKAGE}, \variable{VERSION},
    \variable{BUG-REPORT-ADDRESS})}]~\\
  Mandatory Autoconf initialization.
\item[\texttt{AC\_PREREQ(\variable{VERSION})}]~\\
  Require a minimum Autoconf version.  E.g. \texttt{AC\_PREREQ([\autoconfver])}
\item[\texttt{AC\_CONFIG\_SRCDIR(\variable{FILE})}]~\\
  A safety check.  \variable{FILE} should be a distributed source file,
  and this makes sure that \command{configure} is not run from outer
  space.  E.g. \texttt{AC\_CONFIG\_SRCDIR([src/main.c])}.
\item[\texttt{AC\_CONFIG\_AUX\_DIR(\variable{DIRECTORY})}]~\\
  Auxiliary scripts such as \filename{install-sh} and
  \filename{depcomp} should be in \variable{DIRECTORY}.
  E.g. \texttt{AC\_CONFIG\_AUX\_DIR([build-aux])}.
\end{description}
\end{frame}

\againframe<7| handout:0>{amhello-example-first}

\begin{frame}<handout:2>[fragile]
\frametitle{\texttt{AC\_CONFIG\_AUX\_DIR} Example}

\begin{block}{\filenamew{configure.ac}}
\begin{semiverbatim}
AC_INIT([amhello], [1.1], [bug-report@address])
\uncover<2>{\alert{AC_CONFIG_AUX_DIR([build-aux])}}
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT
\end{semiverbatim}
\end{block}

\begin{block}{}
\begin{semiverbatim}
% \textit{autoreconf --install}
configure.ac:3: installing `\only<all:2>{\alert{build-aux/}}missing'
configure.ac:3: installing `\only<all:2>{\alert{build-aux/}}install-sh'
src/Makefile.am: installing `\only<all:2>{\alert{build-aux/}}depcomp'
\end{semiverbatim}
\end{block}
\end{frame}

\begin{frame}[fragile]
\frametitle{Useful Program Checks}

\begin{description}[xx]
\item<1->[\texttt{AC\_PROG\_CC}, \texttt{AC\_PROG\_CXX}, \texttt{AC\_PROG\_F77}, ...]~\\
  Compiler checks.  (Handle search cross-compilers if needed.)

\item<2->[\texttt{AC\_PROG\_SED}, \texttt{AC\_PROG\_YACC},
  \texttt{AC\_PROG\_LEX}, ...]~\\ Find good implementations
  and set \lstinline{$SED}, \lstinline{$YACC}, \lstinline{$LEX},
  etc.%$
\item<3->[\texttt{AC\_CHECK\_PROGS(\variable{VAR}, \variable{PROGS}, [\variable{VAL-IF-NOT-FOUND}])}]~\\
  Define \variable{VAR} to the first \variable{PROGS} found, or to \variable{VAL-IF-NOT-FOUND} otherwise.

\begin{block}{}
\begin{semiverbatim}
AC_CHECK_PROGS([TAR], [tar gtar], [:])
if test "$TAR" = :; then
  \alert<4>{AC_MSG_ERROR}([This package needs tar.])
fi
\end{semiverbatim}
\end{block}%$

\item<3->[... and many more]~
\end{description}

\end{frame}

\begin{frame}[fragile]
\frametitle{Useful Autoconf Action Macros}

\begin{description}[xx]
\item<1->[\texttt{AC\_MSG\_ERROR(\variable{ERROR-DESCRIPTION}, [\variable{EXIT-STATUS}])}]~\\
  Print \variable{ERROR-DESCRIPTION} (also to \filename{config.log}) and
  abort \command{configure}.
\item<1->[\texttt{AC\_MSG\_WARN(\variable{ERROR-DESCRIPTION})}]~\\
  Likewise, but don't abort.
\item<2->[\texttt{AC\_DEFINE(\variable{VARIABLE}, \variable{VALUE}, \variable{DESCRIPTION})}]~\\
  Output the following to \filename{config.h}.
\begin{block}{}
\begin{semiverbatim}
/* \variable{DESCRIPTION} */
#define \variable{VARIABLE} \variable{VALUE}
\end{semiverbatim}
\end{block}
\item<3->[\texttt{AC\_SUBST(\variable{VARIABLE},
    [\variable{VALUE}])}]~\\ Define \texttt{\$(\variable{VARIABLE})} as
  \variable{VALUE} in \filename{Makefile}.
\begin{columns}
\column{0.37\textwidth}
\begin{block}{}
\begin{semiverbatim}
AC_SUBST([FOO], [foo])
\end{semiverbatim}
\end{block}
\column{0.25\textwidth}
\begin{block}{}
\begin{semiverbatim}
FOO=foo
AC_SUBST([FOO])
\end{semiverbatim}
\end{block}
\column{0.25\textwidth}
\begin{block}{}
\begin{semiverbatim}
AC_SUBST([FOO])
FOO=foo
\end{semiverbatim}
\end{block}
\end{columns}
All equivalent.

\end{description}
\end{frame}

\begin{frame}[fragile,label=checklib]
\frametitle{Checking for Libraries}

\begin{description}[xx]
\item<1->[\texttt{AC\_CHECK\_LIB(\variable{LIBRARY}, \variable{FUNCT}, [\variable{ACT-IF-FOUND}], [\variable{ACT-IF-NOT}])}]~\\
  Check whether \variable{LIBRARY} exists and contains \variable{FUNCT}.

  Execute \variable{ACT-IF-FOUND} if it does, \variable{ACT-IF-NOT}
  otherwise.

\bigskip

\begin{block}<2->{}
\begin{semiverbatim}
AC_CHECK_LIB([efence], [malloc], [EFENCELIB=-lefence])
AC_SUBST([EFENCELIB])
\end{semiverbatim}
\end{block}
\uncover<2->{... we would later use \texttt{\$(EFENCELIB)} in the link rule.}

\bigskip

\uncover<3->{If \variable{ACT-IF-FOUND} is not set and the library
  is found, \texttt{AC\_CHECK\_LIB} will do \texttt{LIBS="-l\variable{LIBRARY} \$LIBS"} and \texttt{\#define} \texttt{HAVE\_LIB\variable{LIBRARY}}.

(Automake uses \texttt{\$LIBS} for linking everything.)}
\end{description}

\end{frame}

\begin{frame}[fragile]
\frametitle{Checking for Headers}

\begin{description}[xx]
\item<1->[\texttt{AC\_CHECK\_HEADERS(\variable{HEADERS}...)}]~\\
  Check for \variable{HEADERS} and \texttt{\#define} \texttt{HAVE\_\variable{HEADER}\_H} for each header found.

\begin{block}<2->{}
\begin{semiverbatim}
AC_CHECK_HEADERS([sys/param.h unistd.h])
AC_CHECK_HEADERS([wchar.h])
\end{semiverbatim}
\end{block}
\uncover<2->{Might \#define \texttt{HAVE\_SYS\_PARAM\_H}, \texttt{HAVE\_UNISTD\_H}, and \texttt{HAVE\_WCHAR\_H}.}

\begin{block}<3->{}
\begin{lstlisting}[language=C]
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
\end{lstlisting}
\end{block}
\item<4->[\texttt{AC\_CHECK\_HEADER(\variable{HEADER}, [\variable{ACT-IF-FOUND}], [\variable{ACT-IF-NOT}])}]~\\
  Check only one header.
\end{description}
\end{frame}


\begin{frame}<handout:2,7>[fragile]
\frametitle{Output Commands}

\begin{description}[xx]
\item<1->[\texttt{AC\_CONFIG\_HEADERS(\variable{HEADERS}...)}]~\\
  Create \variable{HEADER} for all \variable{HEADER}\filename{.in}.
  \alert<1>{Use only one such header} unless you know what you are doing
  (\command{autoheader} creates \variable{HEADER}\filename{.in} only
  for the first \variable{HEADER}).

  \variable{HEADERS} contain definitions made with \texttt{AC\_DEFINE}.

\begin{block}<2->{}
\begin{semiverbatim}
AC_CONFIG_HEADERS([config.h\only<all:3->{\alert<3>{:config.hin}}])
\end{semiverbatim}
\end{block}
\uncover<2->{Will create \filename{config.h} from
  \only<all:-2>{\filename{config.h.in}}\only<all:3>{\alert{\filenamew{config.hin}}}%
  \only<all:4->{\filename{config.hin}}
  \uncover<3->{(DJGPP supports only 1 dot).}}

\item<4->[\texttt{AC\_CONFIG\_FILES(\variable{FILES}...)}]~\\

  Create \variable{FILE} for all \variable{FILE}\filename{.in}.

  \variable{FILES} contain definitions made with \texttt{AC\_SUBST}.

\begin{block}<5->{}
\begin{semiverbatim}
AC_CONFIG_FILES([\alert<6>{Makefile sub/Makefile} \alert<7>{script.sh:script.in}])
\end{semiverbatim}
\end{block}
\uncover<6->{Automake creates \variable{FILE}\filename{.in} for each
  \variable{FILE} that has a \variable{FILE}\filename{.am}.}

\uncover<7->{It's legitimate to process non-\filename{Makefile}s too.}

\end{description}

\end{frame}

\begin{frame}[fragile]
\frametitle{\texttt{AC\_CONFIG\_FILES([script.sh:script.in])} Example}

\begin{columns}
\column{.45\textwidth}
\begin{block}{\filenamew{script.in}}
\begin{semiverbatim}
#!/bin/sh
SED='\alert<2-3>{@SED@}'
TAR='\alert<2-3>{@TAR@}'
d=$1; shift; mkdir "$d"
for f; do
  "$SED" 's/#.*//' "$f" \\
    >"$d/$f"
done
"$TAR" cf "$d.tar" "$d"
\end{semiverbatim}
\end{block}
\column{.45\textwidth}
\begin{block}<3->{\filenamew{script.sh}}
\begin{semiverbatim}
#!/bin/sh
SED='\alert<3>{/usr/xpg4/bin/sed}'
TAR='\alert<3>{/usr/bin/tar}'
d=$1; shift; mkdir "$d"
for f; do
  "$SED" 's/#.*//' "$f" \\
    >"$d/$f"
done
"$TAR" cf "$d.tar" "$d"
\end{semiverbatim}
\end{block}
\end{columns}

\medskip

\filename{.in} files are templates
\uncover<2->{where \variable{@XYZ@} are placeholders for
  \texttt{AC\_SUBST([XYZ])} definitions.}
\uncover<3->{\command{config.status} substitutes them.}

\medskip

\uncover<4->{\filename{Makefile.in}s also use \variable{@XYZ@} as
  placeholders but Automake makes all \texttt{XYZ=@XYZ@} definitions
  and you may simply use \texttt{\$(XYZ)} as needed.}

\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\mysection{Using Automake}

\begin{frame}
\frametitle{Automake Principles}

\begin{itemize}
\item<1-> Automake helps creating portable and \alert<2>{GNU-standard compliant}
  \filename{Makefile}s.
  \begin{itemize}
  \item<2-> You may be used to other kinds of build systems.  \\
    (E.g., no VPATH builds, but all objects go into \filename{obj/}.)
  \item<3-> Do not use Automake if you do not like the GNU Build System:\\
    Automake will get in your way if you don't fit the mold.
  \end{itemize}
\item<4-> \command{automake} creates \alert<5>{complex}
  \filename{Makefile.in}s from simple \filename{Makefile.am}s.
  \begin{itemize}
  \item<5-> Consider \filename{Makefile.in}s as internal details.
  \end{itemize}
\item<6-> \filename{Makefile.am}s follow roughly the same syntax as
  \filename{Makefile}s however they usually contains only variable
  definitions.
  \begin{itemize}
  \item<7-> \command{automake} creates build rules from these definitions.
  \item<8-> It's OK to add extra \filename{Makefile} rules in
    \filename{Makefile.am}:\\
    \command{automake} will preserve them in the output.
  \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}<1>[fragile,label=automake-init]
\frametitle{Declaring Automake in \filenamew{configure.ac}}

\begin{description}[xx]
\item<1->[\texttt{AM\_INIT\_AUTOMAKE([\variable{OPTIONS}...])}]~\\
  Check for tools needed by \command{automake}-generated \filename{Makefile}s.

  \uncover<2->{Useful options:
    \begin{description}
      \item[\texttt{-Wall}] Turn all warnings on.
      \item[\texttt{-Werror}] Report warnings as errors.
      \item[\texttt{foreign}] Relax some GNU standard requirements.
      \item[\texttt{\automakever}]
        Require a minimum version of \command{automake}.
      \item[\texttt{dist-bzip2}] Also create \texttt{tar.bz2} archives during
        \command{make dist} and \command{make distcheck}.
      \item[\texttt{tar-ustar}] Create tar archives using the ustar format.
    \end{description}}

\item<3->[\texttt{AC\_CONFIG\_FILES(\variable{FILES}...)}]~\\

  Automake creates \variable{FILE}\filename{.in} for each
  \variable{FILE} that has a \variable{FILE}\filename{.am}.

\begin{block}<3->{}
\begin{semiverbatim}
AC_CONFIG_FILES([Makefile sub/Makefile])
\end{semiverbatim}
\end{block}
  ... and write \filename{Makefile.am} and \filename{sub/Makefile.am}.

\end{description}
\end{frame}

\againframe<3| handout:0>{structure}
\againframe<2-| handout:0>{automake-init}

\begin{frame}<-3>[fragile,label=where-primary]
\frametitle{\texttt{where\_PRIMARY} Convention for Declaring Targets}

\begin{center}
\begin{minipage}{.66\textwidth}
\begin{block}{\filenamew{Makefile.am}}
\begin{semiverbatim}
\uncover<7->{\alert{option_}}\alert<3-5>{where}_\alert<2>{PRIMARY} = \variable{targets} ...
\end{semiverbatim}
\end{block}
\end{minipage}
\end{center}

\begin{columns}
\column{.45\textwidth}\uncover<3->{
\variable{targets} should be installed in...
\begin{description}[\texttt{\textit{custom}\_}]
\item[\texttt{bin\_}] \texttt{\$(bindir)}
\item[\texttt{lib\_}] \texttt{\$(libdir)}
\item[...]~
\item<4->[\texttt{\textit{custom}\_}] \texttt{\$(\textit{customdir})}\\
  You define \texttt{customdir}.
\item<5->[\texttt{noinst\_}] Not installed.
\item<6->[\texttt{check\_}] Built by \command{make check}.
\end{description}
}
\column{.45\textwidth}\uncover<2->{
\variable{targets} should be built as...
\begin{description}[xx]
\item[\texttt{\_PROGRAMS}]~
\item[\texttt{\_LIBRARIES}]~
\item[\texttt{\_LTLIBRARIES}] (Libtool libraries)
\item[\texttt{\_HEADERS}]~
\item[\texttt{\_SCRIPTS}]~
\item[\texttt{\_DATA}]~
\end{description}
}
\end{columns}

\medskip

\uncover<7->{
\begin{columns}
\column{.15\textwidth}
Optionally:
\column{.8\textwidth}
\begin{description}[\texttt{nodist\_}]
\item[\texttt{dist\_}] Distribute \variable{targets} (if not the default)
\item[\texttt{nodist\_}] Don't.
\end{description}
\end{columns}}

\end{frame}

\againframe<5| handout:0>{standard-dirs}
\againframe<3-| handout:0>{where-primary}

\begin{frame}[fragile]
\frametitle{Declaring Sources}

\begin{block}{\filenamew{Makefile.am}}
\begin{semiverbatim}
\alert<1>{bin}_PROGRAMS = \alert<2>{foo} \alert<3>{run-me}
\alert<2>{foo}_SOURCES = \alert<4>{foo\alert<7>{.c} \alert<5>{foo.\alert<7>{h}} \alert<6>{print\alert<7>{.c}} \alert<5>{print\alert<7>{.h}}}
\alert<3>{run_me}_SOURCES = \alert<4>{run\alert<7>{.c} \alert<5>{run\alert<7>{.h}} \alert<6>{print\alert<7>{.c}}}
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<1-> These programs will be installed in \texttt{\$(bindir)}.
\item<2-> The sources of each \variable{program} go into
  \texttt{\variable{programs}\_SOURCES}.
\item<3-> Non-alphanumeric characters are mapped to `\texttt\_'.
\item<4-> Automake automatically computes the list of objects to build
  and link from these files.
\item<5-> Header files are not compiled.  We list them only
  so they get distributed (Automake does not distribute files
  it does not know about).
\item<6-> It's OK to use the same source for two programs.
\item<7-> Compiler and linker are inferred from the extensions.
\end{itemize}

\end{frame}

\begin{frame}[fragile]
\frametitle{(Static) Libraries}

\begin{itemize}
\item<1-> Add \texttt{AC\_PROG\_RANLIB} to \filename{configure.ac}.

\begin{block}<2->{\filenamew{Makefile.am}}
\begin{semiverbatim}
\alert<3>{lib}_LIBRARIES = \alert<4>{lib}foo\alert<4>{.a lib}bar\alert<4>{.a}
libfoo_a_SOURCES = foo.c \alert<6>{privfoo.h}
libbar_a_SOURCES = bar.c \alert<6>{privbar.h}
\alert<5>{include_HEADERS = foo.h bar.h}
\end{semiverbatim}
\end{block}

\item<3-> These libraries will be installed in \texttt{\$(libdir)}.
\item<4-> Library names must match \texttt{lib*.a}.
\item<5-> Public headers will be installed in \texttt{\$(includedir)}.
\item<6-> Private headers are not installed, like ordinary sources files.
\end{itemize}

\end{frame}

\begin{frame}<handout:5,7>[fragile]
\frametitle{Directory Layout}

\begin{itemize}
\item<1-> You may have one \filename{Makefile} (hence one
  \filename{Makefile.am}) per directory.
\item<2-> They must \alert<2>{all} be declared in \filename{configure.ac}.
\begin{block}<2->{\filenamew{configure.ac}}
\begin{semiverbatim}
AC_CONFIG_FILES([\alert<2>{Makefile lib/Makefile src/Makefile
                 src/dira/Makefile src/dirb/Makefile}])
\end{semiverbatim}
\end{block}
\item<3-> \command{make} is run at the top-level.
\item<3-> \filename{Makefile.am}s should fix the order in which to recurse
  directories using the \variable{SUBDIRS} variable.
\begin{columns}
\column{.45\textwidth}
\begin{block}<4->{\filenamew{Makefile.am}}
\begin{semiverbatim}
SUBDIRS = lib src
\end{semiverbatim}
\end{block}
\column{.45\textwidth}
\begin{block}<4->{\filenamew{src/Makefile.am}}
\begin{semiverbatim}
SUBDIRS = \only<all:8>{\alert<8>. }dira \only<all:7>{\alert<7>. }dirb \only<all:6>{\alert<6>.}
\end{semiverbatim}
\end{block}
\end{columns}
\item<5-> The current directory is implicitly built after subdirectories.
\item<6-> You can put `\alert{.}' where you want to override this.
\end{itemize}
\end{frame}

\begin{frame}<1>[label=srcdir]
\frametitle{\texttt{\$(srcdir) and VPATH Builds}}

\begin{itemize}
\item<1-> Remember VPATH builds: a source file is not necessary in the
  current directory.
\item<2-> There are two twin trees: the \textbf{build tree}, and the
  \textbf{source tree}.
\begin{itemize}
\item \filename{Makefile} and objects files are in the build tree.
\item \filename{Makefile.in}, \filename{Makefile.am}, and source files
  are in the source tree.
\item If \command{./configure} is run in the current directory, the
  two trees are one.
\end{itemize}
\item<3-> In each \filename{Makefile}, \command{config.status} will
  define \variable{\$(srcdir)}: the path to the matching source directory.
\item<4-> When referring to sources files or targets in Automake variables,
  you do not have to worry about \emph{source} vs. \emph{build}, because
  \command{make} will check both directories.
\item<5-> You may need \variable{\$(srcdir)} when specifying flags for
  tools, or writing custom commands.
  E.g., to tell the compiler to include headers from \filename{dir/},
  you should write \texttt{-I\$(srcdir)/dir}, not  \texttt{-Idir}.
  (\texttt{-Idir} would fetch headers from the build tree.)
\end{itemize}
\end{frame}

\againframe<6| handout:0>{VPATH}
\againframe<2-| handout:0>{srcdir}


\begin{frame}<handout:5-6>[fragile]
\frametitle{Convenience Libraries}

\begin{block}{\filenamew{lib/Makefile.am}}
\begin{semiverbatim}
\alert<2>{noinst}_LIBRARIES = libcompat.a
libcompat_a_SOURCES = xalloc.c xalloc.h
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<2-> This is a convenience library, used only when building the package.

\begin{block}<3->{\filenamew{src/Makefile.am}}
\begin{semiverbatim}
\only<all:-5>{\alert<4>{LDADD = ../lib/libcompat.a}
\alert<5>{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\only<all:6->{
\alert<6>{run_me_LDADD = ../lib/libcompat.a
run_me_CPPFLAGS = -I\$(srcdir)/../lib}}
\end{semiverbatim}
\end{block}

\item<4-> \variable{LDADD} is added when linking all programs.
\item<5-> \variable{AM\_CPPFLAGS} contains additional preprocessor flags.
\item<all:6-> You can use per-target variables: they apply to a single program.
\end{itemize}
\end{frame}

\begin{frame}<-3>[fragile,label=per-target]
\frametitle{Per-Target Flags}

Assuming \variable{foo} is a program or library:
\begin{description}[\texttt{foo\_CPPFLAGS}]
\item<1->[\texttt{foo\_CFLAGS}] Additional C compiler flags
\item<1->[\texttt{foo\_CPPFLAGS}] Additional preprocessor flags (\texttt{-I}s and \texttt{-D}s)
\item<2->[\texttt{foo\_LDADD}] Additional link objects, \texttt{-l}s and \texttt{-L}s (if \variable{foo} is a program)
\item<2->[\texttt{foo\_LIBADD}] Additional link objects, \texttt{-l}s and \texttt{-L}s (if \variable{foo} is a library)
\item<2->[\texttt{foo\_LDFLAGS}] Additional linker flags
\end{description}
The default value for \texttt{foo\_\variable{XXX}FLAGS} is \texttt{\$(AM\_\variable{XXX}FLAGS)}.

\uncover<3->{Use plain file names to refer to libraries inside your package
  (keep \texttt{-l}s and \texttt{-L}s for external libraries only).}

\begin{block}<3->{\filenamew{src/Makefile.am}}
\begin{semiverbatim}
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
\alert<3>{run_me_LDADD = ../lib/libcompat.a \uncover<4>{\alert<4>{\$(EFENCELIB)}}}
\end{semiverbatim}
\end{block}
\end{frame}

\againframe<2| handout:0>{checklib}
\againframe<4| handout:0>{per-target}

\begin{frame}[fragile]
\frametitle{What Gets Distributed}

\command{make dist} and \command{make distcheck} create a tarball containing:
\begin{itemize}
\item<1-> All sources declared using \variable{...\_SOURCES}
\item<1-> All headers declared using \variable{...\_HEADERS}
\item<2-> All scripts declared with \variable{dist\_...\_SCRIPTS}
\item<2-> All data files declared with \variable{dist\_...\_DATA}
\item<2-> ...
\item<3-> Common files such as \filename{ChangeLog}, \filename{NEWS}, etc.\\
  See \command{automake --help} for a list of those files.
\item<4-> Extra files or directories listed into
  \variable{EXTRA\_DIST}.
\begin{block}<5->{\filenamew{Makefile.am}}
\begin{semiverbatim}
SUBDIRS = lib src
EXTRA_DIST = HACKING
\end{semiverbatim}
\end{block}
\uncover<5->{  ... will additionally distribute \filename{HACKING}.}
\end{itemize}

\end{frame}

\begin{frame}[fragile]
\frametitle{Conditionals: Usage}

\begin{itemize}
\item<1-> \emph{Conditionals} allow for conditional builds and unconditional
distribution.

\begin{columns}
\column{.45\textwidth}
\begin{block}<2->{Conditional Programs}
\begin{semiverbatim}
bin_PROGRAMS = foo
if WANT_BAR
  bin_PROGRAMS += \alert<4>{bar}
endif
foo_SOURCES = \alert<6>{foo.c}
bar_SOURCES = \alert<6>{bar.c}
\end{semiverbatim}
\end{block}
\column{.45\textwidth}
\begin{block}<3->{Conditional Sources}
\begin{semiverbatim}
bin_PROGRAMS = foo
foo_SOURCES = \alert<6>{foo.c}
if WANT_BAR
  foo_SOURCES += \alert<5-6>{bar.c}
endif
\end{semiverbatim}
\end{block}
\end{columns}

\smallskip

\item<4-> \filename{bar} is built iff \variable{WANT\_BAR} is true.
\item<5-> \filename{bar.o} is linked in \filename{foo} iff
  \variable{WANT\_BAR} is true.
\item<6-> In all cases \filename{foo.c} and \filename{bar.c} are distributed
  regardless of \variable{WANT\_BAR}.
\item<7-> This is portable.  \command{config.status} will comment rules
  of \filename{Makefile.in} that must be disabled.
\item<8-> \variable{WANT\_BAR} must be declared and valued
  in \filename{configure.ac}.
\end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{Conditionals: Declaration}


\begin{description}[<1->][xx]
\item[\texttt{AM\_CONDITIONAL(\variable{NAME}, \variable{CONDITION})}]~\\
  Declare conditional \variable{NAME}.  \variable{CONDITION} should be
  a shell instruction that succeeds iff \variable{NAME} should be enabled.
\end{description}

\begin{block}<2->{\filenamew{configure.ac}}
\begin{semiverbatim}
AC_CHECK_HEADER([bar.h], [use_bar=yes])
AM_CONDITIONAL([WANT_BAR], [test "$use_bar" = yes])
\end{semiverbatim}
\end{block}%$

\uncover<2->{Will enable \variable{WANT\_BAR} only if \filename{bar.h}
  is present on the system.}

\end{frame}

\begin{frame}
\frametitle{Extending Automake Rules}

\begin{itemize}
\item<1-> The contents of \filename{Makefile.am} is copied almost
  verbatim to \filename{Makefile.in}.
\item<1-> \command{automake} adds new rules and variables in
  \filename{Makefile.in}, to achieve the semantics of the special
  variables you have defined.
\item<1-> Some minor rewriting is done to handle constructs like
  conditionals or \texttt{+=} portably.
\end{itemize}

\begin{itemize}
\item<2-> It's OK to define your own rules in \filename{Makefile.am}.
  \begin{itemize}
    \item<3-> Helpful maintenance targets (\command{make style-check})
    \item<3-> Build idiosyncratic files (generate a \filename{FAQ}
      from some random source)
    \item<3-> ...
  \end{itemize}
\item<4-> It's OK to define variables that are meaningless to Automake.
  \begin{itemize}
    \item<4-> For use in custom rules.
  \end{itemize}
\end{itemize}

\begin{itemize}
\item<5-> \alert{Beware of conflicts:} your definitions (of variables or rules)
  will override those of Automake.
  \begin{itemize}
  \item \texttt{-Wall} will diagnose these.
  \end{itemize}
\end{itemize}

\end{frame}

\begin{frame}
\frametitle{Recommendations}

\begin{itemize}
\item<1-> Use \texttt{-Wall -Werror}.
\item<2-> Keep Your Setup Simple (KYSS!).
\begin{itemize}
\item You will spend a large part of time debugging your cunning
  tricks if you try to automatize too much.
\end{itemize}
\item<3-> Do not lie to Automake.
\begin{itemize}
\item Automake can be annoying, but when you lie it gets worse!
\end{itemize}
\end{itemize}

\end{frame}


\begin{frame}[fragile]
\frametitle{Lost?  \command{autoreconf} is Still Your Friend}

If \command{make} fails to rebuild configuration files, run
\command{autoreconf} manually.

\begin{block}{}
\begin{semiverbatim}
~/amhello % \alert<1>{\textit{autoreconf --install}}
\end{semiverbatim}
\end{block}

\bigskip

\uncover<2->{If this does not help, try harder.}

\begin{block}<2->{}
\begin{semiverbatim}
~/amhello % \alert<2>{\textit{autoreconf --install --force}}
\end{semiverbatim}
\end{block}

\bigskip

\uncover<3->{If this still does not help, try even harder.}

\begin{block}<3->{}
\begin{semiverbatim}
~/amhello % \alert<3>{\textit{make -k maintainer-clean}}
~/amhello % \alert<3>{\textit{autoreconf --install --force}}
\end{semiverbatim}
\end{block}

\uncover<3->{Do this only when necessary.  Each of these commands will
  cause your package to take longer to reconfigure and recompile.}

\end{frame}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\mypart{More Autotools}

\section{Writing and Managing Custom Macros}

\mysubsection{Writing Autoconf Macros}

\begin{frame}
\frametitle{Writing an Autoconf Macro? Why? How?}

Two fundamentally different types of new macros:

\begin{itemize}
\item<1-> Macros that factor related tests in a single reusable entity.
  \begin{itemize}
  \item<2-> High-level.
  \item<2-> Combination of existing lower-level macros.
  \item<2-> May not use shell code at all.
  \end{itemize}
\item<1-> Macros that implements new tests.
  \begin{itemize}
  \item<3-> Low-level.
  \item<3-> Actually code the check.
  \item<3-> Need to bother with caching values.
  \end{itemize}
\end{itemize}

\end{frame}

\begin{frame}
\frametitle{Defining Macros}

\begin{description}[xx]
\item<1->[\texttt{AC\_DEFUN(\variable{MACRO-NAME}, \variable{MACRO-BODY})}]~\\
  Define \variable{MACRO-NAME} as \variable{MACRO-BODY}.
\end{description}

\alert<1>{Avoid names that may conflict.}  \uncover<2->{Macro name spaces:
\begin{description}[\texttt{XX\_}]
\item[\texttt{m4\_}] Original M4 macros, plus M4sugar macros.
\item[\texttt{AS\_}] M4sh macros (macroized shell constructs)
\item[\texttt{AH\_}] \textbf{A}uto\textbf{h}eader macros
\item[\texttt{AC\_}] \textbf{A}uto\textbf{c}onf macros (written on top of the above layers)
  \begin{description}[\texttt{AC\_HEADER\_}]
  \item<3->[\texttt{AC\_CHECK\_}] Generic checks.
  \item<3->[\texttt{AC\_FUNC\_}] Specific function checks.
  \item<3->[\texttt{AC\_HEADER\_}] Specific header checks.
  \item<3->[\texttt{AC\_PROG\_}] Specific program checks.
  \item<3->[...]~
  \end{description}
\item[\texttt{AM\_}] \textbf{A}uto\textbf{m}ake macros
\item[\texttt{AT\_}] \textbf{A}uto\textbf{t}est macros
\end{description}
}

\end{frame}

\begin{frame}[fragile]
\frametitle{\texttt{mkdir()} Example}

\begin{itemize}
\item POSIX systems define \texttt{mkdir()} with two arguments.
\item On Mingw32 (at least), \texttt{mkdir()} takes only one argument.
\item On Win32 (at least), the name is \texttt{\_mkdir()} with one argument.
\end{itemize}
\vspace{-.5ex}
\begin{block}<2->{}
\begin{semiverbatim}
#if \alert<3>{HAVE_MKDIR}
# if \alert<3>{MKDIR_ONE_ARG}
#  define mkdir(a,b) mkdir(a)
# endif
#else
# if \alert<3>{HAVE__MKDIR}
#  define mkdir(a,b) _mkdir(a)
# else
#  error "Don't know how to create a directory."
# endif
#endif
\end{semiverbatim}
\end{block}
\vspace{-.5ex}
\uncover<3->{Let's write an Autoconf macro to define \alert<3>{these C macros}.}
\end{frame}


\begin{frame}[fragile]
\frametitle{Writing a High-Level Macro: \texttt{AX\_FUNC\_MKDIR}}

\begin{block}{}
\begin{semiverbatim}
AC_DEFUN([\alert<2>{AX_}\alert<3>{FUNC_}MKDIR],
[\alert<4>{AC_CHECK_FUNCS([mkdir _mkdir])}
\alert<5>{AC_CHECK_HEADERS([io.h])}
\alert<6>{AX_FUNC_MKDIR_ONE_ARG}
])
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<2-> Suggested name space for extension macros.
\item<3-> Use same convention as Autoconf for categorizing macros.
\item<4-> Defines \texttt{HAVE\_MKDIR} and \texttt{HAVE\_\_MKDIR}.
\item<5-> Defines \texttt{HAVE\_IO\_H} if \filename{io.h} exists.\\
  (\texttt{mkdir()} may also be defined there, and \filename{sys/stat.h}
  and \filename{unistd.h} are always tested by \texttt{AC\_PROG\_CC})
\item<6-> Will define \texttt{MKDIR\_ONE\_ARG}... once written.
\end{itemize}
\end{frame}

\begin{frame}<handout:5>[fragile]
\frametitle{Checking \texttt{mkdir()}'s number of arguments}

\vspace*{-.5ex}
\begin{block}<1->{}
\begin{semiverbatim}\small
\alert<all:2>{# _AX_FUNC_MKDIR_ONE_ARG(IF-ONE-ARG, IF-TWO-ARGS)
# -----------------------------------------------
# Execute IF-TWO-ARGS if mkdir() accepts two
# arguments; execute IF-ONE-ARG otherwise.}
AC_DEFUN([\alert<5>{_AX}_FUNC_MKDIR_ONE_ARG],
[\alert<3>{AC_TRY_COMPILE}(\alert<3>{[
#include <sys/stat.h>
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#if HAVE_IO_H
# include <io.h>
#endif
]}, \alert<3>{[mkdir (".", 0700);]}, \alert<3>{[\$2]}, \alert<3>{[\$1]})])
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<4-> Wait! That's not enough for an Autoconf check: we should
  also add some \emph{checking whether...} message on top of this.
\item<5-> We use the \texttt{\_AX} prefix for helper macros not meant
  to be used directly.
\end{itemize}

\vspace*{-15em}\hspace*{.37\textwidth}
\begin{minipage}{.6\textwidth}
\begin{block}<2-3>{\only<all:2>{Comments}\only<3>{\texttt{AC\_TRY\_COMPILE}}}
\only<all:2>{Showcase of the traditional style used to document autoconf
  macros.}\only<3>{Creates a small program and
  attempt to compile it.  In our case it will execute one of the
  \texttt{\_AX\_FUNC\_MKDIR\_ONE\_ARG} arguments depending on whether
  the program compiled or not.}
\end{block}
\end{minipage}
\vspace{5cm}
\end{frame}

\begin{frame}<1>[fragile,label=low-level]
\frametitle{Writing a Low-Level Macro}

Low-level macros need to
\begin{itemize}
\item print a \emph{checking whether...} message
\item do the actual check
\item cache the result of the check
\end{itemize}

\uncover<2->{Most of this is achieved via the \texttt{AC\_CACHE\_CHECK} macro.}

\begin{block}<2->{}
\begin{semiverbatim}
AC_DEFUN(\variable{MACRO-NAME},
[AC_CACHE_CHECK(\variable{WHETHER-MESSAGE},
                \variable{\alert<3>{CACHE-VARIABLE}},
                \variable{\alert<4>{CODE-TO-SET-CACHE-VARIABLE}})
\variable{\alert<5>{CODE-USING-CACHE-VARIABLE}}])
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<3-> The \variable{CACHE-VARIABLE} should match \texttt{*\_cv\_*}.
\item<4-> \variable{CODE-TO-SET-CACHE-VARIABLE} should contain the check.
  It will be skipped when the cache is used.
\item<5-> \variable{CODE-USING-CACHE-VARIABLE} is always executed, use
  \texttt{AC\_SUBST} and \texttt{AC\_DEFINE} here.
\end{itemize}

\end{frame}

\againframe<5| handout:0>{real-configure}
\againframe<2-| handout:0>{low-level}

\begin{frame}<-3|handout:4>[fragile,t]
\frametitle{A Low-Level Macro: \texttt{AX\_FUNC\_MKDIR\_ONE\_ARG}}
\vspace*{-1em}
\begin{block}{}
\begin{semiverbatim}
AC_DEFUN([AX_FUNC_MKDIR_ONE_ARG],
[\alert<2,4>{AC_CACHE_CHECK([whether mkdir takes one argument],
                [ax_cv_mkdir_one_arg],
[_AX_FUNC_MKDIR_ONE_ARG([ax_cv_mkdir_one_arg=yes],
                        [ax_cv_mkdir_one_arg=no])])}
\alert<all:3>{if test x"\$ax_cv_mkdir_one_arg" = xyes; then
  AC_DEFINE([MKDIR_ONE_ARG], 1,
            [Define if mkdir takes only one argument.])
fi}]) # AX_FUNC_MKDIR_ONE_ARG
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<2-> \texttt{AC\_CACHE\_CHECK}
\begin{itemize}
\item prints \emph{checking whether mkdir...}
\item does the check (unless already done)
\item cache the result in \texttt{ax\_cv\_mkdir\_one\_arg}
\end{itemize}
\item<3-> Keep configuration actions outside
  \texttt{AC\_CACHE\_CHECK}: they have to be executed
  whether the check is run or cached.
\end{itemize}

\end{frame}

\begin{frame}
\frametitle{Recommendations for Writing Autoconf Macros}

\begin{itemize}
\item<1-> Test for features, not for systems.
  \begin{itemize}
  \item E.g., check whether mkdir() takes one argument, not whether you
    are compiling for Win32.
  \item Your package will be more likely to adapt to untested systems.
  \end{itemize}
\item<2-> Avoid writing tests that are conditional on previous
  tests.
  \begin{itemize}
  \item Have unconditional tests, with conditional actions.
  \item E.g., check for \texttt{\_mkdir()} even if \texttt{mkdir()} exists.
  \end{itemize}
\item<3-> Do not reinvent the wheel.
  \begin{itemize}
  \item Autoconf comes with a lot of well-tested macros.  Use them.
  \end{itemize}
\item<4-> Remember to \alert<4>{[}quote\alert<4>{]}.
\item<4-> Read the \emph{Portable Shell} section of the Autoconf manual, before
  writing shell code.
\item<5-> Test your macros on different systems.
  \begin{itemize}
  \item Check test results in \filename{config.log}.
  \item Get accounts on foreign systems:\\
    \url{http://www.testdrive.hp.com/} \\
    \url{http://sourceforge.net/docs/E02/}
  \end{itemize}
\end{itemize}
\end{frame}

\mysubsection{Managing Custom Macros with \command{aclocal}}

\begin{frame}<-3>[label=aclocal]
\frametitle{\filenamew{aclocal.m4} and Third-Party Macros}

\begin{itemize}
\item \command{autoconf} knows only the macros it provides.\\
  (\texttt{m4\_*}, \texttt{AS\_*}, \texttt{AH\_*},
  \texttt{AC\_*}, \texttt{AT\_*}).
\item \command{autoconf} knows nothing about macro supplied by third-party
  tools (e.g., Automake's \texttt{AM\_*} macros).
\item<2-> \command{autoconf} reads \filename{aclocal.m4} in addition to
  \filename{configure.ac}.
\item<2-> \filename{aclocal.m4} should define the extra macros required by
  \filename{configure.ac}.
\item<3-> \command{aclocal} automates the construction of \filename{aclocal.m4}
  from various sources.
\end{itemize}

\uncover<4->{\command{aclocal} searches macros in
\begin{itemize}
\item directories specified with \texttt{-I} options
\item a system-wide directory (usually \filename{/usr/share/aclocal/}) where
  third-party packages may install their macros
\item Automake's own private macro directory
\end{itemize}}

\end{frame}

\againframe<10| handout:0>{behind-autoreconf}
\againframe<4-| handout:0>{aclocal}

\begin{frame}
\frametitle{Managing Custom Macros in Your Package}

\begin{itemize}
\item Create a \filename{m4/} subdirectory.
\item Put your macros there.  \\
  E.g., define \texttt{AX\_FUNC\_MKDIR} and
  \texttt{AX\_FUNC\_MKDIR\_ONE\_ARG} in \filename{m4/mkdir.m4}.\\
  (The extension \emph{must} be \filename{*.m4})
\item<2-> Add \alert{\texttt{ACLOCAL\_AMFLAGS = -I m4}} to the top-level
  \filename{Makefile.am}.
\item<2-> Add \alert{\texttt{AC\_CONFIG\_MACRO\_DIR([m4])}} to
  \filename{configure.ac}.  (This is not strictly needed yet, but
  let's be future-proof.)
\item<3-> Use your macros in \filename{configure.ac}.
\end{itemize}

\uncover<2->{The \texttt{ACLOCAL\_AMFLAGS} are used by
  \command{autoreconf} and by the \filename{Makefile} rebuild rule
  when they need to run \command{aclocal}.}

\uncover<3->{Local macros that are used are automatically
  distributed.  (Those that are not used are simply ignored.)}

\uncover<4->{\alert{You need such a setup to use Gettext, and the
    upcoming Libtool 2.0.}}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\mysection{Libtool}

\begin{frame}
\frametitle{Shared Libraries: A Portability Hell}

\begin{itemize}
\item<1-> Almost each system has its own format of shared library
  \begin{itemize}
  \item \filename{libhello.so}
  \item \filename{libhello.dll}
  \item \filename{libhello.sl}
  \item \filename{libhello.dylib}
  \item ...
  \end{itemize}
\item<2-> Building will require different flags
  \begin{itemize}
  \item \texttt{-fPIC}, \texttt{-shared}
  \item \texttt{-KPIC}, \texttt{-G}
  \item \texttt{-bM:SRE}
  \item ...
  \end{itemize}
\item<3-> Linking against the library may also require specific flags.
\item<4-> There is no way for a developer to keep track of all these details.
  \begin{itemize}
  \item Quiz: match each of the above example with its OS.
  \end{itemize}
\item<5-> Not all systems support shared libraries.
\end{itemize}
\end{frame}


\begin{frame}
\frametitle{Shared Libraries: Libtool's Solution}

\begin{itemize}
\item<1-> A new library format that abstracts all the others
  \begin{itemize}
  \item \filename{libhello.la} (\textbf{l}ibtool \textbf{a}rchive)
  \end{itemize}
\item<2-> A wrapper script for the compiler and linker
  \begin{itemize}
  \item translates operations involving \filename{libhello.la} into the
    correct operation for the current system using the real library
  \end{itemize}
\end{itemize}

\bigskip

\begin{itemize}[<3->]
\item In a \filename{Makefile.am}, you simply create and link against
  \filename{*.la} files.
\item These operations are translated appropriately.
\end{itemize}

\end{frame}

\begin{frame}[fragile]
\frametitle{Setting Up Libtool: Roadmap}

\begin{itemize}
% \item<+-> Libtool will require some local Autoconf macros for all the
%   checks it has to perform.  Use an \filename{m4/} subdirectory as
%   explained earlier.
\item<1-> Call \texttt{AC\_PROG\_LIBTOOL} in \filename{configure.ac}.
\item<2-> Use \texttt{\_LTLIBRARIES} to declare libtool archives in
  \filename{Makefile.am}
\item<3-> Use \texttt{\_LDADD} to link against local libtool archives.
\end{itemize}

\begin{block}<2->{\filenamew{Makefile.am}}
\begin{semiverbatim}
lib_LTLIBRARIES = libfoo.la
libfoo_la_SOURCES = foo.c foo.h etc.c
\uncover<3->{
bin_PROGRAMS = runme
runme_SOURCES = main.c
\alert<3>{runme_LDADD = libfoo.la}}
\end{semiverbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]
\frametitle{Hello World Using Libtool: C Files}

\begin{columns}
\column{.65\textwidth}
\begin{block}{\filenamew{lib/say.c}}
\begin{semiverbatim}
#include <config.h>
#include <stdio.h>

void say_hello (void)
\{
  puts ("Hello World!");
  puts ("This is " PACKAGE_STRING ".");
\}
\end{semiverbatim}
\end{block}

\begin{block}{\filenamew{lib/say.h}}
\begin{semiverbatim}
void say_hello (void);
\end{semiverbatim}
\end{block}
\column{.3\textwidth}
\begin{block}{\filenamew{src/main.c}}
\begin{semiverbatim}
#include "say.h"

int main (void)
\{
  say_hello ();
  return 0;
\}
\end{semiverbatim}
\end{block}
\end{columns}
\end{frame}

\begin{frame}[fragile]
\frametitle{Hello World Using Libtool: \filenamew{Makefile.am}s}

\begin{block}{\filenamew{lib/Makefile.am}}
\begin{semiverbatim}
lib_LTLIBRARIES = libhello.la
libhello_la_SOURCES = say.c say.h
\end{semiverbatim}
\end{block}

\begin{block}{\filenamew{src/Makefile.am}}
\begin{semiverbatim}
AM_CPPFLAGS = -I\$(srcdir)/../lib
bin_PROGRAMS = hello
hello_SOURCES = main.c
hello_LDADD = ../lib/libhello.la
\end{semiverbatim}
\end{block}

\begin{block}{\filenamew{Makefile.am}}
\begin{semiverbatim}
SUBDIRS = lib src
\end{semiverbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]
\frametitle{Hello World Using Libtool: \filenamew{configure.ac}}

\begin{block}{\filenamew{configure.ac}}
\begin{semiverbatim}
AC_INIT([amhello], [2.0], [bug-report@address])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
\alert{AC_PROG_LIBTOOL}
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile])
AC_OUTPUT
\end{semiverbatim}
\end{block}
\end{frame}

\begin{frame}<handout:2,4>[fragile]
\frametitle{Hello World Using Libtool: \command{autoreconf}}

\begin{block}{}
\begin{semiverbatim}
\only<all:1-2>{~/amhello % \alert<1>{\textit{ls -R}}
\uncover<2>{.:
Makefile.am  configure.ac  lib/  src/

./lib:
Makefile.am  say.c  say.h

./src:
Makefile.am  main.c}}\only<all:3->{~/amhello % \alert<3>{\textit{autoreconf --install}}
\uncover<4->{Putting files in AC_CONFIG_AUX_DIR, `build-aux'.
configure.ac: installing `build-aux/install-sh'
configure.ac: installing `build-aux/missing'
lib/Makefile.am: installing `build-aux/depcomp'
~/amhello %} \uncover<5->{\alert<5>{\textit{./configure --prefix ~/test}}
...
~/amhello %} \uncover<6->{\alert<6>{\textit{make && make install}}
...
~/amhello %} \uncover<7->{\alert<7>{\textit{~/test/bin/hello}}
Hello World!
This is amhello 2.0.
~/amhello %}}
\end{semiverbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]
\frametitle{What Was Built and Installed}

\begin{block}{}
\begin{semiverbatim}
~/amhello % \alert<1>{\textit{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 % \uncover<2->{\alert<2>{\textit{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 %} \uncover<3->{\alert<3>{\textit{ldd src/hello}}
not a dynamic executable
~/amhello %} \uncover<4->{\alert<4>{\textit{file src/hello}}
src/hello: Bourne shell script text executable
~/amhello %}
\end{semiverbatim}
\end{block}
\end{frame}

\begin{frame}[fragile]
\frametitle{Building Shared or Static Libraries}

\begin{itemize}
\item<1-> By default, both static and shared libraries are built.
\item<1-> This default can be changed in a package using two macros:
  \begin{description}[\texttt{AC\_DISABLE\_STATIC}]
  \item[\texttt{AC\_DISABLE\_SHARED}] do not build shared libraries by default
  \item[\texttt{AC\_DISABLE\_STATIC}] do not build static libraries by default
  \end{description}
\item<2-> The installer can override these settings using
  \filename{configure} options.
  \begin{description}[\texttt{AC\_DISABLE\_STATIC}]
  \item[\texttt{--enable-shared}] build shared libraries
  \item[\texttt{--disable-shared}] don't
  \item[\texttt{--enable-static}] build static libraries
  \item[\texttt{--disable-static}] don't
  \end{description}
\item<3-> At least one flavor is built, always.
\item<3-> Some systems don't leave any choice.
\end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{The \filenamew{src/hello} Wrapper Script}

\begin{itemize}
\item<1-> \filename{src/hello} can be a wrapper script
  \begin{itemize}
  \item Depending on Libtool's configuration.
  \end{itemize}
\item<2-> The real binary has been built elsewhere
  \begin{itemize}
  \item Libtool hides it in the build tree (don't bother about it)
  \end{itemize}
\item<3-> This wrapper script runs the real binary,
  and arranges so it finds the not-yet-installed libraries
  \begin{itemize}
  \item This way \filename{src/hello} can be run, for instance in a test suite
  \end{itemize}
\end{itemize}

\begin{block}<4->{Do not debug the shell script!}
\begin{semiverbatim}
~/amhello % \alert{\textit{gdb -q src/hello}}
{\small "src/hello": not in executable format: File format not recognized}
(gdb)
\end{semiverbatim}
\end{block}

\begin{block}<5->{Prefix such commands with \texttt{libtool --mode=execute}}
\begin{semiverbatim}
~/amhello % \alert{\textit{libtool --mode=execute gdb -q src/hello}}
\end{semiverbatim}
\end{block}

\end{frame}

\begin{frame}[fragile]
\frametitle{Versioning Libtool Libraries: Interfaces}

\begin{itemize}
\item Versioning libraries allow several versions to coexist.
\item It ensures programs use the library that implements the
  interface they require.
\end{itemize}

Interface = public variables and functions, I/O, formats, protocols, ...

\begin{itemize}
\item<2-> Interfaces are identified using integers.
\item<2-> A program remembers the interface numbers of the libraries
  it was linked against.
\item<3-> A library can implement several interfaces.
  \begin{itemize}
  \item E.g., adding new functions changes the interface, but does not
    break old interfaces.
  \end{itemize}
\item<3-> Hence libtool's versioning format encodes \alert<3>{a range
  of supported interfaces}.
\end{itemize}

\uncover<4->{\alert{Interface numbers are not release numbers.}}

\end{frame}

\begin{frame}<handout:2>[fragile]
\frametitle{Versioning Libtool Libraries: Version Triplets}

\begin{description}[\variable{REVISION}]
\item[\variable{CURRENT}] The latest interface implemented.
\item[\variable{REVISION}] The implementation number of \variable{CURRENT}\\
  (read: number of bugs fixed...)
\item[\variable{AGE}] The number of interfaces implemented, minus one.\\
  The library supports all interfaces between \variable{CURRENT} $-$
  \variable{AGE} and \variable{CURRENT}.
\end{description}

\uncover<2->{These numbers should be specified using \texttt{-version-info}.}

\begin{block}<2->{lib/Makefile.am}
\begin{semiverbatim}
lib_LTLIBRARIES = libhello.la
libhello_la_SOURCES = say.c say.h
libhello_la_LDFLAGS = -version-info \only<all:-2>{\variable{CURRENT}:\variable{REVISION}:\variable{AGE}}\only<all:3->{\alert{0:0:0}}
\end{semiverbatim}
\end{block}

\uncover<3->{The default version is 0:0:0.  It's also a good initial version.}
\end{frame}

\begin{frame}
\frametitle{Versioning Libtool Libraries: Bumping Versions}

Remember to bump library versions before a release.\\
Suppose the old version was
\variable{CURRENT}:\variable{REVISION}:\variable{AGE}.

\bigskip

\begin{tabular}{|l|l|}
\hline
If you have & bump the version to \\
\hline
not changed the interface &
  \variable{CURRENT}\textbf{\,:\,}\variable{REVISION}+1\textbf{\,:\,}\variable{AGE} \\
(bug fixes) & \\
\hline
augmented the interface &
  \variable{CURRENT}+1\textbf{\,:\,}0\textbf{\,:\,}\variable{AGE}+1 \\
(new functions) & \\
\hline
broken old interface &
  \variable{CURRENT}+1\textbf{\,:\,}0\textbf{\,:\,}0 \\
(e.g. removed functions) & \\
\hline
\end{tabular}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Gettext}

\mysubsection{Introducing Gettext}

\begin{frame}
\frametitle{Introducing Gettext}

\begin{itemize}
\item I\alert<4>{nternationalizatio}n \uncover<4->{= I\alert<4>{18}n}

\uncover<2->{Changing a program to support for multiple languages and
  cultural habits.

\begin{itemize}[<5->]
\item Character handling (unicode...)
\item Locale awareness (date formats, currencies, numbers, time zones, etc.)
\item \alert<8>{Localizability}
  \begin{itemize}
  \item \alert<8>{Isolate localizable items} (\alert<8>{messages}, pictures, etc.)
  \item \alert<8>{Implement infrastructure necessary for localizing
    above items.}
  \end{itemize}
\end{itemize}

\uncover<7->{\alert<7>{The programmer's work.}}
}

\item L\alert<4>{ocalizatio}n \uncover<4->{= L\alert<4>{10}n}

\uncover<3->{Providing an internationalized package the necessary bits
  to support one's native language and cultural habits.

\begin{itemize}
\item<6-> Translate localizable items (messages, pictures, etc.) for
  one language.
\end{itemize}

\uncover<7->{\alert<7>{The translator's work.}}
}
\end{itemize}

\uncover<8->{\alert<8>{Gettext = complete toolset for translating
    messages output by programs.}}

\end{frame}

\begin{frame}[fragile]
\frametitle{Translating Messages Made Easy}

\begin{block}{}
\begin{semiverbatim}
#include <config.h>
#include <stdio.h>
\uncover<2->{\alert<2>{#include "gettext.h"
#define _(string) \alert<3>{gettext} (string)}}
void say_hello (void)
\{
  puts (\only<all:2->{\alert<2>{_(}}"Hello World!"\only<all:2->{\alert<2>{)}});
  \only<all:1>{puts ("This is " PACKAGE_STRING ".");}\only<all:2->{printf (\alert<2>{_(}"This is %s.\\n"\alert<2>{)}, PACKAGE_STRING);}
\}
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<1-> The program is written in English.
\item<2-> Messages that must be translated are marked with
  \alert<2>{\texttt{\_(\ldots)}}.
    \begin{itemize}
    \item \command{xgettext} builds catalogs of translatable
      messages from such strings.
    \item Translators will provide translated catalogs for their locale.
    \end{itemize}
\item<3-> \alert<3>{\texttt{gettext}} looks up the translation of
  the English message in the current locale's catalog.
\end{itemize}
\end{frame}

\mysubsection{Internationalizing a Package, Start to Finish}

\begin{frame}
\frametitle{Internationalizing a Package, Start to Finish}

Roadmap:

%%% BEWARE: This enumeration is duplicated (by hand) later.
%%% ========================================================
\begin{enumerate}
\item Start with a non-internationalized Hello World.
\item Invoke \texttt{AM\_GNU\_GETTEXT} from \filename{configure.ac}
\item Run \command{gettextize} to provide the basic infrastructure.
\item Fill in the configuration files left by \command{gettextize}.
\item Update \filename{src/Makefile.am} to link \filename{hello} with
  the necessary library.
\item Update the code:
\begin{itemize}
\item Initialize Gettext in \texttt{main()}
\item Mark translatable strings.
\end{itemize}
\item Generate messages catalogs automatically.
\end{enumerate}

We'll talk about localization once this is done.

\end{frame}

\begin{frame}[fragile]
\frametitle{Non Internationalized Hello World (1/2)}

\begin{columns}
\column{.30\textwidth}
\begin{block}{\filenamew{src/main.c}}
\begin{semiverbatim}
#include "say.h"

int
main (void)
\{
  say_hello ();
  return 0;
\}
\end{semiverbatim}
\end{block}
\column{.65\textwidth}

\begin{block}{\filenamew{src/say.h}}
\begin{semiverbatim}
#ifndef AMHELLO_SAY_H
# define AMHELLO_SAY_H
void say_hello (void);
#endif
\end{semiverbatim}
\end{block}
\begin{block}{\filenamew{src/say.c}}
\begin{semiverbatim}
#include <config.h>
#include <stdio.h>

void say_hello (void)
\{
  puts ("Hello World!");
  puts ("This is " PACKAGE_STRING ".");
\}
\end{semiverbatim}
\end{block}
\end{columns}

\end{frame}

\begin{frame}[fragile]
\frametitle{Non Internationalized Hello World (2/2)}

\begin{block}{\filenamew{configure.ac}}
\begin{semiverbatim}
AC_INIT([amhello], [3.0], [bug-report@address])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT
\end{semiverbatim}
\end{block}

\begin{columns}
\column{.35\textwidth}
\begin{block}{\filenamew{Makefile.am}}
\begin{semiverbatim}
SUBDIRS = src
\end{semiverbatim}
\end{block}
\column{.60\textwidth}
\begin{block}{\filenamew{src/Makefile.am}}
\begin{semiverbatim}
bin_PROGRAMS = hello
hello_SOURCES = main.c say.c say.h
\end{semiverbatim}
\end{block}
\end{columns}

\end{frame}


\begin{frame}[fragile]
\frametitle{Update \filenamew{configure.ac} for Gettext}

\begin{block}{\filenamew{configure.ac}}
\begin{semiverbatim}
AC_INIT([amhello], [3.0], [bug-report@address])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
\alert<1-2>{AM_GNU_GETTEXT_VERSION([\gettextver])}
\alert<1,3>{AM_GNU_GETTEXT([external])}
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<2-> \texttt{AM\_GNU\_GETTEXT\_VERSION} = \emph{exactly} which
  Gettext version to use.
\item<3-> \texttt{AM\_GNU\_GETTEXT([external])}
  \begin{itemize}
  \item the GNU libc or an external (= not distributed) Gettext
    library will be used if found
  \item NLS (Native Language System) will be disabled otherwise
  \end{itemize}
\end{itemize}

\end{frame}

\begin{frame}[fragile]
\frametitle{Running \command{gettextize}}

You should run \command{gettextize}:
\begin{itemize}
\item A first time, to install the Gettext infrastructure in your package.
\item Each time you upgrade Gettext to a new version.
\end{itemize}

\begin{block}{}
\begin{semiverbatim}
~/amhello % \uncover<2->{\alert<2>{\textit{gettextize --copy --no-changelog}}
[...]
~/amhello % }\uncover<3->{\alert<3>{\textit{cp /usr/share/gettext/gettext.h src}}}
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<2-> Install most of the Gettext infrastructure.
\item<3-> Copy \filename{gettext.h} in the source tree, it will
  be distributed.
\end{itemize}

\end{frame}


\begin{frame}[fragile]
\frametitle{Gettextize Updated Some Files}

\begin{block}{\filenamew{configure.ac}}
\small
\begin{semiverbatim}
AC_INIT([amhello], [3.0], [bug-report@address])
AC_CONFIG_AUX_DIR([build-aux])
AM_GNU_GETTEXT_VERSION([\gettextver])
AM_GNU_GETTEXT([external])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile src/Makefile \alert<1>{po/Makefile.in}])
AC_OUTPUT
\end{semiverbatim}
\end{block}

\begin{columns}
\column{.38\textwidth}
\begin{block}{\filenamew{Makefile.am}}
\begin{semiverbatim}
SUBDIRS = \alert<1>{po} src
\alert<1>{ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = ...}
\end{semiverbatim}
\end{block}
\column{.57\textwidth}
\begin{block}{\filenamew{src/Makefile.am}}
\begin{semiverbatim}
bin_PROGRAMS = hello
hello_SOURCES = main.c say.c say.h
\end{semiverbatim}
\end{block}
\end{columns}

\end{frame}

\begin{frame}[fragile,t]
\frametitle{\filenamew{po/Makevars} and \filenamew{po/POTFILES.in}}

Fill \filename{po/Makevars.template} and rename it as \filename{po/Makevars}:

\begin{block}{\filenamew{po/Makevars}}
\begin{semiverbatim}
DOMAIN = \$(PACKAGE)
subdir = po
top_builddir = ..
XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
COPYRIGHT_HOLDER = \alert<1>{Your Name or Your Employer}
MSGID_BUGS_ADDRESS = \alert<2>{\$(PACKAGE\_BUGREPORT)}
EXTRA_LOCALE_CATEGORIES =
\end{semiverbatim}
\end{block}

\uncover<3>{
List sources files that (may) contain translatable strings in
\filenamew{POTFILES.in}.}

\begin{block}<3>{\filenamew{po/POTFILES.in}}
\begin{semiverbatim}
\alert{src/main.c
src/say.c}
\end{semiverbatim}
\end{block}

\vspace*{-19.5em}\hspace*{.5\textwidth}
\begin{minipage}{.46\textwidth}
\begin{block}<2>{}
\begin{center}
\alert{\texttt{\$(PACKAGE\_BUGREPORT)}} is the third argument of
\texttt{AC\_INIT}.  Some packages use a mailing list dedicated to
translation issues instead.
\end{center}
\end{block}
\end{minipage}

\end{frame}

\begin{frame}
\frametitle{What's Next?}

%%% BEWARE: This enumeration is a split copy of the one a few slides earlier.
%%% =========================================================================

\alert<1>{Done:}
\begin{enumerate}
\item Start with a non-internationalized Hello World.
\item Invoke \texttt{AM\_GNU\_GETTEXT} from \filename{configure.ac}
\item Run \command{gettextize} to provide the basic infrastructure.
\item Fill in the configuration files left by \command{gettextize}.
\end{enumerate}

Now, \command{autoreconf --install; ./configure; make} should work.

\bigskip

\uncover<2->{
\alert<2>{To do:}
\begin{enumerate}
\setcounter{enumi}{4}
\item Update \filename{src/Makefile.am} to link \filename{hello} with
  the necessary library.
\item Update the code:
\begin{itemize}
\item Initialize Gettext in \texttt{main()}
\item Mark translatable strings.
\end{itemize}
\item Generate messages catalogs automatically.
\end{enumerate}}
\end{frame}

\begin{frame}<handout:5>[fragile]
\frametitle{Updating \filenamew{src/Makefile.am}}

\begin{block}{src/Makefile.am}
\begin{semiverbatim}
\uncover<5->{\alert<5>{AM_CPPFLAGS = -DLOCALEDIR=\\"\$(localedir)\\"}}
bin_PROGRAMS = hello
hello_SOURCES = main.c say.c say.h \uncover<4->{\alert<4>{gettext.h}}
\uncover<2->{\only<all:-2>{hello_}LDADD = \alert<2>{\$(LIBINTL)}}
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<2-> \texttt{\$(LIBINTL)} lists the libraries any internationalized
  program should be linked against.
\item<3-> We can strip the leading \texttt{hello\_} and
  use the global \texttt{LDADD} instead.
\item<4-> Mention \filename{gettext.h} (we will use it shortly) so it
  is distributed.
\item<5-> \texttt{\$(LOCALEDIR)} is the place where message catalogs are
  installed.  \\
  This is needed during initialization.
\end{itemize}

\end{frame}

\begin{frame}[fragile]
  \frametitle{Initializing Gettext}

\begin{columns}
\column{.55\textwidth}
\begin{block}{\filenamew{src/main.c}}
\begin{semiverbatim}
\uncover<3->{\alert<3>{#include <config.h>}}
\uncover<2->{\alert<2>{#include <locale.h>}}
\uncover<3->{\alert<3>{#include "gettext.h"}}
#include "say.h"
int
main (void)
\{
\uncover<2->{\alert<2>{  setlocale (LC_ALL, "");}}
\uncover<3->{\alert<3>{  bindtextdomain (PACKAGE,
                  LOCALEDIR);
  textdomain (PACKAGE);}}
  say_hello();
  return 0;
\}
\end{semiverbatim}
\end{block}
\column{.4\textwidth}
\begin{itemize}
\item<2-> Initialize the locale as specified in the environment. \\
  (E.g., the user sets \texttt{LANG=fr\_FR} in the environment to get
  French messages.)
\item<3-> Tell Gettext where to find message catalogs for this program.\\
  (All programs in the same package usually share the same message
  catalog.)
\end{itemize}
\end{columns}
\end{frame}

\begin{frame}<handout:3>[fragile]
\frametitle{Marking Strings for Translation}

\begin{block}{\filenamew{src/say.c}}
\begin{semiverbatim}
#include <config.h>
#include <stdio.h>
\uncover<2->{\alert<2>{#include "gettext.h"
#define _(string) gettext (string)}}
void say_hello (void)
\{
  puts (\only<all:2->{\alert<2>{_(}}"Hello World!"\only<all:2->{\alert<2>{)}});
  \only<all:1>{puts ("This is " PACKAGE_STRING ".");}\only<all:2->{printf (\alert<2>{_(}"This is %s.\\n"\alert<2>{)}, PACKAGE_STRING);}
\}
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<2-> Messages that must be translated are marked with
  \alert<2>{\texttt{\_(\ldots)}}.
\item<3-> NLS (Native Language System) can be disabled.
  \begin{itemize}
  \item Explicitly with \command{./configure --disable-nls}
  \item Implicitly if no \texttt{gettext} implementation is installed.
  \end{itemize}
  \medskip
  Then \filename{gettext.h} defines \texttt{gettext()},
  \texttt{textdomain()}, \ldots, as no-ops.
\end{itemize}

\end{frame}

\begin{frame}[fragile]
  \frametitle{Building the Whole Shebang}

Our Hello World is now internationalized.

\begin{block}{}
\begin{semiverbatim}
~/amhello % \textit{autoreconf --install}
...
~/amhello % \textit{./configure}
...
~/amhello % \textit{make}
...
\uncover<2->{Making all in po
make amhello.pot-update
...}
\end{semiverbatim}
\end{block}

\uncover<2->{The \filename{po/} directory contains messages catalogs.\\
\filename{po/amhello.pot} is the template message catalog.

\medskip

Updating \filename{po/amhello.pot} is costly and occurs only before
releases (e.g., during \command{make distcheck}) or if the file did
not exist (our case above).

It can be updated explicitly with \command{cd po; make update-po}.}
\end{frame}

\mysubsection{Localizing a Package}

\begin{frame}<1-2| handout:4>[fragile,label=amhello.pot]
\frametitle{\filenamew{po/amhello.pot}: The PO Template File}
\begin{block}{}
\scriptsize
\begin{semiverbatim}
# ... COMMENTS ...
\alert<all:3>{#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\\n"
"Report-Msgid-Bugs-To: bug-report@address\\n"
"POT-Creation-Date: 2005-03-05 00:27+0100\\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
"Language-Team: LANGUAGE <LL@li.org>\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=CHARSET\\n"
"Content-Transfer-Encoding: 8bit\\n"}

\alert<all:2>{#: src/say.c:9
msgid "Hello World!"
msgstr ""

#: src/say.c:10
#, c-format
msgid "This is %s.\\n"
msgstr ""}\only<4>{}
\end{semiverbatim}
\end{block}
\end{frame}

\begin{frame}<1-5| handout:6>[fragile]
\frametitle{\filenamew{po/amhello.pot}: List of Messages}
\begin{block}{}
\begin{semiverbatim}
\alert<all:4>{#: src/say.c:9}
\alert<all:2>{msgid "Hello World!"}
\alert<all:3>{msgstr ""}

\alert<all:4>{#: src/say.c:10}
\alert<all:5>{#, c-format}
\alert<all:2>{msgid "This is %s.\\n"}
\alert<all:3>{msgstr ""}\only<6>{}
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<2-> \texttt{msgid}s identify all strings in the package
\item<3-> empty \texttt{msgstr}s are placeholders for translations
\item<4-> the location of each string is shown, \\
  so the translator can check the context if needed
\item<5-> additional flags can be used
\end{itemize}

\end{frame}

\againframe<2-3| handout:0>{amhello.pot}

\begin{frame}[fragile]
\frametitle{\filenamew{po/amhello.pot}: The Header Entry}
\begin{block}{}
\begin{semiverbatim}
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\\n"
"Report-Msgid-Bugs-To: bug-report@address\\n"
"POT-Creation-Date: 2005-03-05 00:27+0100\\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
"Language-Team: LANGUAGE <LL@li.org>\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=CHARSET\\n"
"Content-Transfer-Encoding: 8bit\\n"
\end{semiverbatim}
\end{block}

The translation of the empty string is a special entry that will
be filled with administrative information.
\end{frame}

\begin{frame}[fragile]
\frametitle{How to Add a New Language?}

\begin{enumerate}
\item Initialize \filename{po/}\variable{LL}\filename{.po} or \filename{po/}\variable{LL}\filename{_}\variable{CC}\filename{.po} from \filename{po/amhello.pot},
  using \command{msginit}.\\
  \variable{LL} is your language code, and \variable{CC} is your country code
  \begin{description}[pt\_BR]
  \item[pt] is Portuguese
  \item[pt\_BR] is Brazilian Portuguese
  \end{description}
  (The annexes of the Gettext manual show lists of \variable{LL}s and
  \variable{CC}s.)
\item Fill in \filename{po/}\variable{LL}\filename{.po} (or \filename{po/}\variable{LL}\filename{_}\variable{CC}\filename{.po})
\item List the new translation in \filename{po/LINGUAS}
\end{enumerate}

\bigskip

\uncover<2->{Let's add a French translation for \texttt{amhello}.}

\end{frame}

\begin{frame}[fragile]
\frametitle{Preparing \filenamew{po/fr.po}}

% Do not put the & below in \textit.  Bruno said not everybody
% would recognize the character.
\begin{block}{}
\begin{semiverbatim}
~/amhello % \textit{cd po}
~/amhello/po % \textit{msginit -l fr}
...
~/amhello/po % \textit{emacs fr.po} &
\end{semiverbatim}
\end{block}

\uncover<2->{
The \texttt{PO} mode of \command{emacs} (\key{M-x} \texttt{po-mode}):

\begin{itemize}
\item The buffer is modified only indirectly.
\item \key{Enter} on a message will open a buffer to edit the translation.
\item Use \key{C-c}\key{C-c} after you have completed the translation,
  to get back to the updated \filename{amhello.pot} buffer.
\item Once all strings are translated, use \key{V} to save and check
  the file.
\item Use \key{Tab} to remove \texttt{fuzzy} attributes.
\end{itemize}}

\end{frame}

\begin{frame}<handout:2>[fragile]
\frametitle{\filenamew{po/fr.po}: Message Translations}
\begin{block}{}
\begin{semiverbatim}
#: src/say.c:9
msgid "Hello World!"
\alert<2>{msgstr "\only<all:2->{Bonjour Monde !}"}

#: src/say.c:10
#, c-format
msgid "This is %s.\\n"
\alert<2>{msgstr "\only<all:2->{Ceci est %s.\\n}"}
\end{semiverbatim}
\end{block}
\end{frame}

\begin{frame}<handout:3>[fragile]
\frametitle{\filenamew{po/fr.po}: Header}
\begin{block}{}
\begin{semiverbatim}
msgid ""
msgstr ""
"Project-Id-Version: \alert<1>{amhello 3.0}\\n"
"Report-Msgid-Bugs-To: bug-report@address\\n"
"POT-Creation-Date: 2005-03-05 00:27+0100\\n"
"PO-Revision-Date: \alert<1,4>{2005-03-15 20:54+0100}\\n"
"Last-Translator: \alert<1>{Alexandre Duret-Lutz <adl@gnu.org>}\\n"
"Language-Team: \alert<1>{French}\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=\only<all:-2>{\alert<1>{ASCII}}\only<all:3->{\alert<3>{iso-8859-1}}\\n"
"Content-Transfer-Encoding: 8bit\\n"
"\alert<1>{Plural-Forms: nplurals=2; plural=(n > 1);\\n}"
\end{semiverbatim}
\end{block}

\begin{itemize}
\item<1-> \command{msginit} filled these fields.
\item<3-> You may have to customize it a bit.
\item<4-> The revision date will also be updated on save.
\end{itemize}

\end{frame}

\begin{frame}[fragile]
\frametitle{\filenamew{po/fr.po}: Validation and Addition}

Once \filename{po/fr.po} is completed, hit \key{V}.
This will:

\begin{enumerate}
\item Update the revision date
\item Save the file
\item Run \command{msgfmt --statistics --check} on
  \filename{po/fr.po}, to validate it.
\end{enumerate}

\bigskip

\uncover<2->{We can now register the language.}

\begin{block}<2->{}
\begin{semiverbatim}
~/amhello/po % \alert{\textit{echo fr >> LINGUAS}}
\end{semiverbatim}
\end{block}

\end{frame}

\begin{frame}[fragile,t]
\frametitle{\texttt{hello} now Speaks French!}

\begin{block}{}
\begin{semiverbatim}
~/amhello % \uncover<1->{\alert<1>{\textit{./configure --prefix ~/test}}
~/amhello % }\uncover<2->{\alert<2>{\textit{make}}
~/amhello % }\uncover<3->{\alert<3>{\textit{cd po}}
~/amhello/po % }\uncover<4->{\alert<4>{\textit{make update-po}}
~/amhello/po % }\uncover<5->{\alert<5>{\textit{cd ..}}
~/amhello % }\uncover<6->{\alert<6>{\textit{make install}}
~/amhello % }\uncover<7->{\alert<7>{\textit{~/test/bin/hello}}
Hello World!
This is amhello 3.0.
~/amhello % }\uncover<8->{\alert<8>{\textit{LANG=fr_FR ~/test/bin/hello}}
Bonjour Monde !
Ceci est amhello 3.0.}
\end{semiverbatim}
\end{block}

\vspace*{-13em}\hspace*{.51\textwidth}
\begin{minipage}{.46\textwidth}
\begin{block}<4>{\texttt{update-po}}
\begin{center}
This step is needed because we just created \filename{fr.po}, and it
has to be compiled.  This happens automatically during \command{make
  dist}.
\end{center}
\end{block}
\end{minipage}

\end{frame}

\begin{frame}
  \frametitle{Updating Message Catalogs}

Because maintainers can change the strings marked for translation, the
messages catalogs are varying, and are not always up-to-date.

\begin{description}[xxx]
\item<2->[Varying messages.]
  \texttt{update-po} modify \filename{*.po} file:
  \begin{itemize}
  \item New messages are added with a blank translation.
  \item Obsolete translations, not used anymore, are commented.
  \item Messages with tiny changes keep their translation, but are marked
    \texttt{fuzzy}. \\ Translators remove \texttt{fuzzy} attributes
    (\key{Tab}) after verification.
  \end{itemize}
\item<3->[Not up-to-date.] \texttt{gettext} copes with incomplete translations
  as follows.
  \begin{itemize}
  \item Untranslated messages are output untranslated.
  \item Fuzzy messages are also output untranslated. (Better output the
    original sentence, rather than an inappropriate translation.)
  \end{itemize}
\end{description}

\medskip

\uncover<4->{\textbf{Good practice: the string freeze.} Two weeks
  before a release, run \command{make update-po} and send the
  \filename{*.pot} file to translators.  Don't change or add strings
  from this point on.  Let translators send you updated
  \filename{*.po} files.}
\end{frame}

\begin{frame}
\frametitle{Language Teams \& The Translation Project}

\begin{center}
\url{http://www.iro.umontreal.ca/translation/}
\end{center}

The Translation Project provides an infrastructure for package
maintainers and translators to exchange messages catalogs.

\begin{itemize}[<2->]
\item
Translators gather in \emph{Language Teams} (consider joining the team
of your own language) to discuss issues.

\item
Maintainer submit \emph{*.pot} files and are notified when \emph{*.po}
files are updated.

\item
Pages in The Translation Project will show where work is needed
(consider adopting an orphan \emph{*.po} file.)
\end{itemize}

\uncover<3->{
This is only one way of getting a project translated.  A lot of
packages have dedicated translators and deal with them directly.}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\mysection{Nested Packages}

\againframe<3>{nested-packages}

\begin{frame}[fragile]
\frametitle{Setting Up Nested Packages}

\begin{itemize}
\item<1-> A sub-package should appear as an ordinary directory.
\item<2-> In \filename{Makefile.am}, this directory must appear in
  \variable{SUBDIRS} so \command{make} recurses into it.
\item<3-> \filename{configure.ac} should also declare this directory
\begin{block}{}
\begin{semiverbatim}
AC_CONFIG_SUBDIRS([subdir])
\end{semiverbatim}
\end{block}
  so \command{configure} calls \filename{subdir/configure}
  recursively.
\end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{Nested Packages Example}

The \filename{arm} program links with an \filename{hand} library, a
nested package in \filename{hand/}.

\begin{columns}
\column{0.66\textwidth}
\begin{block}{\filenamew{arm}'s \filenamew{configure.ac}}
\begin{semiverbatim}
AC_INIT([arm], [1.0])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_FILES([Makefile src/Makefile])
\alert{AC_CONFIG_SUBDIRS([hand])}
AC_OUTPUT
\end{semiverbatim}
\end{block}
\column{0.31\textwidth}
\begin{block}{\filenamew{arm}'s \filenamew{Makefile.am}}
\begin{semiverbatim}
SUBDIRS = \alert{hand} src
\end{semiverbatim}
\end{block}
\end{columns}

\begin{block}{\filenamew{arm}'s \filenamew{src/Makefile.am}}
\begin{semiverbatim}
AM_CPPFLAGS = -I\$(top_srcdir)/hand
bin_PROGRAMS = arm
arm_SOURCES = arm.c
arm_LDADD = ../hand/libhand.a
\end{semiverbatim}
\end{block}
\end{frame}

\mysection{The End}

\begin{frame}
\frametitle{Where to go Now?}

\begin{itemize}
\item<1-> Locate the reference manuals in your preferred format.
\begin{itemize}
\item Autoconf, Automake, Libtool, and Gettext all install
  reference manuals in the Info format.
  (Try \command{info Autoconf}, \command{info Automake}, etc.)
\item The web pages of these tools also have \filename{.html} or
  \filename{.pdf} versions.
\item These manuals may not be easy introductions to the tools, but
  they make good and up-to-date references.
\end{itemize}
\item<2-> Subscribe to these tools' mailing lists, to see other
  people's uses of the tools.
\item<3-> Pick a package that uses these tools and dissect its setup.
\begin{itemize}
\item Try picking something written by somebody who isn't just another
  neophyte!
\item I recommend looking at \emph{GNU Coreutils}.
\end{itemize}
\end{itemize}
\end{frame}

\end{document}

% LocalWords:  Duret Lutz ShareAlike Autotools strtod strchr int setpgrp malloc
% LocalWords:  libm libc ffcall alloc pagesize MMAP DEVZERO fd endif VM vm len
% LocalWords:  getpagesize RDONLY fprintf stderr FSEEKO fseeko fseek errno src
% LocalWords:  EOVERFLOW strdup const strlen memcpy dgfile config bfile pt zxf
% LocalWords:  cd amhello su installcheck uninstall distclean dist dirs bindir
% LocalWords:  libdir includedir datadir mandir infodir usr CXXFLAGS CC CFLAGS
% LocalWords:  CXX LDFLAGS CPPFLAGS gcc sharedir mkdir sudo mingw msvc exe PE
% LocalWords:  sed DESTDIR inst zcvf distcheck autoreconf tfile ac afile INIT
% LocalWords:  AUTOMAKE Werror PROG SUBDIRS depcomp aclocal autom te ztf PROGS
% LocalWords:  gtar cf semiverbatim EFENCELIB checklib tarball ChangeLog foo
% LocalWords:  automake iff VPATH
