27.5. Handling Nested Lists: the Flatten Function

SCons supports a Flatten function which takes an input Python sequence (list or tuple) and returns a flattened list containing just the individual elements of the sequence. This can be handy when trying to examine a list composed of the lists returned by calls to various Builders. For example, you might collect object files built in different ways into one call to the Program Builder by just enclosing them in a list, as follows:

objects = [
    Object('prog1.c'),
    Object('prog2.c', CCFLAGS='-DFOO'),
]
Program(objects)
      

Because the Builder calls in SCons flatten their input lists, this works just fine to build the program:

% scons -Q
cc -o prog1.o -c prog1.c
cc -o prog2.o -c -DFOO prog2.c
cc -o prog1 prog1.o prog2.o

But if you were debugging your build and wanted to print the absolute path of each object file in the objects list, you might try the following simple approach, trying to print each Node's abspath attribute:

objects = [
    Object('prog1.c'),
    Object('prog2.c', CCFLAGS='-DFOO'),
]
Program(objects)

for object_file in objects:
    print object_file.abspath
      

This does not work as expected because each call to str is operating an embedded list returned by each Object call, not on the underlying Nodes within those lists:

% scons -Q
AttributeError: 'NodeList' object has no attribute 'abspath':
  File "/home/my/project/SConstruct", line 8:
    print object_file.abspath

The solution is to use the Flatten function so that you can pass each Node to the str separately:

objects = [
    Object('prog1.c'),
    Object('prog2.c', CCFLAGS='-DFOO'),
]
Program(objects)

for object_file in Flatten(objects):
    print object_file.abspath
      
% scons -Q
/home/me/project/prog1.o
/home/me/project/prog2.o
cc -o prog1.o -c prog1.c
cc -o prog2.o -c -DFOO prog2.c
cc -o prog1 prog1.o prog2.o