OSIMIS Conventions for Building, Installing and Contributing Software
---------------------------------------------------------------------

This is a short document on the OSIMIS conventions for building, installing
and contributing software to become part of future releases. Adhering
strictly to these conventions is very important to guarantee its easy
packaging. Is is noted that OSIMIS is a very large piece of software and 
without such a strict discipline is simply unmanageable.

This document should be read in conjunction to the top level README
OSIMIS file. Parts of the latter and this document will be later merged.


Top-level Directory
-------------------

The OSIMIS tree should always exist under a directory denoting explicitly
the version e.g. "osimis-3.3" . A symbolic link to that directory under the
name "osimis" should always exist for reasons related to creating a tar
image, as it will be explained later. This top level directory is
usually referred to as $(TOP) as it is always accessible through
a variable with that name in Makefiles (see next section).

The usual sequence of extracting the directory tree of a new release
from a compressed tar image should be (an example)

zcat osimis-3.3.tar.Z | tar xf -
mv osimis osimis-3.3
ln -s osimis-3.3 osimis

which would result to the following directory structure:

                               |
                 ---------------------------
                 |                         |
            osimis-3.3 <---------------- osimis


Makefile Organisation
---------------------

The OSIMIS Makefiles are organised in such a way so that changes required
to reflect the needs of a particular environment, such as
locations of required libraries and header files, compiler names,
installation directories etc., should be done in one place. 
That place is a file called CONFIG.make in the $(TOP) directory.
Every other directory containing a Makefile should also contain a file
called "make" which should invoke the CONFIG.make before the local Makefile,
so that the latter inherits the local environment.

The contents of the "make" file for a directory which exists two levels
below the $(TOP) one in the OSIMIS directory tree should be:

#!/bin/sh
exec /bin/make TOP=../.. -f ../../CONFIG.make -f Makefile ${1+"$@"}

Two things are important for contributed software due to that structure:

a. if your software needs a special tool, compiler etc., a special variable
   for that should be added to the CONFIG.make file rather than burying it
   in a Makefile

b. make sure every directory with a Makefile has also a make as above;
   make calls in the Makefile should be explicitly "./make" to ensure
   the local make will be called.


Building and Installing
-----------------------

OSIMIS consists of both generic infrastructure (i.e. a management platform)
and of a few specific applications as examples of using and exercising the
infrastructure. Most places use OSIMIS as a development environment and
are only interested that infrastructure. The build and install
rules take that into account so that it is possible to either build and
install the generic parts only or the whole system. The necessary Makefile
targets to make this possible are described in the next section.

The typical build and install procedure is as follows:

1. the build environment is tailored in CONFIG.make, while installation
   paths are left as they are to point within the OSIMIS tree
2. the system is built
3. the installation paths are tailored only if installation is to take place
   outside the OSIMIS tree
4. contents of the OSIMIS etc directory files are tailored
5. the system is installed
6. the source tree is cleaned

OSIMIS software should assume that header files are installed in $(TOP)/h
and the include path is present as a compilation flag in CONFIG.make.
Libraries though needed for linking programs should be referenced at their
"home" subdirectory i.e. the place where they have been made.

The reason for this asymmetry is the complexity involved in arranging
a scheme whereby header files would be referenced by relative pathnames.
In that case, a script would be needed to remove any relative prefixes
of paths before installing the header files to the target directory.
The additional benefit of such an approach would be that the number
of installed files would be reduced to the absolute minimum
i.e. only generic ones. It seems though sensible to stay with the
current scheme because of its simplicity.


Makefile Targets
----------------

Due to the separation between generic and specific parts, the following
targets are required in Makefiles:

lib:            all the libraries
glib:           the generic libraries only

prog:           all the programs
gprog:          the generic programs only

install-h:      installs all the header files
install-gh:     installs the generic header files only

install-lib:    installs all the libraries
install-glib:   installs the generic libraries only

