28.4. Searching for Files: the FindFile Function

The FindFile function searches for a file in a list of directories. If there is only one directory, it can be given as a simple string. The function returns a File node if a matching file exists, or None if no file is found. (See the documentation for the Glob function for an alternative way of searching for entries in a directory.)


       # one directory
       print FindFile('missing', '.')
       t = FindFile('exists', '.')
       print t.__class__, t
    

       % scons -Q
       None
       SCons.Node.FS.File exists
       scons: `.' is up to date.
    

       # several directories
       includes = [ '.', 'include', 'src/include']
       headers = [ 'nonesuch.h', 'config.h', 'private.h', 'dist.h']
       for hdr in headers:
           print '%-12s' % ('%s:' % hdr), FindFile(hdr, includes)

       % scons -Q
       nonesuch.h:  None
       config.h:    config.h
       private.h:   src/include/private.h
       dist.h:      include/dist.h
       scons: `.' is up to date.
    

If the file exists in more than one directory, only the first occurrence is returned.


        print FindFile('multiple', ['sub1', 'sub2', 'sub3'])
        print FindFile('multiple', ['sub2', 'sub3', 'sub1'])
        print FindFile('multiple', ['sub3', 'sub1', 'sub2'])
    

       % scons -Q
       sub1/multiple
       sub2/multiple
       sub3/multiple
       scons: `.' is up to date.
    

In addition to existing files, FindFile will also find derived files (that is, non-leaf files) that haven't been built yet. (Leaf files should already exist, or the build will fail!)


       # Neither file exists, so build will fail
       Command('derived', 'leaf', 'cat >$TARGET $SOURCE')
       print FindFile('leaf', '.')
       print FindFile('derived', '.')
    

       % scons -Q
       None
       derived
       scons: *** Source `leaf' not found, needed by target `derived'.  Stop.
    

       # Neither file exists, so build will fail
       Command('derived', 'leaf', 'cat >$TARGET $SOURCE')
       print FindFile('leaf', '.')
       print FindFile('derived', '.')

       # Only 'leaf' exists
       Command('derived', 'leaf', 'cat >$TARGET $SOURCE')
       print FindFile('leaf', '.')
       print FindFile('derived', '.')
    

       % scons -Q
       leaf
       derived
       cat > derived leaf
    

If a source file exists, FindFile will correctly return the name in the build directory.


       # Only 'src/leaf' exists
       VariantDir('build', 'src')
       print FindFile('leaf', 'build')
    

       % scons -Q
       build/leaf
       scons: `.' is up to date.