Deciding When a Target File Has Changed: the TargetSignatures Function

As you've just seen, SCons uses signatures to decide whether a target file is up to date or must be rebuilt. When a target file depends on another target file, SCons allows you to configure separately how the signatures of "intermediate" target files are used when deciding if a dependent target file must be rebuilt.

Build Signatures

Modifying a source file will cause not only its direct target file to be rebuilt, but also the target file(s) that depend on that direct target file. In our example, changing the contents of the hello.c file causes the hello.o file to be rebuilt, which in turn causes the hello program to be rebuilt:

         % scons -Q hello
         cc -o hello.o -c hello.c
         cc -o hello hello.o
         % edit hello.c
             [CHANGE THE CONTENTS OF hello.c]
         % scons -Q hello
         cc -o hello.o -c hello.c
         cc -o hello hello.o
      

What's not obvious, though, is that SCons internally handles the signature of the target file(s) (hello.o in the above example) differently from the signature of the source file (hello.c). By default, SCons tracks whether a target file must be rebuilt by using a build signature that consists of the combined signatures of all the files that go into making the target file. This is efficient because the accumulated signatures actually give SCons all of the information it needs to decide if the target file is out of date.

If you wish, you can specify this default behavior (build signatures) explicitly using the TargetSignatures function:

        Program('hello.c')
        TargetSignatures('build')
      

File Contents

Sometimes a source file can be changed in such a way that the contents of the rebuilt target file(s) will be exactly the same as the last time the file was built. If so, then any other target files that depend on such a built-but-not-changed target file actually need not be rebuilt. You can make SCons realize that it does not need to rebuild a dependent target file in this situation using the TargetSignatures function as follows:

        Program('hello.c')
        TargetSignatures('content')
      

So if, for example, a user were to only change a comment in a C file, then the rebuilt hello.o file would be exactly the same as the one previously built (assuming the compiler doesn't put any build-specific information in the object file). SCons would then realize that it would not need to rebuild the hello program as follows:

         % scons -Q hello
         cc -o hello.o -c hello.c
         cc -o hello hello.o
         % edit hello.c
           [CHANGE A COMMENT IN hello.c]
         % scons -Q hello
         cc -o hello.o -c hello.c
         scons: `hello' is up to date.
      

In essence, SCons has "short-circuited" any dependent builds when it realizes that a target file has been rebuilt to exactly the same file as the last build. So configured, SCons does take some extra processing time to scan the contents of the target (hello.o) file, but this may save time if the rebuild that was avoided would have been very time-consuming and expensive.