The boo build process

Written Oct. 18, 2006 by David Piepgrass (blog | home)

boo is built using NAnt. The build process is controlled by default.build in the root directory of the source distribution; the name of the default target in default.build is "all".

Here is a dependency graph for "all":



This page describes the build-related targets. It does not cover all the targets, only those targets that "all" depends on, or that are related to the build process. (I have not analyzed other targets, such as unit tests.) The targets are listed in bottom-up order, so "all" is at the bottom. After each target, the dependencies are listed in brackets. For example,

abra: (cad, ab, [ra])

signifies that target "abra" depends on targets "cad", "ab" and "ra". The square brackets signify that the dependency is redundant because either "cad" or "ab" already depends on "ra".

Summary

Most of the build targets follow a simple pattern: a target called XYZ causes all the source files (*.cs or *.boo) in folder src/XYZ, and all its subfolders, to be compiled into build/XYZ.dll or build/XYZ.exe. The following targets follow this pattern, except those marked with a star (*). Targets marked with ** follow the pattern, but have additional effect(s).

Target Source files Output file(s)
* init - -
* compile-grammar src/Boo.Lang.Parser/*.g output in src/Boo.Lang.Parser/
* resources src/Boo.Lang/Resources/strings.txt et al. build/strings.resources et al.
** Boo.Lang src/Boo.Lang/**/*.cs build/Boo.Lang.dll
* generate-ast ast.model.boo, via scripts/astgen.boo src/Boo.Lang.Compiler/Ast/Impl/*.cs
Boo.Lang.Compiler src/Boo.Lang.Compiler/**/*.cs build/Boo.Lang.Compiler.dll
Boo.Lang.Parser src/Boo.Lang.Parser/**/*.cs build/Boo.Lang.Parser.dll
core - -
** booc src/booc/*.cs build/booc.exe
** Boo.NAnt.Tasks src/Boo.NAnt.Tasks/*.boo build/Boo.NAnt.Tasks.dll
booi src/booi/*.boo (i.e. booi.boo) build/booi.exe
Boo.Lang.Interpreter src/Boo.Lang.Interpreter/*.boo build/Boo.Lang.Interpreter.dll
booish src/booish/*.boo (i.e. booish.boo) build/booish.exe
** Boo.Lang.Useful src/Boo.Lang.Useful/**/*.boo build/Boo.Lang.Useful.dll
boo src/boo/*.boo build/boo.exe
Boo.Lang.CodeDom src/Boo.Lang.CodeDom/**/*.boo build/Boo.Lang.CodeDom.dll
** Boo.Microsoft.Build.Tasks src/Boo.Microsoft.Build.Tasks/**/*.boo build/Boo.Microsoft.Build.Tasks.dll
* all - -

See the following subsections under "Targets" for more details on these targets, including a summary of the purpose of each component.

Namespaces

By the way, here's a table of namespaces, showing which DLLs contribute to each. An easy way to inspect .NET assemblies (DLLs and EXEs) is to open them with Micro Visual Studio or one of the Visual Studio Express Editions. The assemblies' interfaces will be shown in the Object Browser.
Namespace DLL(s)
Boo.Lang Boo.Lang.dll, Boo.Lang.Compiler.dll
Boo.Lang.Runtime Boo.Lang.dll
Boo.Lang.Compiler Boo.Lang.Compiler.dll
Boo.Lang.Compiler.{Ast, Ast.Impl, Ast.Visitors}
Boo.Lang.Compiler.{IO, Pipelines, Resources, Steps, TypeSystem, Util}
Boo.Lang.Parser Boo.Lang.Parser.dll
Boo.Lang.Parser.Util
antlr
antlr.{collections, collections.impl, debug}
Boo.Lang.Useful.{Attributes, BooTemplate, Collections, CommandLine, IO, IOImpl, Resources) Boo.Lang.Useful.dll
Boo.NAnt
Boo.NAnt.Tasks.dll
CompilerGenerated (note: most code written in boo will have compiler-generated stuff in this namespace) Boo.Lang.Interpreter.dll, Boo.Lang.Useful.dll, Boo.Microsoft.Build.Tasks.dll, Boo.NAnt.Tools.dll

