Build process overview

Table of Contents:



build targets and terms:

The build is based on Jakarta Ant. To build, cd to the build subdirectory off the deployment project you wan to build from (for example sand/apps/deploy/TaskHeapDemo/build), and type ant. This will invoke the default "all" target.

The following terms are used in build discussions:

The driving project determines the code that will be generated. See the
sandbuild documentation for details on code generators.

Primary build targets (from mainbuild.xml):

For a complete list of targets, refer to the build.xml file in the build directory of the driving project.

SAND project names must be unique. This provides for unique .jar file names, build element identification, and other uses.

TOC


build dependency checking:

The primary goal of build processing is to produce a consistent result with the minimum possible work. The build must be trustworthy (produce a deployed executable in a reliable manner), and it should provide maximum utility for common development situations. The build should also be flexible enough to be adapted to uncommon situations.

A SAND build is distinguished by its use of generators. Metacoding affects all code in all projects in the dependency graph including the supporting platform project(s). Among other things, in the SAND build:

  1. multiple deployments cannot be combined into a single build
  2. only those projects in the current dependency graph are built
  3. the contents of a .jar file or other compiled artifact varies with the dependency graph
In essence, the SAND build is writing the specified deployment, not just compiling it.

The SAND build is based on Jakarta Ant, and is therefore obviously compatible with conventional static build systems, and extensible in similar ways. It can also be extended through custom generators, which provide broad development power at the source code level without changes to the implementation language or modifications to code.

There are two major categories of build:

A full build is guaranteed to be safe, and you can return your system to a source-only state by typing ant scrub.

The concept of an incremental build is straightforward: don't rebuild the target unless the source has changed, make sure you do rebuild when you have to. However in practice this involves some tradeoffs, the details of which are best described through use cases and flag descriptions.

TOC


use case: general

In general, the expectation is that both novice and advanced users will simply type "ant" to take care of all build and deployment needs. The SAND build should be smart enough to take care of everything without doing extra work or otherwise annoying the developer.

Given the complexities that arise, it is unlikely the SAND build will ever reach 100% of this goal, but we are shooting for 90% and doing the work necessary to make that happen.

TOC


use case: forced recompilation

There are times when code needs to be recompiled, without the generators involved. Known examples include:

Forced recompilation is accomplished through the "clean" and "deepclean" targets, followed by the default "ant" call. There is no need for a separate compilation call, since the generators do not access the compiled files (see SandGenerator comments). However there is some additional overhead from checking this:

with all work occurring in memory. This overhead has not been significant enough to warrant an additional build target, especially as "static linkage problems" occasionally turn out to be due to code that should have been regenerated. The simplicity of just typing "ant" for all build processing is also an advantage for those less familiar with the build system.

TOC


flag: generateJavadoc

Javadoc API documentation is a good thing, but developers whose tools support equal or better code navigation don't want to pay for this ovehead in their local environment. Javadoc behavior in the SAND build is controlled through a flag set as an Ant property:

If the ${generateJavadoc} is not defined, then "update" is assumed. It is recommended that the property be set only in the deployment build file, since it is a global property. To avoid changes to the build.xml file, this property can also be set from an environment variable.

Notes:

TOC


flag: debug

By default java is compiled with debug=on. This can be controlled through an Ant property:

TOC


java static linkage:

Java linkage is done at compile time. That means that if class A references class B, then whatever A knows about B at compile time is what it goes with. If B is recompiled, A still thinks it is looking at the same old B. Given that class loaders can cache stuff, there is even a chance that A will find the old B at runtime. This can be very confusing if you just changed B and are wondering how the devilish system can possibly be ignoring your changes.

By recompiling A when B changes, you have a new A referencing a new B and everything works the way you would expect. But rebuilding everything every time is annoying, slow, and not always possible. Basically the build system does it's best to manage the dependencies, but recompiling everything each time would be prohibitively annoying for most users doing incremental builds.

Note that problems due to compile time linkage don't manifest themselves when building from scratch, so a typical reference build will not run into these issues. If you are using a debugger, you may see what it is going on relatively quickly, but rediscovering this behavior can be a time sink.

TOC


processing overview:

Each deployment or apps project contains a build subdirectory with a build.xml file. When ant loads build.xml, the mainbuild.xml include is processed, which provides the main ant targets ("all", "clean", "deepclean", "scrub", "rebuild" etc). These targets fall into two categories:

Both local and global targets call through to the sandbuild task to manage the build process efficiently. The sandbuild task is mapped to org.sandev.sandbuild.BridgeAnt2SAND, which retrieves the SandBuildDriver and

  1. sets the scope (LOCAL/GLOBAL), type (STATIC/DYNAMIC/ALL), and mode (BUILD/CLEAN) for this build run.
  2. creates a SandProject instance for this project, which initializes the project SandDecl collection (see the SandGenerator interface description for more information on generators and metacoding)
  3. sets the buildRoot to this driving project
  4. starts the build

The SandBuildDriver serves as the central management point for efficient SAND build processing. For a GLOBAL build, SandBuildDriver calls the "sandproject" target in the buildRoot, which (if defined) contains zero or more SAND build tasks:

The build tasks, and the dependency graph, are set up and then processed. By convention, most build targets have a corresponding clean target. The appropriate targets are called depending on the build mode. At the time of this writing, SandBuildDriver calls the following targets to process a GLOBAL build (optional targets are shown in italics):

For a LOCAL scope build, SandBuildDriver only affects the driving project.

TOC














© 2002 SAND Services Inc.
All Rights Reserved.