Documentation

Build

About

build is a replacement for make.
It was conceived out of the slow refinement of the makefiles that I had developed to build the libraries that now form Open XDS.
Eventually the makefiles were refined to a point where I could use the exact same makefile for all libraries, however at that point I began to forget how the makefiles actually worked.

I decided that I may as well code what the makefiles were doing in C and be done with make. Hence, build.

Key concept

Build uses information stored in the directory structure of a
project to correctly build libraries or executables. Each
project directory name is either prefixed with "lib" or not,
indicating whether or not it is a library.

Using build

To build a build compliant project one need only change into
the project directory and type "build":

Header files that would be included in a program making use
of the library are put in the project directory's public
include directory, while header files private to the library
are put in the source directory's include directory.

Below shows the layout of the project directory after a
build. Note that directories beside the hypons (--) are
created during the build process.

The names of binaries are taken from the project's directory
name. Library names also use the version of the package.

{LIB}{NAME}-{VERSION}

As can be seen the product of library projects are object
files for each source file in ./obj, and three libraries in
'./lib' - two versioned shared libraries and one archive.

Non-library projects produce one binary that is placed in the
'./bin' directory.

Platform specific files

Source files located in subdirectories of the source directory
are compiled if the directory name matches a section of the
PLATFORM environment variable, which is delimited by a colon
':' separator, i.e. "posix:linux-gnu:X11". Note that this
variable must be exported. This allows projects to support
multiple operating systems/environments without the need for
#ifdefs within code.

Dealing with library dependencies

There are two types of library dependencies that need to be
catered for by a build system. The first are additional
libraries by yourself or third parties. The second are system
libraries that only require a "-l" argument to be passed to
the linker.

Additional libraries dependencies are handled by build's
ability to recursively descend into and build dependency
project directories that are located within the parent. For
example if our coffee library depended on a sugar library (or
maybe that should be a caffeine library) the directory
structure would be as follows:

When run if a recursive mode is selected (--all, --level n)
build will descend into each dependency and compile it before
compiling those libraries/programs above.

Build will add the public include directories of all
dependency packages and of their dependencies to the header
search path of the project being built.

Build will also include the lib directories of dependency
directories to the library search path of the project being
built. And will add appropriate "-l" arguments for each
library in those directories.

Building third party libraries

Building with system libraries

Build determines system libraries by checking the ./source/lib
directory. Within this directory are either library files or
link files [see using link files] to the library. If the
library is an actual library, or the link is valid. A
"-l" argument is passed to the linker.

Thus if a project relied on linking to the X Window System
library (libX11.so) the following text file would be added to
the project.

libcoffee-0.1.1/source/_system/libX11.so.link

The contents of the file would be the location of the library.

/usr/X11R6/lib/libX11.so

Note that when building a monolithic executable, system
libraries are still dynamically linked.

Using link files

Often it will be inconvenient for libraries to be physically
contained within a parent due to it being a dependency of
multiple projects, or perhaps maintained by another person.
To solve this problem dependency libraries may also use a link
file to indicate the location of a dependency library. For
example our coffee library example could have been arranged as
below:

$BUILD_PATH is an environment variable -- but it is also
pre-populated with a projects ancestry directories to several
levels.

It should be noted that under POSIX-style systems that
symbolic links could be used, however these are not available
on windows. Windows style shortcuts (Cygwin symlinks) were
tried, but these caused problems with CVS.

Link files provide a similar mechanism but also provides some
nice features. A link file may contain multiple paths.
Starting at the top of the file, each path is tried until a
valid path is reached. Thus link files may be used to easily
indicate fine grained library version dependencies. Note also
that the name of the link file need not match the name of the
target library.

Changes to version dependencies may thereby be recorded in
whatever revision control system is used.

This is useful for when your development CVS checkout uses a
larger grained versioning that the one used for releases. If
you keep your link files up-to-date a release may contain
fine grained package version dependency information and still
be appropriately built by build.