<p>I found a great article on this topic here: <a href="" target="_blank">https://opensource.com/article/19/7/introduction-gnu-autotools</a>, so please refer to that as show notes.</p>
<p>
<small>
Page included by Ken, as permitted by cc-by-sa
</small>
</p>
<h1>Introduction to GNU Autotools</h1>

<p id="introduction-to-gnu-autotools">Have you ever downloaded the source code for a popular software project that required you to type the almost ritualistic <strong>./configure; make &amp;&amp; make install</strong> command sequence to build and install it? If so, you’ve used <a href="https://www.gnu.org/software/automake/faq/autotools-faq.html" target="_blank">GNU Autotools</a>. If you’ve ever looked into some of the files accompanying such a project, you’ve likely also been terrified at the apparent complexity of such a build system.</p>

<p>Good news! GNU Autotools is a lot simpler to set up than you think, and it’s GNU Autotools itself that generates those 1,000-line configuration files for you. Yes, you can write 20 or 30 lines of installation code and get the other 4,000 for free.</p>

<h2 id="autotools-at-work">Autotools at work</h2>

<p>If you’re a user new to Linux looking for information on how to install applications, you do not have to read this article! You’re welcome to read it if you want to research how software is built, but if you’re just installing a new application, go read my article about <a href="https://opensource.com/article/18/1/how-install-apps-linux">installing apps on Linux</a>.</p>

<p>For developers, Autotools is a quick and easy way to manage and package source code so users can compile and install software. Autotools is also well-supported by major packaging formats, like DEB and RPM, so maintainers of software repositories can easily prepare a project built with Autotools.</p>

<p>Autotools works in stages:</p>

<ol>
<li>First, during the <strong>./configure</strong> step, Autotools scans the host system (the computer it’s being run on) to discover the default settings. Default settings include where support libraries are located, and where new software should be placed on the system.</li>
<li>Next, during the <strong>make</strong> step, Autotools builds the application, usually by converting human-readable source code into machine language.</li>
<li>Finally, during the <strong>make install</strong> step, Autotools copies the files&nbsp;it built to the appropriate locations (as detected during the configure stage) on your computer.</li>
</ol><p>This process seems simple, and it is, as long as you use Autotools.</p>

<h2 id="the-autotools-advantage">The Autotools advantage</h2>

<p>GNU Autotools is a big and important piece of software that most of us take for granted. Along with <a href="https://en.wikipedia.org/wiki/GNU_Compiler_Collection" target="_blank">GCC (the GNU Compiler Collection)</a>, Autotools is the scaffolding that allows Free Software to be constructed and installed to a running system. If you’re running a <a href="https://en.wikipedia.org/wiki/POSIX" target="_blank">POSIX</a> system, it’s not an understatement to say that most of your operating system exists as runnable software on your computer because of these projects.</p>

<p>In the likely event that your pet project isn’t an operating system, you might assume that Autotools is overkill for your needs. But, despite its reputation, Autotools has lots of little features that may benefit you, even if your project is a relatively simple application or series of scripts.</p>

<h3 id="portability">Portability</h3>

<p>First of all, Autotools comes with portability in mind. While it can’t make your project work across all POSIX platforms (that’s up to you, as the coder), Autotools can ensure that the files you’ve marked for installation get installed to the most sensible locations on a known platform. And because of Autotools, it’s trivial for a power user to customize and override any non-optimal value, according to their own system.</p>

<p>With Autotools, all you need to know is what files need to be installed to what general location. It takes care of everything else. No more custom install scripts that break on any untested OS.</p>

<h3 id="packaging">Packaging</h3>

<p>Autotools is also well-supported. Hand a project with Autotools over to a distro packager, whether they’re packaging an RPM, DEB, TGZ, or anything else, and their job is simple. Packaging tools know Autotools, so there’s likely to be no patching, hacking, or adjustments necessary. In many cases, incorporating an Autotools project into a pipeline can even be automated.</p>

<h2 id="how-to-use-autotools">How to use Autotools</h2>

<p>To use Autotools, you must first have Autotools installed. Your distribution may provide one package meant to help developers build projects, or it may provide separate packages for each component, so you may have to do some research on your platform to discover what packages you need to install.</p>

<p>The primary components of Autotools are:</p>

<ul>
<li><strong>automake</strong></li>
<li><strong>autoconf</strong></li>
<li><strong>make</strong></li>
</ul>

<p>While you likely need to install the compiler (GCC, for instance) required by your project, Autotools works just fine with scripts or binary assets that don’t need to be compiled. In fact, Autotools can be useful for such projects because it provides a <strong>make uninstall</strong> script for easy removal.</p>

<p>Once you have all of the components installed, it’s time to look at the structure of your project’s files.</p>

<h3 id="autotools-project-structure">Autotools project structure</h3>

<p>GNU Autotools has very specific expectations, and most of them are probably familiar if you download and build source code often. First, the source code itself is expected to be in a subdirectory called <strong>src</strong>.</p>

<p>Your project doesn’t have to follow all of these expectations, but if you put files in non-standard locations (from the perspective of Autotools), then you’ll have to make adjustments for that in your Makefile later.</p>

