21.8. Extending SCons: Adding Your Own Custom Checks
Prev | Chapter 21. Multi-Platform Configuration (Autoconf Functionality) | Next

## 21.8. Extending SCons: Adding Your Own Custom Checks

A custom check is a Python function that checks for a certain condition to exist on the running system, usually using methods that SCons supplies to take care of the details of checking whether a compilation succeeds, a link succeeds, a program is runnable, etc. A simple custom check for the existence of a specific library might look as follows:

    mylib_test_source_file = """
    #include <mylib.h>
    int main(int argc, char **argv)
    {
        MyLibrary mylib(argc, argv);
        return 0;
    }
    """

    def CheckMyLibrary(context):
        context.Message('Checking for MyLibrary...')
        result = context.TryLink(mylib_test_source_file, '.c')
        context.Result(result)
        return result

The `Message` and `Result` methods should typically begin and end a custom check to let the user know what's going on: the `Message` call prints the specified message (with no trailing newline) and the `Result` call prints `yes` if the check succeeds and `no` if it doesn't. The `TryLink` method actually tests for whether the specified program text will successfully link.

(Note that a custom check can modify its check based on any arguments you choose to pass it, or by using or modifying the configure context environment in the `context.env` attribute.)

This custom check function is then attached to the configure context by passing a dictionary to the `Configure` call that maps a name of the check to the underlying function:

    env = Environment()
    conf = Configure(env, custom_tests={'CheckMyLibrary': CheckMyLibrary})

You'll typically want to make the check and the function name the same, as we've done here, to avoid potential confusion.

We can then put these pieces together and actually call the `CheckMyLibrary` check as follows:

    mylib_test_source_file = """
    #include <mylib.h>
    int main(int argc, char **argv)
    {
        MyLibrary mylib(argc, argv);
        return 0;
    }
    """

    def CheckMyLibrary(context):
        context.Message('Checking for MyLibrary... ')
        result = context.TryLink(mylib_test_source_file, '.c')
        context.Result(result)
        return result

    env = Environment()
    conf = Configure(env, custom_tests={'CheckMyLibrary': CheckMyLibrary})
    if not conf.CheckMyLibrary():
        print('MyLibrary is not installed!')
        Exit(1)
    env = conf.Finish()

    # We would then add actual calls like Program() to build
    # something using the "env" construction environment.

If MyLibrary is not installed on the system, the output will look like:

    % scons
    scons: Reading SConscript file ...
    Checking for MyLibrary... no
    MyLibrary is not installed!

If MyLibrary is installed, the output will look like:

    % scons
    scons: Reading SConscript file ...
    Checking for MyLibrary... yes
    scons: done reading SConscript
    scons: Building targets ...
        .
        .
        .

Prev | Up | Next
21.7. Checking for the Presence of a program | Home | 21.9. Not Configuring When Cleaning Targets