Bam is a build system with the focus on being having fast build times and flexiable build scripts. Instead of having a custom language it uses Lua to describe the build steps. It's written in clean C and is distrubuted under the liberal zlib licence. Available on many platforms including but not limited to Linux, Mac OS X and Windows.
Building Bam is easy and have very few dependencies. Make sure that you have GCC and pthreads installed and run this command:
sh make_unix.sh
This will build bam with optimizations turned on. If you want a debug version of bam, you can invoke the script like this:
sh make_unix.sh -O0 -g
That will turn off the optimizations and include debug information in the build.
To build on windows you need to have either Microsoft Visual C++ or MinGW.
To build with Visual C++, just run press Start, Run and enter cmd.exe and press enter. Then navigate to the Bam directory and type this:
make_win32_msvc.bat
The batch file will automaticly detect the Visual C++ version and setup the compile environment and then build an optimized version of Bam. You should find the exe in the base directory of Bam.
To build with MinGW, make sure that you have a correct build environment setup in a console and then run this:
make_win32_mingw.bat
An optimized version of Bam will be built and the exe can be located in the base directory of Bam.
Building Bam works the same way as on Unix-like systems but the script is called make_beos.sh instead. You can build Bam by running:
sh make_beos.sh
Bam comes with a test suite to verify that Bam is working like it should. The suite requires Python to be installed. This test suite is used during the development of Bam to verify that nothing breaks between releases. You can run the test suite by typing this:
python scripts/test.py
It will either print out that all tests where successfull or what tests it didn't pass.
This section is a short introduction to bam and is designed to get you started quickly.
1: settings = NewSettings() 2: source = Collect("src/*.c") 3: objects = Compile(settings, source) 4: exe = Link(settings, "my_app", objects) 5: DefaultTarget(exe)
Line 1 creates a new settings object. This contains all the settings on how to compile, link etc. See NewSettings.
Line 2 gathers all the files under the src/ directory which has .c as extention. Collect returns a table of strings which are the files. See Collect.
Line 3 compiles the source using the specified settings and returns a table of the object files. See Compile.
Line 4 links the object files to an executable named "my_app", using the specified settings. See Link.
Line 5 tells bam that the executable is the default target to build. If you invoke bam without specifying what to build, it will use the default target. See DefaultTarget.
This section describes how you can make your own custom actions needed for your perticular project. An action is just a normal Lua function that adds a series of jobs and dependencies.
For the sake of demonstration, we are going to compile an application without using the supplied Compile and Link actions. Instead we are going to add the jobs and dependencies by hand. We assume that we are running under a Unix like operating system with GCC as tool chain for sake of simplicity.
A job is a command line that needs to be executed to generate an output file. All actions results in a series of jobs being added to the node graph.
To compile myapp.c into myapp.o we simply add this to our bam file:
AddJob("myapp.o", "compiling myapp.c", "gcc -c myapp.c -o myapp.o")
Bam now knows that inorder to get myapp.o, it must run "gcc -c myapp.c -o myapp.o". It will print "compiling myapp.c" when this is happening as a nice indicator instead of spewing out the whole command line that it ran. See AddJob for a complete reference of the function.
Now that we can compile our object, we need to link it as well. To link the application, we add this to our bam file:
AddJob("myapp", "linking myapp", "gcc myapp.o -o myapp")
Bam now knows that inorder to get myapp, it must run "gcc myapp.o -o myapp".
We can now build our application by running these commands from a shell:
# bam myapp.o # bam myapp
We must run both commands because Bam does not yet know that it needs to build myapp.o before it can build myapp. This is where dependencies comes in.
To tell Bam that myapp needs myapp.o we simply add a dependency. This is done with the AddDependency function like this:
AddDependency("myapp", "myapp.o") AddDependency("myapp.o", "myapp.c")
This tells Bam that myapp needs myapp.o inorder to build. We also added myapp.c as a dependency for myapp.o. This will make sure that bam rebuilds myapp.o when myapp.c changes. See AddDependency for a complete reference of the function.
TODO: Some nice text about this
AddJob("myapp.o", "compiling myapp.c", "gcc -c myapp.c -o myapp.o") AddJob("myapp", "linking myapp", "gcc myapp.o -o myapp") AddDependency("myapp", "myapp.o") AddDependency("myapp.o", "myapp.c") DefaultTarget("myapp")
TODO: Some nice text about this
Here is a small function that takes one C file as a string and returns the object file as one string. This is an over simplification of the supplied Compile function and serves just as an example.
function Compile(cfile) output = PathBase(cfile) .. ".o" AddJob( output, "Compiling " .. cfile, "gcc -c " .. cfile .. " -o " .. output ) AddDependency(output, cfile) return output end
Specify a target to be built. A target can be any output specified to the AddJob function.
If no targets are specified, the default target will be built If there are no default target and there is only one target specified with the Target function, it will be built. Otherwise bam will report an error.
There is a special pseudo target named all that represents all targets specified by the Target function.
TODO
Base file to use. In normal operation, Bam executes the builtin base.bam during startup before executing the build script itself. This option allows to control that behaviour and loading your own base file if wanted.
Bam file to use. In normal operation, Bam executes default.bam. This option allows you to specify another bam file.
Cleans the specified targets or the default target.
Prints all commands that are runned when building.
Sets the number of threads used when building. Set to 0 to disable.
Prints out a short reference of the command line options and quits directly after.
Sets the format of the progress report when building.
Does everything that it normally would do but does not execute any commands.
Prints out the time spent building the targets when done.
Dumps all nodes in the dependency graph, their state and their dependent nodes. This is useful if you are writing your own actions to verify that dependencies are correctly added.
Tells bam what version this script is written for. It will either make sure that it behaves like that version or print out an error.
CheckVersion("0.1.0")
Flatterns a tree of tables
Normalizes the path in str by removing ".." and "." from it
Path("test/./path/../file.name.ext") -- Returns "test/file.name.ext"
Returns the everthing except the extention in the path.
Path("test/path/file.name.ext") -- Returns "test/path/file.name"
Path("test/path/file.name") -- Returns "test/path/file"
Path("test/path/file") -- Returns "test/path/file"
Returns the filename of the path in str.
PathFilename("test/path/file.name.ext") -- Returns "file.name.ext"
Returns the extension of the filename in str.
PathFileExt("test/path/file.name.ext") -- Returns "ext"
Returns the path of the filename in str.
PathPath("test/path/file.name.ext") -- Returns "test/path"
TODO
TODO
Gathers a set of files using wildcard. Accepts strings and tables of strings as input and returns a table of all the files that matches A single wildcard * may be used in each string to collect a set of files.
Example:
source_files = Collect('src/*.c", "lib/*.c")
Note. This version collects files, non-recursive.
Collects files as the Collect but does so recursivly.
Collects directories in the same fashion as Collect but returns directories instead.
Collects directories in the same fashion as Collect but does so recursivly and returns directories instead.
TODO
Specifies filename as a target. This target will be include when specifying the all target.
Specifies the default target use build when no targets are specified when bam is invoked.
TODO
TODO
TODO
TODO
TODO
TODO
TODO
Adds a job to be done. The output string specifies the file that will be created by the command line specified in command string. The label is printed out before command is runned.
Specifies a dependency of a file. The file specified in the depfilename is a dependency of filename.
TODO
TODO
TODO
TODO
Copyright (c) 2008 Magnus Auvinen
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.