diff options
author | Steven Knight <knight@baldmt.com> | 2005-01-07 00:42:01 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2005-01-07 00:42:01 (GMT) |
commit | 4e17c7182977812c7751523ef08f7b221ae6aa61 (patch) | |
tree | 2207659ec602bdd8a4ae9c462692b5cdce26ea76 /test/QT | |
parent | 8209788c5d6a2554317a13416bb953b6c3f572ab (diff) | |
download | SCons-4e17c7182977812c7751523ef08f7b221ae6aa61.zip SCons-4e17c7182977812c7751523ef08f7b221ae6aa61.tar.gz SCons-4e17c7182977812c7751523ef08f7b221ae6aa61.tar.bz2 |
Finish the display-customization variables: , , , , , and .
Diffstat (limited to 'test/QT')
-rw-r--r-- | test/QT/QT.py | 930 | ||||
-rw-r--r-- | test/QT/QTFLAGS.py | 279 |
2 files changed, 1209 insertions, 0 deletions
diff --git a/test/QT/QT.py b/test/QT/QT.py new file mode 100644 index 0000000..680784f --- /dev/null +++ b/test/QT/QT.py @@ -0,0 +1,930 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Testing the 'qt' tool, i.e. support for .ui files and automatic +generation of qt's moc files. +""" + +import os.path +import re +import string + +import TestSCons + +python = TestSCons.python +_exe = TestSCons._exe +lib_ = TestSCons.lib_ +_lib = TestSCons._lib +dll_ = TestSCons.dll_ +_dll = TestSCons._dll +_shobj = TestSCons._shobj + +test = TestSCons.TestSCons() + +test.subdir( 'qt', ['qt', 'bin'], ['qt', 'include'], ['qt', 'lib'] ) + +# create a dummy qt installation + +test.write(['qt', 'bin', 'mymoc.py'], """ +import getopt +import sys +import string +import re +cmd_opts, args = getopt.getopt(sys.argv[1:], 'io:', []) +output = None +impl = 0 +opt_string = '' +for opt, arg in cmd_opts: + if opt == '-o': output = open(arg, 'wb') + elif opt == '-i': impl = 1 + else: opt_string = opt_string + ' ' + opt +for a in args: + contents = open(a, 'rb').read() + subst = r'{ my_qt_symbol( "' + a + '\\\\n" ); }' + if impl: + contents = re.sub( r'#include.*', '', contents ) + output.write(string.replace(contents, 'Q_OBJECT', subst)) +output.close() +sys.exit(0) +""" ) + +test.write(['qt', 'bin', 'myuic.py'], """ +import os.path +import re +import sys +import string +output_arg = 0 +impl_arg = 0 +impl = None +source = None +for arg in sys.argv[1:]: + if output_arg: + output = open(arg, 'wb') + output_arg = 0 + elif impl_arg: + impl = arg + impl_arg = 0 + elif arg == "-o": + output_arg = 1 + elif arg == "-impl": + impl_arg = 1 + else: + if source: + sys.exit(1) + source = open(arg, 'rb') + sourceFile = arg +if impl: + output.write( '#include "' + impl + '"\\n' ) + includes = re.findall('<include.*?>(.*?)</include>', source.read()) + for incFile in includes: + # this is valid for ui.h files, at least + if os.path.exists(incFile): + output.write('#include "' + incFile + '"\\n') +else: + output.write( '#include "my_qobject.h"\\n' + source.read() + " Q_OBJECT \\n" ) +output.close() +sys.exit(0) +""" ) + +test.write(['qt', 'include', 'my_qobject.h'], r""" +#define Q_OBJECT ; +void my_qt_symbol(const char *arg); +""") + +test.write(['qt', 'lib', 'my_qobject.cpp'], r""" +#include "../include/my_qobject.h" +#include <stdio.h> +void my_qt_symbol(const char *arg) { + printf( arg ); +} +""") + +test.write(['qt', 'lib', 'SConstruct'], r""" +env = Environment() +env.StaticLibrary( 'myqt', 'my_qobject.cpp' ) +""") + +test.run(chdir=test.workpath('qt','lib'), arguments = '.', + stderr=TestSCons.noisy_ar, + match=TestSCons.match_re_dotall) + +QT = test.workpath('qt') +QT_LIB = 'myqt' +QT_MOC = '%s %s' % (python, test.workpath('qt','bin','mymoc.py')) +QT_UIC = '%s %s' % (python, test.workpath('qt','bin','myuic.py')) + +############################################################################## +# Test cases with different operation modes + +def createSConstruct(test,place): + test.write(place, """ +if ARGUMENTS.get('noqtdir', 0): QTDIR=None +else: QTDIR=r'%s' +env = Environment(QTDIR = QTDIR, + QT_LIB = r'%s', + QT_MOC = r'%s', + QT_UIC = r'%s', + tools=['default','qt']) +dup = 1 +if ARGUMENTS.get('build_dir', 0): + if ARGUMENTS.get('chdir', 0): + SConscriptChdir(1) + else: + SConscriptChdir(0) + dup=int(ARGUMENTS.get('dup', 1)) + if dup == 0: + builddir = 'build_dup0' + env['QT_DEBUG'] = 1 + else: + builddir = 'build' + BuildDir(builddir, '.', duplicate=dup) + print builddir, dup + sconscript = Dir(builddir).File('SConscript') +else: + sconscript = File('SConscript') +Export("env dup") +SConscript( sconscript ) +""" % (QT, QT_LIB, QT_MOC, QT_UIC)) + +test.subdir( 'work1', 'work2', 'work3', 'work4', + 'work5', 'work6', 'work7', 'work8', + 'work9', ['work9', 'local_include'], + 'work10', ['work10', 'sub'], ['work10', 'sub', 'local_include'], + 'work11', ['work11', 'include'], ['work11', 'ui'], + 'work12') + +############################################################################## +# 1. create a moc file from a header file. + +aaa_exe = 'aaa' + _exe +moc = 'moc_aaa.cc' + +createSConstruct(test, ['work1', 'SConstruct']) +test.write( ['work1', 'SConscript'], """ +Import("env") +env.Program(target = 'aaa', source = 'aaa.cpp') +""") + +test.write(['work1', 'aaa.cpp'], r""" +#include "aaa.h" +int main() { aaa(); return 0; } +""") + +test.write(['work1', 'aaa.h'], r""" +#include "my_qobject.h" +void aaa(void) Q_OBJECT; +""") + +test.run(chdir='work1', arguments = aaa_exe) +test.up_to_date(chdir='work1', options = '-n', arguments=aaa_exe) + +test.up_to_date(chdir='work1', options = '-n', arguments = aaa_exe) +test.write(['work1', 'aaa.h'], r""" +/* a change */ +#include "my_qobject.h" +void aaa(void) Q_OBJECT; +""") +test.not_up_to_date(chdir='work1', options='-n', arguments = moc) +test.run(program = test.workpath('work1', aaa_exe), stdout = 'aaa.h\n') + +test.run(chdir='work1', + arguments = "build_dir=1 " + + test.workpath('work1', 'build', aaa_exe) ) +test.run(chdir='work1', + arguments = "build_dir=1 chdir=1 " + + test.workpath('work1', 'build', aaa_exe) ) + +test.fail_test( not os.path.exists(test.workpath('work1', 'build', moc)) ) + +test.run(chdir='work1', + arguments = "build_dir=1 chdir=1 dup=0 " + + test.workpath('work1', 'build_dup0', aaa_exe) ) +test.must_exist(['work1', 'build_dup0', moc], + ['work1', 'build_dup0', aaa_exe]) + +############################################################################## +# 2. create .cpp, .h, moc_....cpp from .ui file + +aaa_dll = dll_ + 'aaa' + _dll +moc = 'moc_aaa.cc' +cpp = 'uic_aaa.cc' +obj = os.path.splitext(cpp)[0] + _shobj +h = 'aaa.h' + +createSConstruct(test, ['work2', 'SConstruct']) +test.write(['work2', 'SConscript'], """ +Import("env dup") +if dup == 0: env.Append(CPPPATH=['#', '.']) +env.SharedLibrary(target = 'aaa', source = ['aaa.ui', 'useit.cpp']) +""") + +test.write(['work2', 'aaa.ui'], r""" +#if defined (_WIN32) || defined(__CYGWIN__) +#define DLLEXPORT __declspec(dllexport) +#else +#define DLLEXPORT +#endif +DLLEXPORT void aaa(void) +""") + +test.write(['work2', 'useit.cpp'], r""" +#include "aaa.h" +void useit() { + aaa(); +} +""") + +test.run(chdir='work2', arguments = aaa_dll) +test.up_to_date(chdir='work2', options='-n',arguments = aaa_dll) +test.write(['work2', 'aaa.ui'], r""" +/* a change */ +#if defined (_WIN32) || defined(__CYGWIN__) +#define DLLEXPORT __declspec(dllexport) +#else +#define DLLEXPORT +#endif +DLLEXPORT void aaa(void) +""") +test.not_up_to_date(chdir='work2', options = '-n', arguments = moc) +test.not_up_to_date(chdir='work2', options = '-n', arguments = cpp) +test.not_up_to_date(chdir='work2', options = '-n', arguments = h) +test.run(chdir='work2', arguments = aaa_dll) +test.write(['work2', 'aaa.ui'], r""" +void aaa(void) +//<include>aaa.ui.h</include> +""") +test.run(chdir='work2', arguments = aaa_dll) # test that non-existant ui.h files are ignored (as uic does) +test.write(['work2', 'aaa.ui.h'], r""" +/* test dependency to .ui.h */ +""") +test.run(chdir='work2', arguments = aaa_dll) +test.write(['work2', 'aaa.ui.h'], r""" +/* changed */ +""") +test.not_up_to_date(chdir='work2', options = '-n', arguments = obj) +test.not_up_to_date(chdir='work2', options = '-n', arguments = cpp) +test.not_up_to_date(chdir='work2', options = '-n', arguments = h) +test.not_up_to_date(chdir='work2', options = '-n', arguments = moc) +# clean up +test.run(chdir='work2', arguments = '-c ' + aaa_dll) + +test.run(chdir='work2', + arguments = "build_dir=1 " + + test.workpath('work2', 'build', aaa_dll) ) +test.fail_test(not os.path.exists(test.workpath('work2','build',moc)) or + not os.path.exists(test.workpath('work2','build',cpp)) or + not os.path.exists(test.workpath('work2','build',h)) or + os.path.exists(test.workpath('work2', moc)) or + os.path.exists(test.workpath('work2', cpp)) or + os.path.exists(test.workpath('work2', h))) +cppContents = test.read(test.workpath('work2', 'build', cpp)) +test.fail_test(string.find(cppContents, '#include "aaa.ui.h"') == -1) + +test.run(chdir='work2', + arguments = "build_dir=1 chdir=1 " + + test.workpath('work2', 'build', aaa_dll) ) +test.fail_test(not os.path.exists(test.workpath('work2','build',moc)) or + not os.path.exists(test.workpath('work2','build',cpp)) or + not os.path.exists(test.workpath('work2','build',h)) or + os.path.exists(test.workpath('work2', moc)) or + os.path.exists(test.workpath('work2', cpp)) or + os.path.exists(test.workpath('work2', h))) + +test.run(chdir='work2', + arguments = "build_dir=1 chdir=1 dup=0 " + + test.workpath('work2', 'build_dup0', aaa_dll) ) + +test.must_exist(['work2','build_dup0',moc], + ['work2','build_dup0',cpp], + ['work2','build_dup0',h]) +test.must_not_exist(['work2', moc], + ['work2', cpp], + ['work2', h]) + +############################################################################## +# 3. create a moc file from a cpp file + +lib_aaa = lib_ + 'aaa' + _lib +moc = 'aaa.moc' + +createSConstruct(test, ['work3', 'SConstruct']) +test.write(['work3', 'SConscript'], """ +Import("env dup") +if dup == 0: env.Append(CPPPATH=['.']) +env.StaticLibrary(target = '%s', source = ['aaa.cpp','useit.cpp']) +""" % lib_aaa) + +test.write(['work3', 'aaa.h'], r""" +void aaa(void); +""") + +test.write(['work3', 'aaa.cpp'], r""" +#include "my_qobject.h" +void aaa(void) Q_OBJECT +#include "%s" +""" % moc) + +test.write(['work3', 'useit.cpp'], r""" +#include "aaa.h" +void useit() { + aaa(); +} +""") + +test.run(chdir='work3', arguments = lib_aaa, + stderr=TestSCons.noisy_ar, + match=TestSCons.match_re_dotall) +test.up_to_date(chdir='work3', options = '-n', arguments = lib_aaa) +test.write(['work3', 'aaa.cpp'], r""" +#include "my_qobject.h" +/* a change */ +void aaa(void) Q_OBJECT +#include "%s" +""" % moc) +test.not_up_to_date(chdir='work3', options = '-n', arguments = moc) +test.run(chdir='work3', options = '-c', arguments = lib_aaa) + +test.run(chdir='work3', + arguments = "build_dir=1 " + + test.workpath('work3', 'build', lib_aaa), + stderr=TestSCons.noisy_ar, + match=TestSCons.match_re_dotall) +test.run(chdir='work3', + arguments = "build_dir=1 chdir=1 " + + test.workpath('work3', 'build', lib_aaa) ) + +test.fail_test(not os.path.exists(test.workpath('work3', 'build', moc))) + +test.run(chdir='work3', + arguments = "build_dir=1 dup=0 " + + test.workpath('work3', 'build_dup0', lib_aaa), + stderr=TestSCons.noisy_ar, + match=TestSCons.match_re_dotall) +test.must_exist(['work3', 'build_dup0', moc]) + +############################################################################## +# 4. Test with a copied environment. + +createSConstruct(test, ['work4', 'SConstruct']) +test.write(['work4', 'SConscript'], """\ +Import("env") +env.Append(CPPDEFINES = ['FOOBAZ']) + +copy = env.Copy() +copy.Append(CPPDEFINES = ['MYLIB_IMPL']) + +copy.SharedLibrary( + target = 'MyLib', + source = ['MyFile.cpp','MyForm.ui'] +) +""") + +test.write(['work4', 'MyFile.h'], r""" +void aaa(void); +""") + +test.write(['work4', 'MyFile.cpp'], r""" +#include "MyFile.h" +void useit() { + aaa(); +} +""") + +test.write(['work4', 'MyForm.ui'], r""" +void aaa(void) +""") + +test.run(chdir='work4') +moc_MyForm = filter(lambda x: string.find(x, 'moc_MyForm') != -1, + string.split(test.stdout(), '\n')) +MYLIB_IMPL = filter(lambda x: string.find(x, 'MYLIB_IMPL') != -1, moc_MyForm) +if not MYLIB_IMPL: + print "Did not find MYLIB_IMPL on moc_MyForm compilation line:" + print test.stdout() + test.fail_test() + +############################################################################## +# 5. Test creation from a copied environment that already has QT variables. +# This makes sure the tool initialization is re-entrant. + +createSConstruct(test, ['work5', 'SConstruct']) +test.write( ['work5', 'SConscript'], """ +Import("env") +env = env.Copy(tools=['qt']) +env.Program('main', 'main.cpp', CPPDEFINES=['FOO'], LIBS=[]) +""") + +test.write(['work5', 'main.cpp'], r""" +#include "foo5.h" +int main() { foo5(); return 0; } +""") + +test.write(['qt', 'include', 'foo5.h'], """\ +#include <stdio.h> +void +foo5(void) +{ +#ifdef FOO + printf("qt/include/foo5.h\\n"); +#endif +} +""") + +test.run(chdir='work5') + +main_exe = 'main' + _exe +test.run(program = test.workpath('work5', main_exe), + stdout = 'qt/include/foo5.h\n') + +############################################################################## +# 6. Test creation from a copied empty environment. + +test.write(['work6', 'SConstruct'], """\ +orig = Environment() +env = orig.Copy(QTDIR = r'%s', + QT_LIB = r'%s', + QT_MOC = r'%s', + QT_UIC = r'%s', + tools=['qt']) +env.Program('main', 'main.cpp', CPPDEFINES=['FOO'], LIBS=[]) +""" % (QT, QT_LIB, QT_MOC, QT_UIC)) + +test.write(['work6', 'main.cpp'], r""" +#include "foo6.h" +int main() { foo6(); return 0; } +""") + +test.write(['qt', 'include', 'foo6.h'], """\ +#include <stdio.h> +void +foo6(void) +{ +#ifdef FOO + printf("qt/include/foo6.h\\n"); +#endif +} +""") + +# we can receive warnings about a non detected qt (empty QTDIR) +# these are not critical, but maybe annoying +test.run(chdir='work6', stderr=None) + +main_exe = 'main' + _exe +test.run(program = test.workpath('work6', main_exe), + stderr = None, + stdout = 'qt/include/foo6.h\n') + +############################################################################## +# 7. look if qt is installed, and try out all builders + +if os.environ.get('QTDIR', None): + + QTDIR=os.environ['QTDIR'] + + + test.write( ['work7', 'SConstruct'],""" +import os +dummy_env = Environment() +ENV = dummy_env['ENV'] +try: + PATH=ARGUMENTS['PATH'] + if ENV.has_key('PATH'): + ENV_PATH = PATH + os.pathsep + ENV['PATH'] + else: + Exit(0) # this is certainly a weird system :-) +except KeyError: + ENV_PATH=ENV.get('PATH', '') + +env = Environment(tools=['default','qt'], + ENV={'PATH':ENV_PATH, + 'PATHEXT':os.environ.get('PATHEXT'), + 'HOME':os.getcwd()}, + # moc / uic want to write stuff in ~/.qt + CXXFILESUFFIX=".cpp") + +conf = env.Configure() +if not conf.CheckLib(env.subst("$QT_LIB"), autoadd=0): + conf.env['QT_LIB'] = 'qt-mt' + if not conf.CheckLib(env.subst("$QT_LIB"), autoadd=0): + Exit(0) +env = conf.Finish() +BuildDir('bld', '.') +env.Program('bld/test_realqt', ['bld/mocFromCpp.cpp', + 'bld/mocFromH.cpp', + 'bld/anUiFile.ui', + 'bld/main.cpp']) +""") + + test.write( ['work7', 'mocFromCpp.h'],""" +void mocFromCpp(); +""") + + test.write( ['work7', 'mocFromCpp.cpp'],""" +#include <qobject.h> +#include "mocFromCpp.h" +class MyClass1 : public QObject { + Q_OBJECT + public: + MyClass1() : QObject() {}; + public slots: + void myslot() {}; +}; +void mocFromCpp() { + MyClass1 myclass; +} +#include "mocFromCpp.moc" +""") + + test.write( ['work7', 'mocFromH.h'],""" +#include <qobject.h> +class MyClass2 : public QObject { + Q_OBJECT; + public: + MyClass2(); + public slots: + void myslot(); +}; +void mocFromH(); +""") + + test.write( ['work7', 'mocFromH.cpp'],""" +#include "mocFromH.h" + +MyClass2::MyClass2() : QObject() {} +void MyClass2::myslot() {} +void mocFromH() { + MyClass2 myclass; +} +""") + + test.write( ['work7', 'anUiFile.ui'],""" +<!DOCTYPE UI><UI> +<class>MyWidget</class> +<widget> + <class>QWidget</class> + <property name="name"> + <cstring>MyWidget</cstring> + </property> + <property name="caption"> + <string>MyWidget</string> + </property> +</widget> +<includes> + <include location="local" impldecl="in implementation">anUiFile.ui.h</include> +</includes> +<slots> + <slot>testSlot()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> +""") + test.write( ['work7', 'anUiFile.ui.h'], r""" +#include <stdio.h> +#if QT_VERSION >= 0x030100 +void MyWidget::testSlot() +{ + printf("Hello World\n"); +} +#endif +""") + + test.write( ['work7', 'main.cpp'], r""" +#include <qapp.h> +#include "mocFromCpp.h" +#include "mocFromH.h" +#include "anUiFile.h" +#include <stdio.h> + +int main(int argc, char **argv) { + QApplication app(argc, argv); + mocFromCpp(); + mocFromH(); + MyWidget mywidget; +#if QT_VERSION >= 0x030100 + mywidget.testSlot(); +#else + printf("Hello World\n"); +#endif + return 0; +} +""") + + test.run(chdir='work7', arguments="bld/test_realqt" + _exe) + test.run(program=test.workpath("work7", "bld", "test_realqt"), + stdout="Hello World\n") + + QTDIR=os.environ['QTDIR'] + del os.environ['QTDIR'] + PATH=os.environ['PATH'] + os.environ['PATH']='.' + + test.run(chdir='work7', stderr=None, arguments="-c bld/test_realqt" + _exe) + test.fail_test(not test.match_re_dotall(test.stderr(), r""".* +scons: warning: Could not detect qt, using empty QTDIR +""" + TestSCons.file_expr)) + + os.environ['PATH'] = PATH + + test.run(chdir='work7', stderr=None, + arguments="PATH=%s%sbin bld%stest_realqt%s"%(QTDIR,os.sep,os.sep,_exe)) + test.fail_test(not test.match_re(test.stderr(), (r""" +scons: warning: Could not detect qt, using moc executable as a hint \(QTDIR=%s\) +""" + TestSCons.file_expr) % re.escape(QTDIR))) + + +else: + print "Could not find QT, skipping test(s)." + +############################################################################## +# 8. test the $QT_AUTOBUILD_MOC_SOURCES variable +# +# This has been removed, but I'm leaving the test here, commented out, +# in case we ever resurrect this functionality again in the future. +# +#aaa_dll = dll_ + 'aaa' + _dll +#moc = 'moc_aaa.cc' +# +#createSConstruct(test, ['work8', 'SConstruct']) +# +#test.write(['work8', 'SConscript'], """ +#Import("env") +#env = env.Copy(QT_AUTOBUILD_MOC_SOURCES = 0) +#env.SharedLibrary(target = 'aaa', source = ['aaa.ui', 'useit.cpp', 'aaa_function.cpp']) +#""") +# +#test.write(['work8', 'aaa.ui'], r""" +##if defined (_WIN32) || defined(__CYGWIN__) +##define DLLEXPORT __declspec(dllexport) +##else +##define DLLEXPORT +##endif +#DLLEXPORT void aaa(void) +#""") +# +#test.write(['work8', 'useit.cpp'], r""" +##include "aaa.h" +#void useit() { +# aaa(); +#} +#""") +# +#test.write(['work8', 'aaa_function.cpp'], r""" +##include "my_qobject.h" +##if defined (_WIN32) || defined(__CYGWIN__) +##define DLLEXPORT __declspec(dllexport) +##else +##define DLLEXPORT +##endif +#DLLEXPORT void aaa(void) +# { my_qt_symbol( "aaa_function.cpp\n" ); } +#""") +# +#test.run(chdir='work8', arguments = aaa_dll) +# +#test.must_not_exist(test.workpath('work8', moc)) +# +#test.write(['work8', 'SConscript'], """ +#Import("env") +#env = env.Copy(QT_AUTOBUILD_MOC_SOURCES = 1) +#env.SharedLibrary(target = 'aaa', source = ['aaa.ui', 'useit.cpp']) +#""") +# +#test.run(chdir='work8', arguments = aaa_dll) +# +#test.must_exist(test.workpath('work8', moc)) + +############################################################################## +# 9. test that an overwritten CPPPATH is working with generated files + +# this is basically test 1, but with an additional include +aaa_exe = 'aaa' + _exe + +createSConstruct(test, ['work9', 'SConstruct']) +test.write( ['work9', 'SConscript'], """ +Import("env") +env.Program(target = 'aaa', source = 'aaa.cpp', CPPPATH=['$CPPPATH', './local_include']) +""") + +test.write(['work9', 'aaa.cpp'], r""" +#include "aaa.h" +int main() { aaa(); return 0; } +""") + +test.write(['work9', 'aaa.h'], r""" +#include "my_qobject.h" +#include "local_include.h" +void aaa(void) Q_OBJECT; +""") + +test.write(['work9', 'local_include', 'local_include.h'], r""" +/* empty; just needs to be found */ +""") + +test.run(chdir='work9', arguments = aaa_exe) + +############################################################################## +# 10. test that an appended relative CPPPATH is working with generated files + +# this is basically test 9, but the include path is env.Append-ed and +# everything goes into sub directory "sub" +aaa_exe = os.path.join('sub', 'aaa' + _exe) + +createSConstruct(test, ['work10', 'SConstruct']) +test.write( ['work10', 'SConscript'], r""" +SConscript('sub/SConscript') +""") + +test.write( ['work10', 'sub', 'SConscript'], r""" +Import("env") +env.Append(CPPPATH=['./local_include']) +env.Program(target = 'aaa', source = 'aaa.cpp') +""") + +test.write(['work10', 'sub', 'aaa.cpp'], r""" +#include "aaa.h" +int main() { aaa(); return 0; } +""") + +test.write(['work10', 'sub', 'aaa.h'], r""" +#include "my_qobject.h" +#include "local_include.h" +void aaa(void) Q_OBJECT; +""") + +test.write(['work10', 'sub', 'local_include', 'local_include.h'], r""" +/* empty; just needs to be found */ +""") + +test.run(chdir='work10', arguments = aaa_exe) + +############################################################################### +# 11. test the manual QT builder calls + +aaa_exe = 'aaa' + _exe + +createSConstruct(test, ['work11', 'SConstruct']) +test.write( ['work11', 'SConscript'], r""" +Import("env") +sources = ['aaa.cpp', 'bbb.cpp', 'ddd.cpp', 'eee.cpp', 'main.cpp'] + +# normal invocation +sources.append(env.Moc('include/aaa.h')) +env.Moc('bbb.cpp') +sources.extend(env.Uic('ui/ccc.ui')[1:]) + +# manual target specification +sources.append(env.Moc('moc-ddd.cpp', 'include/ddd.h', + QT_MOCHPREFIX='')) # Watch out ! +env.Moc('moc_eee.cpp', 'eee.cpp') +sources.extend(env.Uic(['include/uic_fff.hpp', 'fff.cpp', 'fff.moc.cpp'], + 'ui/fff.ui')[1:]) + +print map(str,sources) +env.Program(target='aaa', + source=sources, + CPPPATH=['$CPPPATH', './include'], + QT_AUTOSCAN=0) +""") + +test.write(['work11', 'aaa.cpp'], r""" +#include "aaa.h" +""") + +test.write(['work11', 'include', 'aaa.h'], r""" +#include "my_qobject.h" +void aaa(void) Q_OBJECT; +""") + +test.write(['work11', 'bbb.h'], r""" +void bbb(void); +""") + +test.write(['work11', 'bbb.cpp'], r""" +#include "my_qobject.h" +void bbb(void) Q_OBJECT +#include "bbb.moc" +""") + +test.write(['work11', 'ui', 'ccc.ui'], r""" +void ccc(void) +""") + +test.write(['work11', 'ddd.cpp'], r""" +#include "ddd.h" +""") + +test.write(['work11', 'include', 'ddd.h'], r""" +#include "my_qobject.h" +void ddd(void) Q_OBJECT; +""") + +test.write(['work11', 'eee.h'], r""" +void eee(void); +""") + +test.write(['work11', 'eee.cpp'], r""" +#include "my_qobject.h" +void eee(void) Q_OBJECT +#include "moc_eee.cpp" +""") + +test.write(['work11', 'ui', 'fff.ui'], r""" +void fff(void) +""") + +test.write(['work11', 'main.cpp'], r""" +#include "aaa.h" +#include "bbb.h" +#include "ui/ccc.h" +#include "ddd.h" +#include "eee.h" +#include "uic_fff.hpp" + +int main() { + aaa(); bbb(); ccc(); ddd(); eee(); fff(); return 0; +} +""") + +test.run(chdir='work11', arguments = aaa_exe) + +# normal invocation +test.must_exist(test.workpath('work11', 'include', 'moc_aaa.cc')) +test.must_exist(test.workpath('work11', 'bbb.moc')) +test.must_exist(test.workpath('work11', 'ui', 'ccc.h')) +test.must_exist(test.workpath('work11', 'ui', 'uic_ccc.cc')) +test.must_exist(test.workpath('work11', 'ui', 'moc_ccc.cc')) + +# manual target spec. +test.must_exist(test.workpath('work11', 'moc-ddd.cpp')) +test.must_exist(test.workpath('work11', 'moc_eee.cpp')) +test.must_exist(test.workpath('work11', 'include', 'uic_fff.hpp')) +test.must_exist(test.workpath('work11', 'fff.cpp')) +test.must_exist(test.workpath('work11', 'fff.moc.cpp')) + + +############################################################################## +# 12. test the tool warings +createSConstruct(test, ['work12', 'SConstruct']) + +test.write(['work12', 'aaa.cpp'], r""" +#include "my_qobject.h" +void aaa(void) Q_OBJECT +""") + +test.write(['work12', 'SConscript'], r""" +Import("env") +import os +env.StaticLibrary('aaa.cpp') +""") + +test.run(chdir='work12', stderr=None) + +match12 = r""" +scons: warning: Generated moc file 'aaa.moc' is not included by 'aaa.cpp' +""" + TestSCons.file_expr + +# In case 'ar' gives a warning about creating a library. +test.fail_test(not test.match_re(test.stderr(), match12) and \ + not test.match_re(test.stderr(), match12 + ".+\n")) + +os.environ['QTDIR'] = QT +test.run(chdir='work12', arguments='-n noqtdir=1') + +# We'd like to eliminate $QTDIR from the environment as follows: +# del os.environ['QTDIR'] +# But unfortunately, in at least some versions of Python, the Environment +# class doesn't implement a __delitem__() method to make the library +# call to actually remove the deleted variable from the *external* +# environment, so it only gets removed from the Python dictionary. +# Consequently, we need to just wipe out its value as follows> +os.environ['QTDIR'] = '' +test.run(chdir='work12', stderr=None, arguments='-n noqtdir=1') +test.fail_test(not test.match_re(test.stderr(), r""" +scons: warning: Could not detect qt, using empty QTDIR +""" + TestSCons.file_expr)) + +test.pass_test() diff --git a/test/QT/QTFLAGS.py b/test/QT/QTFLAGS.py new file mode 100644 index 0000000..f9cb917 --- /dev/null +++ b/test/QT/QTFLAGS.py @@ -0,0 +1,279 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Testing the configuration mechanisms of the 'qt' tool. +""" + +import TestSCons +import os.path + +python = TestSCons.python +_exe = TestSCons._exe + +test = TestSCons.TestSCons() + +test.subdir( 'qt', ['qt', 'bin'], ['qt', 'include'], ['qt', 'lib'], + 'work1', 'work2') + +# create a dummy qt installation + +test.write(['qt', 'bin', 'mymoc.py'], """ +import getopt +import sys +import string +import re +cmd_opts, args = getopt.getopt(sys.argv[1:], 'wzio:', []) +output = None +impl = 0 +opt_string = '' +for opt, arg in cmd_opts: + if opt == '-o': output = open(arg, 'wb') + elif opt == '-i': impl = 1 + else: opt_string = opt_string + ' ' + opt +output.write( "/* mymoc.py%s */\\n" % opt_string) +for a in args: + contents = open(a, 'rb').read() + subst = r'{ my_qt_symbol( "' + a + '\\\\n" ); }' + if impl: + contents = re.sub( r'#include.*', '', contents ) + output.write(string.replace(contents, 'Q_OBJECT', subst)) +output.close() +sys.exit(0) +""" ) + +test.write(['qt', 'bin', 'myuic.py'], """ +import sys +import string +output_arg = 0 +impl_arg = 0 +impl = None +source = None +opt_string = '' +for arg in sys.argv[1:]: + if output_arg: + output = open(arg, 'wb') + output_arg = 0 + elif impl_arg: + impl = arg + impl_arg = 0 + elif arg == "-o": + output_arg = 1 + elif arg == "-impl": + impl_arg = 1 + elif arg[0:1] == "-": + opt_string = opt_string + ' ' + arg + else: + if source: + sys.exit(1) + source = open(arg, 'rb') +output.write("/* myuic.py%s */\\n" % opt_string) +if impl: + output.write( '#include "' + impl + '"\\n' ) +else: + output.write( '#include "my_qobject.h"\\n' + source.read() + " Q_OBJECT \\n" ) +output.close() +sys.exit(0) +""" ) + +test.write(['qt', 'include', 'my_qobject.h'], r""" +#define Q_OBJECT ; +void my_qt_symbol(const char *arg); +""") + +test.write(['qt', 'lib', 'my_qobject.cpp'], r""" +#include "../include/my_qobject.h" +#include <stdio.h> +void my_qt_symbol(const char *arg) { + printf( arg ); +} +""") + +test.write(['qt', 'lib', 'SConstruct'], r""" +env = Environment() +env.StaticLibrary( 'myqt', 'my_qobject.cpp' ) +""") + +test.run(chdir=test.workpath('qt','lib'), arguments = '.', + stderr=TestSCons.noisy_ar, + match=TestSCons.match_re_dotall) + +QT = test.workpath('qt') +QT_LIB = 'myqt' +QT_MOC = '%s %s' % (python, test.workpath('qt','bin','mymoc.py')) +QT_UIC = '%s %s' % (python, test.workpath('qt','bin','myuic.py')) + +def createSConstruct(test,place,overrides): + test.write(place, """ +env = Environment(QTDIR = r'%s', + QT_LIB = r'%s', + QT_MOC = r'%s', + QT_UIC = r'%s', + %s + tools=['default','qt']) +if ARGUMENTS.get('build_dir', 0): + if ARGUMENTS.get('chdir', 0): + SConscriptChdir(1) + else: + SConscriptChdir(0) + BuildDir('build', '.', duplicate=1) + sconscript = Dir('build').File('SConscript') +else: + sconscript = File('SConscript') +Export("env") +SConscript( sconscript ) +""" % (QT, QT_LIB, QT_MOC, QT_UIC, overrides)) + + +createSConstruct(test, ['work1', 'SConstruct'], + """QT_UICIMPLFLAGS='-x', + QT_UICDECLFLAGS='-y', + QT_MOCFROMHFLAGS='-z', + QT_MOCFROMCXXFLAGS='-i -w', + QT_UICDECLPREFIX='uic-', + QT_UICDECLSUFFIX='.hpp', + QT_UICIMPLPREFIX='', + QT_UICIMPLSUFFIX='.cxx', + QT_MOCHPREFIX='mmm', + QT_MOCHSUFFIX='.cxx', + QT_MOCCXXPREFIX='moc', + QT_MOCCXXSUFFIX='.inl', + QT_UISUFFIX='.myui',""") +test.write(['work1', 'SConscript'],""" +Import("env") +env.Program('mytest', ['mocFromH.cpp', + 'mocFromCpp.cpp', + 'an_ui_file.myui', + 'another_ui_file.myui', + 'main.cpp']) +""") + +test.write(['work1', 'mocFromH.hpp'], """ +#include "my_qobject.h" +void mocFromH() Q_OBJECT +""") + +test.write(['work1', 'mocFromH.cpp'], """ +#include "mocFromH.hpp" +""") + +test.write(['work1', 'mocFromCpp.cpp'], """ +#include "my_qobject.h" +void mocFromCpp() Q_OBJECT +#include "mocmocFromCpp.inl" +""") + +test.write(['work1', 'an_ui_file.myui'], """ +void an_ui_file() +""") + +test.write(['work1', 'another_ui_file.myui'], """ +void another_ui_file() +""") + +test.write(['work1', 'another_ui_file.desc.hpp'], """ +/* just a dependency checker */ +""") + +test.write(['work1', 'main.cpp'], """ +#include "mocFromH.hpp" +#include "uic-an_ui_file.hpp" +#include "uic-another_ui_file.hpp" +void mocFromCpp(); + +int main() { + mocFromH(); + mocFromCpp(); + an_ui_file(); + another_ui_file(); +} +""") + +test.run(chdir = 'work1', arguments = "mytest" + _exe) + +test.must_exist(['work1', 'mmmmocFromH.cxx'], + ['work1', 'mocmocFromCpp.inl'], + ['work1', 'an_ui_file.cxx'], + ['work1', 'uic-an_ui_file.hpp'], + ['work1', 'mmman_ui_file.cxx'], + ['work1', 'another_ui_file.cxx'], + ['work1', 'uic-another_ui_file.hpp'], + ['work1', 'mmmanother_ui_file.cxx']) + +def _flagTest(test,fileToContentsStart): + import string + for f,c in fileToContentsStart.items(): + if string.find(test.read(test.workpath('work1', f)), c) != 0: + return 1 + return 0 + +test.fail_test(_flagTest(test, {'mmmmocFromH.cxx':'/* mymoc.py -z */', + 'mocmocFromCpp.inl':'/* mymoc.py -w */', + 'an_ui_file.cxx':'/* myuic.py -x */', + 'uic-an_ui_file.hpp':'/* myuic.py -y */', + 'mmman_ui_file.cxx':'/* mymoc.py -z */'})) + +test.write(['work2', 'SConstruct'], """ +import os.path +env1 = Environment(tools=['qt'], + QTDIR = r'%(QTDIR)s', + QT_BINPATH='$QTDIR/bin64', + QT_LIBPATH='$QTDIR/lib64', + QT_CPPPATH='$QTDIR/h64') + +cpppath = env1.subst('$CPPPATH') +if os.path.normpath(cpppath) != os.path.join(r'%(QTDIR)s', 'h64'): + print cpppath + Exit(1) +libpath = env1.subst('$LIBPATH') +if os.path.normpath(libpath) != os.path.join(r'%(QTDIR)s', 'lib64'): + print libpath + Exit(2) +qt_moc = env1.subst('$QT_MOC') +if os.path.normpath(qt_moc) != os.path.join(r'%(QTDIR)s', 'bin64', 'moc'): + print qt_moc + Exit(3) + +env2 = Environment(tools=['default', 'qt'], + QTDIR = None, + QT_LIB = None, + QT_CPPPATH = None, + QT_LIBPATH = None) + +env2.Program('main.cpp') +""" % {'QTDIR':QT}) + +test.write(['work2', 'main.cpp'], """ +int main() { return 0; } +""") + +# Ignore stderr, because if Qt is not installed, +# there may be a warning about an empty QTDIR on stderr. +test.run(chdir='work2', stderr=None) + +test.must_exist(['work2', 'main' + _exe]) + +test.pass_test() |