One approach for introducing scanners into the build is in
conjunction with a Builder. There are two relvant 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 re include_re = re.compile(r'^include\s+(\S+)$', re.M) def kfile_scan(node, env, path, arg): contents = node.get_text_contents() return env.File(include_re.findall(contents)) 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='.foo', source_scanner=kscan, src_suffix='.input', ) env = Environment(BUILDERS={'Foo': bld}) env.Foo('file')
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).