The code that goes into a make rule implementation file,
     preplugin.mk, or
     plugin.mk file is regular GNU
     Make code.  There are certain practices that you
     should follow when writing GNU Make
     code for use within abuild.  A good way to learn about writing
     rules for abuild is to study existing rules.  Here we will
     briefly list some things that rules authors must keep in mind:
     
        If you are about to write some rules, consider carefully
        whether they should be local rules for a specific build item
        (accessed with the LOCAL_RULES variable),
        exported rules provided by a build item (accessed with the
        RULES variable), or whether they should be
        made globally accessible by being included in a plugin.  The
        last case will be rare and should only be used for
        functionality that really should work “out of the
        box” in a particular build tree.  Plugin rules and build
        item rules must appear in the
        rules/
        directory or the target-typerules/all directory
        within the providing build item.  Local rules can appear
        anywhere, and the location must be named in the
        LOCAL_RULES variable in
        Abuild.mk.  It is also possible to create
        global make code that is loaded from a plugin directory:
        abuild will load any preplugin.mk and
        plugin.mk files defined in plugins in the
        order in which the plugins are declared.  Remember that
        preplugin.mk is loaded before
        Abuild.mk, and
        plugin.mk is loaded after
        Abuild.mk.  This makes it possible for a
        plugin to provide some initial variable settings for the user
        in preplugin.mk, have the user do
        something with or modify those values in
        Abuild.mk, and then use the result that
        operation in plugin.mk.
       
Abuild invokes make with the --warn-undefined-variables flag. This means that your users will see warnings if you assume that an undefined variable has the empty string as a value. If it is your intention to have an undefined variable default to the empty string, then you should include
VARIABLE ?=
        in your rules, where VARIABLE is the name
        of the variable you are setting.  You can always provide
        default values for variables in this fashion if the intention
        is to allow users to override those values in their own
        Abuild.mk files.
       
        Note that Abuild.mk files are included
        before rules files.  This is necessary because the
        Abuild.mk file contains information about
        which rules are to be included.  If your rules are providing
        values that users will use in their
        Abuild.mk files, you should recognize
        that your users will need to avoid referencing those variables
        in assignment statements that use :=
        instead of = since the
        Rules.mk variables will not yet be
        defined when Abuild.mk is read.
        Alternatively, you can make use of the
        preplugin.mk functionality for rules
        supplied by plugins.
       
        You should always provide a help file for your rules.  The
        help file is called
        ,
        and lives in the same directory as the rule implementation.
        For an example and discussion of this, see Chapter 22, Build Item Rules and Automatically Generated Code  and Chapter 8, Help System.
       rulename-help.txt
        If your rules require certain variables to be set, check for
        those variables and given an error if they are not defined.
        For an example of this, see Section 22.2, “Code Generator Example for Make”.  The
        ccxx.mk rules in the abuild sources
        (Appendix I, The ccxx.mk File) provide a somewhat more
        elaborate example of doing this since they actually generate
        dynamically in terms of other values the list of variables
        that should be defined.
       
All rules should provide an all:: target. Note that abuild never invokes a user-supplied clean target, so providing a clean target is not useful. [61] Although you can add additional targets in your rules files, think carefully before doing so. Having too many custom targets will make a source tree hard to build and maintain. If you are adding functionality that should be done as part of every build, consider making it part of the all:: target.
        If you are adding support for a new test driver, you should
        make sure that your test driver is invoked from the
        check, test, and
        test-only targets.  You must also ensure
        that both the check and
        test targets depend on the
        all target but that the
        test-only target does not depend on the
        all target.  Abuild internally provides
        this construct for these targets that don't do anything, so if
        your test support only operates conditionally upon the
        presence of test files, you don't have to worry about
        conditionally defining empty targets.  For an example, see
        make/qtest-support.mk in the abuild
        distribution.
       
        Sometimes it may be useful to provide debugging targets for your
        users that provide some information about the state as your
        rules see it.  The ccxx rules provide a
        ccxx_debug target for this purpose.
       
        Always remember that any targets you define in your rules files
        are run from the output subdirectory.  The variable
        $(SRCDIR) points to the directory that
        contains the actual Abuild.mk file and
        therefore presumably the source files.  Abuild sets the
        VPATH variable to this as well, but you may
        have to explicitly run your actions with arguments that point
        back to the source directory (e.g., -I
        $(SRCDIR)).  If make finds a target's prerequisite
        using VPATH, the full relative path to the
        prerequisite will be accurately reflected in
        $< and $^, which will
        be sufficient for many cases.
       
        In order to have your rules behave properly with the
        --verbose and --silent
        flags, you should avoid putting
        @ in front of commands that the user should
        see in verbose mode, and you should have all your rules print
        short, simple descriptive messages about what they are doing.
        These rules should be printed using
        @$(PRINT).  The PRINT
        variable is usually set to echo, but it is
        set to @: when abuild is running in
        silent mode.  Note that we put an @ sign at
        the beginning of the @$(PRINT) command so
        that the user will not see the echo command itself (in
        addition to what is being echoed) being echoed when they are
        running in verbose mode.
       
        There are some convenience functions provided by abuild's
        GNU Make code.  The best way to learn is to read existing
        rules.  If you are going to be writing a lot of
        make code for abuild, it will be
        in your interest to familiarize yourself with the code in
        make/global.mk in the abuild
        distribution.
       
[61] In abuild 1.0, user-supplied clean targets were run when abuild was invoked from inside an output directory, but this turned out not to be particularly useful or reliable. The practice of having clean targets simply remove output directories seems to have emerged as a best practice in the community anyway.