install-prog:   installs all the programs
install-gprog:  installs the generic programs only

install-man:    installs all the manual pages
install-gman:   installs the generic manual pages only

clean:          cleans all the object files, libraries, programs and
                any compiler produced files

As the build and install procedure is initiated from the $(TOP) directory
and then cascades down the directory tree, in theory all the Makefiles
need to have all the above targets. In practice though, all the targets
are only needed by the first level directories: the Makefile in those
could "shield" any subordinate Makefiles from unnecessary targets.

As an example, in the $(TOP)/manager directory there is generic manager
infrastructure and generic and specific programs. In that directory the
generic and specific subdirectories are separated so that any subordinate
ones need not care about this separation i.e. generic targets are not needed.
Also, this Makefile could also shield subordinate ones from unnecessary
specific targets e.g. a library only directory does not need a program
or manual page target.

If you choose to implement such optimisations, make sure the owner of the
parent directory and Makefile (if it is not you) knows exactly
your needs and implements the necessary scheme.


Support for Generating Tar Images
---------------------------------

As OSIMIS is constantly evolving, it is often necessary to generate a tar
image without having to clean the source tree. In order to be able to do that,
OSIMIS supports a scheme whereby every directory whose parts only should
exist in the tar image should indicates which these are through a file
called I-tar (from the -I option of the tar(1) program).

Every such file should contain a list of files or immediately subordinate
directories which are to be included in the tar image (all the contents
of subdirectories will be included that way). These files are pointed to
through a full path from the top of the OSIMIS tree WITHOUT the version number.
As an example, the I-tar in $(TOP) is:

osimis/CONFIG.make
osimis/I-tar
osimis/Makefile
osimis/README
osimis/doc
osimis/etc
osimis/h
osimis/include
osimis/make
osimis/make-log
osimis/version

Note that doc/, etc/ h/, include/ and make-log/ are directories whose
whole contents (including subdirectories) are included in the tar image.

The $(TOP)/Makefile contains a tar target which references every I-tar file
in the tree. If you are adding a new directory, please follow the procedure:

a. if your directory should be tar'ed as a whole, add its pathname
   to the parent directory I-tar (please keep an alphabetical order)
   and let its owner know

b. if this directory may contain code, produced files etc., create an I-tar
   in there and modify the $(TOP)/Makefile to reference it.

In the latter case, please make sure that the I-tar and the directory's
contents are consistent, else an incomplete image will be tar'ed with all
the ghastly consequences.

A quick method to check the correctness of the I-tar file, is the following
for a directory two levels down in the directory tree:

cd ../../..
tar cvf /tmp/<mydir>.tar -I osimis/<dir>/<mydir>/I-tar
mv osimis/<dir>/<mydir> osimis/<dir>/<mydir>.old
tar xvf /tmp/<mydir>.tar
cd osimis/<dir>/<mydir>
make
rm -rf ../<mydir>.old


Applying Patches
----------------

When a new OSIMIS version is distributed, header files needed to be seen
by various directories are already installed in $(TOP)/h .
OSIMIS patches usually contain whole source code files and should be untared
in the directory containing the osimis/ one where OSIMIS was initially made.
Patches are usually incremental i.e. all of a series of pathes need
to be applied up to the last one for a particular version.

Patches may contain header files but they do not contain copies of those
in $(TOP)/h. As such, before re-making OSIMIS after applying patches one
needs first to install the header files in $(TOP)/h. If you have installed
OSIMIS outside its source tree, modify the $(TOP)/CONFIG.make and make
the install paths as they were in the initial tar image i.e. to point
in the source tree. Now type install-h (or install-gh if you make the generic
parts only) in the top level directory and then follow the build instructions
as you did the first time.

Having rebuilt OSIMIS with the patches, you may want to change again
the install paths in $(TOP)/CONFIG.make to point in places outside the
tree in your local environment before you re-install OSIMIS.