<p>Additionally, these files are required:</p>

<ul>
<li><strong>NEWS</strong></li>
<li><strong>README</strong></li>
<li><strong>AUTHORS</strong></li>
<li><strong>ChangeLog</strong></li>
</ul>

<p>You don’t have to actively use the files, and they can be symlinks to a monolithic document (like <strong>README.md</strong>) that encompasses all of that information, but they must be present.</p>

<h3 id="autotools-configuration">Autotools configuration</h3>

<p>Create a file called <strong>configure.ac</strong> at your project’s root directory. This file is used by <strong>autoconf</strong> to create the <strong>configure</strong> shell script that users run before building. The file must contain, at the very least, the <strong>AC_INIT</strong> and <strong>AC_OUTPUT</strong> <a href="https://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Initializing-configure.html" target="_blank">M4 macros</a>. You don’t need to know anything about the M4 language to use these macros; they’re already written for you, and all of the ones relevant to Autotools are defined in the documentation.</p>

<p>Open the file in your favorite text editor. The <strong>AC_INIT</strong> macro may consist of the package name, version, an email address for bug reports, the project URL, and optionally the name of the source TAR file.</p>

<p>The <strong><a href="https://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Output.html#Output" target="_blank">AC_OUTPUT</a></strong> macro is much simpler and accepts no arguments.</p>

<pre>AC_INIT([penguin], [2019.3.6], [seth@example.com])<br>
AC_OUTPUT</pre>

<p>If you were to run <strong>autoconf</strong> at this point, a <strong>configure</strong> script would be generated from your <strong>configure.ac</strong> file, and it would run successfully. That’s all it would do, though, because all you have done so far is define your project’s metadata and called for a configuration script to be created.</p>

<p>The next macros you must invoke in your <strong>configure.ac</strong> file are functions to create a <a href="https://www.gnu.org/software/make/manual/html_node/Introduction.html" target="_blank">Makefile</a>. A Makefile tells the <strong>make</strong> command what to do (usually, how to compile and link a program).</p>

<p>The macros to create a Makefile are <strong>AM_INIT_AUTOMAKE</strong>, which accepts no arguments, and <strong>AC_CONFIG_FILES</strong>, which accepts the name you want to call your output file.</p>

<p>Finally, you must add a macro to account for the compiler your project needs. The macro you use obviously depends on your project. If your project is written in C++, the appropriate macro is <strong>AC_PROG_CXX</strong>, while a project written in C requires <strong>AC_PROG_CC</strong>, and so on, as detailed in the <a href="https://www.gnu.org/software/automake/manual/html_node/Programs.html#Programs" target="_blank">Building Programs and Libraries</a> section in the Autoconf documentation.</p>

<p>For example, I might add the following for my C++ program:</p>

<pre>AC_INIT([penguin], [2019.3.6], [seth@example.com])<br>
AC_OUTPUT<br>
AM_INIT_AUTOMAKE<br>
AC_CONFIG_FILES([Makefile])<br>
AC_PROG_CXX</pre>

<p>Save the file. It’s time to move on to the Makefile.</p>

<h3 id="autotools-makefile-generation">Autotools Makefile generation</h3>

<p>Makefiles aren’t difficult to <a href="https://opensource.com/article/18/8/what-how-makefile" target="_blank">write manually</a>, but Autotools can write one for you, and the one it generates will use the configuration options detected during the <code>./configure</code> step, and it will contain far more options than you would think to include or want to write yourself. However, Autotools can’t detect everything your project requires to build, so you have to add some details in the file <strong>Makefile.am</strong>, which in turn is used by <strong>automake</strong> when constructing a Makefile.</p>

<p><strong>Makefile.am</strong> uses the same syntax as a Makefile, so if you’ve ever written a Makefile from scratch, then this process will be familiar and simple. Often, a <strong>Makefile.am</strong> file needs only a few variable definitions to indicate what files are to be built, and where they are to be installed.</p>

<p>Variables ending in <strong>_PROGRAMS</strong> identify code that is to be built (this is usually considered the <em>primary</em> target; it’s the main reason the Makefile exists). Automake recognizes other primaries, like <strong>_SCRIPTS</strong>, <strong>_DATA</strong>, <strong>_LIBRARIES</strong>, and other common parts that make up a software project.</p>

<p>If your application is literally compiled during the build process, then you identify it as a binary program with the <strong>bin_PROGRAMS</strong> variable, and then reference any part of the source code required to build it (these parts may be one or more files to be compiled and linked together) using the program name as the variable prefix:</p>

<pre>bin_PROGRAMS = penguin<br>
penguin_SOURCES = penguin.cpp</pre>

<p>The target of <strong>bin_PROGRAMS</strong> is installed into the <strong>bindir</strong>, which is user-configurable during compilation.</p>

<p>If your application isn’t actually compiled, then your project doesn’t need a <strong>bin_PROGRAMS</strong> variable at all. For instance, if your project is a script written in Bash, Perl, or a similar interpreted language, then define a <strong>_SCRIPTS</strong> variable instead:</p>

<pre>bin_SCRIPTS = bin/penguin</pre>

