27.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("%s"%FindFile('missing', '.'))
t = FindFile('exists', '.')
print("%s %s"%(t.__class__, t))
      
% scons -Q
None
<class '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
leaf
derived
cat > derived leaf
# 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.