Windows portability.
[scons.git] / test / multi.py
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2001, 2002 Steven Knight
4 #
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:
12 #
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
15 #
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.
23 #
24
25 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
26
27 import TestSCons
28 import os.path
29
30 test = TestSCons.TestSCons()
31
32 test.write('SConstruct', """
33 def build(env, target, source):
34     file = open(str(target[0]), 'wb')
35     for s in source:
36         file.write(open(str(s), 'rb').read())
37
38 B = Builder(name='B', action=build, multi=1)
39 env = Environment(BUILDERS = [B])
40 env.B(target = 'foo.out', source = 'foo.in')
41 env.B(target = 'foo.out', source = 'bar.in')
42 """)
43
44 test.write('foo.in', 'foo.in\n')
45 test.write('bar.in', 'bar.in\n')
46
47 test.run(arguments='foo.out')
48
49 test.fail_test(not os.path.exists(test.workpath('foo.out')))
50 test.fail_test(not test.read('foo.out') == 'foo.in\nbar.in\n')
51
52 test.write('SConstruct', """
53 def build(env, target, source):
54     file = open(str(target[0]), 'wb')
55     for s in source:
56         file.write(open(str(s), 'rb').read())
57
58 B = Builder(name='B', action=build, multi=0)
59 env = Environment(BUILDERS = [B])
60 env.B(target = 'foo.out', source = 'foo.in')
61 env.B(target = 'foo.out', source = 'bar.in')
62 """)
63
64 test.run(arguments='foo.out', 
65          status=2, 
66          stderr="""
67 SCons error: Multiple ways to build the same target were specified for: foo.out
68 File "SConstruct", line 10, in ?
69 """)
70
71 test.write('SConstruct', """
72 def build(env, target, source):
73     file = open(str(target[0]), 'wb')
74     for s in source:
75         file.write(open(str(s), 'rb').read())
76
77 B = Builder(name='B', action=build, multi=1)
78 env = Environment(BUILDERS = [B])
79 env.B(target = 'foo.out', source = 'foo.in', foo=1)
80 env.B(target = 'foo.out', source = 'bar.in', foo=2)
81 """)
82
83 test.run(arguments='foo.out', 
84          status=2, 
85          stderr="""
86 SCons error: Two different sets of build arguments were specified for the same target: foo.out
87 File "SConstruct", line 10, in ?
88 """)
89
90 test.write('SConstruct', """
91 def build(env, target, source):
92     file = open(str(target[0]), 'wb')
93     for s in source:
94         file.write(open(str(s), 'rb').read())
95
96 B = Builder(name='B', action=build, multi=1)
97 env = Environment(BUILDERS = [B])
98 env2 = env.Copy(CCFLAGS='foo')
99 env.B(target = 'foo.out', source = 'foo.in')
100 env2.B(target = 'foo.out', source = 'bar.in')
101 """)
102
103 test.run(arguments='foo.out', 
104          status=2, 
105          stderr="""
106 SCons error: Two different environments were specified for the same target: foo.out
107 File "SConstruct", line 11, in ?
108 """)
109
110 test.write('SConstruct', """
111 def build(env, target, source):
112     file = open(str(target[0]), 'wb')
113     for s in source:
114         file.write(open(str(s), 'rb').read())
115
116 B = Builder(name='B', action=build, multi=0)
117 env = Environment(BUILDERS = [B])
118 env.B(target = 'foo.out', source = 'foo.in')
119 env.B(target = 'foo.out', source = 'foo.in')
120 """)
121
122 test.run(arguments='foo.out')
123 test.fail_test(not test.read('foo.out') == 'foo.in\n')
124
125 test.write('SConstruct', """
126 def build(env, target, source):
127     file = open(str(target[0]), 'wb')
128     for s in source:
129         file.write(open(str(s), 'rb').read())
130
131 B = Builder(name='B', action=build, multi=1)
132 C = Builder(name='C', action=build, multi=1)
133 env = Environment(BUILDERS = [B,C])
134 env.B(target = 'foo.out', source = 'foo.in')
135 env.C(target = 'foo.out', source = 'bar.in')
136 """)
137
138 test.run(arguments='foo.out', 
139          status=2, 
140          stderr="""
141 SCons error: Two different builders (B and C) were specified for the same target: foo.out
142 File "SConstruct", line 11, in ?
143 """)
144
145 test.write('SConstruct', """
146 def build(env, target, source):
147     for t in target:
148         file = open(str(t), 'wb')
149         for s in source:
150             file.write(open(str(s), 'rb').read())
151
152 B = Builder(name='B', action=build, multi=1)
153 env = Environment(BUILDERS = [B])
154 env.B(target = ['foo.out', 'bar.out'], source = 'foo.in')
155 env.B(target = ['foo.out', 'bar.out'], source = 'bar.in')
156 """)
157
158 test.run(arguments='bar.out')
159 test.fail_test(not os.path.exists(test.workpath('bar.out')))
160 test.fail_test(not test.read('bar.out') == 'foo.in\nbar.in\n')
161 test.fail_test(not os.path.exists(test.workpath('foo.out')))
162 test.fail_test(not test.read('foo.out') == 'foo.in\nbar.in\n')
163
164 test.write('SConstruct', """
165 def build(env, target, source):
166     for t in target:
167         file = open(str(target[0]), 'wb')
168         for s in source:
169             file.write(open(str(s), 'rb').read())
170
171 B = Builder(name='B', action=build, multi=1)
172 env = Environment(BUILDERS = [B])
173 env.B(target = ['foo.out', 'bar.out'], source = 'foo.in')
174 env.B(target = ['bar.out', 'foo.out'], source = 'bar.in')
175 """)
176
177 # This is intentional. The order of the targets matter to the
178 # builder because the build command can contain things like ${TARGET[0]}:
179 test.run(arguments='foo.out', 
180          status=2, 
181          stderr="""
182 SCons error: Two different target sets have a target in common: bar.out
183 File "SConstruct", line 11, in ?
184 """)
185
186 # XXX It would be nice if the following two tests could be made to 
187 # work by executing the action once for each unique set of
188 # targets. This would make it simple to deal with PDB files on Windows like so:
189 #
190 #     env.Object(['foo.obj', 'vc60.pdb'], 'foo.c')
191 #     env.Object(['bar.obj', 'vc60.pdb'], 'bar.c')
192
193 test.write('SConstruct', """
194 def build(env, target, source):
195     for t in target:
196         file = open(str(target[0]), 'wb')
197         for s in source:
198             file.write(open(str(s), 'rb').read())
199
200 B = Builder(name='B', action=build, multi=1)
201 env = Environment(BUILDERS = [B])
202 env.B(target = ['foo.out', 'bar.out'], source = 'foo.in')
203 env.B(target = ['bar.out', 'blat.out'], source = 'bar.in')
204 """)
205
206 test.run(arguments='foo.out', 
207          status=2, 
208          stderr="""
209 SCons error: Two different target sets have a target in common: bar.out
210 File "SConstruct", line 11, in ?
211 """)
212
213 test.write('SConstruct', """
214 def build(env, target, source):
215     for t in target:
216         file = open(str(target[0]), 'wb')
217         for s in source:
218             file.write(open(str(s), 'rb').read())
219
220 B = Builder(name='B', action=build, multi=1)
221 env = Environment(BUILDERS = [B])
222 env.B(target = ['foo.out', 'bar.out'], source = 'foo.in')
223 env.B(target = 'foo.out', source = 'bar.in')
224 """)
225
226 test.run(arguments='foo.out', 
227          status=2, 
228          stderr="""
229 SCons error: Two different builders (ListBuilder(B) and B) were specified for the same target: foo.out
230 File "SConstruct", line 11, in ?
231 """)
232
233
234
235
236 test.pass_test()