Introduction
------------

Pathan is now built using TMAKE, GNU autoconf and GNU libtool.

TMAKE handles turning the Makefile.pro's --> Makefile s.

autoconf provides a means of testing certain attributes of a target
compile platform (endiness, compiler type etc.).

autoconf is used to create Makefile.def from Makefile.def.in with
correct defines for the platform.

Additionally src/config.h is written which contains relevant #defines
for the platform involved, eg. #define WORDS_BIGENDIAN.

This fine grained control allows us to dispense with #define LINUX or
#define SOLARIS.

All unix platforms fall under the umbrella of #define UNIX.
Windows is #define WIN32.

Libtool allows seamless production of the correct type of
shared/static libraries on any UNIX system, something it is difficult
to achieve without detailed knowledge of each platform.

Build process
-------------

cd Pathan
./DSLrunConfigure
make
make install
(make test)
(make examples)
[make uninstall]

DSLrunConfigure runs tmake and configure. It requires the environment
variables XERCESCROOT & TMAKEPATH in the environment.

XERCESCROOT=<path>/devel/Xerces1_5  - RedHat 6.2/glibc2.1 (tugela) build

In order to use the following XERCESCROOTs, run makeSymLinks in the Xerces1_5 directory.

XERCESCROOT=<path>/devel/Xerces1_5/xerces-glibc2.2  - Redhat 7.1/glibc2.2 build
XERCESCROOT=<path>/devel/Xerces1_5/xerces-solaris   - Solaris/SPARC (dart) build

TMAKEROOT=<path>/devel/DSLtmake/lib/linux-g++/  - for ALL UNIX PLATFORMS! (Solaris, Linux)

Usage: DSLrunConfigure [ --target=optimised/debug/profile ] [ --build=internal/external ]
                    [ --help ] [ configure-options ]

   --help              this help screen
   --help-configure    configure help screen
   --compiletype
                       debug     (unoptimised debugging build [default])
                       optimised (optimised build)
                       profiling (profiling build)
   --verbose-libtool   don't hide libtool output
   --buildtype
                       internal [default]
                       external

       all other options passed to configure

--verbose--libtool

libtool tends to produce a lot of output on platforms where both
shared & static libraries exist since it will build both types.

Hence in the Makefiles we have:

@echo $(CXX) -c $(DEFINES) $(CXXFLAGS) $(INCPATH) -o $(srcdir)/objs/$@ $<
@$(LIBTOOL) $(CXX) -c $(DEFINES) $(CXXFLAGS) $(INCPATH) -o $(srcdir)/objs/$@ $<

which produces the usual g++ file.c -o thing

Errors from the build come out as normal.

--

Note: Optimised builds can throw out new errors when producing code to
be made into a shared library. When libtool is building both shared &
static libraries it will suppress 2>&1 >/dev/null the output of the
second build so as not to duplicate any errors. If you use -Werror,
therefore, any new warnings may cause the build to fail but the
warning (error) would not be echoed. For this reason, I disabled
-Werror when running runConfigure, the release script, however the
problem could still occur when running DSLrunConfigure and making an
optomised build.

If you really want to track these errors down open the autogenerate
libtool script in the Pathan/ directory and find the line

suppress_output=' >/dev/null 2>&1'

delete the code between the '' and any warnings will be echoed.

Although this problem is irritating it doesn't crop up except when
running optimised builds and cross-platform builds without using
libtool would be very difficult to achieve.

--

--buildtype = internal / external

For our distributions we don't want to have to include our hacked
version of TMAKE.

buildtype = internal: the makefiles are created normally.

buildtype = external: the makefiles are changed so as not to refer to
TMAKE (ie. dependences on Makefile.pro are removed)


Distribution process
--------------------

Our distributions won't include certain files within the tree, for
example:

Makefile.pro
CVS directories
Internal documentation
Distribution scripts
DSLrunConfigure

A user compiling the package will run a script in Pathan/ called

./runConfigure

which takes a subset of DSLrunConfigure options.

XERCESCROOT must be in the environment: Xerces comes with no install
scripts and hence I cannot assume where it is.


To build a distribution

cvs co devel/Pathan
cd devel/Pathan
cd distrib
./buildTGZ
./buildRPM

It's important to checkout a new copy since otherwise backup~ or
temporary files may get errornously added to the distribution.

./buildTGZ

This builds libpathan-x.y.tar.gz which contains the entire source
tree, minus the inappropriate bits.

