GNU Autotools Ultimate Tutorial for Beginners
I decided to document a modern and very simplistic test that I created with GNU Autotools.
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
andconfigure.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 toconfigure.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/
andconfigure
.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 thesrc/
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 theman/
directory:
vim man/Makefile.am
And insert this content in:
man_MANS = teste.1
- 8 → Creating the
Makefile.am
file only this time inside thescripts/
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 thedoc/
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 theexamples/
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/ && ./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, otherwisemake install
only work withroot
.
./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
orman 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 correctconfigure.ac
file by performing simple parses on package files; - The
autoconf
command produces two files:autom4te.cache
andconfigure
; - 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
andautoconf
.automake
generates some “templates” that scripts generated byautoconf
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 correspondingMakefile.in
file.These*.in
files will be used byautoconf
scripts to produce the finalMakefile
files.+ Usually in thesrc/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 theaclocal.m4
file that contains macros forautomake
things; - The
automake
command readsconfigure.ac
andMakefile.a
m, interprets them, and for eachMakefile.am
produces aMakefile.in
.The--add-missing
argument tellsautomake
to provide default scripts for any reported errors, so it can be omitted in future executions; - The
autoreconf
command (used to rectify the lack ofconfig.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, callautoheader
).We could still join the-v
parameter by getting-vfi
to see the details of the procedures.
Summing up
autotools
→ autoscan
(configure.scan) → configure.ac
→ autoconf
(autom4te.cache and initial configure) → Makefile.am
( *
) → aclocal
(aclocal.m4) → automake
(Makefile.in) → autoreconf
( config.h.in/header
) → autoconf ( ./configure
) → Makefile
(make && make install)
References
- https://www.gnu.org/software/autoconf/
- https://www.gnu.org/software/automake/
- https://www.gnu.org/software/libtool/
- https://www.gnu.org/software/make/
- https://www.gnu.org/software/gettext/
- https://en.wikipedia.org/wiki/GNU_Autotools
- https://klebermota.eti.br/2010/10/13/tutorial-para-criar-a-estrutura-de-arquivos-do-autoconf-automake-para-seu-projeto/
- https://developer.gnome.org/anjuta-build-tutorial/stable/create-autotools.html.en
- https://dwheeler.com/autotools/
gnu autotools make language-c cpp
Comments