Fix tests on systems where 'ar' prints warnings about creating archives. (Kevin...
[scons.git] / test / QTFLAGS.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 """
28 Testing the configuration mechanisms of the 'qt' tool.
29 """
30
31 import TestSCons
32 import os.path
33
34 python = TestSCons.python
35 _exe = TestSCons._exe
36
37 test = TestSCons.TestSCons(match=TestSCons.match_re_dotall)
38
39 test.subdir( 'qt', ['qt', 'bin'], ['qt', 'include'], ['qt', 'lib'] )
40
41 # create a dummy qt installation
42
43 test.write(['qt', 'bin', 'mymoc.py'], """
44 import getopt
45 import sys
46 import string
47 import re
48 cmd_opts, args = getopt.getopt(sys.argv[1:], 'wzio:', [])
49 output = None
50 impl = 0
51 opt_string = ''
52 for opt, arg in cmd_opts:
53     if opt == '-o': output = open(arg, 'wb')
54     elif opt == '-i': impl = 1
55     else: opt_string = opt_string + ' ' + opt
56 output.write( "/* mymoc.py%s */\\n" % opt_string)
57 for a in args:
58     contents = open(a, 'rb').read()
59     subst = r'{ my_qt_symbol( "' + a + '\\\\n" ); }'
60     if impl:
61         contents = re.sub( r'#include.*', '', contents )
62     output.write(string.replace(contents, 'Q_OBJECT', subst))
63 output.close()
64 sys.exit(0)
65 """ )
66
67 test.write(['qt', 'bin', 'myuic.py'], """
68 import sys
69 import string
70 output_arg = 0
71 impl_arg = 0
72 impl = None
73 source = None
74 opt_string = ''
75 for arg in sys.argv[1:]:
76     if output_arg:
77         output = open(arg, 'wb')
78         output_arg = 0
79     elif impl_arg:
80         impl = arg
81         impl_arg = 0
82     elif arg == "-o":
83         output_arg = 1
84     elif arg == "-impl":
85         impl_arg = 1
86     elif arg[0:1] == "-":
87         opt_string = opt_string + ' ' + arg
88     else:
89         if source:
90             sys.exit(1)
91         source = open(arg, 'rb')
92 output.write("/* myuic.py%s */\\n" % opt_string)
93 if impl:
94     output.write( '#include "' + impl + '"\\n' )
95 else:
96     output.write( '#include "my_qobject.h"\\n' + source.read() + " Q_OBJECT \\n" )
97 output.close()
98 sys.exit(0)
99 """ )
100
101 test.write(['qt', 'include', 'my_qobject.h'], r"""
102 #define Q_OBJECT ;
103 void my_qt_symbol(const char *arg);
104 """)
105
106 test.write(['qt', 'lib', 'my_qobject.cpp'], r"""
107 #include "../include/my_qobject.h"
108 #include <stdio.h>
109 void my_qt_symbol(const char *arg) {
110   printf( arg );
111 }
112 """)
113
114 test.write(['qt', 'lib', 'SConstruct'], r"""
115 env = Environment()
116 env.StaticLibrary( 'myqt', 'my_qobject.cpp' )
117 """)
118
119 test.run(chdir=test.workpath('qt','lib'), arguments = '.',
120          stderr=TestSCons.noisy_ar)
121
122 QT = test.workpath('qt')
123 QT_LIB = 'myqt'
124 QT_MOC = '%s %s' % (python, test.workpath('qt','bin','mymoc.py'))
125 QT_UIC = '%s %s' % (python, test.workpath('qt','bin','myuic.py'))
126
127 # 3 test cases with 3 different operation modes
128
129 def createSConstruct(test,place,overrides):
130     test.write(place, """
131 env = Environment(QTDIR = r'%s',
132                   QT_LIB = r'%s',
133                   QT_MOC = r'%s',
134                   QT_UIC = r'%s',
135                   %s
136                   tools=['default','qt'])
137 if ARGUMENTS.get('build_dir', 0):
138     if ARGUMENTS.get('chdir', 0):
139         SConscriptChdir(1)
140     else:
141         SConscriptChdir(0)
142     BuildDir('build', '.', duplicate=1)
143     sconscript = Dir('build').File('SConscript')
144 else:
145     sconscript = File('SConscript')
146 Export("env")
147 SConscript( sconscript )
148 """ % (QT, QT_LIB, QT_MOC, QT_UIC, overrides))
149
150
151 createSConstruct(test, ['SConstruct'],
152                  """QT_UICIMPLFLAGS='-x',
153                     QT_UICDECLFLAGS='-y',
154                     QT_MOCFROMHFLAGS='-z',
155                     QT_MOCFROMCXXFLAGS='-i -w',
156                     QT_UICDECLPREFIX='uic-',
157                     QT_UICDECLSUFFIX='.hpp',
158                     QT_UICIMPLPREFIX='',
159                     QT_UICIMPLSUFFIX='.cxx',
160                     QT_MOCHPREFIX='mmm',
161                     QT_MOCHSUFFIX='.cxx',
162                     QT_MOCCXXPREFIX='moc',
163                     QT_MOCCXXSUFFIX='.inl',
164                     QT_UISUFFIX='.myui',""")
165 test.write('SConscript',"""
166 Import("env")
167 env.Program('mytest', ['mocFromH.cpp',
168                        'mocFromCpp.cpp',
169                        'an_ui_file.myui',
170                        'another_ui_file.myui',
171                        'main.cpp'])
172 """)
173
174 test.write('mocFromH.hpp', """
175 #include "my_qobject.h"
176 void mocFromH() Q_OBJECT
177 """)
178
179 test.write('mocFromH.cpp', """
180 #include "mocFromH.hpp"
181 """)
182
183 test.write('mocFromCpp.cpp', """
184 #include "my_qobject.h"
185 void mocFromCpp() Q_OBJECT
186 #include "mocmocFromCpp.inl"
187 """)
188
189 test.write('an_ui_file.myui', """
190 void an_ui_file()
191 """)
192
193 test.write('another_ui_file.myui', """
194 void another_ui_file()
195 """)
196
197 test.write('another_ui_file.desc.hpp', """
198 /* just a dependency checker */
199 """)
200
201 test.write('main.cpp', """
202 #include "mocFromH.hpp"
203 #include "uic-an_ui_file.hpp"
204 #include "uic-another_ui_file.hpp"
205 void mocFromCpp();
206
207 int main() {
208   mocFromH();
209   mocFromCpp();
210   an_ui_file();
211   another_ui_file();
212 }
213 """)
214
215 test.run( arguments = "mytest" + _exe )
216
217 def _existAll( test, files ):
218     return reduce(lambda x,y: x and y,
219                   map(os.path.exists,map(test.workpath, files)))
220                        
221 createSConstruct(test, ['SConstruct'],
222                  """QT_UICIMPLFLAGS='-x',
223                     QT_UICDECLFLAGS='-y',
224                     QT_MOCFROMHFLAGS='-z',
225                     QT_MOCFROMCXXFLAGS='-i -w',
226                     QT_UICDECLPREFIX='uic-',
227                     QT_UICDECLSUFFIX='.hpp',
228                     QT_UICIMPLPREFIX='',
229                     QT_UICIMPLSUFFIX='.cxx',
230                     QT_MOCHPREFIX='mmm',
231                     QT_MOCHSUFFIX='.cxx',
232                     QT_MOCCXXPREFIX='moc',
233                     QT_MOCCXXSUFFIX=`.inl',
234                     QT_UISUFFIX='.myui',""")
235
236 test.fail_test(not _existAll(test, ['mmmmocFromH.cxx',
237                                     'mocmocFromCpp.inl',
238                                     'an_ui_file.cxx',
239                                     'uic-an_ui_file.hpp',
240                                     'mmman_ui_file.cxx',
241                                     'another_ui_file.cxx',
242                                     'uic-another_ui_file.hpp',
243                                     'mmmanother_ui_file.cxx']))
244
245 def _flagTest(test,fileToContentsStart):
246     import string
247     for f,c in fileToContentsStart.items():
248         if string.find(test.read(f), c) != 0:
249             return 1
250     return 0
251
252 test.fail_test(_flagTest(test, {'mmmmocFromH.cxx':'/* mymoc.py -z */',
253                                 'mocmocFromCpp.inl':'/* mymoc.py -w */',
254                                 'an_ui_file.cxx':'/* myuic.py -x */',
255                                 'uic-an_ui_file.hpp':'/* myuic.py -y */',
256                                 'mmman_ui_file.cxx':'/* mymoc.py -z */'}))
257
258 test.pass_test()