Chapter 12. Platform-Independent File System Manipulation

SCons provides a number of platform-independent functions, called factories, that perform common file system manipulations like copying, moving or deleting files and directories, or making directories. These functions are factories because they don't perform the action at the time they're called, they each return an Action object that can be executed at the appropriate time.

12.1. Copying Files or Directories: The Copy Factory

Suppose you want to arrange to make a copy of a file, and don't have a suitable pre-existing builder. [3] One way would be to use the Copy action factory in conjunction with the Command builder:

Command("file.out", "file.in", Copy("$TARGET", "$SOURCE"))
      

Notice that the action returned by the Copy factory will expand the $TARGET and $SOURCE strings at the time file.out is built, and that the order of the arguments is the same as that of a builder itself--that is, target first, followed by source:

% scons -Q
Copy("file.out", "file.in")

You can, of course, name a file explicitly instead of using $TARGET or $SOURCE:

Command("file.out", [], Copy("$TARGET", "file.in"))
      

Which executes as:

% scons -Q
Copy("file.out", "file.in")

The usefulness of the Copy factory becomes more apparent when you use it in a list of actions passed to the Command builder. For example, suppose you needed to run a file through a utility that only modifies files in-place, and can't "pipe" input to output. One solution is to copy the source file to a temporary file name, run the utility, and then copy the modified temporary file to the target, which the Copy factory makes extremely easy:

Command("file.out", "file.in",
        [
          Copy("tempfile", "$SOURCE"),
          "modify tempfile",
          Copy("$TARGET", "tempfile"),
        ])
      

The output then looks like:

% scons -Q
Copy("tempfile", "file.in")
modify tempfile
Copy("file.out", "tempfile")

The Copy factory has a third optional argument which controls how symlinks are copied.

# Symbolic link shallow copied as a new symbolic link:
Command("LinkIn", "LinkOut", Copy("$TARGET", "$SOURCE"[, True]))

# Symbolic link target copied as a file or directory:
Command("LinkIn", "FileOrDirectoryOut", Copy("$TARGET", "$SOURCE", False))
      


[3] Unfortunately, in the early days of SCons design, we used the name Copy for the function that returns a copy of the environment, otherwise that would be the logical choice for a Builder that copies a file or directory tree to a target location.