20.3. Using scanners with Builders
Prev | Chapter 20. Extending SCons: Writing Your Own Scanners | Next

## 20.3. Using scanners with Builders

One approach for introducing a Scanner into the build is in conjunction with a Builder. There are two relevant optional parameters we can use when creating a Builder: `source_scanner` and `target_scanner`. `source_scanner` is used for scanning source files, and `target_scanner` is used for scanning the target once it is generated.

    import os, re

    include_re = re.compile(r"^include\s+(\S+)$", re.M)

    def kfile_scan(node, env, path, arg=None):
        includes = include_re.findall(node.get_text_contents())
        print(f"DEBUG: scan of {str(node)!r} found {includes}")
        deps = []
        for inc in includes:
            for dir in path:
                file = str(dir) + os.sep + inc
                if os.path.exists(file):
                    deps.append(file)
                    break
        print(f"DEBUG: scanned dependencies found: {deps}")
        return env.File(deps)

    kscan = Scanner(
        function=kfile_scan,
        skeys=[".k"],
        path_function=FindPathDirs("KPATH"),
    )

    def build_function(target, source, env):
        # Code to build "target" from "source"
        return None

    bld = Builder(
        action=build_function,
        suffix=".k",
        source_scanner=kscan,
        src_suffix=".input",
    )

    env = Environment(BUILDERS={"KFile": bld}, KPATH="inc")
    env.KFile("file")

Running this example would only show that the stub `build_function` is getting called, so some debug prints were added to the scanner function, just to show the scanner is being invoked.

    % scons -Q
    DEBUG: scan of 'file.input' found ['other_file']
    DEBUG: scanned dependencies found: ['inc/other_file']
    build_function(["file.k"], ["file.input"])

The path-search implementation in `kfile_scan` works, but is quite simple-minded - a production scanner will probably do something more sophisticated.

An emitter function can modify the list of sources or targets passed to the action function when the Builder is triggered.

A scanner function will not affect the list of sources or targets seen by the Builder during the build action. The scanner function will, however, affect if the Builder should rebuild (if any of the files sourced by the Scanner have changed for example).

Prev | Up | Next
20.2. Adding a search path to a Scanner: `FindPathDirs` | Home | Chapter 21. Multi-Platform Configuration (Autoconf Functionality)