Update Copyright years.
[scons.git] / test / Repository / variants.py
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2001, 2002, 2003 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 os.path
28 import sys
29 import time
30 import TestSCons
31
32 if sys.platform == 'win32':
33     _obj = '.obj'
34     _exe = '.exe'
35 else:
36     _obj = '.o'
37     _exe = ''
38
39 test = TestSCons.TestSCons()
40
41 test.subdir('repository',
42             ['repository', 'src1'],
43             ['repository', 'src2'],
44             ['repository', 'src2', 'include'],
45             ['repository', 'src2', 'xxx'],
46             ['repository', 'build2'],
47             ['repository', 'build2', 'foo'],
48             ['repository', 'build2', 'bar'],
49             'work1',
50             ['work1', 'src1'],
51             'work2',
52             ['work2', 'src2'],
53             ['work2', 'src2', 'include'],
54             ['work2', 'src2', 'xxx'])
55
56 aaa_obj = 'aaa' + _obj
57 bbb_obj = 'bbb' + _obj
58 main_obj = 'main' + _obj
59
60 xxx_exe = 'xxx' + _exe
61
62 repository_build1_foo_xxx = test.workpath('repository', 'build1', 'foo', 'xxx')
63 work1_build1_foo_xxx = test.workpath('work1', 'build1', 'foo', 'xxx')
64 work1_build1_bar_xxx = test.workpath('work1', 'build1', 'bar', 'xxx')
65
66 repository_build2_foo_src2_xxx_xxx = test.workpath('repository', 'build2',
67                                                    'foo', 'src2', 'xxx', 'xxx')
68 repository_build2_bar_src2_xxx_xxx = test.workpath('repository', 'build2',
69                                                    'bar', 'src2', 'xxx', 'xxx')
70 work2_build2_foo_src2_xxx_xxx = test.workpath('work2', 'build2',
71                                               'foo', 'src2', 'xxx', 'xxx')
72 work2_build2_bar_src2_xxx_xxx = test.workpath('work2', 'build2',
73                                               'bar', 'src2', 'xxx', 'xxx')
74
75 opts = "-Y " + test.workpath('repository')
76
77 #
78 test.write(['repository', 'SConstruct'], r"""
79 OS = ARGUMENTS.get('OS', '')
80 build1_os = "#build1/" + OS
81 default_ccflags = Environment()['CCFLAGS']
82 ccflags = {
83     ''    : '',
84     'foo' : '-DFOO',
85     'bar' : '-DBAR',
86 }
87 env1 = Environment(CCFLAGS = default_ccflags + ' ' + ccflags[OS],
88                    CPPPATH = build1_os)
89 BuildDir(build1_os, 'src1')
90 SConscript(build1_os + '/SConscript', "env1")
91
92 SConscript('build2/foo/SConscript')
93 SConscript('build2/bar/SConscript')
94 """)
95
96 test.write(['repository', 'src1', 'SConscript'], r"""
97 Import("env1")
98 env1.Program('xxx', ['aaa.c', 'bbb.c', 'main.c'])
99 """)
100
101 test.write(['repository', 'build2', 'foo', 'SConscript'], r"""
102 BuildDir('src2', '#src2')
103
104 default_ccflags = Environment()['CCFLAGS']
105 env2 = Environment(CCFLAGS = default_ccflags + ' -DFOO',
106                    CPPPATH = ['#src2/xxx', '#src2/include'])
107
108 SConscript('src2/xxx/SConscript', "env2")
109 """)
110
111 test.write(['repository', 'build2', 'bar', 'SConscript'], r"""
112 BuildDir('src2', '#src2')
113
114 default_ccflags = Environment()['CCFLAGS']
115 env2 = Environment(CCFLAGS = default_ccflags + ' -DBAR',
116                    CPPPATH = ['#src2/xxx', '#src2/include'])
117
118 SConscript('src2/xxx/SConscript', "env2")
119 """)
120
121 test.write(['repository', 'src2', 'xxx', 'SConscript'], r"""
122 Import("env2")
123 env2.Program('xxx', ['main.c'])
124 """)
125
126 test.write(['repository', 'src1', 'iii.h'], r"""
127 #ifdef  FOO
128 #define STRING  "REPOSITORY_FOO"
129 #endif
130 #ifdef  BAR
131 #define STRING  "REPOSITORY_BAR"
132 #endif
133 """)
134
135 test.write(['repository', 'src1', 'aaa.c'], r"""
136 #include <iii.h>
137 void
138 aaa(void)
139 {
140         printf("repository/src1/aaa.c:  %s\n", STRING);
141 }
142 """)
143
144 test.write(['repository', 'src1', 'bbb.c'], r"""
145 #include <iii.h>
146 void
147 bbb(void)
148 {
149         printf("repository/src1/bbb.c:  %s\n", STRING);
150 }
151 """)
152
153 test.write(['repository', 'src1', 'main.c'], r"""
154 #include <iii.h>
155 extern void aaa(void);
156 extern void bbb(void);
157 int
158 main(int argc, char *argv[])
159 {
160 #ifdef  BAR
161         printf("Only when -DBAR.\n");
162 #endif
163         aaa();
164         bbb();
165         printf("repository/src1/main.c:  %s\n", STRING);
166         exit (0);
167 }
168 """)
169
170 test.write(['repository', 'src2', 'include', 'my_string.h'], r"""
171 #ifdef  FOO
172 #define INCLUDE_OS      "FOO"
173 #endif
174 #ifdef  BAR
175 #define INCLUDE_OS      "BAR"
176 #endif
177 #define INCLUDE_STRING  "repository/src2/include/my_string.h:  %s\n"
178 """)
179
180 test.write(['repository', 'src2', 'xxx', 'include.h'], r"""
181 #include <my_string.h>
182 #ifdef  FOO
183 #define XXX_OS          "FOO"
184 #endif
185 #ifdef  BAR
186 #define XXX_OS          "BAR"
187 #endif
188 #define XXX_STRING      "repository/src2/xxx/include.h:  %s\n"
189 """)
190
191 test.write(['repository', 'src2', 'xxx', 'main.c'], r"""
192 #include <include.h>
193 #ifdef  FOO
194 #define MAIN_OS         "FOO"
195 #endif
196 #ifdef  BAR
197 #define MAIN_OS         "BAR"
198 #endif
199 main()
200 {
201         printf(INCLUDE_STRING, INCLUDE_OS);
202         printf(XXX_STRING, XXX_OS);
203         printf("repository/src2/xxx/main.c:  %s\n", MAIN_OS);
204         exit (0);
205 }
206 """)
207
208 #
209 test.run(chdir = 'repository', options = opts + " OS=foo", arguments = '.')
210
211 test.run(program = repository_build1_foo_xxx, stdout = """\
212 repository/src1/aaa.c:  REPOSITORY_FOO
213 repository/src1/bbb.c:  REPOSITORY_FOO
214 repository/src1/main.c:  REPOSITORY_FOO
215 """)
216
217 test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
218 test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
219 test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
220 test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
221
222 test.run(program = repository_build2_foo_src2_xxx_xxx, stdout = """\
223 repository/src2/include/my_string.h:  FOO
224 repository/src2/xxx/include.h:  FOO
225 repository/src2/xxx/main.c:  FOO
226 """)
227
228 test.run(program = repository_build2_bar_src2_xxx_xxx, stdout = """\
229 repository/src2/include/my_string.h:  BAR
230 repository/src2/xxx/include.h:  BAR
231 repository/src2/xxx/main.c:  BAR
232 """)
233
234 test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
235 test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
236 test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
237 test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
238
239 # Make the entire repository non-writable, so we'll detect
240 # if we try to write into it accidentally.
241 test.writable('repository', 0)
242
243 #
244 test.up_to_date(chdir = 'work1', options = opts + " OS=foo", arguments = 'build1')
245
246 test.fail_test(os.path.exists(test.workpath('work1', 'build1', 'foo', aaa_obj)))
247 test.fail_test(os.path.exists(test.workpath('work1', 'build1', 'foo', bbb_obj)))
248 test.fail_test(os.path.exists(test.workpath('work1', 'build1', 'foo', main_obj)))
249
250 test.fail_test(os.path.exists(test.workpath('work1', 'build1', 'foo', xxx_exe)))
251
252 #
253 test.run(chdir = 'work1', options = opts, arguments = 'OS=bar .')
254
255 test.run(program = work1_build1_bar_xxx, stdout = """\
256 Only when -DBAR.
257 repository/src1/aaa.c:  REPOSITORY_BAR
258 repository/src1/bbb.c:  REPOSITORY_BAR
259 repository/src1/main.c:  REPOSITORY_BAR
260 """)
261
262 test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
263 test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
264 test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
265 test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
266
267 test.up_to_date(chdir = 'work1', options = opts + " OS=bar", arguments = 'build1')
268
269 # Ensure file time stamps will be newer.
270 time.sleep(2)
271
272 test.write(['work1', 'src1', 'iii.h'], r"""
273 #ifdef  FOO
274 #define STRING  "WORK_FOO"
275 #endif
276 #ifdef  BAR
277 #define STRING  "WORK_BAR"
278 #endif
279 """)
280
281 #
282 test.run(chdir = 'work1', options = opts + " OS=bar", arguments = 'build1')
283
284 test.run(program = work1_build1_bar_xxx, stdout = """\
285 Only when -DBAR.
286 repository/src1/aaa.c:  WORK_BAR
287 repository/src1/bbb.c:  WORK_BAR
288 repository/src1/main.c:  WORK_BAR
289 """)
290
291 test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
292 test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
293 test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
294 test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
295
296 test.up_to_date(chdir = 'work1', options = opts + " OS=bar", arguments = 'build1')
297
298 #
299 test.run(chdir = 'work1', options = opts + " OS=foo", arguments = 'build1')
300
301 test.run(program = work1_build1_foo_xxx, stdout = """\
302 repository/src1/aaa.c:  WORK_FOO
303 repository/src1/bbb.c:  WORK_FOO
304 repository/src1/main.c:  WORK_FOO
305 """)
306
307 test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
308 test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
309 test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
310 test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
311
312 test.up_to_date(chdir = 'work1', options = opts + " OS=foo", arguments = 'build1')
313
314 #
315 test.up_to_date(chdir = 'work2', options = opts, arguments = 'build2')
316
317 test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'foo', 'src2', 'xxx', aaa_obj)))
318 test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'foo', 'src2', 'xxx', bbb_obj)))
319 test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'foo', 'src2', 'xxx', main_obj)))
320 test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'foo', 'src2', 'xxx', xxx_exe)))
321 test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'bar', 'src2', 'xxx', aaa_obj)))
322 test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'bar', 'src2', 'xxx', bbb_obj)))
323 test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'bar', 'src2', 'xxx', main_obj)))
324 test.fail_test(os.path.exists(test.workpath('work2', 'build2', 'bar', 'src2', 'xxx', xxx_exe)))
325
326 # Ensure file time stamps will be newer.
327 time.sleep(2)
328
329 test.write(['work2', 'src2', 'include', 'my_string.h'], r"""
330 #ifdef  FOO
331 #define INCLUDE_OS      "FOO"
332 #endif
333 #ifdef  BAR
334 #define INCLUDE_OS      "BAR"
335 #endif
336 #define INCLUDE_STRING  "work2/src2/include/my_string.h:  %s\n"
337 """)
338
339 #
340 test.run(chdir = 'work2', options = opts, arguments = 'build2')
341
342 test.run(program = work2_build2_foo_src2_xxx_xxx, stdout = """\
343 work2/src2/include/my_string.h:  FOO
344 repository/src2/xxx/include.h:  FOO
345 repository/src2/xxx/main.c:  FOO
346 """)
347
348 test.run(program = work2_build2_bar_src2_xxx_xxx, stdout = """\
349 work2/src2/include/my_string.h:  BAR
350 repository/src2/xxx/include.h:  BAR
351 repository/src2/xxx/main.c:  BAR
352 """)
353
354 test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
355 test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
356 test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
357 test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
358
359 # Ensure file time stamps will be newer.
360 time.sleep(2)
361
362 test.write(['work2', 'src2', 'xxx', 'include.h'], r"""
363 #include <my_string.h>
364 #ifdef  FOO
365 #define XXX_OS          "FOO"
366 #endif
367 #ifdef  BAR
368 #define XXX_OS          "BAR"
369 #endif
370 #define XXX_STRING      "work2/src2/xxx/include.h:  %s\n"
371 """)
372
373 test.run(chdir = 'work2', options = opts, arguments = 'build2')
374
375 test.run(program = work2_build2_foo_src2_xxx_xxx, stdout = """\
376 work2/src2/include/my_string.h:  FOO
377 work2/src2/xxx/include.h:  FOO
378 repository/src2/xxx/main.c:  FOO
379 """)
380
381 test.run(program = work2_build2_bar_src2_xxx_xxx, stdout = """\
382 work2/src2/include/my_string.h:  BAR
383 work2/src2/xxx/include.h:  BAR
384 repository/src2/xxx/main.c:  BAR
385 """)
386
387 test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
388 test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
389 test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
390 test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
391
392 #
393 test.unlink(['work2', 'src2', 'include', 'my_string.h'])
394
395 test.run(chdir = 'work2', options = opts, arguments = 'build2')
396
397 test.run(program = work2_build2_foo_src2_xxx_xxx, stdout = """\
398 repository/src2/include/my_string.h:  FOO
399 work2/src2/xxx/include.h:  FOO
400 repository/src2/xxx/main.c:  FOO
401 """)
402
403 test.run(program = work2_build2_bar_src2_xxx_xxx, stdout = """\
404 repository/src2/include/my_string.h:  BAR
405 work2/src2/xxx/include.h:  BAR
406 repository/src2/xxx/main.c:  BAR
407 """)
408
409 test.fail_test(os.path.exists(test.workpath('repository', 'src1', '.sconsign')))
410 test.fail_test(os.path.exists(test.workpath('repository', 'src2', '.sconsign')))
411 test.fail_test(os.path.exists(test.workpath('work1', 'src1', '.sconsign')))
412 test.fail_test(os.path.exists(test.workpath('work2', 'src2', '.sconsign')))
413
414 #
415 test.pass_test()