1# Copyright 2002-2006 Vladimir Prus 2# Copyright 2005 Alo Sarv 3# Copyright 2005-2012 Juergen Hunold 4# 5# Distributed under the Boost Software License, Version 1.0. (See 6# accompanying file LICENSE_1_0.txt or copy at 7# http://www.boost.org/LICENSE_1_0.txt) 8 9# Qt5 library support module 10# 11# The module attempts to auto-detect QT installation location from QTDIR 12# environment variable; failing that, installation location can be passed as 13# argument: 14# 15# toolset.using qt5 : /usr/local/Trolltech/Qt-5.0.0 ; 16# 17# The module supports code generation from .ui and .qrc files, as well as 18# running the moc preprocessor on headers. Note that you must list all your 19# moc-able headers in sources. 20# 21# Example: 22# 23# exe myapp : myapp.cpp myapp.h myapp.ui myapp.qrc 24# /qt5//QtGui /qt5//QtNetwork ; 25# 26# It's also possible to run moc on cpp sources: 27# 28# import cast ; 29# 30# exe myapp : myapp.cpp [ cast _ moccable-cpp : myapp.cpp ] /qt5//QtGui ; 31# 32# When moccing source file myapp.cpp you need to include "myapp.moc" from 33# myapp.cpp. When moccing .h files, the output of moc will be automatically 34# compiled and linked in, you don't need any includes. 35# 36# This is consistent with Qt guidelines: 37# http://qt-project.org/doc/qt-5.0/moc.html 38 39# The .qrc processing utility supports various command line option (see 40# http://qt-project.org/doc/qt-5.0/rcc.html for a complete list). The 41# module provides default arguments for the "output file" and 42# "initialization function name" options. Other options can be set through 43# the <rccflags> build property. E.g. if you wish the compression settings 44# to be more aggressive than the defaults, you can apply them too all .qrc 45# files like this: 46# 47# project my-qt-project : 48# requirements 49# <rccflags>"-compress 9 -threshold 10" 50# ; 51# 52# Of course, this property can also be specified on individual targets. 53 54 55import modules ; 56import feature ; 57import errors ; 58import type ; 59import "class" : new ; 60import generators ; 61import project ; 62import toolset : flags ; 63import os ; 64import virtual-target ; 65import scanner ; 66 67# The Qt version used for requirements 68# Valid are <qt>5.0 or <qt>5.1.0 69# Auto-detection via qmake sets '<qt>major.minor.patch' 70feature.feature qt5 : : propagated ; 71 72# Extra flags for rcc 73# $TODO: figure out how to declare this only once 74# feature.feature rccflags : : free ; 75 76project.initialize $(__name__) ; 77project qt5 ; 78 79# Save the project so that we tolerate 'import + using' combo. 80.project = [ project.current ] ; 81 82# Helper utils for easy debug output 83if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] 84{ 85 .debug-configuration = TRUE ; 86} 87 88local rule debug-message ( message * ) 89{ 90 if $(.debug-configuration) = TRUE 91 { 92 ECHO notice\: "[qt5-cfg]" $(message) ; 93 } 94} 95 96# Capture qmake output line by line 97local rule read-output ( content ) 98{ 99 local lines ; 100 local nl = " 101" ; 102 local << = "([^$(nl)]*)[$(nl)](.*)" ; 103 local line+ = [ MATCH "$(<<)" : "$(content)" ] ; 104 while $(line+) 105 { 106 lines += $(line+[1]) ; 107 line+ = [ MATCH "$(<<)" : "$(line+[2])" ] ; 108 } 109 return $(lines) ; 110} 111 112# Capture Qt version from qmake 113local rule check-version ( bin_prefix ) 114{ 115 full-cmd = $(bin_prefix)"/qmake -v" ; 116 debug-message Running '$(full-cmd)' ; 117 local output = [ SHELL $(full-cmd) ] ; 118 for line in [ read-output $(output) ] 119 { 120 # Parse the output to get all the results. 121 if [ MATCH "QMake" : $(line) ] 122 { 123 # Skip first line of output 124 } 125 else 126 { 127 temp = [ MATCH "([0-9]*)\\.([0-9]*)\\.([0-9]*)" : $(line) ] ; 128 } 129 } 130 return $(temp) ; 131} 132 133# Validate the version string and extract the major/minor part we care about. 134# 135local rule split-version ( version ) 136{ 137 local major-minor = [ MATCH "^([0-9]+)\.([0-9]+)(.*)$" : $(version) : 1 2 3 ] ; 138 if ! $(major-minor[2]) || $(major-minor[3]) 139 { 140 ECHO "Warning: 'using qt' expects a two part (major, minor) version number; got" $(version) instead ; 141 142 # Add a zero to account for the missing digit if necessary. 143 major-minor += 0 ; 144 } 145 146 return $(major-minor[1]) $(major-minor[2]) ; 147} 148 149# Initialize the QT support module. 150# Parameters: 151# - 'prefix' parameter tells where Qt is installed. 152# - 'version' optional version of Qt, else autodetected via 'qmake -v' 153# - 'condition' optional requirements 154# - 'namespace' optional support for configure -qtnamespace 155# - 'infix' optional support for configure -qtlibinfix 156# - 'full_bin' optional full path to Qt binaries (qmake,moc,uic,rcc) 157# - 'full_inc' optional full path to Qt top-level include directory 158# - 'full_lib' optional full path to Qt library directory 159rule init ( prefix : version ? : condition * : namespace ? : infix ? : full_bin ? : full_inc ? : full_lib ? ) 160{ 161 project.push-current $(.project) ; 162 163 debug-message "==== Configuring Qt ... ====" ; 164 for local v in version prefix condition namespace infix full_bin full_inc full_lib 165 { 166 if $($(v)) 167 { 168 debug-message " user-specified $(v):" '$($(v))' ; 169 } 170 } 171 172 # Needed as default value 173 .prefix = $(prefix) ; 174 175 # pre-build paths to detect reinitializations changes 176 local inc_prefix lib_prefix bin_prefix ; 177 if $(full_inc) 178 { 179 inc_prefix = $(full_inc) ; 180 } 181 else 182 { 183 inc_prefix = $(prefix)/include ; 184 } 185 if $(full_lib) 186 { 187 lib_prefix = $(full_lib) ; 188 } 189 else 190 { 191 lib_prefix = $(prefix)/lib ; 192 } 193 if $(full_bin) 194 { 195 bin_prefix = $(full_bin) ; 196 } 197 else 198 { 199 bin_prefix = $(prefix)/bin ; 200 } 201 202 # Globally needed variables 203 .incprefix = $(inc_prefix) ; 204 .libprefix = $(lib_prefix) ; 205 .binprefix = $(bin_prefix) ; 206 207 if ! $(.initialized) 208 { 209 # Make sure this is initialised only once 210 .initialized = true ; 211 212 # Generates cpp files from header files using "moc" tool 213 generators.register-standard qt5.moc : H : CPP(moc_%) : <allow>qt5 ; 214 215 # The OBJ result type is a fake, 'H' will be really produced. See 216 # comments on the generator class, defined below the 'init' function. 217 generators.register [ new uic-5-generator qt5.uic : UI : OBJ : 218 <allow>qt5 ] ; 219 220 # The OBJ result type is a fake here too. 221 generators.register [ new moc-h-5-generator 222 qt5.moc.inc : MOCCABLE5_CPP : OBJ : <allow>qt5 ] ; 223 224 generators.register [ new moc-inc-5-generator 225 qt5.moc.inc : MOCCABLE5_H : OBJ : <allow>qt5 ] ; 226 227 # Generates .cpp files from .qrc files. 228 generators.register-standard qt5.rcc : QRC : CPP(qrc_%) : <allow>qt5 ; 229 230 # dependency scanner for wrapped files. 231 type.set-scanner QRC : qrc-5-scanner ; 232 233 # Save value of first occurring prefix 234 .PREFIX = $(prefix) ; 235 } 236 237 if $(version) 238 { 239 major-minor = [ split-version $(version) ] ; 240 version = $(major-minor:J=.) ; 241 } 242 else 243 { 244 version = [ check-version $(bin_prefix) ] ; 245 if $(version) 246 { 247 version = $(version:J=.) ; 248 } 249 debug-message Detected version '$(version)' ; 250 } 251 252 local target-requirements = $(condition) ; 253 254 # Add the version, if any, to the target requirements. 255 if $(version) 256 { 257 if ! $(version) in [ feature.values qt5 ] 258 { 259 feature.extend qt5 : $(version) ; 260 } 261 target-requirements += <qt5>$(version:E=default) ; 262 } 263 264 local target-os = [ feature.get-values target-os : $(condition) ] ; 265 if ! $(target-os) 266 { 267 target-os ?= [ feature.defaults target-os ] ; 268 target-os = $(target-os:G=) ; 269 target-requirements += <target-os>$(target-os) ; 270 } 271 272 # Build exact requirements for the tools 273 local tools-requirements = $(target-requirements:J=/) ; 274 275 debug-message "Details of this Qt configuration:" ; 276 debug-message " prefix: " '$(prefix:E=<empty>)' ; 277 debug-message " binary path: " '$(bin_prefix:E=<empty>)' ; 278 debug-message " include path:" '$(inc_prefix:E=<empty>)' ; 279 debug-message " library path:" '$(lib_prefix:E=<empty>)' ; 280 debug-message " target requirements:" '$(target-requirements)' ; 281 debug-message " tool requirements: " '$(tools-requirements)' ; 282 283 # setup the paths for the tools 284 toolset.flags qt5.moc .BINPREFIX $(tools-requirements) : $(bin_prefix) ; 285 toolset.flags qt5.rcc .BINPREFIX $(tools-requirements) : $(bin_prefix) ; 286 toolset.flags qt5.uic .BINPREFIX $(tools-requirements) : $(bin_prefix) ; 287 288 # TODO: 2009-02-12: Better support for directories 289 # Most likely needed are separate getters for: include,libraries,binaries and sources. 290 toolset.flags qt5.directory .PREFIX $(tools-requirements) : $(prefix) ; 291 292 # Test for a buildable Qt. 293 if [ glob $(.prefix)/Jamroot ] 294 { 295 .bjam-qt = true 296 297 # this will declare QtCore (and qtmain on <target-os>windows) 298 add-shared-library QtCore ; 299 } 300 else 301 # Setup common pre-built Qt. 302 # Special setup for QtCore on which everything depends 303 { 304 local link = [ feature.get-values link : $(condition) ] ; 305 306 local usage-requirements = 307 <include>$(.incprefix) 308 <library-path>$(.libprefix) 309 <threading>multi 310 <allow>qt5 ; 311 312 if $(link) in shared 313 { 314 usage-requirements += <dll-path>$(.libprefix) ; 315 usage-requirements += <target-os>windows:<dll-path>$(.binprefix) ; 316 } 317 318 local suffix ; 319 320 # debug versions on unix have to be built 321 # separately and therefore have no suffix. 322 .infix_version = "" ; 323 .suffix_debug = "" ; 324 325 # Control flag for auto-configuration of the debug libraries. 326 # This setup requires Qt 'configure -debug-and-release'. 327 # Only available on some platforms. 328 # ToDo: 2009-02-12: Maybe throw this away and 329 # require separate setup with <variant>debug as condition. 330 .have_separate_debug = FALSE ; 331 332 # Setup other platforms 333 if $(target-os) in windows cygwin 334 { 335 .have_separate_debug = TRUE ; 336 337 # On NT, the libs have "d" suffix in debug builds. 338 .suffix_debug = "d" ; 339 340 .infix_version = "5" ; 341 342 # On Windows we must link against the qtmain library 343 lib qtmain 344 : # sources 345 : # requirements 346 <name>qtmain$(.suffix_debug) 347 <variant>debug 348 $(target-requirements) 349 ; 350 351 lib qtmain 352 : # sources 353 : # requirements 354 <name>qtmain 355 $(target-requirements) 356 ; 357 } 358 else if $(target-os) = darwin 359 { 360 # On MacOS X, both debug and release libraries are available. 361 .suffix_debug = "_debug" ; 362 363 .have_separate_debug = TRUE ; 364 365 alias qtmain ; 366 } 367 else 368 { 369 alias qtmain : : $(target-requirements) ; 370 .infix_version = "5" ; 371 } 372 373 lib QtCore : qtmain 374 : # requirements 375 <name>Qt$(.infix_version)Core 376 $(target-requirements) 377 : # default-build 378 : # usage-requirements 379 <define>QT_CORE_LIB 380 <define>QT_NO_DEBUG 381 <include>$(.incprefix)/QtCore 382 $(usage-requirements) 383 ; 384 385 if $(.have_separate_debug) = TRUE 386 { 387 debug-message Configure debug libraries with suffix '$(.suffix_debug)' ; 388 389 lib QtCore : $(main) 390 : # requirements 391 <name>Qt$(.infix_version)Core$(.suffix_debug) 392 <variant>debug 393 $(target-requirements) 394 : # default-build 395 : # usage-requirements 396 <define>QT_CORE_LIB 397 <include>$(.incprefix)/QtCore 398 $(usage-requirements) 399 ; 400 } 401 } 402 403 if [ glob $(.incprefix)/QtAngle ] 404 { 405 # Setup support of ANGLE builds. 406 alias QtAngle 407 : # sources 408 : # requirements 409 $(target-requirements) 410 : # default-build 411 : # usage-requirements 412 <define>QT_OPENGL_ES_2 413 <define>QT_OPENGL_ES_2_ANGLE 414 <include>$(.incprefix)/QtAngle 415 $(usage-requirements) 416 ; 417 } 418 else 419 { 420 alias QtAngle 421 : # sources 422 : # requirements 423 $(target-requirements) 424 ; 425 } 426 427 # Initialising the remaining libraries is canonical 428 # parameters 'module' : 'depends-on' : 'usage-define' : 'requirements' : 'include' 429 # 'include' only for non-canonical include paths. 430 add-shared-library QtGui : QtCore QtAngle : QT_GUI_LIB : $(target-requirements) ; 431 add-shared-library QtWidgets : QtGui : QT_WIDGETS_LIB : $(target-requirements) ; 432 add-shared-library QtNetwork : QtCore : QT_NETWORK_LIB : $(target-requirements) ; 433 add-shared-library QtSql : QtCore : QT_SQL_LIB : $(target-requirements) ; 434 add-shared-library QtXml : QtCore : QT_XML_LIB : $(target-requirements) ; 435 add-shared-library QtPrintSupport : QtGui : QT_PRINTSUPPORT_LIB : $(target-requirements) ; 436 add-shared-library QtConcurrent : QtCore : QT_CONCURRENT_LIB : $(target-requirements) ; 437 438 add-shared-library QtPositioning : QtCore : QT_POSITIONING_LIB : $(target-requirements) ; 439 440 add-shared-library QtOpenGL : QtGui : QT_OPENGL_LIB : $(target-requirements) ; 441 add-shared-library QtSvg : QtXml QtOpenGL : QT_SVG_LIB : $(target-requirements) ; 442 443 add-shared-library QtTest : QtCore : : $(target-requirements) ; 444 445 # Qt designer library et. al. 446 add-shared-library QtDesigner : QtGui QtXml : : $(target-requirements) ; 447 add-shared-library QtDesignerComponents : QtGui QtXml : : $(target-requirements) ; 448 add-static-library QtUiTools : QtGui QtXml : $(target-requirements) ; 449 450 # DBus-Support 451 add-shared-library QtDBus : QtXml : : $(target-requirements) ; 452 453 # Script-Engine and Tools 454 add-shared-library QtScript : QtGui QtXml : QT_SCRIPT_LIB : $(target-requirements) ; 455 add-shared-library QtScriptTools : QtScript : QT_SCRIPTTOOLS_LIB : $(target-requirements) ; 456 457 # WebKit 458 add-shared-library QtWebKit : QtGui : QT_WEBKIT_LIB : $(target-requirements) ; 459 add-shared-library QtWebKitWidgets : QtGui : QT_WEBKITWIDGETS_LIB : $(target-requirements) ; 460 461 # Multimedia engine 462 add-shared-library QtMultimedia : QtGui : QT_MULTIMEDIA_LIB : $(target-requirements) ; 463 add-shared-library QtMultimediaWidgets : QtMultimedia : QT_MULTIMEDIAWIDGETS_LIB : $(target-requirements) ; 464 465 # 466 add-shared-library QtXmlPatterns : QtNetwork : QT_XMLPATTERNS_LIB : $(target-requirements) ; 467 468 # Help-Engine 469 add-shared-library QtHelp : QtGui QtSql QtXml : : $(target-requirements) ; 470 add-shared-library QtCLucene : QCore QtSql QtXml : : $(target-requirements) ; 471 472 # QtQuick 473 add-shared-library QtQml : QtCore QtNetwork QtGui : QT_QML_LIB : $(target-requirements) ; 474 add-shared-library QtQuick : QtQml : QT_QUICK_LIB : $(target-requirements) ; 475 add-shared-library QtQuickParticles : QtQml : : $(target-requirements) ; 476 add-shared-library QtQuickTest : QtQml : : $(target-requirements) ; 477 478 add-shared-library QtSerialPort : QtCore : QT_SERIALPORT_LIB : $(target-requirements) ; 479 480 # QtLocation (since 5.4) 481 add-shared-library QtLocation : QtQuick QtPositioning : QT_LOCATION_LIB : $(target-requirements) ; 482 483 # Webengine support (since 5.4) 484 add-shared-library QtWebEngine : QtGui : QT_WEBENGINE_LIB : $(target-requirements) ; 485 add-shared-library QtWebEngineCore : QtWebEngine : QT_WEBENGINECORE_LIB : $(target-requirements) ; 486 add-shared-library QtWebEngineWidgets : QtWebEngineCore QtWidgets : QT_WEBENGINEWIDGETS_LIB : $(target-requirements) ; 487 488 add-shared-library QtWebChannel : QtQml : QT_WEBCHANNEL_LIB : $(target-requirements) ; 489 add-shared-library QtWebSockets : QtNetwork : QT_WEBSOCKETS_LIB : $(target-requirements) ; 490 491 add-shared-library QtWebView : QtWebEngineCore QtWebChannel : QT_WEBVIEW_LIB : $(target-requirements) ; 492 493 # Qt3d libraries (since 5.6) 494 add-shared-library Qt3DCore : QtGui : QT_3DCORE_LIB : $(target-requirements) ; 495 add-shared-library Qt3DRender : Qt3DCore QtConcurrent : QT_3DRENDER_LIB : $(target-requirements) ; 496 add-shared-library Qt3DLogic : Qt3DCore : QT_3DLOGIC_LIB : $(target-requirements) ; 497 add-shared-library Qt3DInput : Qt3DRender : QT_3DINPUT_LIB : $(target-requirements) ; 498 499 # QtCharts (since 5.7) 500 add-shared-library QtCharts : QtWidgets : QT_CHARTS_LIB : $(target-requirements) ; 501 502 # 3D data visualization (since 5.7) 503 add-shared-library QtDataVisualization : QtGui : QT_DATAVISUALIZATION_LIB : $(target-requirements) ; 504 505 # In-App purchase API (since 5.7) 506 add-shared-library QtPurchasing : QtCore : QT_PURCHASING_LIB : $(target-requirements) ; 507 508 # Qt Connectivity (since 5.3) 509 add-shared-library QtBluetooth : QtCore : QT_BLUETOOTH_LIB : $(target-requirements) ; 510 add-shared-library QtNfc : QtCore : QT_NFC_LIB : $(target-requirements) ; 511 512 # Gamepad (since 5.7) 513 add-shared-library QtGamepad : QtCore : QT_GAMEPAD_LIB : $(target-requirements) ; 514 515 # SCXML state machine (since 5.7) 516 add-shared-library QtScxml : QtCore : QT_SCXML_LIB : $(target-requirements) ; 517 518 # Tech Preview QtQuick 519 # SerialBus (since 5.7) 520 add-shared-library QtSerialBus : QtCore : QT_SERIALBUS_LIB : $(target-requirements) ; 521 522 # Platform dependent libraries 523 # Regular expression support 524 add-shared-library QtV8 : QtCore : : $(target-requirements) ; 525 526 # QML-Engine version1 527 add-shared-library QtDeclarative : QtXml : : $(target-requirements) ; 528 529 debug-message "==== Configured Qt-$(version) ====" ; 530 531 project.pop-current ; 532} 533 534rule initialized ( ) 535{ 536 return $(.initialized) ; 537} 538 539 540 541# This custom generator is needed because in QT5, UI files are translated only 542# into H files, and no C++ files are created. Further, the H files need not be 543# passed via MOC. The header is used only via inclusion. If we define a standard 544# UI -> H generator, B2 will run MOC on H, and then compile the 545# resulting cpp. It will give a warning, since output from moc will be empty. 546# 547# This generator is declared with a UI -> OBJ signature, so it gets invoked when 548# linking generator tries to convert sources to OBJ, but it produces target of 549# type H. This is non-standard, but allowed. That header won't be mocced. 550# 551class uic-5-generator : generator 552{ 553 rule __init__ ( * : * ) 554 { 555 generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; 556 } 557 558 rule run ( project name ? : property-set : sources * ) 559 { 560 if ! $(name) 561 { 562 name = [ $(sources[0]).name ] ; 563 name = $(name:B) ; 564 } 565 566 local a = [ new action $(sources[1]) : qt5.uic : $(property-set) ] ; 567 568 # The 'ui_' prefix is to match qmake's default behavior. 569 local target = [ new file-target ui_$(name) : H : $(project) : $(a) ] ; 570 571 local r = [ virtual-target.register $(target) ] ; 572 573 # Since this generator will return a H target, the linking generator 574 # won't use it at all, and won't set any dependency on it. However, we 575 # need the target to be seen by bjam, so that dependency from sources to 576 # this generated header is detected -- if jam does not know about this 577 # target, it won't do anything. 578 DEPENDS all : [ $(r).actualize ] ; 579 580 return $(r) ; 581 } 582} 583 584 585class moc-h-5-generator : generator 586{ 587 rule __init__ ( * : * ) 588 { 589 generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; 590 } 591 592 rule run ( project name ? : property-set : sources * ) 593 { 594 if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE5_CPP 595 { 596 name = [ $(sources[0]).name ] ; 597 name = $(name:B) ; 598 599 local a = [ new action $(sources[1]) : qt5.moc.inc : 600 $(property-set) ] ; 601 602 local target = [ new file-target $(name) : MOC : $(project) : $(a) 603 ] ; 604 605 local r = [ virtual-target.register $(target) ] ; 606 607 # Since this generator will return a H target, the linking generator 608 # won't use it at all, and won't set any dependency on it. However, 609 # we need the target to be seen by bjam, so that dependency from 610 # sources to this generated header is detected -- if jam does not 611 # know about this target, it won't do anything. 612 DEPENDS all : [ $(r).actualize ] ; 613 614 return $(r) ; 615 } 616 } 617} 618 619 620class moc-inc-5-generator : generator 621{ 622 rule __init__ ( * : * ) 623 { 624 generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; 625 } 626 627 rule run ( project name ? : property-set : sources * ) 628 { 629 if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE5_H 630 { 631 name = [ $(sources[0]).name ] ; 632 name = $(name:B) ; 633 634 local a = [ new action $(sources[1]) : qt5.moc.inc : 635 $(property-set) ] ; 636 637 local target = [ new file-target moc_$(name) : CPP : $(project) : 638 $(a) ] ; 639 640 # Since this generator will return a H target, the linking generator 641 # won't use it at all, and won't set any dependency on it. However, 642 # we need the target to be seen by bjam, so that dependency from 643 # sources to this generated header is detected -- if jam does not 644 # know about this target, it won't do anything. 645 DEPENDS all : [ $(target).actualize ] ; 646 647 return [ virtual-target.register $(target) ] ; 648 } 649 } 650} 651 652 653# Query the installation directory. This is needed in at least two scenarios. 654# First, when re-using sources from the Qt-Tree. Second, to "install" custom Qt 655# plugins to the Qt-Tree. 656# 657rule directory 658{ 659 return $(.PREFIX) ; 660} 661 662# Add a shared Qt library. 663rule add-shared-library ( lib-name : depends-on * : usage-defines * : requirements * : include ? ) 664{ 665 add-library $(lib-name) : $(.infix_version) : $(depends-on) : $(usage-defines) : $(requirements) : $(include) ; 666} 667 668# Add a static Qt library. 669rule add-static-library ( lib-name : depends-on * : usage-defines * : requirements * : include ? ) 670{ 671 add-library $(lib-name) : $(.infix_version) : $(depends-on) : $(usage-defines) : $(requirements) : $(include) ; 672} 673 674# Add a Qt library. 675# Static libs are unversioned, whereas shared libs have the major number as suffix. 676# Creates both release and debug versions on platforms where both are enabled by Qt configure. 677# Flags: 678# - lib-name Qt library Name 679# - version Qt major number used as shared library suffix (QtCore5.so) 680# - depends-on other Qt libraries 681# - usage-defines those are set by qmake, so set them when using this library 682# - requirements additional requirements 683# - include non-canonical include path. The canonical path is $(.incprefix)/$(lib-name). 684rule add-library ( lib-name : version ? : depends-on * : usage-defines * : requirements * : include ? ) 685{ 686 if $(.bjam-qt) 687 { 688 # Import Qt module 689 # Eveything will be setup there 690 alias $(lib-name) 691 : $(.prefix)//$(lib-name) 692 : 693 : 694 : <allow>qt5 ; 695 } 696 else 697 { 698 local real_include ; 699 real_include ?= $(include) ; 700 real_include ?= $(lib-name) ; 701 702 local real_name = [ MATCH ^Qt(.*) : $(lib-name) ] ; 703 704 lib $(lib-name) 705 : # sources 706 $(depends-on) 707 : # requirements 708 <name>Qt$(version)$(real_name) 709 $(requirements) 710 : # default-build 711 : # usage-requirements 712 <define>$(usage-defines) 713 <include>$(.incprefix)/$(real_include) 714 ; 715 716 if $(.have_separate_debug) = TRUE 717 { 718 lib $(lib-name) 719 : # sources 720 $(depends-on) 721 : # requirements 722 <name>Qt$(version)$(real_name)$(.suffix_debug) 723 $(requirements) 724 <variant>debug 725 : # default-build 726 : # usage-requirements 727 <define>$(usage-defines) 728 <include>$(.incprefix)/$(real_include) 729 ; 730 } 731 } 732 733 # Make library explicit so that a simple <use>qt5 will not bring in everything. 734 # And some components like QtDBus/Phonon may not be available on all platforms. 735 explicit $(lib-name) ; 736} 737 738# Use $(.BINPREFIX[-1]) for the paths as several tools-requirements can match. 739# The exact match is the last one. 740 741# Get <include> and <defines> from current toolset. 742flags qt5.moc INCLUDES <include> ; 743flags qt5.moc DEFINES <define> ; 744 745# need a newline for expansion of DEFINES and INCLUDES in the response file. 746.nl = " 747" ; 748 749# Processes headers to create Qt MetaObject information. Qt5-moc has its 750# c++-parser, so pass INCLUDES and DEFINES. 751# We use response file with one INCLUDE/DEFINE per line 752# 753actions moc 754{ 755 $(.BINPREFIX[-1])/moc $(>) -o $(<) @"@($(<).rsp:E=-D$(DEFINES)$(.nl) -I$(INCLUDES:T)$(.nl))" 756} 757 758# When moccing files for include only, we don't need -f, otherwise the generated 759# code will include the .cpp and we'll get duplicated symbols. 760# 761actions moc.inc 762{ 763 $(.BINPREFIX[-1])/moc $(>) -o $(<) @"@($(<).rsp:E=-D$(DEFINES)$(.nl) -I$(INCLUDES:T)$(.nl))" 764} 765 766 767# Get extra options for RCC 768flags qt5.rcc RCC_OPTIONS <rccflags> ; 769 770# Generates source files from resource files. 771# 772actions rcc 773{ 774 $(.BINPREFIX[-1])/rcc $(>) -name $(>:B) $(RCC_OPTIONS) -o $(<) 775} 776 777 778# Generates user-interface source from .ui files. 779# 780actions uic 781{ 782 $(.BINPREFIX[-1])/uic $(>) -o $(<) 783} 784 785 786# Scanner for .qrc files. Look for the CDATA section of the <file> tag. Ignore 787# the "alias" attribute. See http://doc.trolltech.com/qt/resources.html for 788# detailed documentation of the Qt Resource System. 789# 790class qrc-5-scanner : common-scanner 791{ 792 rule pattern ( ) 793 { 794 return "<file.*>(.*)</file>" ; 795 } 796} 797 798 799# Wrapped files are "included". 800scanner.register qrc-5-scanner : include ; 801