
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.
All topics have been separated with Step by Step and Lists sorted for ease of understanding.
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 ++.
mkdir testes && cd testes
mkdir doc examples man scripts srctouch doc/README.md examples/my-example-teste.dat man/teste.1 scripts/script-teste.sh src/teste.c# 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.ctestes/
├── doc
│ └── README.md
├── examples
│ └── my-example-teste.dat
├── man
│ └── teste.1
├── scripts
│ └── script-teste.sh
└── src
└── teste.c
5 directories, 5 filesls ../testes/ | md5sum
ac0bacadc6861ab22a44af572b255ff1 -
configure.ac file, run:autoscanThe files
autoscan-2.69.logandconfigure.scanwere 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_OUTPUTconfigure.scan file to configure.ac :mv configure.scan configure.acconfigure.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.acOr 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_OUTPUTconfigure script:autoconf1 new directory and 1 new file were created:
autom4te.cache/andconfigure.Their contents are extensive,configurefor example has 3549 lines .
Makefile.am File:vim Makefile.am
And insert this content in:
AUTOMAKE_OPTIONS = foreign
SUBDIRS = src doc examples man scriptsMakefile.am file only this time inside the src/ directory:vim src/Makefile.amAnd 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.cMakefile.am file only this time inside the man/ directory:vim man/Makefile.amAnd insert this content in:
man_MANS = teste.1Makefile.am file only this time inside the scripts/ directory:vim scripts/Makefile.amAnd insert this content in:
bin_SCRIPTS = script-teste.shMakefile.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.mdMakefile.am file only this time inside the examples/ directory:vim examples/Makefile.amAnd insert this content in:
exampledir = $(datarootdir)/doc/@PACKAGE@
example_DATA = my-example-teste.datautoconf part with the automake.
Open the
vim configure.acfile
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.acChanging 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.acconfigure script and Makefile templates:aclocal
aclocal.m4file was generated in the project root directory named:aclocal.m4
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' insteadNote the line: configure.ac:8: error: required file ‘config.h.in’ not found , if this also appears to you, run:
autoreconf -ficonfigure script:autoconfIf 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
sudoinstalled and are part of the group, otherwisemake installonly work withroot.
./configure
make
sudo make installA 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'
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 ;info teste or man teste (regardless of the directory you are in) you will get the manual;cat /usr/local/share/doc/teste/README.md ;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 uninstallAbsolutely 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 $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
In summary GNU Autotools :
autoscan command attempts to produce a correct configure.ac file by performing simple parses on package files;autoconf command produces two files: autom4te.cache and configure;autom4te.cache directory is a directory used to speed up the work of tools, and can be removed when the package is released;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;
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;automake will take.The “foreign” mode means non-GNU, and is commonly used;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.cscripts/ 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 "$@"/opt in its proper directory;aclocal command creates the tools that generate each script generates the aclocal.m4 file that contains macros for automake things;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;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.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)

gnu autotools make language-c cpp