Eliminate unnecessary WIN32/Win32/win32 references in tests, too.
[scons.git] / test / NodeOps.py
1 #!/usr/bin/env python
2 #
3 # __COPYRIGHT__
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 # This test is used to verify that the Buildability of a set of nodes
28 # is unaffected by various querying operations on those nodes:
29 #
30 # 1) Calling exists() on a Node (e.g. from find_file) in a BuildDir
31 #    will cause that node to be duplicated into the builddir.
32 #    However, this should *not* occur during a dryrun (-n).  When not
33 #    performed during a dryrun, this should not affect buildability.
34 # 2) Calling is_derived() should not affect buildability.
35 # 3) Calling is_pseudo_derived() may cause the sbuilder to be set, and
36 #    it may caues the builder to be set as well, but it should not
37 #    adversely affect buildability.
38
39 import sys
40 import TestSCons
41 import os
42 import string
43
44 _exe = TestSCons._exe
45 lib_ = TestSCons.lib_
46 _lib = TestSCons._lib
47 _obj = TestSCons._obj
48 dll_ = TestSCons.dll_
49 _dll = TestSCons._dll
50
51 if sys.platform == 'win32':
52     fooflags = '/nologo -DFOO'
53     barflags = '/nologo -DBAR'
54 else:
55     fooflags = '-DFOO'
56     barflags = '-DBAR'
57     
58 if os.name == 'posix':
59     os.environ['LD_LIBRARY_PATH'] = '.'
60 if string.find(sys.platform, 'irix') > -1:
61     os.environ['LD_LIBRARYN32_PATH'] = '.'
62
63 test = TestSCons.TestSCons()
64
65 test.subdir('bld', 'src', ['src', 'subsrcdir'])
66
67 sconstruct = r"""
68 foo = Environment(SHCXXFLAGS = '%(fooflags)s', WINDOWS_INSERT_DEF=1)
69 bar = Environment(SHCXXFLAGS = '%(barflags)s', WINDOWS_INSERT_DEF=1)
70 src = Dir('src')
71 BuildDir('bld', src, duplicate=1)
72 Nodes=[]
73 Nodes.extend(foo.SharedObject(target = 'foo%(_obj)s', source = 'prog.cpp'))
74 Nodes.extend(bar.SharedObject(target = 'bar%(_obj)s', source = 'prog.cpp'))
75 SConscript('bld/SConscript', ['Nodes'])
76 if %(_E)s:
77   import os
78   derived = map(lambda N: N.is_derived(), Nodes)
79   p_derived = map(lambda N: N.is_pseudo_derived(), Nodes)
80   real1 = map(lambda N: os.path.exists(str(N)), Nodes)
81   exists = map(lambda N: N.exists(), Nodes)
82   real2 = map(lambda N: os.path.exists(str(N)), Nodes)
83   for N,D,P,R,E,F in map(None, Nodes, derived, p_derived,
84                                real1, exists, real2):
85     print '%%s: %%s %%s %%s %%s %%s'%%(N,D,P,R,E,F)
86 foo.SharedLibrary(target = 'foo', source = 'foo%(_obj)s')
87 bar.SharedLibrary(target = 'bar', source = 'bar%(_obj)s')
88
89 fooMain = foo.Copy(LIBS='foo', LIBPATH='.')
90 foo_obj = fooMain.Object(target='foomain', source='main.c')
91 fooMain.Program(target='fooprog', source=foo_obj)
92
93 barMain = bar.Copy(LIBS='bar', LIBPATH='.')
94 bar_obj = barMain.Object(target='barmain', source='main.c')
95 barMain.Program(target='barprog', source=bar_obj)
96
97 gooMain = foo.Copy(LIBS='goo', LIBPATH='bld')
98 goo_obj = gooMain.Object(target='goomain', source='main.c')
99 gooMain.Program(target='gooprog', source=goo_obj)
100 """
101            
102
103 test.write('foo.def', r"""
104 LIBRARY        "foo"
105 DESCRIPTION    "Foo Shared Library"
106
107 EXPORTS
108    doIt
109 """)
110
111 test.write('bar.def', r"""
112 LIBRARY        "bar"
113 DESCRIPTION    "Bar Shared Library"
114
115 EXPORTS
116    doIt
117 """)
118
119 test.write('prog.cpp', r"""
120 #include <stdio.h>
121
122 extern "C" void
123 doIt()
124 {
125 #ifdef FOO
126         printf("prog.cpp:  FOO\n");
127 #endif
128 #ifdef BAR
129         printf("prog.cpp:  BAR\n");
130 #endif
131 }
132 """)
133
134 sconscript = r"""
135 import os
136 Import('*')
137
138 import __builtin__
139 try:
140     __builtin__.True
141 except AttributeError:
142     __builtin__.True = 1
143     __builtin__.False = 0
144
145 def mycopy(env, source, target):
146     open(str(target[0]),'w').write(open(str(source[0]),'r').read())
147
148 def exists_test(node):
149     before = os.path.exists(str(node))  # doesn't exist yet in BuildDir
150     via_node = node.exists()            # side effect causes copy from src
151     after = os.path.exists(str(node))
152     node.is_derived()
153     node.is_pseudo_derived()
154     import SCons.Script
155     if SCons.Script.Main.options.noexec:
156         if (before,via_node,after) != (False,False,False):
157             import sys
158             sys.stderr.write('BuildDir exits() populated during dryrun!\n')
159             sys.exit(-2)
160     else:
161         if (before,via_node,after) != (False,True,True):
162             import sys
163             sys.stderr.write('BuildDir exists() population did not occur! (%%s:%%s,%%s,%%s)\n'%%(str(node),before,via_node,after))
164             sys.exit(-2)
165     
166 goo = Environment(CPPFLAGS = '%(fooflags)s')
167 goof_in = File('goof.in')
168 if %(_E)s:
169     exists_test(goof_in)
170 Nodes.append(goof_in)
171 Nodes.extend(goo.Command(target='goof.c', source='goof.in', action=mycopy))
172 boo_src = File('subsrcdir/boo.c')
173 if %(_E)s:
174     exists_test(boo_src)
175 boo_objs = goo.Object(target='subsrcdir/boo%(_obj)s', source = boo_src)
176 Nodes.extend(boo_objs)
177 Nodes.extend(goo.Object(target='goo%(_obj)s',source='goof.c'))
178 goo.Library(target = 'goo', source = ['goo%(_obj)s'] + boo_objs)
179 """
180
181 test.write(['src', 'goof.in'], r"""
182 #include <stdio.h>
183
184 extern char *boo_sub();
185
186 void
187 doIt()
188 {
189 #ifdef FOO
190         printf("prog.cpp:  %s\n", boo_sub());
191 #endif
192 }
193 """)
194
195 test.write(['src', 'subsrcdir', 'boo.c'], r"""
196 char *
197 boo_sub()
198 {
199     return "GOO";
200 }
201 """)
202
203 test.write('main.c', r"""
204
205 void doIt();
206
207 int
208 main(int argc, char* argv[])
209 {
210     doIt();
211     return 0;
212 }
213 """)
214
215 builddir_srcnodes = [ os.path.join('bld', 'goof.in'),
216                       os.path.join('bld', 'subsrcdir', 'boo.c'),
217                     ]
218
219 sub_build_nodes = [ os.path.join('bld', 'subsrcdir','boo' + _obj),
220                     os.path.join('bld', 'goo' + _obj),
221                     os.path.join('bld', 'goof.c'),
222                     os.path.join('bld', lib_ + 'goo' + _lib),
223 ]
224
225 build_nodes = ['fooprog' + _exe,
226                dll_ + 'foo' + _dll,
227                'foo' + _obj,
228                'barprog' + _exe,
229                dll_ + 'bar' + _dll,
230                'bar' + _obj,
231
232                'gooprog' + _exe,
233
234                ] + builddir_srcnodes + sub_build_nodes
235
236 def cleanup_test():
237     "cleanup after running a test"
238     for F in builddir_srcnodes:
239         test.unlink(F)  # will be repopulated during clean operation
240     test.run(arguments = '-c')
241     for F in builddir_srcnodes:
242         test.unlink(F)
243     for name in build_nodes:
244         test.must_not_exist(test.workpath(name))
245
246
247 ### First pass, make sure everything goes quietly
248
249 for name in build_nodes:
250     test.must_not_exist(test.workpath(name))
251
252 _E=0
253 test.write('SConstruct', sconstruct % locals() )
254 test.write(['src', 'SConscript'], sconscript % locals() )
255
256 test.run(arguments = '.',
257          stderr=TestSCons.noisy_ar,
258          match=TestSCons.match_re_dotall)
259
260 test.run(program = test.workpath('fooprog'), stdout = "prog.cpp:  FOO\n")
261 test.run(program = test.workpath('barprog'), stdout = "prog.cpp:  BAR\n")
262 test.run(program = test.workpath('gooprog'), stdout = "prog.cpp:  GOO\n")
263
264 for name in build_nodes:
265     test.must_exist(test.workpath(name))
266
267 cleanup_test()
268
269 ### Next pass: add internal Node ops that may have side effects to
270 ### ensure that those side-effects don't interfere with building
271
272 for name in build_nodes:
273     test.must_not_exist(test.workpath(name))
274
275 _E=1
276 test.write('SConstruct', sconstruct % locals() )
277 test.write(['src', 'SConscript'], sconscript % locals() )
278
279 test.run(arguments = '.',
280          stderr=TestSCons.noisy_ar,
281          match=TestSCons.match_re_dotall)
282
283 test.run(program = test.workpath('fooprog'), stdout = "prog.cpp:  FOO\n")
284 test.run(program = test.workpath('barprog'), stdout = "prog.cpp:  BAR\n")
285 test.run(program = test.workpath('gooprog'), stdout = "prog.cpp:  GOO\n")
286
287 for name in build_nodes:
288     test.must_exist(test.workpath(name))
289
290 cleanup_test()
291
292 ### Next pass: try a dry-run first and verify that it doesn't change
293 ### the buildability.
294
295 for name in build_nodes:
296     test.must_not_exist(test.workpath(name))
297
298 _E=1
299 test.write('SConstruct', sconstruct % locals() )
300 test.write(['src', 'SConscript'], sconscript % locals() )
301
302 test.run(arguments = '-n .',
303          stderr=TestSCons.noisy_ar,
304          match=TestSCons.match_re_dotall)
305
306 for name in build_nodes:
307     test.must_not_exist(test.workpath(name))
308
309 test.run(arguments = '.',
310          stderr=TestSCons.noisy_ar,
311          match=TestSCons.match_re_dotall)
312
313 test.run(program = test.workpath('fooprog'), stdout = "prog.cpp:  FOO\n")
314 test.run(program = test.workpath('barprog'), stdout = "prog.cpp:  BAR\n")
315 test.run(program = test.workpath('gooprog'), stdout = "prog.cpp:  GOO\n")
316
317 for name in build_nodes:
318     test.must_exist(test.workpath(name))
319
320 cleanup_test()
321
322 ### Next pass: do an up-build from a BuildDir src
323
324
325 for name in build_nodes:
326     test.must_not_exist(test.workpath(name))
327
328 _E=0
329 test.write('SConstruct', sconstruct % locals() )
330 test.write(['src', 'SConscript'], sconscript % locals() )
331
332 test.run(chdir='src', arguments = '-u',
333          stderr=TestSCons.noisy_ar,
334          match=TestSCons.match_re_dotall)
335
336 for name in build_nodes:
337     if name in sub_build_nodes or name in builddir_srcnodes:
338         test.must_exist(test.workpath(name))
339     else:
340         test.must_not_exist(test.workpath(name))
341
342 cleanup_test()
343
344 ### Next pass: do an up-build from a BuildDir src with Node Ops
345 ### side-effects
346
347 for name in build_nodes:
348     test.must_not_exist(test.workpath(name))
349
350 _E=1
351 test.write('SConstruct', sconstruct % locals() )
352 test.write(['src', 'SConscript'], sconscript % locals() )
353
354 test.run(chdir='src', arguments = '-u',
355          stderr=TestSCons.noisy_ar,
356          match=TestSCons.match_re_dotall)
357
358 for name in build_nodes:
359     if name in sub_build_nodes or name in builddir_srcnodes:
360         test.must_exist(test.workpath(name))
361     else:
362         test.must_not_exist(test.workpath(name))
363
364 cleanup_test()
365
366 test.pass_test()