Targets

init:

Creates the build/ folder. That's it!

clean:

Deletes the build/ folder and its contents.

compile-grammar: (init)

Generates a series of C# files:
BooLexer.cs
BooParserBase.cs
BooTokenTypes.cs
BooTokenTypes.txt
BooExpressionLexer.cs
BooExpressionLexerTokenTypes.cs
BooExpressionLexerTokenTypes.txt
WSABooLexer.cs
WSABooParserBase.cs
WSABooTokenTypes.cs
WSABooTokenTypes.txt
WSABooExpressionLexer.cs
WSABooExpressionLexerTokenTypes.cs
WSABooExpressionLexerTokenTypes.txt
from *.g files in src/Boo.Lang.Parser:
boo.g
booel.g
wsaboo.g
wsabooel.g

This is done with ANTLR, a Java program at lib\antlr-2.7.5\antlr-2.7.5.jar.

Parser grammar files (*.g) are written by hand and compiled by ANTLR to generate a C# parser and lexer automatically.

For some reason, this target touches src/Boo.Lang.Parser/BooParserBase.cs.

The actual command used to compile the *.g files is obfuscated by the NAnt syntax. From src\Boo.Lang.Parser, the following commands can be used to compile the *.g files:
java -cp ../../lib/antlr-2.7.5/antlr-2.7.5.jar antlr.Tool -o . boo.g
java -cp ../../lib/antlr-2.7.5/antlr-2.7.5.jar antlr.Tool -o . booel.g
java -cp ../../lib/antlr-2.7.5/antlr-2.7.5.jar antlr.Tool -o . wsaboo.g
java -cp ../../lib/antlr-2.7.5/antlr-2.7.5.jar antlr.Tool -o . wsabooel.g
"WSA" stands for White Space Agnostic. The WSA parser is almost identical to the normal one, but instead of using idention for control, ":" and "end" are used instead. To enable the WSA parser, pass the -wsa option to booc.

resources: (init)

This target builds build/strings.resources from src/Boo.Lang/Resources/strings.txt. The latter is simply a list of text strings; a standard .NET tool (part of the .NET and mono SDKs) called resgen is used to convert the text file into a binary resource file.

This target also calls a sub-target, "build-resource", to make resource files from other text files in src/Boo.Lang/Resources (looks like boo is available in Italian and Portugese.)

Boo.Lang: (resources)

Builds:
build/Boo.Lang.dll
from:
1. src/Boo.Lang/**/*.cs (*.cs in src/Boo.Lang.Compiler and subfolders)
2. the string resource files (e.g. build/strings.resources)
It appears that non-English resources are included only when using a Microsoft framework.

Boo.Lang contains "core" classes that can be used by boo code, such as List and Hash, and built-in functions (in class Boo.Lang.Builtins) including as array(), cat(), enumerate(), map(), join(), zip(), shell(), ...

generate-ast: (init)

Builds:
100 files in src/Boo.Lang.Compiler/Ast/Impl
using:
1. scripts/astgen.boo
2. bin/booi
3. ast.model.boo
Invokes scripts/astgen.boo, which in turn parses ast.model.boo and generates a set of C# classes in src/Boo.Lang.Compiler/Ast/Impl. astgen.boo is invoked via bin/booi (that's why a binary version of boo is included in the source distribution), but without arguments (the filename ast.model.boo is hard-coded in astgen.boo).

All 100 files in src/Boo.Lang.Compiler/Ast/Impl are automatically generated, and all the filenames end in "Impl.cs". An interesting thing is that every file in src/Boo.Lang.Compiler/Ast/Impl contains a base class for a corresponding file in src/Boo.Lang.Compiler/Ast. For example, AttributeImpl.cs contains a class AttributeImpl (namespace: Boo.Lang.Compiler.Ast.Impl). The corresponding file src/Boo.Lang.Compiler/Ast/Attribute.cs defines a class Attribute (namespace: Boo.Lang.Compiler.Ast) that is derived from AttributeImpl.

The 119 files in src/Boo.Lang.Compiler/Ast might be automatically generated as well. TODO figure it out. The following 19 files in src/Boo.Lang.Compiler/Ast do NOT have a corresponding file in src/Boo.Lang.Compiler/Ast/Impl:

