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.

@GROUP Dependency Graph @END

At the core of Bam there is a dependency graphs that tells one files
are dependent on other files. This graph is used to figure out what
order to build the target.

Here is a simple graph over and application called ^app^ which has the
^src1.c^, ^src2.c^, ^header1.h^, ^header2.h^ and ^shared.h^ files.

!IMG depgraph.png

The commands encased in brackets are the commands that is executed in
order to build that node.

@GROUP Jobs @END

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 ^src1.c^ into ^obj1.o^ we simply add this to our bam file:

{{{{
AddJob("obj1.o", "compiling src1.c", "gcc -c src1.c -o obj1.o")
}}}}

Bam now knows that inorder to get ^obj1.o^, it must run
^"gcc -c src1.c -o obj1.o"^. It will print ^"compiling app.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("app", "linking app", "gcc obj1.o obj2.o -o app")
}}}}

Bam now knows that inorder to get ^app^, it must run
^"gcc obj1.o obj2.o -o app"^.

We can now build our application by running these commands from a
shell:

{{{{
# bam obj1.o
# bam obj2.o
# bam app
}}}}

We must run all three commands because Bam does not yet know that it needs
to build ^obj1.o^ and ^obj2.o^ before it can build ^app^. This is where dependencies
comes in.

@GROUP Dependencies @END

To tell Bam that ^app^ needs ^obj1.o^ and ^obj2.o^, we simply add a dependency. This
is done with the AddDependency function like this:

{{{{
AddDependency("app", "obj1.o", "obj2.o")
AddDependency("obj1.o", "src1.c")
AddDependency("obj2.o", "src2.c")
AddDependency("src1.c", "header1.h", "header2.h", "shared.h")
AddDependency("src2.c", "shared.h")
AddDependency("shared.h", "header2.h")
}}}}

This tells Bam that ^app^ needs ^obj1.o^ and ^obj2.o^ inorder to build. We also
added the source files as dependencies for the object files. This will make sure that
bam rebuilds ^obj1.o^ when ^src1.c^ changes. Also, we added the dependencies for the
source and header files so Bam can figure out want needs to be built if one of those
changes. See [AddDependency] for a complete reference of the function.

@GROUP All Together @END

Here is an example of it all working together.

{{{{
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")
}}}}

There is also a shortcut that you can use 

@GROUP Examples @END

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)
&nbsp;	output = PathBase(cfile) .. ".o"
&nbsp;	AddJob(
&nbsp;		output,
&nbsp;		"Compiling " .. cfile,
&nbsp;		"gcc -c " ..  cfile .. " -o " .. output
&nbsp;	)
&nbsp;	AddDependency(output, cfile)
&nbsp;	return output		
end
}}}}

