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.
30 If &SCons; is unaware that a build step produces an extra file,
31 the &SideEffect; method can be used to identify it,
32 so that the file can be used as a dependency in subsequent build steps.
33 However, the primary use for the &SideEffect; method
34 is to prevent two build steps from simultaneously modifying the same file.
38 TODO: currently doesn't work due to issue #2154:
39 http://scons.tigris.org/issues/show_bug.cgi?id=2154
43 If more than one build step creates or manipulates the same file,
44 it can cause unpleasant results if both build steps are run at the same time.
45 The shared file is declared as a side-effect of building the primary targets
46 and &SCons; will prevent the two build steps from running in parallel.
52 In this example, the <filename>SConscript</filename> uses
53 &SideEffect; to inform &SCons; about the additional output file.
57 <scons_example name="SideEffectSimple">
58 <file name="SConstruct" printme="1">
60 f2 = env.Command('file2', 'log', Copy('$TARGET', '$SOURCE'))
61 f1 = env.Command('file1', [],
62 'echo >$TARGET data1; echo >log updated file1'))
63 env.SideEffect('log', env.Command('file1', [],
64 'echo >$TARGET data1; echo >log updated file1'))
70 Even when run in parallel mode, &SCons; will run the two steps in order:
74 <scons_output example="SideEffectSimple">
75 <scons_output_command>scons -Q --jobs=2</scons_output_command>
82 Sometimes a program the you need to call
83 to build a target file
84 will also update another file,
85 such as a log file describing what the program
86 does while building the target.
87 For example, we the folowing configuration
88 would have &SCons; invoke a hypothetical
89 script named <application>build</application>
90 (in the local directory)
91 with command-line arguments that write
92 log information to a common
93 <filename>logfile.txt</filename> file:
99 env.Command('file1.out', 'file.in',
100 './build --log logfile.txt $SOURCE $TARGET')
101 env.Command('file2.out', 'file.in',
102 './build --log logfile.txt $SOURCE $TARGET')
107 This can cause problems when running
108 the build in parallel if
109 &SCons; decides to update both targets
110 by running both program invocations at the same time.
111 The multiple program invocations
112 may interfere with each other
113 writing to the common log file,
114 leading at best to intermixed output in the log file,
115 and at worst to an actual failed build
116 (on a system like Windows, for example,
117 where only one process at a time can open the log file for writing).
123 We can make sure that &SCons; does not
124 run these <application>build</application>
125 commands at the same time
126 by using the &SideEffect; function
127 to specify that updating
128 the <filename>logfile.txt</filename> file
129 is a side effect of building the specified
130 <filename>file1</filename>
132 <filename>file2</filename>
139 f1 = env.Command('file1.out', 'file1.in',
140 './build --log logfile.txt $SOURCE $TARGET')
141 f2 = env.Command('file2.out', 'file2.in',
142 './build --log logfile.txt $SOURCE $TARGET')
143 env.SideEffect('logfile.txt', f1 + f2)
152 This makes sure the the two
153 <application>./build</application> steps are run sequentially,
154 even withthe <filename>--jobs=2</filename> in the command line:
159 % <userinput>scons -Q --jobs=2</userinput>
160 ./build --log logfile.txt file1.in file1.out
161 ./build --log logfile.txt file2.in file2.out
166 The &SideEffect; function can be called multiple
167 times for the same side-effect file.
168 Additionally, the name used as a &SideEffect; does not
169 even need to actually exist as a file on disk.
170 &SCons; will still make sure
171 that the relevant targets
172 will be executed sequentially, not in parallel:
178 f1 = env.Command('file1.out', [], 'echo >$TARGET data1')
179 env.SideEffect('not_really_updated', f1)
180 f2 = env.Command('file2.out', [], 'echo >$TARGET data2')
181 env.SideEffect('not_really_updated', f2)
185 % <userinput>scons -Q --jobs=2</userinput>
186 echo > file1.out data1
187 echo > file2.out data2
192 Note that it might be tempting to
193 use &SideEffect; for additional target files
194 that a command produces.
195 For example, versions the Microsoft Visual C/C++ compiler
196 produce a <filename>foo.ilk</filename>
197 alongside compiling <filename>foo.obj</filename> file.
198 Specifying <filename>foo.ilk</filename> as a
199 side-effect of <filename>foo.obj</filename>
200 is <emphasis>not</emphasis> a recommended use of &SideEffect;,
201 because &SCons; handle side-effect files
202 slightly differently in its analysis of the dependency graph.
203 When a command produces multiple output files,
204 they should be specified as multiple targets of
205 the call to the relevant builder function,
206 and the &SideEffect; function itself should really only be used
207 when it's important to ensure that commands are not executed in parallel,
208 such as when a "peripheral" file (such as a log file)
209 may actually updated by more than one command invocation.