<p>Automake expects sources to be located in a directory called <strong>src</strong>, so if your project uses an alternative directory structure for its layout, you must tell Automake to accept code from outside sources:</p>

<pre>AUTOMAKE_OPTIONS = foreign subdir-objects</pre>

<p>Finally, you can create any custom Makefile rules in <strong>Makefile.am</strong> and they’ll be copied verbatim into the generated Makefile. For instance, if you know that a temporary value needs to be replaced in your source code before the installation proceeds, you could make a custom rule for that process:</p>

<pre>all-am: penguin<br>
&nbsp; &nbsp; &nbsp; &nbsp; touch bin/penguin.sh<br>
&nbsp; &nbsp; &nbsp; &nbsp; <br>
penguin: bin/penguin.sh<br>
&nbsp; &nbsp; &nbsp; &nbsp; @sed "s|__datadir__|@datadir@|" $&lt; &gt;bin/$@</pre>

<p>A particularly useful trick is to extend the existing <strong>clean</strong> target, at least during development. The <strong>make clean</strong> command generally removes all generated build files with the exception of the Automake infrastructure. It’s designed this way because most users rarely want <strong>make clean</strong> to obliterate the files that make it easy to build their code.</p>

<p>However, during development, you might want a method to reliably return your project to a state relatively unaffected by Autotools. In that case, you may want to add this:</p>

<pre>clean-local:<br>
&nbsp; &nbsp; &nbsp; &nbsp; @rm config.status configure config.log<br>
&nbsp; &nbsp; &nbsp; &nbsp; @rm Makefile <br>
&nbsp; &nbsp; &nbsp; &nbsp; @rm -r autom4te.cache/<br>
&nbsp; &nbsp; &nbsp; &nbsp; @rm aclocal.m4 <br>
&nbsp; &nbsp; &nbsp; &nbsp; @rm compile install-sh missing Makefile.in</pre>

<p>There’s a lot of flexibility here, and if you’re not already familiar with Makefiles, it can be difficult to know what your <strong>Makefile.am</strong> needs. The barest necessity is a primary target, whether that’s a binary program or a script, and an indication of where the source code is located (whether that’s through a <strong>_SOURCES</strong> variable or by using <strong>AUTOMAKE_OPTIONS</strong> to tell Automake where to look for source code).</p>

<p>Once you have those variables and settings defined, you can try generating your build scripts as you see in the next section, and adjust for anything that’s missing.</p>

<h3 id="autotools-build-script-generation">Autotools build script generation</h3>

<p>You’ve built the infrastructure, now it’s time to let Autotools do what it does best: automate your project tooling. The way the developer (you) interfaces with Autotools is different from how users building your code do.</p>

<p>Builders generally use this well-known sequence:</p>

<pre>$ ./configure<br>
$ make<br>
$ sudo make install</pre>

<p>For that incantation to work, though, you as the developer must bootstrap the build infrastructure. First, run <strong>autoreconf</strong> to generate the configure script that users invoke before running <strong>make</strong>. Use the <strong>–install</strong> option to bring in auxiliary files, such as a symlink to <strong>depcomp</strong>, a script to generate dependencies during the compiling process, and a copy of the <strong>compile</strong> script, a wrapper for compilers to account for syntax variance, and so on.</p>

<pre>$ autoreconf --install<br>
configure.ac:3: installing './compile'<br>
configure.ac:2: installing './install-sh'<br>
configure.ac:2: installing './missing'</pre>

<p>With this development build environment, you can then create a package for source code distribution:</p>

<pre>$ make dist</pre>

<p>The <strong>dist</strong> target is a rule you get for "free"&nbsp;from Autotools.<br>
It’s a feature that gets built into the Makefile generated from your humble <strong>Makefile.am</strong> configuration. This target produces a <strong>tar.gz</strong> archive containing all of your source code and all of the essential Autotools infrastructure so that people downloading the package can build the project.</p>

<p>At this point, you should review the contents of the archive carefully to ensure that it contains everything you intend to ship to your users. You should also, of course, try building from it yourself:</p>

<pre>$ tar --extract --file penguin-0.0.1.tar.gz<br>
$ cd penguin-0.0.1<br>
$ ./configure <br>
$ make <br>
$ DESTDIR=/tmp/penguin-test-build make install</pre>

<p>If your build is successful, you find a local copy of your compiled application specified by <strong>DESTDIR</strong> (in the case of this example, <strong>/tmp/penguin-test-build</strong>).</p>

<pre>$ /tmp/example-test-build/usr/local/bin/example <br>
hello world from GNU Autotools</pre>

<h2 id="time-to-use-autotools">Time to use Autotools</h2>

<p>Autotools is a great collection of scripts for a predictable and automated release process. This toolset may be new to you if you’re used to Python or Bash builders, but it’s likely worth learning for the structure and adaptability it provides to your project.</p>

<p>And Autotools is not just for code, either. Autotools can be used to build <a href="https://opensource.com/article/17/9/docbook">Docbook</a> projects, to keep media organized (I use Autotools for my music releases), documentation projects, and anything else that could benefit from customizable install targets.</p>
