From 1f0d1d058487112d75225fef026abca64faf901e Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Mon, 10 Apr 2006 09:44:30 +0000 Subject: [PATCH] Merge from trunk [SVN r33628] --- example/qt/qt4/hello/Jamroot | 14 +++ example/qt/qt4/hello/arrow.cpp | 158 ++++++++++++++++++++++++++++ example/qt/qt4/hello/arrow.h | 30 ++++++ example/qt/qt4/hello/main.cpp | 27 +++++ example/qt/qt4/moccable-cpp/Jamroot | 16 ++- example/qt/qt4/uic/Jamroot | 13 ++- scripts/nightly.sh | 1 + src/build/targets.jam | 31 ++++-- src/tools/common.jam | 2 +- src/tools/package.jam | 13 ++- src/tools/qt3.jam | 14 +-- src/tools/qt4.jam | 39 +++++-- test/alternatives.py | 4 +- test/searched_lib.py | 26 ++++- 14 files changed, 348 insertions(+), 40 deletions(-) create mode 100644 example/qt/qt4/hello/Jamroot create mode 100644 example/qt/qt4/hello/arrow.cpp create mode 100644 example/qt/qt4/hello/arrow.h create mode 100644 example/qt/qt4/hello/main.cpp diff --git a/example/qt/qt4/hello/Jamroot b/example/qt/qt4/hello/Jamroot new file mode 100644 index 000000000..83952f17b --- /dev/null +++ b/example/qt/qt4/hello/Jamroot @@ -0,0 +1,14 @@ + +import qt4 ; + +if ! [ qt4.initialized ] +{ + ECHO "Warning: Qt4 not initialized in user-config.jam" ; + ECHO "Assuming /space/p2/ghost/build/Qt4 as location." ; + ECHO "This is very likely won't work for you. " ; + using qt4 : /space/p2/ghost/build/Qt4 ; +} + +project : requirements multi ; + +exe arrow : main.cpp arrow.cpp arrow.h /qt//QtGui ; \ No newline at end of file diff --git a/example/qt/qt4/hello/arrow.cpp b/example/qt/qt4/hello/arrow.cpp new file mode 100644 index 000000000..e821b1690 --- /dev/null +++ b/example/qt/qt4/hello/arrow.cpp @@ -0,0 +1,158 @@ +// Copyright Vladimir Prus 2005. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include "arrow.h" + +#include + +#include +#include +#include + +#include +#include + +Arrow_widget::Arrow_widget(QWidget* parent) : QWidget(parent), color_(0) +{ + QPalette pal = palette(); + pal.setBrush(backgroundRole(), QBrush(Qt::white)); + setPalette(pal); +} + +void Arrow_widget::slotChangeColor() +{ + color_ = (color_ + 1) % 3; + update(); +} + +void +Arrow_widget::draw_arrow(int x1, int y1, int x2, int y2, QPainter& painter) +{ + // The length of the from the tip of the arrow to the point + // where line starts. + const int arrowhead_length = 16; + + QPainterPath arrow; + arrow.moveTo(x1, y1); + + // Determine the angle of the straight line. + double a1 = (x2-x1); + double a2 = (y2-y1); + double b1 = 1; + double b2 = 0; + + double straight_length = sqrt(a1*a1 + a2*a2); + + double dot_product = a1*b1 + a2*b2; + double cosine = dot_product/ + (sqrt(pow(a1, 2) + pow(a2, 2))*sqrt(b1 + b2)); + double angle = acos(cosine); + if (y1 < y2) + { + angle = -angle; + } + double straight_angle = angle*180/M_PI; + + double limit = 10; + + double angle_to_vertical; + if (fabs(straight_angle) < 90) + angle_to_vertical = fabs(straight_angle); + else if (straight_angle > 0) + angle_to_vertical = 180-straight_angle; + else + angle_to_vertical = 180-(-straight_angle); + + double angle_delta = 0; + if (angle_to_vertical > limit) + angle_delta = 30 * (angle_to_vertical - limit)/90; + double start_angle = straight_angle > 0 + ? straight_angle - angle_delta : + straight_angle + angle_delta; + + + QMatrix m1; + m1.translate(x1, y1); + m1.rotate(-start_angle); + + double end_angle = straight_angle > 0 + ? (straight_angle + 180 + angle_delta) : + (straight_angle + 180 - angle_delta); + + QMatrix m2; + m2.reset(); + m2.translate(x2, y2); + m2.rotate(-end_angle); + + arrow.cubicTo(m1.map(QPointF(straight_length/2, 0)), + m2.map(QPointF(straight_length/2, 0)), + m2.map(QPointF(arrowhead_length, 0))); + + painter.save(); + painter.setBrush(Qt::NoBrush); + painter.drawPath(arrow); + painter.restore(); + + painter.save(); + painter.translate(x2, y2); + + painter.rotate(-90); + painter.rotate(-end_angle); + painter.rotate(180); + + QPolygon arrowhead(4); + arrowhead.setPoint(0, 0, 0); + arrowhead.setPoint(1, arrowhead_length/3, -arrowhead_length*5/4); + arrowhead.setPoint(2, 0, -arrowhead_length); + arrowhead.setPoint(3, -arrowhead_length/3, -arrowhead_length*5/4); + + painter.drawPolygon(arrowhead); + + painter.restore(); + +} + + +void Arrow_widget::paintEvent(QPaintEvent*) +{ + QPainter p(this); + + p.setRenderHint(QPainter::Antialiasing); + + int base_x = 550; + int base_y = 200; + + if (color_ == 0) + p.setBrush(Qt::black); + else if (color_ == 1) + p.setBrush(Qt::green); + else if (color_ == 2) + p.setBrush(Qt::yellow); + else + p.setBrush(Qt::black); + + for (int x_step = 0; x_step < 6; ++x_step) + { + for (int y_step = 1; y_step <= 3; ++y_step) + { + draw_arrow(base_x, base_y, base_x+x_step*100, + base_y - y_step*50, p); + + draw_arrow(base_x, base_y, base_x+x_step*100, + base_y + y_step*50, p); + + draw_arrow(base_x, base_y, base_x-x_step*100, + base_y + y_step*50, p); + + draw_arrow(base_x, base_y, base_x-x_step*100, + base_y - y_step*50, p); + } + } + + draw_arrow(50, 400, 1000, 450, p); + draw_arrow(1000, 400, 50, 450, p); + +} + diff --git a/example/qt/qt4/hello/arrow.h b/example/qt/qt4/hello/arrow.h new file mode 100644 index 000000000..d7743864f --- /dev/null +++ b/example/qt/qt4/hello/arrow.h @@ -0,0 +1,30 @@ +// Copyright Vladimir Prus 2005. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +#include +#include +#include + +#include +#include + +class Arrow_widget : public QWidget +{ + Q_OBJECT +public: + Arrow_widget(QWidget* parent = 0); + +public slots: + void slotChangeColor(); + +private: + void draw_arrow(int x1, int y1, int x2, int y2, QPainter& painter); + void paintEvent(QPaintEvent*); + +private: + int color_; +}; diff --git a/example/qt/qt4/hello/main.cpp b/example/qt/qt4/hello/main.cpp new file mode 100644 index 000000000..df27444bd --- /dev/null +++ b/example/qt/qt4/hello/main.cpp @@ -0,0 +1,27 @@ +// Copyright Vladimir Prus 2005. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include "arrow.h" + +#include +#include + +int main(int ac, char* av[]) +{ + QApplication app(ac, av); + Arrow_widget* w = new Arrow_widget; + w->resize(1100, 480); + + QTimer timer; + QObject::connect(&timer, SIGNAL(timeout()), + w, SLOT(slotChangeColor())); + + timer.start(2000); + + w->show(); + app.exec(); + return 0; +} + diff --git a/example/qt/qt4/moccable-cpp/Jamroot b/example/qt/qt4/moccable-cpp/Jamroot index cf38c5223..d07b9c7d3 100644 --- a/example/qt/qt4/moccable-cpp/Jamroot +++ b/example/qt/qt4/moccable-cpp/Jamroot @@ -1,12 +1,18 @@ +import qt4 ; +if ! [ qt4.initialized ] +{ + ECHO "Warning: Qt4 not initialized in user-config.jam" ; + ECHO "Assuming /space/p2/ghost/build/Qt4 as location." ; + ECHO "This is very likely won't work for you. " ; + using qt4 : /space/p2/ghost/build/Qt4 ; +} import cast ; - - - exe main : main.cpp [ cast _ moccable-cpp : main.cpp ] - /qt4//QtGui ; + /qt//QtGui + : multi + ; -#cast _ moccable-cpp : main.cpp ; diff --git a/example/qt/qt4/uic/Jamroot b/example/qt/qt4/uic/Jamroot index b343868c3..40675a72e 100644 --- a/example/qt/qt4/uic/Jamroot +++ b/example/qt/qt4/uic/Jamroot @@ -3,7 +3,16 @@ # (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) -project +import qt4 ; +if ! [ qt4.initialized ] +{ + ECHO "Warning: Qt4 not initialized in user-config.jam" ; + ECHO "Assuming /space/p2/ghost/build/Qt4 as location." ; + ECHO "This is very likely won't work for you. " ; + using qt4 : /space/p2/ghost/build/Qt4 ; +} + +project : requirements multi ; -exe hello : main.cpp hello_world_widget.ui : /qt4//QtGui ; +exe hello : main.cpp hello_world_widget.ui : /qt//QtGui ; diff --git a/scripts/nightly.sh b/scripts/nightly.sh index ffc8afaa8..6fb31b868 100644 --- a/scripts/nightly.sh +++ b/scripts/nightly.sh @@ -13,3 +13,4 @@ cd boost-build/build/v2 ./roll.sh > ../roll-log cd .. scp boost-build.zip boost-build.tar.bz2 vladimir_prus@shell.sf.net:/home/groups/b/bo/boost/htdocs/boost-build2 > scp-log +echo "Upload successfull" diff --git a/src/build/targets.jam b/src/build/targets.jam index 96c60ac36..cab4436e1 100644 --- a/src/build/targets.jam +++ b/src/build/targets.jam @@ -584,7 +584,7 @@ class main-target : abstract-target # Returns the best viable alternative for this property-set # See the documentation for selection rules. - local rule select-alternatives ( property-set ) + local rule select-alternatives ( property-set debug ? ) { # When selecting alternatives we have to consider defaults, # for example: @@ -607,7 +607,7 @@ class main-target : abstract-target while $(worklist) && ! $(bad) { local v = $(worklist[1]) ; - local properties = [ $(v).match $(property-set) ] ; + local properties = [ $(v).match $(property-set) $(debug) ] ; if $(properties) != no-match { @@ -752,11 +752,8 @@ class main-target : abstract-target local best-alternatives = [ select-alternatives $(property-set) ] ; if ! $(best-alternatives) { - errors.error - "failed to build" [ full-name ] - "with properties" [ $(property-set).raw ] - "because no best-matching alternative could be found" - ; + ECHO "error: No best alternative for" [ full-name ] ; + select-alternatives $(property-set) debug ; return [ property-set.empty ] ; } else @@ -931,7 +928,8 @@ rule common-properties2 ( build-request requirements ) # Apply non-conditional requirements. # There's a slight bug here: it's possible that conditional # requirement change a value set by non-conditional requirements. This - # should be error, but we don't detect it yet. + # should be error, but we don't detect it yet. + local raw = [ $(build-request).raw ] ; raw = [ property.refine $(raw) : [ feature.expand [ $(requirements).non-conditional ] ] ] ; @@ -1071,7 +1069,7 @@ class basic-target : abstract-target # Returns the alternative condition for this alternative, if # the condition is satisfied by 'property-set'. - rule match ( property-set ) + rule match ( property-set debug ? ) { # The condition is composed of all base non-conditional properties. # It's not clear if we should expand 'self.requirements' or not. @@ -1084,12 +1082,25 @@ class basic-target : abstract-target local bcondition = [ $(self.requirements).base ] ; local ccondition = [ $(self.requirements).conditional ] ; local condition = [ set.difference $(bcondition) : $(ccondition) ] ; + if $(debug) + { + ECHO " next alternative: required properties:" $(condition:E=(empty)) ; + } + if $(condition) in [ $(property-set).raw ] { - return $(condition) ; + if $(debug) + { + ECHO " matched" ; + } + return $(condition) ; } else { + if $(debug) + { + ECHO " not matched" ; + } return no-match ; } } diff --git a/src/tools/common.jam b/src/tools/common.jam index 00b8d8284..0c42a15d3 100644 --- a/src/tools/common.jam +++ b/src/tools/common.jam @@ -249,7 +249,7 @@ rule get-invocation-command ( if $(.debug-configuration) { ECHO "warning: toolset $(toolset) initialization: " ; - ECHO "warning: can't find user-provided command '$(user-provided-command:J= )'" ; + ECHO "warning: can't find user-provided command " '$(user-provided-command)' ; ECHO "warning: initialized from" [ errors.nearest-user-location ] ; } # It's possible, in theory, that user-provided command is OK, but we're diff --git a/src/tools/package.jam b/src/tools/package.jam index 06547ebe3..ff9dd0eb0 100644 --- a/src/tools/package.jam +++ b/src/tools/package.jam @@ -41,9 +41,10 @@ rule install ( name : requirements * : binaries * : libraries * : headers * ) { local install-source-root = [ property.select : $(requirements) ] ; - install-source-root ?= "." ; - - + # If is not specified, all headers are installed + # to prefix/include, no matter what their relative path is. Sometimes + # that's what needed. + requirements = [ property.change $(requirements) : ] ; @@ -70,7 +71,11 @@ rule install ( name : requirements * : binaries * : libraries * : headers * ) stage.install $(name)-bin : $(binaries) : $(requirements) $(bin-locate) ; - stage.install $(name)-lib : $(libraries) : $(requirements) $(lib-locate) ; + stage.install $(name)-lib : + $(binaries) $(libraries) + : $(requirements) $(lib-locate) + on LIB + ; stage.install $(name)-headers : $(headers) : $(requirements) $(include-locate) $(install-source-root) ; alias $(name) : $(name)-bin $(name)-lib $(name)-headers ; diff --git a/src/tools/qt3.jam b/src/tools/qt3.jam index 4148f9422..ba7c63928 100644 --- a/src/tools/qt3.jam +++ b/src/tools/qt3.jam @@ -51,19 +51,19 @@ rule init ( prefix ? ) .initialized = true ; .prefix = $(prefix) ; - generators.register-standard qt3.moc : H : CPP(moc_%) : qt ; + generators.register-standard qt3.moc : H : CPP(moc_%) : qt3 ; # Note: the OBJ target type here is fake, take a look # at qt4.jam/uic-h-generator for explanations that # apply in this case as well. - generators.register [ new moc-h-generator - qt3.moc.cpp : MOCCABLE_CPP : OBJ : qt ] ; + generators.register [ new moc-h-generator-qt3 + qt3.moc.cpp : MOCCABLE_CPP : OBJ : qt3 ] ; # The UI type is defined in types/qt.jam, # and UIC_H is only used in qt.jam, but not in qt4.jam, so # define it here. type.register UIC_H : : H ; - generators.register-standard qt3.uic-h : UI : UIC_H : qt ; + generators.register-standard qt3.uic-h : UI : UIC_H : qt3 ; # The following generator is used to convert UI files to CPP # It creates UIC_H from UI, and constructs CPP from UI/UIC_H @@ -73,7 +73,7 @@ rule init ( prefix ? ) { rule __init__ ( ) { - generator.__init__ qt3.uic-cpp : UI UIC_H : CPP : qt ; + generator.__init__ qt3.uic-cpp : UI UIC_H : CPP : qt3 ; } rule run ( project name ? : properties * : sources + ) @@ -118,14 +118,14 @@ rule init ( prefix ? ) $(.prefix)/include $(.prefix)/lib $(.prefix)/lib - qt + qt3 ; lib qt : : qt-mt multi : : $(usage-requirements) ; lib qt : : qt single : : $(usage-requirements) ; } } -class moc-h-generator : generator +class moc-h-generator-qt3 : generator { rule __init__ ( * : * ) { diff --git a/src/tools/qt4.jam b/src/tools/qt4.jam index eb35658b1..72bf1d67d 100644 --- a/src/tools/qt4.jam +++ b/src/tools/qt4.jam @@ -1,5 +1,7 @@ -# Copyright 2002 Vladimir Prus +# Copyright 2002-2006 Vladimir Prus # Copyright 2005 Alo Sarv +# Copyright 2005-2006 Juergen Hunold +# # Distributed under the Boost Software License, Version 1.0. (See # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) @@ -48,10 +50,16 @@ import virtual-target ; project.initialize $(__name__) ; project qt ; +# Save the project so that we tolerate 'import + using' combo. +.project = [ project.current ] ; + + # Initialized the QT support module. The 'prefix' parameter # tells where QT is installed. rule init ( prefix ) { + project.push-current $(.project) ; + if $(.initialized) { if $(prefix) != $(.prefix) @@ -66,19 +74,20 @@ rule init ( prefix ) .prefix = $(prefix) ; # Generates cpp files from header files using "moc" tool - generators.register-standard qt4.moc : H : CPP(moc_%) ; + generators.register-standard qt4.moc : H : CPP(moc_%) : qt4 ; # The OBJ result type is a fake, 'H' will be really produces. # See comments on the generator calss, defined below # the 'init' function. - generators.register [ new uic-h-generator qt4.uic-h : UI : OBJ ] ; + generators.register [ new uic-h-generator qt4.uic-h : UI : OBJ + : qt4 ] ; # The OBJ result type is a fake here too. generators.register [ new moc-h-generator - qt4.moc.inc : MOCCABLE_CPP : OBJ ] ; + qt4.moc.inc : MOCCABLE_CPP : OBJ : qt4 ] ; generators.register [ new moc-inc-generator - qt4.moc.inc : MOCCABLE_H : OBJ ] ; + qt4.moc.inc : MOCCABLE_H : OBJ : qt4 ] ; # Generates .cpp file from qrc file generators.register-standard qt4.rcc : QRC : CPP(qrc_%) ; @@ -90,7 +99,12 @@ rule init ( prefix ) local all-libraries = QtCore QtGui QtNetwork QtXml QtSql QtSvg Qt3Support QtTest QtAssistantClient QtUiTools ; for local l in $(all-libraries) { - alias $(l) : $(.prefix)//$(l) ; + alias $(l) + : $(.prefix)//$(l) + : + : + : qt4 + ; explicit $(l) ; } } @@ -101,7 +115,9 @@ rule init ( prefix ) $(.prefix)/include $(.prefix)/lib $(.prefix)/lib - multi ; + multi + qt4 + ; local suffix ; if [ os.name ] = NT @@ -294,8 +310,17 @@ rule init ( prefix ) ; } } + + project.pop-current ; } +rule initialized ( ) +{ + return $(.initialized) ; +} + + + # This custom generator is needed because it QT4, UI files are translated # only in H files, and no C++ files are created. Further, the H files # need not be passed via MOC. The header is used only via inclusion. diff --git a/test/alternatives.py b/test/alternatives.py index f9d60feea..5c5ada90e 100644 --- a/test/alternatives.py +++ b/test/alternatives.py @@ -86,7 +86,7 @@ exe a : a_empty.cpp ; exe a : a.cpp ; """) t.run_build_system("--no-error-backtrace", status=1) -t.fail_test(find(t.stdout(), "because no best-matching alternative could be found") == -1) +t.fail_test(find(t.stdout(), "No best alternative") == -1) # Another ambiguity test: two matches properties in one alternative are # neither better nor worse than a single one in another alternative. @@ -96,7 +96,7 @@ exe a : a.cpp : on ; """) t.run_build_system("--no-error-backtrace", status=1) -t.fail_test(find(t.stdout(), "because no best-matching alternative could be found") == -1) +t.fail_test(find(t.stdout(), "No best alternative") == -1) diff --git a/test/searched_lib.py b/test/searched_lib.py index e6a61ca7a..8de51dcaf 100644 --- a/test/searched_lib.py +++ b/test/searched_lib.py @@ -41,7 +41,7 @@ local here = [ project.attribute $(__name__) location ] ; here = [ path.root $(here) [ path.pwd ] ] ; exe main : main.cpp helper ; -lib helper : helper.cpp test_lib : $(here)/lib ; +lib helper : helper.cpp test_lib ; lib test_lib : : test_lib lib ; """) t.write("main.cpp", """ @@ -57,10 +57,32 @@ __declspec(dllexport) #endif helper() { foo(); } """) -t.run_build_system(stderr=None) # gcc warns about libraries which are not in -rpath. +t.run_build_system() t.expect_addition("bin/$toolset/debug/main.exe") t.rm("bin/$toolset/debug/main.exe") +# Test the 'unit-test' will correctly add runtime paths +# to searched libraries. +t.write('Jamfile', """ + +import path ; +import project ; +import testing ; + +project : requirements false ; + +local here = [ project.attribute $(__name__) location ] ; +here = [ path.root $(here) [ path.pwd ] ] ; + +unit-test main : main.cpp helper ; +lib helper : helper.cpp test_lib ; +lib test_lib : : test_lib lib ; +""") +t.run_build_system() +t.expect_addition("bin/$toolset/debug/main.passed") +t.rm("bin/$toolset/debug/main.exe") + + # Now try using searched lib from static lib. Request shared version # of searched lib, since we don't have static one handy. t.write('Jamfile', """