Features Download
From: Gregory Crosswhite <gcross <at> phys.washington.edu>
Subject: ANNOUNCE: Blueprint 0.1 -- PREVIEW
Newsgroups: gmane.comp.lang.haskell.cafe
Date: Monday 30th November 2009 15:23:36 UTC (over 8 years ago)
I earlier posted to this list asking for help in getting Cabal to play with
a Fortran compiler.  When it turned out that there was no answer to this, I
of course did the obvious thing --- I wrote my own build system.  :-)

It already boasts the following features:

	* Fully self-hosting --- can both build and install itself.

	* Implicitly detects and tracks module dependencies.

	* Builds in parallel as much as possible.

	* Can scan through a source directory to add all files, saving the trouble
of adding them manually.

	* Supports compiling C and Fortran sources in addition to Haskell sources,
and linking everything together.

	* Utilizes a “tool” system to make it easy to extend its
functionality, such as by adding a new language.

	* Flexible configuration system:  tool options (e.g., path to the Fortran
compiler) can be detected automatically, set in a configuration file, or
specified on the command line.

	* Provides help messages both to list the targets and to explain the
configuration command-line options.

	* Does not terminate at the first error, but instead tries to do as much
as possible and then report all errors.  (This is a general philosophy that
holds both for the build, the configuration, etc.)

	* Easily supports multiple targets that can depend on the results from
other targets.

	* Automatically resolves package dependencies, as read from .cabal file. 
Detects when a module is not in any known dependency, and reports an error
that also lists all packages that export this module.

What separates this system apart from others is that it uses Haskell’s
built-in laziness to handle dependency ordering and parallelism.  That is,
one expresses the desired build result as a function of the input sources; 
when the result is demanded, it causes Haskell to go through and execute
on-demand all of the necessary build steps.  To get parallelism, just tell
GHC to use multiple threads with the “+RTS -N# -RTS” option, where # is
the number of threads.  (All that I had to do to get this to work was put
parLists in a couple of places.)  This is a big win for me because it means
that I get the correct behavior without having to write and test my own
complicated graph data structure for tracking the dependencies between
build steps.

The philosophy of building up a big calculation of which only parts need be
lazily demanded can be extended further to the build phases, which I call
“targets”.  For example, the first line of the code defining the build
target is:

	build = configure >>= \configuration -> ...

This demands the configuration target, and then uses the result in the
build.  So when you run “./Setup configure”, you only demand that Setup
compute the value of “configure”, but when you run “./Setup build”
you demand both “build” and also “configure”.

All of the errors that are reported are “composable” in the sense that
they can be combined into a new error message that leaves nothing out and
also has no duplicates.  As much as possible the system tries not to stop
until it has nothing else that it can do, allowing it to uncover as many
errors as possible and then compose them into a single message.

I have posted Blueprint to Hackage so that people can see what I have done
and possibly play with it.  I hope to eventually document it and add
examples, but I figured it was better to release early and get it out there
sooner rather than later so that people can see what I’ve done.  Thus, at
this point it should be considered a PREVIEW release, not even an alpha
release.  Having said that, within the domain of the functionality it
implements it works well enough that I use it myself as the build system
for a Physics simulation code that is a mixture of C, Haskell, and Fortran.

To see what Blueprint looks like in action, take a look at Setup.hs.  For
example, Setup can either build a library (“build” target) or it can
build itself (“bootstrap” target);  it is smart enough to use different
flags and directories in the two cases so that there ends up being in
essence two parallel builds.  Setup also has a lot of targets:  configure,
reconfigure (delete cached configuration and then configure), build,
rebuild (clean then build), clean, distclean, install, bootstrap (build
itself rather than a library), haddock (documentation generation that does
not work particularly well yet). 

Anyway, take a look if any of this sounds interesting to you, and let me
know if you have any questions!

- Greg

PS:  You're best bet for browsing through the sources is to use Leo
(leo.sourceforge.net), since this makes it easier for you to see how
everything is organized.
CD: 2ms