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:
54 <scons_example name="Copy1">
55 <file name="SConstruct" printme="1">
56 Command("file.out", "file.in", Copy("$TARGET", "$SOURCE"))
58 <file name="file.in">file.in</file>
63 Notice that the action returned by the &Copy; factory
64 will expand the &cv-link-TARGET; and &cv-link-SOURCE; strings
65 at the time &file_out; is built,
66 and that the order of the arguments
67 is the same as that of a builder itself--that is,
68 target first, followed by source:
72 <scons_output example="Copy1">
73 <scons_output_command>scons -Q</scons_output_command>
78 You can, of course, name a file explicitly
79 instead of using &cv-TARGET; or &cv-SOURCE;:
83 <scons_example name="Copy2">
84 <file name="SConstruct" printme="1">
85 Command("file.out", [], Copy("$TARGET", "file.in"))
87 <file name="file.in">file.in</file>
96 <scons_output example="Copy2">
97 <scons_output_command>scons -Q</scons_output_command>
102 The usefulness of the &Copy; factory
103 becomes more apparent when
104 you use it in a list of actions
105 passed to the &Command; builder.
106 For example, suppose you needed to run a
107 file through a utility that only modifies files in-place,
108 and can't "pipe" input to output.
109 One solution is to copy the source file
110 to a temporary file name,
112 and then copy the modified temporary file to the target,
113 which the &Copy; factory makes extremely easy:
117 <scons_example name="Copy3">
118 <file name="S" printme="1">
119 Command("file.out", "file.in",
121 Copy("tempfile", "$SOURCE"),
123 Copy("$TARGET", "tempfile"),
126 <file name="SConstruct">
127 env = DefaultEnvironment()
129 env['ENV']['PATH'] = env['ENV']['PATH'] + os.pathsep + os.getcwd()
132 <file name="file.in">file.in</file>
133 <file name="modify" chmod="0755">
140 The output then looks like:
144 <scons_output example="Copy3">
145 <scons_output_command>scons -Q</scons_output_command>
151 <title>Deleting Files or Directories: The &Delete; Factory</title>
155 If you need to delete a file,
156 then the &Delete; factory
157 can be used in much the same way as
159 For example, if we want to make sure that
161 in our last example doesn't exist before
163 we could add &Delete; to the beginning
168 <scons_example name="Delete1">
169 <file name="S" printme="1">
170 Command("file.out", "file.in",
173 Copy("tempfile", "$SOURCE"),
175 Copy("$TARGET", "tempfile"),
178 <file name="SConstruct">
179 env = DefaultEnvironment()
181 env['ENV']['PATH'] = env['ENV']['PATH'] + os.pathsep + os.getcwd()
184 <file name="file.in">file.in</file>
185 <file name="modify" chmod="0755">
192 When then executes as follows:
196 <scons_output example="Delete1">
197 <scons_output_command>scons -Q</scons_output_command>
202 Of course, like all of these &Action; factories,
203 the &Delete factory also expands
204 &cv-link-TARGET; and &cv-link-SOURCE; variables appropriately.
209 <scons_example name="Delete2">
210 <file name="SConstruct" printme="1">
211 Command("file.out", "file.in",
214 Copy("$TARGET", "$SOURCE")
217 <file name="file.in">file.in</file>
226 <scons_output example="Delete2">
227 <scons_output_command>scons -Q</scons_output_command>
232 (Note, however, that you typically don't need to
233 call the &Delete; factory explicitly in this way;
234 by default, &SCons; deletes its target(s)
235 for you before executing any action.
242 <title>Moving (Renaming) Files or Directories: The &Move; Factory</title>
247 allows you to rename a file or directory.
248 For example, if we don't want to copy the temporary file,
253 <scons_example name="Move">
254 <file name="S" printme="1">
255 Command("file.out", "file.in",
257 Copy("tempfile", "$SOURCE"),
259 Move("$TARGET", "tempfile"),
262 <file name="SConstruct">
263 env = DefaultEnvironment()
265 env['ENV']['PATH'] = env['ENV']['PATH'] + os.pathsep + os.getcwd()
268 <file name="file.in">file.in</file>
269 <file name="modify" chmod="0755">
276 Which would execute as:
280 <scons_output example="Move">
281 <scons_output_command>scons -Q</scons_output_command>
287 <title>Updating the Modification Time of a File: The &Touch; Factory</title>
291 If you just need to update the
292 recorded modification time for a file,
293 use the &Touch; factory:
297 <scons_example name="Touch">
298 <file name="S" printme="1">
299 Command("file.out", "file.in",
301 Copy("$TARGET", "$SOURCE"),
305 <file name="SConstruct">
306 env = DefaultEnvironment()
308 env['ENV']['PATH'] = env['ENV']['PATH'] + os.pathsep + os.getcwd()
311 <file name="file.in">file.in</file>
320 <scons_output example="Touch">
321 <scons_output_command>scons -Q</scons_output_command>
327 <title>Creating a Directory: The &Mkdir; Factory</title>
331 If you need to create a directory,
332 use the &Mkdir; factory.
333 For example, if we need to process
334 a file in a temporary directory
335 in which the processing tool
336 will create other files that we don't care about,
341 <scons_example name="Mkdir">
342 <file name="S" printme="1">
343 Command("file.out", "file.in",
347 Copy("tempdir/${SOURCE.file}", "$SOURCE"),
349 Move("$TARGET", "tempdir/output_file"),
353 <file name="SConstruct">
354 env = DefaultEnvironment()
356 env['ENV']['PATH'] = env['ENV']['PATH'] + os.pathsep + os.getcwd()
359 <file name="file.in">file.in</file>
360 <file name="process" chmod="0755">
371 <scons_output example="Mkdir">
372 <scons_output_command>scons -Q</scons_output_command>
378 <title>Changing File or Directory Permissions: The &Chmod; Factory</title>
382 To change permissions on a file or directory,
383 use the &Chmod; factory.
384 The permission argument uses POSIX-style
385 permission bits and should typically
386 be expressed as an octal,
391 <scons_example name="Chmod">
392 <file name="SConstruct" printme="1">
393 Command("file.out", "file.in",
395 Copy("$TARGET", "$SOURCE"),
396 Chmod("$TARGET", 0755),
399 <file name="file.in">file.in</file>
408 <scons_output example="Chmod">
409 <scons_output_command>scons -Q</scons_output_command>
415 <title>Executing an action immediately: the &Execute; Function</title>
419 We've been showing you how to use &Action; factories
420 in the &Command; function.
421 You can also execute an &Action; returned by a factory
422 (or actually, any &Action;)
423 at the time the &SConscript; file is read
424 by wrapping it up in the &Execute; function.
425 For example, if we need to make sure that
426 a directory exists before we build any targets,
431 <scons_example name="Execute">
432 <file name="SConstruct" printme="1">
433 Execute(Mkdir('__ROOT__/tmp/my_temp_directory'))
439 Notice that this will
440 create the directory while
441 the &SConscript; file is being read:
445 <scons_output example="Execute">
446 <scons_output_command>scons</scons_output_command>
451 If you're familiar with Python,
452 you may wonder why you would want to use this
453 instead of just calling the native Python
454 <function>os.mkdir()</function> function.
455 The advantage here is that the &Mkdir;
456 action will behave appropriately if the user
457 specifies the &SCons; <option>-n</option> or
458 <option>-q</option> options--that is,
459 it will print the action but not actually
460 make the directory when <option>-n</option> is specified,
461 or make the directory but not print the action
462 when <option>-q</option> is specified.