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.
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", action=[ 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", symlinks=True)) # Symbolic link target copied as a file or directory: Command("LinkIn", "FileOrDirectoryOut", Copy("$TARGET", "$SOURCE", symlinks=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.