# Autotools Basics

This page gives a general introduction to the autotools, in the specific context of using them in COIN-OR.
If you want to use them, first make sure that you are [using the correct version of the autotools](./autotools).

## `autoconf`

The goal of `autoconf` is to provide developers of open source software with an **easy way to ensure the portability** of their code.
`Autoconf` knows how to **perform tests to find out platform and compiler dependent properties**, for example, the presence of particular program, library, or header files.

Anyone who has downloaded and installed a GNU package has seen the configure step in the installation process ("`... type ./configure ...`").
`Autoconf` is the software that generates the rather complicated shell script, `configure`, from a simple input file, `configure.ac`.
The `configure` script is a shell script for `sh`, the basic shell that is available on every UNIX-like system (including Linux, macOS, and MSys).
So that it will work on every system known to the autotools developers, it assumes only the least common denominator over all `sh` implementations.
`configure` scripts can be very long --- it takes a lot of simple shell commands to accomplish complicated tests.

`Autoconf` uses the macro processor `m4` to generate the `configure` script from the `configure.ac` file.
In `configure.ac` you specify `autoconf` macros, some of which take arguments.
In a sense these macros can be understood as subroutines, but it's a bit more subtle than that.
**Keep firmly in mind that macros in `configure.ac` are expanded when the autotools are run, in the project manager's development environment, to create the `configure` shell script.
The shell commands in the `configure` script are run by the user, in their environment, to adapt the source code and build process to the user's environment.**
An easy and frustrating conceptual mistake, when using the autotools, is to expect shell code to execute during macro expansion.

### Template Files

When run by the user, the `configure` script will **generate output files based on templates for these files**.
A template file typically has the extension `.in`.
Template files contain strings (**`autoconf` output variable** names) surrounded by ``@``.
For example, `Makefile` is generated from `Makefile.in`.
The `autoconf` variable for the name of the C compiler is `CC`, and in `Makefile.in` you will find a line like
```
CC = @CC@
```
The generated `Makefile` will then contain this line, with ``@CC@`` replaced by the name of the C compiler (`cc`, `gcc`, `xlc`, _etc_.) appropriate for the build environment, as determined by the `configure` script.

You **don't have to create most template files**; they are generated by the various autotools.
For example, `automake` automatically generates `Makefile.in` from `Makefile.am` and `configure.ac`.

Another template file found in many COIN-OR projects are the pkg-config configuration files _prjct_`.pc.in`, used to generate _prjct_`.pc`.
The generated file includes information on dependencies of the project and which compiler and linker flags are required to link against the project.
For example, the OSI project uses the template file `osi.pc.in`; it contains the lines
```
@COIN_RELOCATABLE_FALSE@prefix=@prefix@
@COIN_RELOCATABLE_TRUE@prefix=${pcfiledir}/../..
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@/coin-or

Name: @PACKAGE_NAME@
Description: COIN-OR Open Solver Interface
URL: @PACKAGE_URL@
Version: @PACKAGE_VERSION@
Cflags: -I${includedir}
@COIN_STATIC_BUILD_FALSE@Libs: -L${libdir} -lOsi
@COIN_STATIC_BUILD_FALSE@Requires.private: @OSILIB_PCFILES@
@COIN_STATIC_BUILD_TRUE@Libs: -L${libdir} -lOsi @OSILIB_LFLAGS_NOPC@
@COIN_STATIC_BUILD_TRUE@Requires: @OSILIB_PCFILES@
```
As can be seen, this file makes heavy use `autoconf` output variables like `@COIN_RELOCATABLE_FALSE@`, `@prefix@`, `@OSILIB_PCFILES@`, or `@PACKAGE_URL@`.

