Internally, &SCons; represents all of the files and directories it knows about as &Nodes;. These internal objects (not object files) can be used in a variety of ways to make your &SConscript; files portable and easy to read.
Builder Methods Return Lists of Target Nodes All builder methods return a list of &Node; objects that identify the target file or files that will be built. These returned &Nodes; can be passed as source files to other builder methods, For example, suppose that we want to build the two object files that make up a program with different options. This would mean calling the &Object; builder once for each object file, specifying the desired options: Object('hello.c', CCFLAGS='-DHELLO') Object('goodbye.c', CCFLAGS='-DGOODBYE') One way to combine these object files into the resulting program would be to call the &Program; builder with the names of the object files listed as sources: Object('hello.c', CCFLAGS='-DHELLO') Object('goodbye.c', CCFLAGS='-DGOODBYE') Program(['hello.o', 'goodbye.o']) The problem with listing the names as strings is that our &SConstruct; file is no longer portable across operating systems. It won't, for example, work on Windows because the object files there would be named &hello_obj; and &goodbye_obj;, not &hello_o; and &goodbye_o;. A better solution is to assign the lists of targets returned by the calls to the &Object; builder to variables, which we can then concatenate in our call to the &Program; builder: hello_list = Object('hello.c', CCFLAGS='-DHELLO') goodbye_list = Object('goodbye.c', CCFLAGS='-DGOODBYE') Program(hello_list + goodbye_list) int main() { printf("Hello, world!\n"); } int main() { printf("Goodbye, world!\n"); } This makes our &SConstruct; file portable again, the build output on Linux looking like: scons -Q And on Windows: scons -Q We'll see examples of using the list of nodes returned by builder methods throughout the rest of this guide.
Explicitly Creating File and Directory Nodes It's worth mentioning here that &SCons; maintains a clear distinction between Nodes that represent files and Nodes that represent directories. &SCons; supports &File; and &Dir; functions that, repectively, return a file or directory Node: hello_c = File('hello.c') Program(hello_c) classes = Dir('classes') Java(classes, 'src') Normally, you don't need to call &File; or &Dir; directly, because calling a builder method automatically treats strings as the names of files or directories, and translates them into the Node objects for you. The &File; and &Dir; functions can come in handy in situations where you need to explicitly instruct &SCons; about the type of Node being passed to a builder or other function, or unambiguously refer to a specific file in a directory tree. There are also times when you may need to refer to an entry in a file system without knowing in advance whether it's a file or a directory. For those situations, &SCons; also supports an &Entry; function, which returns a Node that can represent either a file or a directory. xyzzy = Entry('xyzzy') The returned xyzzy Node will be turned into a file or directory Node the first time it is used by a builder method or other function that requires one vs. the other.
Printing &Node; File Names One of the most common things you can do with a Node is use it to print the file name that the node represents. For example, the following &SConstruct; file: object_list = Object('hello.c') program_list = Program(object_list) print "The object file is:", object_list[0] print "The program file is:", program_list[0] int main() { printf("Hello, world!\n"); } Would print the following file names on a POSIX system: scons -Q And the following file names on a Windows system: scons -Q
Using a &Node;'s File Name as a String Printing a &Node;'s name as described in the previous section works because the string representation of a &Node; is the name of the file. If you want to do something other than print the name of the file, you can fetch it by using the builtin Python &str; function. For example, if you want to use the Python os.path.exists to figure out whether a file exists while the &SConstruct; file is being read and executed, you can fetch the string as follows: import os.path program_list = Program('hello.c') program_name = str(program_list[0]) if not os.path.exists(program_name) print program_name, "does not exist!" int main() { printf("Hello, world!\n"); } Which executes as follows on a POSIX system: scons -Q