This is a very short overview of build systems used in Linux or in general
GNU softwares. These tools are also ported to Windows, but generally only GNU
tools ported to windows, which makes use of cygwin or mingw use these build
systems. Tools aimed at windows only systems usually use Visual Studio build
environments.
So quick description of basic terminologies:
Build: It usually means compiling the source code and generating binary
(executable) file. Optionally it contains features to scan host system (system
on which code is being compiled) and make changes in source code accordingly.
Example would be GUI in Linux. Linux supports multiple GUI libraries eg: GTK,
QT. So build system may scan host to determine which library should be used for
compiling this code.
Installer: This program installs the generated executables, shared libraries and
other build outputs to some location, so that OS can find it easily while
executing the programs. Sometimes installer is part of build system itself,
while some times build and installer comes in pair.
Now let us see some very popular build systems:
1. Shell Script: Used for very small and very simple tools or utterly
complex builds. For simple builds, it just contains few lines to compile the
code files and generate and install binaries.
2. Makefile: Most common build system on unix and related environment. Makefile
contains rules about source files and their dependency with each other. It
effectively makes a dependency tree. Also, once built, it can detect which
files have been changed in subsequent builds and compile only those.
3. CMake: I am not too familier with it, so I’ll just mention that it is
another build system.
4. SCons: Build system created in python. Gives you flexibility of specifying
rules like Makefile and also add python code to make very complex build
systems.
5. Configure Scripts: These are not truelly build systems, but rather pair up
usually with Makefiles. These scripts are very versatile in the sense they detect
host environment and change Makefiles accordingly. Can be modified to make a
generic build system, which will fit multiple host environments very smoothly.
6. Automake and Autoconf: These are tools to generate Makefile and configure
scripts from specification files. In rest of this post, we’ll talk about these
two with few examples.
Building source code:
These steps are common for most of the codes that make use of configure script
and Makefile for building. Change in command line might be needed to change
default build options.
1. Make configure script executable if it is not already: chmod +x ./configure
2. ./configure (optionally –prefix=/custom/install/folder)
3. make
4. make install
5. make clean (only if you want to rebuild everything next time)
Autoconf: As name indicates, it is a tool used to generate configure scripts
from some options file. Usually this options file is named configure.ac or
configure.in. It’ll have multiple macros having “AC_” prefix. Most interesting
ones are AC_ARG_ENABLE and AC_ARG_WITH. Here is what GNU manual says about theses
macros:
AC_ARG_ENABLE: “If a software package has optional compile-time features, the
user can give configure command line options to specify whether to compile them.
The options have one of these forms:
–enable-feature[=arg]
–disable-feature”
Structure of this macro is: AC_ARG_ENABLE(feature, help-string, [action-if-given],
[action-if-not-given]). Here action-if-not-given simply means default value.
AC_ARG_WITH: “Some packages require, or can optionally use, other software
packages that are already installed. The user can give configure command line
options to specify which such external software to use. The options have one of
these forms:
–with-package[=arg]
–without-package”
Structure of this macro is: AC_ARG_WITH(package, help-string, [action-if-given],
[action-if-not-given]). Here action-if-not-given simply means default value.
So let’s see first example of Autoconf options file:
1. Bash:
I am using bash 4.2 source for this example. Source availble at
http://ftp.gnu.org/gnu/bash/bash-4.2.tar.gz. It has a configure.in file. Lets
open it. As I said, it contains lots of AC_ macros. Description of those can be
found at GNU site. First AC_ARG_WITH macro is present on line number 106. We can
see which optional packages bash has like afs, bash-malloc, gnu-malloc etc. Help
string is the string displayed as description about that package. First
AC_ARG_ENABLE macro is found on line 211. Features like alias, array-variables, debugger are specified here. Interestingly none of these macros had default
value specified. Lets find out where it is specified. eg To find default value
of debugger feature, let’s see action associated with it. Third argument of
macro is opt_debugger=$enableval, which means enable value of this feature is
stored in opt_debugger. Simple grep command ‘grep -n “opt_debugger”
configure.in |less‘ on configure.in shows its default value is set on line
number 184 as yes. In configure.in file surrounding lines set default value for
other features. Similar search on curses package shows default package values
are initialized around line 58.
2. Gnash:
Now we’ll see confgure file for gnash, the open source flash player. I am
using version 0.8.9 from ftp://ftp.gnu.org/gnu/gnash/0.8.9/. It has a
configure.ac file. Simple grep shows it has 36 features and 13 packages
configureble through config script. Few of them have default value in macro,
others use shell scripting lines to decide values.
3. Nautilus:
The reason behind understanding structure of autoconf file is that all features
and packages may not have enough description. So if one wants to probe for
enabling/disabling specific functionality he can easily look into these macros
and corresponding shell variables to see its effect on output of configure file.
So, suppose we want to add configure option of enabling/disabling debug flag
during compilation of nautilus , we can add following lines to corresponding
configure.in files and generate configure file from it.
I have added following option to line 110 of configure.in after option for
enabling debug.
AC_ARG_ENABLE(
[debug],
[ –enable-debug Enable Debug Flags (default: enabled)],
[case “${enableval}” in
yes) CFLAGS=”$CFLAGS -g -O0″ ;;
no) CFLAGS=”$CFLAGS -g -O3″ ;;
*) AC_MSG_ERROR([bad value ${enableval} for –enable-debug option]) ;;
esac],
CFLAGS=”$CFLAGS -g -O0″)
This option when set, makes CFLAGS(used when compiling .c files) to be -g and
-O0 thus enabling debug output and disabling all optimizations.
Generate configure script using ‘autoconf’. Now if we type ./configure –help,
we can see enable-debug option in it. If we do ./configure –enable-debug, and
make, CLFAGS used while compiling .c files will have -g -O0 arguments in it.
Thus debug version of nautilus will be built.
If we want to show enbaled-disabled debug feature after completion of configure
script, we can add following lines at end of configure.in file. That part
usually contains echo statements for other features. We can add status of our
own feature by adding
if test x”echo $CFLAGS | grep \”-g -O0″= “x”; then
echo ” Debug disabled”
else
echo ” Debug enabled ”
fi
at very end of the file. Generate configure file again, and configure it. On
successful configuration it’ll show the message Debug disabled/enabled on last
line of output.
Automake: As you can guess from name, this is used to generate a Makefile from
provided template, usually specified in Makefile.am file.
Important thing to note here is nomenclature of macros defined in Makefile.am
files. It is usually specified as “folder name”_”description” or “file
name”_”description” where file/folder name is name of file to be built or name
of the folder relevent files should be copied into.
So e.g. “bin_PROGRAM = asd” means binary executable named asd should be built
(PROGRAM) and copied into “bin” folder.
Here are few other common macros:
1. bin_PROGRAM : binary name to be built and copied to bin folder.
2. libexec_PROGRAM : binary name to be built and copied to libexec folder.
3. lib_LIBRARIES : library name to be built and copied to lib folder.
4. lib_LTLIBRARIES : shared library name to be built and copied to lib folder.
5. noinst_PROGRAM : just build program but don’t copy it anywhere
6. asd_SOURCES : Now this important one. Here we specify source files for
building asd (binary)
7. asd_a_SOURCES : sources for building asd as static library.
8. asd_la_SOURCES : sources for building asd as shared library.
9. EXTRA_asd_SOURCES : Source files usually for conditional compilation.
10. asd_LDFLAGS : linker flags for building asd.
11. asd_CFLAGS : C flags for building asd.
12. asd_LDADD : libraries to be linked while building asd
13. EXTRA_DIST : copy all mentioned files/folders to installation path.
14. SUBDIRS : List of subdirectories to be traversed while ‘Making’ package. May
or may not contain Makefile.am files.
As we can see from these macros, it is very easy to alter Makefiles by finding
required macros in Makefile.am and tweaking few macros to change flags, add or
remove sources or do something else.
Important thing is to regenerate Makefile using automake, you must go to parent
folder which contains config.ac or config.in and then execute following
commands:
aclocal
automake
Lets see few example Makefile.am now.
1. AS31
First package we will see here is AS31 an assembler and compiler for 8051
code. It is available on http://www.pjrc.com/tech/8051/.
So Makefile.am in root source dir contains just SUBDIR macro pointing to ‘as31
example’ to indicate these folders will contain Makefile.am or Makefile for
actual code and examples.
Now Makefile.am in as31 folder contains bin_PROGRAMS having value as31 and
conditionally as31gtk. Both these binary targets have their source file macro
defined with list of code files to be compiled for its generation. There is also
one LDADD macro to indicate linking of libraries.
Makefile.am in examples directory only contains EXTRA_DIST macro to move those
files to installation location.
2. Extreme Tux Racer:
A 3D game available at http://extremetuxracer.com/.
As with previous case its root Makefile.am contains SUBDIR and EXTRA_DIST macro.
Makefile.am in src is also trivial. Contains one bin_PROOGRAM and huge list of
source code files for it.
Now data directory does not contain Makefile.am at all but simple Makefile
indicating it is not to be regenerated through Automake. Modifying such Makefile
has to be done manually as far as I know.
3. Nautilus:
File manager for GNOME. Availalble at
http://ftp.gnome.org/pub/GNOME/sources/nautilus/.
As expected root Makefile.am contains list of subdirectories along with few
extra dist folders.
In libnautilus-extension, we see a new directive named includedir and
include_HEADER which means header files under $(includedir) should be installed
or copied to install location. Usually done for installing header along with
libraries for developers.
In src folder, there is a directive libexec_PROGRAM indicating binary to be
copied to libexec folder rather than usual bin folder.
So that’s all I have for basic build info on open source softwares. Please
comment if there is any specific topic missing here or any peculiar
configuration files you came across and wish to be explained here.
Link: https://anondissector.blogspot.com/2012/10/overview-of-build-systems.html