5 Permission is hereby granted, free of charge, to any person obtaining
6 a copy of this software and associated documentation files (the
7 "Software"), to deal in the Software without restriction, including
8 without limitation the rights to use, copy, modify, merge, publish,
9 distribute, sublicense, and/or sell copies of the Software, and to
10 permit persons to whom the Software is furnished to do so, subject to
11 the following conditions:
13 The above copyright notice and this permission notice shall be included
14 in all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17 KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 &SCons; provides a number of platform-independent functions,
29 called <literal>factories</literal>,
30 that perform common file system manipulations
31 like copying, moving or deleting files and directories,
32 or making directories.
33 These functions are <literal>factories</literal>
34 because they don't perform the action
35 at the time they're called,
36 they each return an &Action; object
37 that can be executed at the appropriate time.
42 <title>Copying Files or Directories: The &Copy; Factory</title>
46 Suppose you want to arrange to make a copy of a file,
47 and the &Install; builder isn't appropriate
48 because it may make a hard link on POSIX systems.
49 One way would be to use the &Copy; action factory
50 in conjunction with the &Command; builder:
55 Command("file.out", "file.in", Copy("$TARGET", "$SOURCE"))
60 Notice that the action returned by the &Copy; factory
61 will expand the &cv-TARGET; and &cv-SOURCE; strings
62 at the time &file_out; is built,
63 and that the order of the arguments
64 is the same as that of a builder itself--that is,
65 target first, followed by source:
70 % <userinput>scons -Q</userinput>
71 Copy("file.out", "file.in")
76 You can, of course, name a file explicitly
77 instead of using &cv-TARGET; or &cv-SOURCE;:
82 Command("file.out", [], Copy("$TARGET", "file.in"))
92 % <userinput>scons -Q</userinput>
93 Copy("file.out", "file.in")
98 The usefulness of the &Copy; factory
99 becomes more apparent when
100 you use it in a list of actions
101 passed to the &Command; builder.
102 For example, suppose you needed to run a
103 file through a utility that only modifies files in-place,
104 and can't "pipe" input to output.
105 One solution is to copy the source file
106 to a temporary file name,
108 and then copy the modified temporary file to the target,
109 which the &Copy; factory makes extremely easy:
114 Command("file.out", "file.in",
116 Copy("tempfile", "$SOURCE"),
118 Copy("$TARGET", "tempfile"),
124 The output then looks like:
129 % <userinput>scons -Q</userinput>
130 Copy("tempfile", "file.in")
132 Copy("file.out", "tempfile")
138 <title>Deleting Files or Directories: The &Delete; Factory</title>
142 If you need to delete a file,
143 then the &Delete; factory
144 can be used in much the same way as
146 For example, if we want to make sure that
148 in our last example doesn't exist before
150 we could add &Delete; to the beginning
156 Command("file.out", "file.in",
159 Copy("tempfile", "$SOURCE"),
161 Copy("$TARGET", "tempfile"),
167 When then executes as follows:
172 % <userinput>scons -Q</userinput>
174 Copy("tempfile", "file.in")
176 Copy("file.out", "tempfile")
181 Of course, like all of these &Action; factories,
182 the &Delete; factory also expands
183 &cv-TARGET; and &cv-SOURCE; variables appropriately.
189 Command("file.out", "file.in",
192 Copy("$TARGET", "$SOURCE")
203 % <userinput>scons -Q</userinput>
205 Copy("file.out", "file.in")
210 (Note, however, that you typically don't need to
211 call the &Delete; factory explicitly in this way;
212 by default, &SCons; deletes its target(s)
213 for you before executing any action.
220 <title>Moving (Renaming) Files or Directories: The &Move; Factory</title>
225 allows you to rename a file or directory.
226 For example, if we don't want to copy the temporary file,
232 Command("file.out", "file.in",
234 Copy("tempfile", "$SOURCE"),
236 Move("$TARGET", "tempfile"),
242 Which would execute as:
247 % <userinput>scons -Q</userinput>
248 Copy("tempfile", "file.in")
250 Move("file.out", "tempfile")
256 <title>Updating the Modification Time of a File: The &Touch; Factory</title>
260 If you just need to update the
261 recorded modification time for a file,
262 use the &Touch; factory:
267 Command("file.out", "file.in",
269 Copy("tempfile", "$SOURCE"),
271 Move("$TARGET", "tempfile"),
282 % <userinput>scons -Q</userinput>
283 Copy("tempfile", "file.in")
285 Move("file.out", "tempfile")
291 <title>Creating a Directory: The &Mkdir; Factory</title>
295 If you need to create a directory,
296 use the &Mkdir; factory.
297 For example, if we need to process
298 a file in a temporary directory
299 in which the processing tool
300 will create other files that we don't care about,
306 Command("file.out", "file.in",
310 Copy("tempdir/${SOURCE.file}", "$SOURCE"),
312 Move("$TARGET", "tempdir/output_file"),
324 % <userinput>scons -Q</userinput>
327 Copy("tempdir/file.in", "file.in")
329 Move("file.out", "tempdir/output_file")
330 scons: *** [file.out] No such file or directory
336 <title>Changing File or Directory Permissions: The &Chmod; Factory</title>
340 To change permissions on a file or directory,
341 use the &Chmod; factory.
342 The permission argument uses POSIX-style
343 permission bits and should typically
344 be expressed as an octal,
350 Command("file.out", "file.in",
352 Copy("$TARGET", "$SOURCE"),
353 Chmod("$TARGET", 0755),
364 % <userinput>scons -Q</userinput>
365 Copy("file.out", "file.in")
366 Chmod("file.out", 0755)
372 <title>Executing an action immediately: the &Execute; Function</title>
376 We've been showing you how to use &Action; factories
377 in the &Command; function.
378 You can also execute an &Action; returned by a factory
379 (or actually, any &Action;)
380 at the time the &SConscript; file is read
381 by wrapping it up in the &Execute; function.
382 For example, if we need to make sure that
383 a directory exists before we build any targets,
389 Execute(Mkdir('/tmp/my_temp_directory'))
394 Notice that this will
395 create the directory while
396 the &SConscript; file is being read:
401 % <userinput>scons</userinput>
402 scons: Reading SConscript files ...
403 Mkdir("/tmp/my_temp_directory")
404 scons: done reading SConscript files.
405 scons: Building targets ...
406 scons: `.' is up to date.
407 scons: done building targets.
412 If you're familiar with Python,
413 you may wonder why you would want to use this
414 instead of just calling the native Python
415 <function>os.mkdir()</function> function.
416 The advantage here is that the &Mkdir;
417 action will behave appropriately if the user
418 specifies the &SCons; <option>-n</option> or
419 <option>-q</option> options--that is,
420 it will print the action but not actually
421 make the directory when <option>-n</option> is specified,
422 or make the directory but not print the action
423 when <option>-q</option> is specified.