[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Axiom-developer] Compiling

From: root
Subject: Re: [Axiom-developer] Compiling
Date: Sat, 26 Apr 2003 12:24:46 -0400


> I've successfully gotten the compiler to run, and, after some poking,
> found that obj/linux/bin/interpsys would give me a prompt at which I
> could do some computations.  But, as warned, the compilation is very
> incomplete.  I played around to try to see, e.g., why FFIELDC from
> ffcat.spad.pamphlet was not being compiled, and got to the point of
> getting a 'Value stack overflow', which is now an error I could try to
> address.  (Could it just be that some gcl limits are set too low?)

Ah, would that it were so simple... This is the primary bug that I'm
tracing. The compiler will load definitions of domains and categories
from previously compiled files in order to build the new domain or
category. You can see some of the dependency relationships in the
src/alebra/Makefile comments where I've been documenting them as I
discover them. They basically form a graph which is the source of 
the problem. I've been flattening the graph into a lattice by eliminating
cycles. There appears to be a cycle involving RING which I've been
unable to unwind. The stack overflow occurs because RING involves RING.
My usual attack on this problem is to compile the intermediate lisp code
(Axiom's compiler generates common lisp) rather than compile the Axiom
source. You can see this by looking at the bottom layer of the lattice.
(Each of the stanza's for the bottom layer target the ${MID} file rather
than the ${OUT} file.) For some obscure reason this won't work with RING.
The reason isn't obvious to me yet, thus the delay. It's not all wasted
time as I'm beginning to document how the compiler works. The compiler
was written in a coffee-induced fever and is comment-free.

An algebra rewrite is in order so that the algebra is built as a lattice.
But that won't happen for a long while.

> One thing that seemed clear to me is that there must be automated
> tools for doing this; also, it doesn't seem that this is a very
> efficient use of make, since there are about 24 lines per individual
> category in the Makefile, and many different places that need to be
> changed when you want to, say, add a new file.

Well, I considered using either a common-lisp package or ANT but since
I'd already written most of it before I continued on my path.

Adding a file basically involves cloning the lines of a similar file.

Makefiles ONLY build files in the directory where the Makefile lives.
There is a Makefile for every directory in the source subtree.

Each Makefile MUST ensure that all of the preconditions for building
every subdirectory are satisfied then it walks each subdirectory calling
make in each subdirectory. Thus a leaf Makefile can assume that all of
its preconditions exist (e.g. output directories exist, other files in
other directories have been made, etc). Each non-leaf Makefile can
assume that it's preconditions exist and must only deal with files
either in its own directory or its subdirectories.

The reason the Makefiles are so verbose is that Make is unable to to
automatically handle dependencies if the files are not in the same
directory. The underlying assumption of make is that you build your
code in the directory containing the source code.

Axiom was designed to run on many different platforms and we wanted a
common source tree. In particular, it used to take one to three days of
compiling to build for a particular system (back in the day of 33Mhz).
One observation is that a large portion of the work could be cached and
shared in a read-only manner across many systems  so the "int" directory 
was born. Another observation was that there were system-specific files
that needed to be built (such as .o files) which would not be part of
the customer final image so "obj" was born. "mnt" contains only customer
shipped files. (NAG actually damaged this model by introducing "share"
but I'll fix that eventually).  "lsp" was born because I ported Axiom 
so it ran on about a dozen common lisps though some were never shipped 
because of license issues but we had private copies for test purposes.

Make is really an old tool that is unable to handle the underlying idea
that it needs to compare timestamps of files in different directories.
In order to overcome that lack (Make was all we had) the scheme was to
impose a "pull-flow" model on the stanzas. Each file is compiled because
it is required my MNT, usually from a file compiled in a platform
specific way into OBJ:

${MNT}/foo: ${OBJ}/foo

Now the OBJ file usually comes from an intermediate, cached source file:

${OBJ}/foo: ${INT}/foo

and the intermediate file was built from the source:

${INT}/foo: ${SRC}/foo

So changing a source file causes:

${SRC}/foo -> ${INT}/foo -> ${OBJ}/foo -> ${MNT}/foo

so the makefile stanzas tend to come in groups of 4 per file. 
Many times you'll find that there are less than 4 stanza's per file.

To build for a new system you need only NFS mount the SRC and INT
directories, type make and you get:

              ${INT}/foo -> ${OBJ}/foo -> ${MNT}/foo

Even a source change will only cascade a small ripple (usually) across
all the systems since only a small number of INT, OBJ, and MNT files
will have to change which is the whole point of make. And the source
change will only be done once per multiple systems, cached in INT.

(By the way, you'll notice that the Makefiles actually reference
${IN}, ${MID}, and ${OUT} instead of ${SRC}, ${INT}, ${OBJ} and ${MNT}
as there are various "IN" and "OUT" directories for different types
of files. ${IN}, etc, are constructed at the top of each Makefile.)

If make supported the notion of cross-directory timestamps the makefiles
would be less verbose. You'll note, however, that the stanzas, while
seemingly repeated copies, yet there is a lot of "special" knowledge built
in to customize the dependencies. Almost all of the customization is
there to ensure that the minimum of work is done to build the system.

I eventually reduced the 3 day builds to about 1 hour and they could
all run in parallel because SRC and INT were read-only after the first
build occurs, a factor of 48 (3*24) speedup.

Given the speed of systems these days, given the fact that users will
not be doing parallel, NFS mounted builds, given the fact that read-only
sources are not necessary for individual systems, etc. a lot of the 
assumptions that went into designing the Makefiles are invalid. 
Nevertheless, Axiom is STILL a large system and building it in a 
a simplistic manner on my 1Ghz machine STILL takes a long time whereas
the Makefiles reduce this to seconds, it probably is worthwhile rethinking
the design but "throwing it all away and doing it by brute force" is 
still a lose. 

In the cleverest of implementations the user should just be able to
NFS mount the CVS directories, type make and get a working Axiom
without ever copying the sources. In such a world you could rebuild
Axiom from savannah each time the user runs it so their image
reflects the very latest changes. No more downloads, no more tar.gz
files, etc. Axiom's makefiles could support this. Now THAT would be novel.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]