AstUtil.cs
BinaryOperatorType.cs
DepthFirstTransformer.cs
DepthFirstVisitor.cs
IAstVisitor.cs
IExplicitMember.cs
INodeWithArguments.cs
INodeWithAttributes.cs
INodeWithParameters.cs
LexicalInfo.cs
MethodImplementationFlags.cs
Node.cs
NodeCollection.cs
NodeType.cs
OmittedExpression.cs
ParameterModifiers.cs
StatementModifierType.cs
TypeMemberModifiers.cs
UnaryOperatorType.cs

TODO figure out the purpose of all this!

Note that this target needs bin/booi; that's why a binary version of boo is included in the source distribution.

Boo.Lang.Compiler: (Boo.Lang, generate-ast)

Builds:
build/Boo.Lang.Compiler.dll
from:
src/Boo.Lang.Compiler/**/*.cs (*.cs in src/Boo.Lang.Compiler and
its subfolders, including sources generated by generate-ast.)
using:
build/Boo.Lang.dll

Boo.Lang.Parser: (Boo.Lang.Compiler, compile-grammar)

Builds:
build/Boo.Lang.Parser.dll
from:
src/Boo.Lang.Parser/**/*.cs (*.cs in src/Boo.Lang.Parser and its
subfolders, including the sources generated by compile-grammar.)
using:
build/Boo.Lang.dll
build/Boo.Lang.Compiler.dll

core: (Boo.Lang.Parser, [Boo.Lang], [Boo.Lang.Compiler])

This target does nothing.

booc: (core)

Builds the boo compiler front-end:
build/booc.exe
from:
src/booc/*.cs
using:
build/Boo.Lang.dll
build/Boo.Lang.Compiler.dll
build/Boo.Lang.Parser.dll
Also:
- Copies src/booc/booc.rsp to build/
- If platform is not Win32, copies extras/booc.in to build/booc,
replacing @RUNTIME@ with mono and @prefix@ with ${install.prefix}.
- Copies extras/template.config.in to build/booc.exe.config,
replacing @SUPPORTEDVERSIONS@ with ${supported.runtimes}.
- Runs ngen (if available) on Boo.Lang.dll, build/Boo.Lang.Compiler.dll,
build/Boo.Lang.Parser.dll and booc.exe.
Note that booc itself is a very small program--it relies on the DLLs to do the actual work of compiling.

Boo.NAnt.Tasks: (booc)

Builds:
build/Boo.NAnt.Tasks.dll
from:
src/Boo.NAnt.Tasks/*.boo; specifically
src/Boo.NAnt.Tasks/UpdateAssemblyVersionTask.boo
src/Boo.NAnt.Tasks/InsertLicenseTask.boo
src/Boo.NAnt.Tasks/BoocTask.boo
src/Boo.NAnt.Tasks/BooTask.boo
src/Boo.NAnt.Tasks/AbstractBooTask.boo
using:
build/booc.exe
${nant.location}/NAnt.Core.dll
${nant.location}/NAnt.DotNetTasks.dll
Builds build/Boo.NAnt.Tasks.dll and loads that DLL into NAnt itself. This DLL contains boo-related tasks, which make it easier to compile boo code from within a NAnt build file. Without a boo task, boo has to be invoked using the "exec" task, which, from what I've seen, is very cumbersome to use.

The "booc" task invokes the boo compiler, booc.exe. The "boo" task runs boo code that is stored directly in the NAnt build file; for example:
	<boo>
print("Hello from boo task!")
print("Framework directory: ${Project.TargetFramework.FrameworkAssemblyDirectory}")
</boo>

booi: (Boo.NAnt.Tasks)

Builds the boo interpreter front-end:
build/booi.exe
from:
src/booi/*.boo (specifically booi.boo)
using:
build/Boo.Lang.Parser.dll
booi is even smaller than booc. Again, the boo DLLs do all the work. This program may be a good demonstration of how you can run a boo script from your own code (But don't quote me.) Note that booi does NOT use Boo.Lang.Interpreter, probably because booi is not interactive.

Boo.Lang.Interpreter: (Boo.NAnt.Tasks)

Builds:
build/Boo.Lang.Interpreter.dll
from:
src/Boo.Lang.Interpreter/*.boo

booish: (Boo.Lang.Interpreter)

Builds an interactive interpreter front-end:
build/booish.exe
from:
src/booish/*.boo (specifically booish.boo)
using:
Boo.Lang.Interpreter.dll
Also:
- Copies extras/template.config.in to build/booc.exe.config,
replacing @SUPPORTEDVERSIONS@ with ${supported.runtimes}.
(note: target booc does exactly the same thing)
- If platform is not Win32, copies extras/booish.in to build/booish,
replacing @RUNTIME@ with mono and @prefix@ with ${install.prefix}.
booish is even smaller than booi. Boo.Lang.Interpreter.dll does all the work.

Boo.Lang.Useful: (Boo.NAnt.Tasks)

This target is built in two stages.
The first stage builds:
src/Boo.Lang.Useful/IO/Impl/PreProcessorExpressionEvaluator.boo
src/Boo.Lang.Useful/IO/Impl/PreProcessorExpressionLexer.boo
src/Boo.Lang.Useful/IO/Impl/PreProcessorExpressionParser.boo
src/Boo.Lang.Useful/IO/Impl/PreProcessorExpressionParserTokenTypes.boo
from:
src/Boo.Lang.Useful/IO/PreProcessorExpressions.g
using:
lib/antlr-2.7.5/antlr-2.7.5.jar (a parser generator that requires Java)

The second stage builds:
build/Boo.Lang.Useful.dll
from:
src/Boo.Lang.Useful/**/*.boo
using:
Boo.Lang.Parser.dll
I was told Boo.Lang.Useful "wraps functionality of booi, booish, and booc" and that it's "an external library of contributed (mostly) code."