When the user requests that OSI is configured, the resulting `osi.pc` file contains
```
prefix=/usr/local
#prefix=${pcfiledir}/../..
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include/coin-or

Name: Osi
Description: COIN-OR Open Solver Interface
URL: https://github.com/coin-or/Osi
Version: trunk
Cflags: -I${includedir}
Libs: -L${libdir} -lOsi
Requires.private: coinutils
#Libs: -L${libdir} -lOsi
#Requires: coinutils
```
As can be seen, all variables were replaced by a value.
`COIN_RELOCATABLE` was declared as an "automake conditional" (see also [the introduction of Automake](./automake-intro)), which resulted in two
`autoconf` output variables (`COIN_RELOCATABLE_FALSE` and `COIN_RELOCATABLE_TRUE`), one of them obtaining value `#` and the other an empty string.


### Configuration Header Files

Some output files generated by the `configure` script are worth separate mention.
The configuration header file (you may have noticed the `config.h` file in GNU packages) can be used to **convey information about the configuration run to the source code** of the package.
Some examples:
  * System calls, such as those for obtaining the CPU time, are different on different platforms, and the header files in which they are declared are also different.
    The `configure` script can **test for the presence of header files and functions**.

  * The `configure` script can **test for the presence of libraries and functions in libraries**.
    In the `CoinUtils` package, `configure` checks whether the compression libraries `libz` and `libbz2` are available.

  * The **user of a package can specify certain aspects of the configuration when `configure` is run**, for example, the set of available linear programming solvers, and where their libraries and header files reside.

  * The `AC_INIT` macro in the `configure.ac` file leads information about the package name and package version number in the header file, so these parameters to be maintained only in the `configure.ac` file.

The `configure` script will place `#define` statements in the configuration header files.
These can simply define a symbol or set a symbols to a specific value (such as the path to a default directory).
However, since the `define` statements in different projects may define the same symbols (e.g., `PACKAGE_NAME` or `HAVE_ZLIB`), it is undesirable to install the config header files and requiring them for building against the package.
On the other hand, sometimes it is necessary to convey some information about a package configuration via the header file to users of that package.
Information on how this is handled within COIN-OR projects is given on [this page](./config-header).


## `automake`

Automake **generates `Makefile.in` template files for `autoconf`**.
The generated makefiles are very powerful; for example, they support automatic header file dependency tracking, if this information can be somehow obtained from the compiler.
The makefiles work with any UNIX `make`, they have targets like `all`, `install`, `uninstall`, `clean`.

`Makefiles` generated by `automake` can **work recursively** and support parallel execution (_e.g._, with the `-j` flag of GNU `make`).
Also, it is possible to specify conditional content in the `Makefile`, the activation of which depends on the output of a test performed by the `configure` script.
This facility is limited, but it's portable (again, think 'least common denominator' over all known implementations of `make`).

As a user of `automake`, **you write an input file, called `Makefile.am`**, for each `Makefile.in` you want to create.
In `Makefile.am` you tell `automake` what you want to build (a program, a library, _etc._), and what source code files are required to build this target.
`Automake` will take it from there.
There are ways to specify more information, _e.g._, if additional libraries are required for linking.

For more introduction on automake, see also [here](./automake-intro).

## `libtool`

`Libtool` **helps to build static and shared libraries on different platforms**.
It works together with `autoconf` and `automake`, so that **you usually don't need to interact with it directly**.
Still, a bit of background information will help you understand its role.

Like `configure`, `libtool` is a shell script.
It's generated when `configure` is run in the user's environment and contains the correct commands to compile code, create libraries, and link programs.
`Automake` assumes that it will work through `libtool`.
In the output produced during compilation and linking, you  first see the `libtool` command line, then the command executed from the `libtool` script.

`Libtool` **generates auxiliary files**: **.lo** files correspond to object files, and **.la** files correspond to libraries.
These files are instructions (in plain ascii) that `libtool` leaves for itself for later use.
The compiled object files and fully or partially linked libraries are **hidden in a `.libs` subdirectory**.
(The command `make install` will move the hidden programs and libraries to the installation directory.)
