Last modified: Feb 24, 2014
A build manager is a tool for scripting the automated steps required to produce a software artifact.
What Should a Build Manager Do?
A good build manager should be
easy to use
easy to set up for a given project
Here are some of the project builds I have had to automate in the opening weeks of one semester:
Set up to allow students to easily compile code for an assignment.
Build each missing or out-of-date .o file by compiling a corresponding .cpp file.
Link all .o files to produce an executable
The code annotation tool is a program I use to convert C++ and Java code with optional markup comments like this into this.
Building the Code Annotation Tool
The steps involved in building this tool are:
Run the program jflex on each file in src/main/jflex, generating a pair of .java files that get placed in src/main/java
Compile the Java files in src/main/java, placing the results in target/classes
Compile the Java files in src/test/java (using the target/classes compilation results, placing the results in target/test-classes.
Run the JUnit tests in target/test-classes.
If all tests pass, package the compiled classes in target/classes into a .jar file.
It’s worth noting how many of the steps in this project build are not simply compile and link steps.
Class Assignment Setup
In preparing to release a programming assignment to a class, the steps are
Run the executable produced in the last step on each test*.dat in the Tests directory, capturing the output as a corresponding .out file.
Copy all source code from the Work directory into a winWork directory.
5.Use a cross-compiler to compile and link the .cpp files in winWork into a Windows executable
The lectures notes for this course are prepared through a process:
Why Not Just Write a Script?
We could simply write a “simple” script to perform each of the steps in sequence …
#!/bin/sh
cp Public/* Work/
cp -f Solution/* Work/
g++ -o Work/program Work/*.cpp
find Tests -name 'test*.dat' -exec sh runTest.sh Work/program {} \;
mkdir WinWork
cp Work/*.h Work/*.cpp WinWork
x86_64-w64-mingw32-g++ -o WinWork/program WinWork/*.cpp --static
mkdir $releaseDir/bin
mkdir $releaseDir/bin/Linux
cp Work/program $releaseDir/bin/Linux
mkdir $releaseDir/bin/Windows
cp WinWork/program $releaseDir/bin/Windows
chmod 775 $releaseDir/bin/*/program
cp *.html *.png $website/
Scripting
But how does this fare according to our earlier build manager goals?
easy to use? Y
easy to set up for a given project? N
Most IDEs come with a built-in project manager.
typically limited to compiling and linking
maybe some support for packaging Compare to our \hyperlink{studentProg}{sample projects}.
Boxes are files.
Arrows denote dependencies. “A depends on B” means that if B is missing or changed, then A must be (re)generated.
Labels on arrows indicate the program used to generate the file at the base of the arrow.
Analysis of such a graph facilitates
efficiency - easy to tell what needs to be rebuilt after a change
incrementality - can determine required build step for any file, not just the “final” one
make is the canonical example of a build manager of this type.
Ellipses are tasks (activities). Each task can involve multiple steps.
Arrows denote success dependencies. “A depends on B” means that A will be run after B and only if task B finished successfully.
This approach facilitates
ease of setup: usually less detailed than a full file-based dependency graph
incrementality - can request any intermediate step
ant is based on this approach.