It should be possible to process PreProcessorExpressions.g manually from the root folder using this command:

java -cp lib/antlr-2.7.5/antlr-2.7.5.jar antlr.Tool -o src/Boo.Lang.Useful/IO/Impl src/Boo.Lang.Useful/IO/PreProcessorExpressions.g

If you know anything about ANTLR, you may be puzzled because ANTLR 2.7.5 supposedly does NOT support boo as a target language. I assume Rodrigo has included the specially modified version of ANTLR that he made some time ago.

boo: (Boo.Lang.Useful, Boo.Lang.Interpreter.dll)

Builds another interactive interpreter front-end:
build/boo.exe
from:
src/boo/*.boo
using:
build/Boo.Lang.Useful.dll
build/Boo.Lang.Interpreter.dll
When run with no arguments, boo acts like booish. "Geek Ninja" says "boo.exe wraps functionality of booi, booish, and booc."

Boo.Lang.CodeDom: (Boo.NAnt.Tasks)

Builds:
build/Boo.Lang.CodeDom.dll
from:
src/Boo.Lang.CodeDom/**/*.boo
using standard (but non-default) .NET libraries:
System.Data.dll
System.Xml.dll
Boo.Lang.CodeDom is not used by the compiler tools. "PC Bender" says it is "Used by asp.net and other codedom apps, including webbness."

Boo.Microsoft.Build.Tasks: (Boo.NAnt.Tasks)

Runs the 'msbuild' target if the "target-framework" is "net-2.0". msbuild builds:
Boo.Microsoft.Build.Tasks.dll
from:
src/Boo.Microsoft.Build.Tasks/**/*.boo
using:
Microsoft.Build.Utilities.dll
Microsoft.Build.Tasks.dll
Microsoft.Build.Framework.dll
Copies:
src/Boo.Microsoft.Build.Tasks/Boo.Microsoft.Build.targets to build/
Microsoft's "new build platform for Microsoft and Visual Studio", msbuild, can use this DLL.

all: ([booc], booi, booish, boo-pkgconfig, Boo.Lang.CodeDom, [Boo.Lang.Useful], boo, Boo.Microsoft.Build.Tasks)

This is the "main" target--the one used when you start NAnt with no parameters.

rebuild: (clean)

Hosted by www.Geocities.ws

1