./buildRPM

This builds 2 RPMs for libpathan (found in pathan_rpm/RPMS/i386 after
the build).

libpathan.rpm - just the shared library so binaries build with
libpathan will run.

libpathan-devel.rpm - additional static library and header for
development work.

A note about building the rpms: I use a fake root, pathan_root and
build the libararies in pathan_root/usr/local/lib. When libtool is
compiling the shared libraries it claims to encode the install path
(ie. this fake path) within the shared library. However, as far as I
can see on Solaris and Linux it doesn't and we can freely install and
use the libraries in /usr/local/lib [I use sed to correct the .la file
used for uninstall] If there is ever a problem, just build the RPM as
root using the real /usr/local/lib path, rather than using a fake
path.

Additional notes
----------------

Autoconf/libtool - I suggest you read

http://sources.redhat.com/autobook/

which is pretty good.

Particularly for libtool:

http://www.gnu.org/software/libtool/manual.html

A tricky point is the stuff on interfaces. Basically, they say we
should increment the interface number on libpathan if we change the
interface so that programmes linked against the old library will not
link against the new library (ie. function names/parameters changed).

If we do this, we may get

libpathan.so.0 - old interface, old programmes link against this and still work
libpathan.so.1 - new interface, new programmes can link against this

So everything still works.

Note that these interface numbers are _not version numbers_. They are
often used as such but this is fairly broken!

Autodependences
---------------

I've added automatic dependency generation to the makefiles,
ie. change a header and all the relevant .cpp files are recompiled.

Basically gcc -MM produces a file (the .d file) on stdout which is in
the form (after sed transformation) of

file.cpp file.d : file.cpp file.h otherfile.h

etc.

ie. The cpp file and dependency file will be recompiled if anything
file.cpp depends on is changed.

These targets are included into the main makefile with

-include $(patsubst %.cpp,$(srcdir)/objs/%.d,$(filter %.cpp,$(SOURCES)))
-include $(patsubst %.cpp,$(srcdir)/objs/%.dtest,$(filter %.cpp,$(SOURCES)))

ie. include $(srcdir)/objs/*.d , *.dtest (the hyphen means don't
complain if the dependences not there [they will be rebuilt])

The implicit rules are:

$(srcdir)/objs/%.d: %.cpp
	@set -e; $(CXX) -MM $(DEFINES) $(CXXFLAGS) $(INCPATH) $< \
	| sed 's^\($*\)\.o[ :]*^\1.o $@ : ^g' > $@; \
	[ -s $@ ] || rm -f $@
$(srcdir)/objs/%.dtest: %.cpp
	@set -e; $(CXX) -MM $(DEFINES) $(CXXFLAGS) $(INCPATH) $(TESTFLAGS) $< \
	| sed 's^\($*\)\.o[ :]*^\1.otest $@ : ^g' > $@; \
	[ -s $@ ] || rm -f $@

Normally I use VPATH = $(srcdir)/objs which allows me to leave the
path [$(srcdir)/objs/] off the normal %.o and %.otest implicit rules.

Unfortuately, this doesn't work for the includes and must be specified
in full for the %.d and %.dtest implicit rules.

HEISENBUG
---------

Heisenbug is easy to build but I haven't updated the build system is
not automatic like Pathan's.

in heisenbug/src/Makefile.defs

glibc2.2 build (RedHat 7.1)
---------------------------

INCPATH      = -I../../../Xerces1_5/xerces-glibc2.2/include -I../ -I../../../tcl8.4a2/generic -I ../../../Pathan/include
LIBPATH      = -L../../../Xerces1_5/xerces-glibc2.2/lib -L../../../tcl8.4a2/libs -L../../../Path

Solaris build (dart)
--------------------

INCPATH      = -I../../../Xerces1_5/xerces-solaris/include -I../ -I../../../tcl8.4a2/generic -I ../../../Pathan/include
LIBPATH      = -L../../../Xerces1_5/xerces-solaris/lib -L../../../tcl8.4a2/unix -L../../../Path
LIBS         = -lxerces-c1_5_1 -ldl -lpthread -lpathan -ltcl8.4


For Solaris heisenbug, we have to build libtcl first.

cd <path>/devel/tcl8.4a2/unix
./configure
make

When running make sure your LD_LIBRARY_PATH points at
<devel>/tcl8.4a2/unix and <devel>/Xerces1_5/xerces-solaris

