GNU Autotools Ultimate Tutorial for Beginners

I decided to document a modern and very simplistic test that I created with GNU Autotools.


GNU Autotools Ultimate Tutorial for Beginners

Although there are some other alternatives to GNU’s automatic tools, GNU Autotools is still the most widely used in the world for reasons of confidence in the end results. That is, experience has led to this stability.

Unfortunately, there is a lot of obsolete documentation on the internet about Autotools and a lot of complaints about automated tools, so I decided to document a modern and very simplistic test that I created and I will share with you this experience that I made sure to make it as basic as possible. in order to reach understanding.

But still, be sure to display examples that work in larger projects, which by the way the idea is the same, just need a little more attention in the settings.

This article will be summarized in:

All topics have been separated with Step by Step and Lists sorted for ease of understanding.

1. Introduction

2. Environment Preparation

3. Using the automatic tools

4. Theoretical explanations of each command and file

5. Git Ready Resources (my examples)

6. Bash scripts (make it easy to note the steps)

7. Summary (Mini Mind Map)

8. References


Introduction

GNU Autotools , also known as the GNU Build System , is a set of programming tools designed to help make source code packages portable to many Unix systems.

It can be difficult to make a software program portable: the C compiler differs from system to system;Some library functions are missing on some systems;Header files may have different names.One way to deal with this is to write conditional code, with code blocks selected using preprocessor directives (#ifdef);But due to the wide variety of building environments, this approach quickly becomes unmanageable. Autotools is designed to solve this problem more easily.

Autotools is part of the GNU tool chain and is widely used in many open source and open source packages. Its component tools are licensed by free software under the GNU General Public License, with special license exceptions allowing their use with proprietary software.

The GNU Build System makes it possible to create many programs using a two-step process: configure followed by make.

Autotools consists of the GNU Autoconf , Automake, and Libtool utility programs.Other related tools often used alongside it include the GNU make program, GNU gettext , pkg-config, and the GNU Compiler Collection , also called GCC/G ++.


Part 1: Setting Up the Test Files

  • 1 → Create the directories for the tests:
mkdir testes && cd testes
mkdir doc examples man scripts src
  • 2 → Create the test files
touch doc/README.md examples/my-example-teste.dat man/teste.1 scripts/script-teste.sh src/teste.c
  • 3 → Popular the files
# Content for doc/
echo "Docs for teste" >> doc/README.md

# Conteúdo para o arquivo em examples/
echo -e '#!/bin/bash\necho "Teste in Bash"\nexit 0' >> examples/my-example-teste.dat

# Content for man/
echo -e '.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.47.8.
.TH teste "1" "October 2019" "teste 1.1" "User Commands"
.SH NAME
teste \- Only teste for Autotools.' > man/teste.1

# Content for scripts/
echo -e '#!/bin/sh\nprintf "Only a teste\\n" "%s"\nexit 0' > scripts/script-teste.sh

# Content for src/
echo -e '#include <stdio.h>

int main(){
	printf("Only one test for Autotools\\n");
	return 0;
}' > src/teste.c
  • 4 → Final result of the archives:
testes/
├── doc
│   └── README.md
├── examples
│   └── my-example-teste.dat
├── man
│   └── teste.1
├── scripts
│   └── script-teste.sh
└── src
    └── teste.c
5 directories, 5 files
  • 5 → Optional: directory hash:
ls ../testes/ | md5sum
ac0bacadc6861ab22a44af572b255ff1  -


Part 2: Using GNU Autotools Tools

  • 1 → Generate the configure.ac file, run:
autoscan

The files autoscan-2.69.log and configure.scan were created.Where the content of autoscan-2.69.log is empty and the content of configure.ac is:

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([src/teste.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT
  • 2 → Rename the configure.scan file to configure.ac :
mv configure.scan configure.ac
  • 3 → Change the line of the configure.ac file that has the information: AC_INIT (FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) to your project names, eg AC_INIT (test, 1.0, teste@terminalroot.com .br) .If you wish, use Sed for this, like this:
sed -i 's/FULL-PACKAGE-NAME\],/teste],/g' configure.ac
sed -i 's/VERSION\],/1.0],/g' configure.ac
sed -i 's/BUG-REPORT-ADDRESS\]/teste@terminalroot.com.br]/g' configure.ac

Or use a preferred text editor, for example: Vim . In the end my file looked like this:

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([teste], [1.0], [teste@terminalroot.com.br])
AC_CONFIG_SRCDIR([src/teste.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT
  • 4 → Generating an initial configure script:
autoconf

1 new directory and 1 new file were created: autom4te.cache/ and configure .Their contents are extensive, configure for example has 3549 lines .

  • Creating the Makefile.am File:
vim Makefile.am

And insert this content in:

AUTOMAKE_OPTIONS = foreign
SUBDIRS = src doc examples man scripts
  • 6 → Creating the Makefile.am file only this time inside the src/ directory:
vim src/Makefile.am

And insert this content in:

# what flags you want to pass to the C compiler & linker
CFLAGS = --pedantic -Wall -std=c99 -O2
# LDFLAGS =
# this lists the binaries to produce, the (non-PHONY, binary) targets in
# the previous manual Makefile
bin_PROGRAMS = teste
teste_SOURCES = teste.c
  • 7 → Creating the Makefile.am file only this time inside the man/ directory:
vim man/Makefile.am

And insert this content in:

man_MANS = teste.1
  • 8 → Creating the Makefile.am file only this time inside the scripts/ directory:
vim scripts/Makefile.am

And insert this content in:

bin_SCRIPTS = script-teste.sh
  • 9 → Creating the Makefile.am file only this time inside the doc/ directory:
vim doc/Makefile.am

And insert this content in:

docdir = $(datadir)/doc/@PACKAGE@
doc_DATA = README.md
  • 10 → Creating one more Makefile.am file only this time inside the examples/ directory:
vim examples/Makefile.am

And insert this content in:

exampledir = $(datarootdir)/doc/@PACKAGE@
example_DATA = my-example-teste.dat
  • 11 → Integrating the autoconf part with the automake.

    Open the vim configure.ac file

And insert the content AM_INIT_AUTOMAKE(teste, 1.0) , right after AC_INIT([teste], [1.0], [teste@terminalroot.com.br]) :

If you want it to be easier, just use this command below ( Sed ):

sed -i '/AC_INIT/{p;s/.*/AM_INIT_AUTOMAKE(teste, 1.0)/;}' configure.ac
  • 12 → Let autoconf generate a configure script whose output will be Makefiles for all directories mentioned:

    Changing the line that contains: AC_OUTPUT with Sed (if you want to use a text editor and do it manually):

sed -i 's@AC_OUTPUT@AC_OUTPUT(Makefile src/Makefile doc/Makefile examples/Makefile man/Makefile scripts/Makefile)@' configure.ac
  • 13 → Making the tools produce the configure script and Makefile templates:
aclocal

aclocal.m4 file was generated in the project root directory named: aclocal.m4

  • 14 → Producing Makefile.in with the argument --add-missing :
automake --add-missing

The output will look something similar or the same (if you used the files in this tutorial) to:

configure.ac:6: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated.  For more info, see:
configure.ac:6: https://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
configure.ac:11: installing './compile'
configure.ac:6: installing './install-sh'
configure.ac:6: installing './missing'
configure.ac:8: error: required file 'config.h.in' not found
src/Makefile.am: installing './depcomp'
src/Makefile.am:2: warning: 'CFLAGS' is a user variable, you should not override it;
src/Makefile.am:2: use 'AM_CFLAGS' instead
src/Makefile.am:3: warning: 'LDFLAGS' is a user variable, you should not override it;
src/Makefile.am:3: use 'AM_LDFLAGS' instead

Note the line: configure.ac:8: error: required file ‘config.h.in’ not found , if this also appears to you, run:

autoreconf -fi
  • And finally we generate the final configure script:
autoconf

If you want to make sure everything is fine, run ./configure , make and test program execution: cd src/ &amp;&amp; ./teste , the output will be: Just a test for Autotools .And if you want to install on the system, run:

Since you have sudo installed and are part of the group, otherwise make install only work with root .

./configure
make
sudo make install

A instalação vai criar alguns diretório e fazer as seguintes cópias dos arquivos para os caminhos:

/bin/mkdir -p '/usr/local/bin'
/usr/bin/install -c teste '/usr/local/bin'

/bin/mkdir -p '/usr/local/share/doc/teste'
/usr/bin/install -c -m 644 README.md '/usr/local/share/doc/teste

/bin/mkdir -p '/usr/local/share/doc/teste'
/usr/bin/install -c -m 644 my-example-teste.dat '/usr/local/share/doc/teste'

/bin/mkdir -p '/usr/local/share/man/man1'
/usr/bin/install -c -m 644 teste.1 '/usr/local/share/man/man1'

/bin/mkdir -p '/usr/local/bin'
/usr/bin/install -c script-teste.sh '/usr/local/bin'

  • Running the command: teste (regardless of the directory you are in) will get program execution output: Only one test for Autotools ;
  • script-teste.sh the command: script-teste.sh (regardless of the directory you are in) will get the output of the program execution: Only a test ;
  • If you run the command: info teste or man teste (regardless of the directory you are in) you will get the manual;
  • If you want to see the documentation, run: cat /usr/local/share/doc/teste/README.md ;
  • If you want to see the examples, run: cat /usr/local/share/doc/teste/my-example-teste.dat .

To uninstall you will need to be in the testes/ directory and run the command:

sudo make uninstall

Absolutely EVERYTHING will be uninstalled, the output will be similar/equal:

marcos@gentoo ~/testes $ sudo make uninstall
Senha:
Making uninstall in src
make[1]: Entering directory '/home/marcos/testes/src'
 ( cd '/usr/local/bin' && rm -f teste )
make[1]: Leaving directory '/home/marcos/testes/src'
Making uninstall in doc
make[1]: Entering directory '/home/marcos/testes/doc'
 ( cd '/usr/local/share/doc/teste' && rm -f README.md )
make[1]: Leaving directory '/home/marcos/testes/doc'
Making uninstall in examples
make[1]: Entering directory '/home/marcos/testes/examples'
 ( cd '/usr/local/share/doc/teste' && rm -f my-example-teste.dat )
make[1]: Leaving directory '/home/marcos/testes/examples'
Making uninstall in man
make[1]: Entering directory '/home/marcos/testes/man'
 ( cd '/usr/local/share/man/man1' && rm -f teste.1 )
make[1]: Leaving directory '/home/marcos/testes/man'
Making uninstall in scripts
make[1]: Entering directory '/home/marcos/testes/scripts'
 ( cd '/usr/local/bin' && rm -f script-teste.sh )
make[1]: Leaving directory '/home/marcos/testes/scripts'
make[1]: Entering directory '/home/marcos/testes'
make[1]: Nothing to be done for 'uninstall-am'.
make[1]: Leaving directory '/home/marcos/testes'
marcos@gentoo ~/testes $

Part 3: Preparing Files or Generating Everything via Shell Script

If you want to see everything we’ve done here, use pre-made files or run a simple Bash script:

git clone https://github.com/terroo/gnu-autotools
cd gnu-autotools/

And use the pre-created environment files: gnu-autotools/testes/ or simply run the script that creates the files from scratch: ./gnu-autotools.sh

Or generate everything including Autotools commands via script with the file: ./gnu-autotools-full.sh


Part 4: Explaining Autotools Files and Commands

In summary GNU Autotools :

  • Checks the availability of required libraries;
  • Possibly sets some things (like some paths in scripts or documentation) at compile time;
  • Install everything in its place;
  • All of this in a standardized way and dealing with all possible errors that may exist in the construction and installation of software;
  • The autoscan command attempts to produce a correct configure.ac file by performing simple parses on package files;
  • The autoconf command produces two files: autom4te.cache and configure;
  • The autom4te.cache directory is a directory used to speed up the work of tools, and can be removed when the package is released;
  • The configure file is the shell script that is called by end users.At this point, what the configure file does is just dependency checking as suggested by autoscan , so nothing too conclusive yet;

  • Once we have the system checking part, we move on to compiling and installing.This is done by the cooperation between automake and autoconf .automake generates some “templates” that scripts generated by autoconf translate into Makefiles.An initial makefile file is required at the root of the package: ./Makefile.am;
  • The AUTOMAKE_OPTIONS = foreign sets the mode automake will take.The “foreign” mode means non-GNU, and is commonly used;
  • The second line shows the list of sub directories where the files to be worked are located.The first has things to compile, while the rest just needs to be installed, but we don’t care about this file.We will now prepare the Makefile.am file for each of these directories.automake will pass one of them home to produce the corresponding Makefile.in file.These *.in files will be used by autoconf scripts to produce the final Makefile files.+ Usually in the src/Makefile.am file we define all files that will be created and compiled.In general, uppercase suffixes like “_PROGRAMS” are called primary and partially tell you what to do in your argument;prefixes, in lower case letters (do not have a predefined name) tell the directory where it will be installed.To inform several files, it is used more or less like this:
# what flags you want to pass to the C compiler & linker
CFLAGS = --pedantic -Wall -std=c99 -O2
LDFLAGS =
# this lists the binaries to produce, the (non-PHONY, binary) targets in
# the previous manual Makefile
bin_PROGRAMS = targetbinary1 targetbinary2 [...] targetbinaryN
targetbinary1_SOURCES = targetbinary1.c myheader.h [...]
targetbinary2_SOURCES = targetbinary2.c
.
.
targetbinaryN_SOURCES = targetbinaryN.c
  • Files in scripts/ usually have the Shell Script that will call the executable, as well as parameter autocomplete (compgen) templates. We use a sample content, but the same would be true (example of the Firefox script):
#!/bin/sh
unset LD_PRELOAD
LD_LIBRARY_PATH="/usr/lib64/apulse:/opt/firefox/" \
GTK_PATH=/usr/lib64/gtk-3.0/ \
exec /opt/firefox/firefox "$@"
  • That is, it will call the executable that was compiled and installed in /opt in its proper directory;
  • The aclocal command creates the tools that generate each script generates the aclocal.m4 file that contains macros for automake things;
  • The automake command reads configure.ac and Makefile.a m, interprets them, and for each Makefile.am produces a Makefile.in .The --add-missing argument tells automake to provide default scripts for any reported errors, so it can be omitted in future executions;
  • The autoreconf command (used to rectify the lack of config.h.in ) compiles all relevant tools in the correct order and installs missing files.The parameters -f (assume everything is obsolete and force reconfiguration) and -i (make a copy of auxiliary files present in the system for your project, call autoheader ).We could still join the -v parameter by getting -vfi to see the details of the procedures.

Summing up

autotoolsautoscan (configure.scan) → configure.acautoconf (autom4te.cache and initial configure) → Makefile.am ( * ) → aclocal (aclocal.m4) → automake (Makefile.in) → autoreconf ( config.h.in/header ) → autoconf ( ./configure ) → Makefile (make && make install)

Autotools


References


gnu autotools make language-c cpp


Share


YouTube channel

Subscribe


Marcos Oliveira

Marcos Oliveira

Software developer
https://github.com/terroo

Related articles