<!--  vim: set sw=2 sts=2 et ft=docbk:

  Part of the A-A-P recipe executive: Customizing Tools

  Copyright (C) 2002-2003 Stichting NLnet Labs
  Permission to copy and use this file is specified in the file COPYING.
  If this file is missing you can find it here: http://www.a-a-p.org/COPYING

-->

<para>
Tools are used to execute actions.  Examples are a compiler and a linker.
Each tool must be executed with specific arguments.  But the recipe attempts
to be portable, thus not include the literal command to be executed.
The mechanism described in this chapter takes care of translating the generic
action into invoking a specific tool with its arguments.
</para>

<para>
It all starts with an action.  Let us use the C compile action as an example.
In the default recipe a default C compile action is defined.  This one works
for most C compilers that take arguments like the Unix "cc" command.  If
another kind of compiler is to be used, the $C_COMPILE_ACTION variable is set
to the name of the action to be used, for example "compile_msvc".
The default compile action will check the $C_COMPILE_ACTION variable and
invoke the "compile_msvc" action instead of using its generic compile command.
</para>

<para>
During startup the default recipe will check for existence of tools for C and
C++.  A specific sequence of tools is checked for, depending on the platform.
Thus in MS-Windows "msvc" will be checked for, while on Unix this doesn't
happen.  This is implemented with a Python module.  For msvc it is
"tools/msvc.py".
</para>

<para>
Each tool module defines an exists() function.  It contains a check if the
tool can be found.  Mostly this is done by looking for a certain executable
program.  The msvc tool searches for "cl" (the compiler) and "vcvars32" (a
command to start using the MSVC command line tools).
</para>

<para>
If a tool is detected, the actions for it are defined.  This is always done,
also when another tool was already detected.  This allows the user to invoke
specific actions or switch toolchain where he wants to.  For MSVC the
"compile_msvc" action is defined.  That is like the normal "compile" action
but with MSVC specific arguments.
</para>

<para>
The first tool that is detected will be used by default.  The
use_actions() function of the tool is invoked, which sets a number of
variables, such as $C_COMPILE_ACTION, to the name of the action to be used.
As mentioned above, the result will be that the generic actions will invoke
the tool-specific action.
</para>

<bridgehead>Building in a different way</bridgehead>

<para>
The default build action works for object files generated from C source files.
It might also work for other object files, in that case you do not need to do
anything.
</para>

<para>
When building needs to be done in a different way, depending on the kind of
source files used, add a "buildaction" attribute to the object file.  This will
make the default build action invoke the action specified with "buildaction"
instead of the default build commands.  Sources without a "buildaction"
attribute do not influence this choice.
</para>

<para>
Note that it is not possible to have two different "buildaction" attributes on
the sources of the build action.  If you want to handle this set the
$BUILD_ACTION variable to the build action that can handle this.
</para>

<para>
If a tool needs to do building for C and C++ files differently, set the
$C_BUILD_ACTION and/or $CXX_BUILD_ACTION variables to the action that will
do the building.
</para>



<bridgehead>Adding A New Tool</bridgehead>

<para>
You need to write a Python module and place it in the "tools" directory.  Copy
one of the existing tool files to start with.  Then make changes to the
functions:
<variablelist>
  <varlistentry><term>
      exists()
    </term>
    <listitem>
      <para>
        Return True if the tool can be located.  This is mostly done by simply
        checking for an executable program with the
        <link linkend="python-program-path">program_path()</link> function.
        But you might do something more complicated, such as running the
        program with a "--version" argument and check the output.
      </para>
    </listitem>
  </varlistentry>

  <varlistentry><term>
      define_actions()
    </term>
    <listitem>
      <para>
        Define the actions that this tool can accomplish.  Each action
        name should be formed from the basic action name with "_toolname"
        appended.  Thus a compile action for the MSVC compiler uses the action
        name "compile_msvc".  You can define this action for several file
        types.
      </para>
      <para>
        The action usually supports using variables, so that the user can
        modify them in a recipe.  Some variables are generic and can be used
        by all tools, such as $CFLAGS.  Your tool may need to translate it
        from the generic form to the tool-specific argument.  For example, if
        $DEFINE contains "-DFOO=foo" you might have to translate this to
        "/D:FOO=foo".
      </para>
      <para>
        You can also support specific variables for your tool.  For example
        $MSVC is used to specify the name of the compiler.  You give it a
        default value in the toplevel scope, but only when the user didn't do
        that already.  The toplevel scope can be obtained from the Global
        module: "Global.globals".
      </para>
    </listitem>
  </varlistentry>

  <varlistentry><term>
      use_actions(scope)
    </term>
    <listitem>
      <para>
        This function is called when the actions of the tool will be used
        as the default actions in "scope".  When the tool is the first one
        found it will be called from the startup code.  But the user may also
        use this to select a specific tool to be used in one recipe, or even
        one dependency.
      </para>
    </listitem>
  </varlistentry>
</variablelist>
</para>


<bridgehead>Using A Specific Tool</bridgehead>

<para>
  The
  <link linkend="cmd-usetool">:usetool</link> command can be used to specify a
  specific tool to be used in
the current scope.  When used in the toplevel recipe the tool becomes the
default tool.  When used in a child recipe the tool will be used in that
recipe or by all actions invoked there.  It can also be used in build
commands, the tool will be used by invoked actions and dependencies.
</para>

<para>
Example:
<programlisting>
        :usetool mingw
        :update prog_A
        :usetool msvc
        :update prog_B
</programlisting>
</para>


<para>
This actually works by defining the tool-specific actions and defining
variables such as $C_COMPILE_ACTION in the current scope.
</para>
