<page xmlns="http://projectmallard.org/1.0/" type="guide" id="rules">
<info>
    <link type="guide" xref="index#recipes"/>
</info>

<title>Rules</title>

<p>
A <em>rule</em> defines how to combine a number of <em>input</em> files into one or more <em>output</em> files.
For simple projects you should not need to write any rules - where Bake knows about the language or data type it can be used without you writing rules for them.
</p>
<p>
The syntax for a rule is:
</p>
<code>
<em>output0</em> <em>output1</em> ... : <em>input0</em> <em>input1</em> ...
    <em>command0</em>
    <em>command1</em>
    ...
</code>
<p>
Inputs and commands are optional but there must always be one output.
Outputs, input and commands may all contain <link xref="variables">variables</link>.
The commands are indented using whitespace.
It does not matter what whitespace you choose, as long at the following commands use the same indentation.
The rule is terminated by another line with different indentation (e.g. a new rule).
</p>
<p>
This rule states "whenever the inputs change, run the commands and this will create/update the outputs".
It is an error if the inputs do not exist or all the outputs are not generated.
An input may already exist in the project (i.e. the file was written by the project author) or be a generated file from another rule.
</p>
<example>
<p>
For example, the following rule will take two C files and generate a program by running them through a compiler:
</p>
<code>
foo : foo1.c foo2.c
    gcc -o foo foo1.c foo2.c
</code>
</example>
<p>
When bake runs a command it will print out the full command line that is run.
If you want to suppress this then put a '@' at the start of the command.
</p>
<example>
<p>
For example, the following rule:
</p>
<code>
foo : foo1.c foo2.c
    @echo "Compiling foo..."
    @gcc -o foo foo1.c foo2.c
</code>
<p>
prints out a description of what is being done rather than the command that is used to build it.
</p>
</example>
<note>
<p>
You can force bake to always show the commands that are run by running <code>bake --verbose</code>.
</p>
</note>
<p>
Normally each output specified a file that will be generated.
If you want to make a rule that doesn't generate any files you can make a special named output by preceeding it with a '%'.
This means you can run this rule by building that name but not expect any output.
</p>
<example>
<p>
For example, the following rule:
</p>
<code>
%install : foo
    cp foo /usr/bin
</code>
<p>
allows you to run <code>bake install</code> to build and copy your program foo into the system binary directory.
</p>
</example>
<note>
<p>
You can see all the available targets by running <code>bake --list-targets</code>.
</p>
</note>
<note>
<p>
Bake works by converting known variables to rules and running those rules.
You can see what rules are generated by running <code>bake --expand</code> in the directory of the recipe to show the recipe as Bake will run it.
</p>
</note>
</page>
