Background: Installing a software or package in Unix-like systems is quite different from that in Windows environment. Hence, whenever someone wants to install a new software or software in a Unix-like environment, question arises whether there is any standard for this. Typically, there are two methods of installing a software in Unix-like systems:
1. Installation by using a package manager.
2. Installation from source code.
However, as per GNU standard, users should follow the following method:
1. Packages normally come in the form of a tarball (archive of compressed files in .tar format).
2. Package should first be decompressed e.g. ….:~$tar -xzvf <tarball-of-package>
3. After decompressing, enter the decompressed directory.
4. In decompressed directory, locate and run configure script e.g. …:~$./configure.
5. Once, configure script is run successfully, then run make e.g. …:~$make. This will compile all necessary files for installing the package.
6. Once it completes, then run make install e.g. …:~$sudo make install
This is from user’s point of view. For a developer, the ultimate consideration is how to bundle the source code files and other relevant resources in a distributable package so that it can be run across various platforms. Following are some issues to be taken care of while packaging the system for a release as per GNU standards:
1. Naming and Versioning of the package.
2. Portability of system on a variety of platforms.
3. Configuration script configure with standard configurations options.
4. Makefile.inS required by configure script.
5. Conformity of Makefile and directory layout as per GNU standards.
6. Necessary documentation files and tests.
7. Bundling of the package into a tarball.
8. Licensing of the system.
However, this post is mainly about the use of GNU Build System in creating a distributable package..
Why GNU build system: Creating a configuration script and Makefiles from scratch is a tedious, time-consuming and error-prone task. Moreover, some users may be left unsatisfied due to unavailability of some desired features and at the same time, it may be needed to upgrade the overall setup to follow the changes to the GNU Coding Standards. This is where GNU build system fits in. It helps simplify the development of portable programs. It also simplifies the building of programs distributed as source code. Apart from it, any bug fixes and improvements can be made at one place. And, users don’t require any utilities of build system at their end.
Introduction to GNU build system: So, what do we mean by GNU build system? GNU Build System comprises:
1. autoconf: It is a tool for generating configuration script “configure”.
2. automake: It is a tool for generating makefile templates “Makfile.inS”.
3. libtool: It is a tool that helps creating the portable compiled libraries.
4. Some other auxilary tools:
i. autoscan: It is used for generating intial input file for autoconf.
ii. autoheader: It generates template header for “configure”.
iii. aclocal: It generates a file named aclocal.m4.
Installation of GNU build system:
• First check, if already installed in their most recent versions:
•…:~$autoconf – -version
• If not installed, then to install (on any debian-like system):
•…:~$apt-cache search <tool-name> – it searches for the package <tool-name> in available package list.
•…:~$sudo apt-get install <tool-name> – it installs the package <tool-name>.
Using GNU Build System:
1. Basic requirements: Basic requirements for using the GNU Build System are as follows:
i. Source and documentation files of the package.
ii. One “configure.ac” or “configure.in” as initial input file for autoconf.
iii. One “Makefile.am” for each directory in the package.
2. Source and Documentation files: These are the files containing source code and necessary documentation to be distributed in the package. Ex.: .c, .cpp files, README etc..
3. What is configure.ac? : It is initial input file for autoconf to generate configure script. It is also used by automake, while creating Makefile.amS. This file normally contains macros needed to test the system features required or used by the package.
4. Using autoscan: autoscan scans source files and creates configure.scan. After making some adjustments, if required, configure.scan can be renamed to configure.ac. Adjustments may be like adding some missing macros or changing the order of some macros etc..
5. Common macros: Following are the common macros normally used in “configure.ac”.
i. AC_PREREQ: This macro specifies the minimum version of autoconf that can successfully compile a given configure.ac.
ii. AC_INIT: This macro initializes autoconf.
iii. AM_INIT_AUTOMAKE: It initializes automake.
iv. AC_PROG_CC: This macro determines a C compiler to use and sets output variable CC to its value.
v. AC_PROG_CXX: This macro determines a C++ compiler to use and sets output variable CXX to its value.
vi. AC_CONFIG_HEADER: It causes to create a config.h file gathering ‘#define’s defined by other macros in configure.ac.
vii. AC_CONFIG_FILES: It declares the list of files to be created from their *.in templates.
viii. AC_OUTPUT: It generates and runs config.status, which in turn creates the makefiles and any other files resulting from configuration.
6. Example configure.ac:
AC_INIT([hello], [0.1], [email@example.com])
7. What is Makefile.am?: It is an initial input file for automake to generate Makefile.in. One Makefile.am is required for each directory in package including root directory. This file normally contains a list of variable (and rule) definitions required, when make is invoked.
8. Common Makefile targets: Following are common makefile targets.
i. make all: This target is used to build programs, libraries, documentation etc.
ii. make install: This target is used to install what needs to be installed, copying the files from the package’s tree to system-wide directories.
iii. make uninstall: This is opposite of “make install”. It erases the installed files.
iv. make clean: It erases from the build tree the files built by “make all”.
v. make distclean: It additionally erases anything ./configure created.
vi. make check: It is used to run the test suite, if any.
vii. make installcheck: It checks the installed programs or libraries, if supported.
viii. make dist: It recreate package-version.tar.gz from all the source files.
9. Common variables for Makefile.am: Following are some common varibales that can be used to create an initial Makefile.am.
i. bin_PROGRAMS: It specifies the <program> to be built and installed on …/bin directory.
ii. <program>_SOURCES: It lists one or more source files compiled to build the <program>.
iii. SUBDIRS: It lists all sub-directories to be built.
iv. dist_doc_DATA: It lists documentation files to be distributed and installed in ../doc directory.
v. <program>_DEPENDENCIES: It specifies dependencies, if any.
vi. <program>_<FLAGS>: Various compilation flags can be set.
vii. <program>_LDADD: It specifies extra objects and libraries to be added with <program>.
viii. <program>_LDFLAGS: It specifies extra linker flags for <program>.
10. An example Makefile.am:
bin_PROGRAMS = hello
hello_SOURCES = hello.c
Some characteristics of GNU Build System: Following are the some characteristics of GNU Build System:
1. VPATH Builds: When source tree and build tree are different, such builds are called VPATH builds.
2. Cross-compilation: When a program is built on one platform and run on another platform is called cross-compilation.
3. Renaming: GNU build system allows to automatically rename executables etc. before installation.
4. Dependency tracking: GNU build system allows to track dependencies automatically.
5. Nested packages: Autoconfiscated packages can be nested to arbitrary depth.
Applying tools of GNU Build System to create the package: Following steps need to be performed for creating a package.
1. Ensure all necessary source, documentation and Makefiel.amS files have been created.
2. Run autoscan to create prelimanary configure.scan e.g. ..:~/<pkg-dir>$autoscan
3. If required, edit configure.scan to update package-name, version, invocation to AM_INIT_AUTOMAKE macro etc. and rename it to configure.ac.
4. Run aclocal to create aclocal.m4. This file contains macro definitions not part of standard autoconf macro e.g. ..:~/<pkg-dir>$aclocal.
5. Run autoheader to create config.h.in. This file is a template header for configure e.g ..:~/<pkg-dir>$autoheader.
6. Run autoconf to create configure from configure.ac and aclocal.m4 e.g. ..:~/<pkg-dir>$autoconf.
7. Run automake to create Makefile.inS from Makefile.amS e.g. ..:~/<pkg-dir>$automake.
8. Run configure to create Makefiles from Makefile.inS, config.h from config.h.in and perform various checks about the environment e.g. ..:~/<pkg-dir>$./configure.
9. Now run make to build the system e.g. ..:~/<pkg-dir>$make.
10. If make executes successfully, run make distcheck to create the package for distribution as a tarballe.g. ..:~/<pkg-dir>$make distcheck.
11. Run make install to install the package e.g. ..:~/<pkg-dir>$sudo make install.
12. Run make uninstall to uninstall the package e.g. ..:~/<pkg-dir>$sudo make uninstall.
From User’s point of view: It provides a standard procedure for installation. This procedure consists of only a small set of commands.
From Developer’s point of view: Creating portable distributions becomes easy. Updations or improvements, if any, can be done at one place.