6.5. Dependencies From External Files: the `ParseDepends` Function
Prev | Chapter 6. Dependencies | Next

## 6.5. Dependencies From External Files: the `ParseDepends` Function

SCons has built-in scanners for a number of languages. Sometimes these scanners fail to extract certain implicit dependencies due to limitations of the scanner implementation.

The following example illustrates a case where the built-in C scanner is unable to extract the implicit dependency on a header file.

    #define FOO_HEADER <foo.h>
    #include FOO_HEADER

    int main() {
        return FOO;
    }

    % scons -Q
    cc -o hello.o -c -I. hello.c
    cc -o hello hello.o
    %    [CHANGE CONTENTS OF foo.h]
    % scons -Q
    scons: `.' is up to date.

Apparently, the scanner does not know about the header dependency. Not being a full-fledged C preprocessor, the scanner does not expand the macro.

In these cases, you may also use the compiler to extract the implicit dependencies. `ParseDepends` can parse the contents of the compiler output in the style of Make, and explicitly establish all of the listed dependencies.

The following example uses `ParseDepends` to process a compiler generated dependency file which is generated as a side effect during compilation of the object file:

    obj = Object('hello.c', CCFLAGS='-MD -MF hello.d', CPPPATH='.')
    SideEffect('hello.d', obj)
    ParseDepends('hello.d')
    Program('hello', obj)

    % scons -Q
    cc -o hello.o -c -MD -MF hello.d -I. hello.c
    cc -o hello hello.o
    %    [CHANGE CONTENTS OF foo.h]
    % scons -Q
    cc -o hello.o -c -MD -MF hello.d -I. hello.c

Parsing dependencies from a compiler-generated `.d` file has a chicken-and-egg problem, that causes unnecessary rebuilds:

    % scons -Q
    cc -o hello.o -c -MD -MF hello.d -I. hello.c
    cc -o hello hello.o
    % scons -Q --debug=explain
    scons: rebuilding `hello.o' because `foo.h' is a new dependency
    cc -o hello.o -c -MD -MF hello.d -I. hello.c
    % scons -Q
    scons: `.' is up to date.

In the first pass, the dependency file is generated while the object file is compiled. At that time, SCons does not know about the dependency on `foo.h`. In the second pass, the object file is regenerated because `foo.h` is detected as a new dependency.

`ParseDepends` immediately reads the specified file at invocation time and just returns if the file does not exist. A dependency file generated during the build process is not automatically parsed again. Hence, the compiler-extracted dependencies are not stored in the signature database during the same build pass. This limitation of `ParseDepends` leads to unnecessary recompilations. Therefore, `ParseDepends` should only be used if scanners are not available for the employed language or not powerful enough for the specific task.

Prev | Up | Next
6.4. Explicit Dependencies: the `Depends` Function | Home | 6.6. Ignoring Dependencies: the `Ignore` Function