1# this must be done outside any function 2QT_SOURCE_TREE = $$PWD 3QT_BUILD_TREE = $$shadowed($$PWD) 4 5# custom command line handling 6 7defineTest(qtConfCommandline_qmakeArgs) { 8 contains(1, QMAKE_[A-Z0-9_]+ *[-+]?=.*) { 9 config.input.qmakeArgs += $$1 10 export(config.input.qmakeArgs) 11 return(true) 12 } 13 return(false) 14} 15 16defineTest(qtConfCommandline_cxxstd) { 17 arg = $${1} 18 val = $${2} 19 isEmpty(val): val = $$qtConfGetNextCommandlineArg() 20 !contains(val, "^-.*"):!isEmpty(val) { 21 contains(val, "(c\+\+)?11") { 22 qtConfCommandlineSetInput("c++14", "no") 23 qtConfCommandlineSetInput("c++1z", "no") 24 qtConfCommandlineSetInput("c++2a", "no") 25 } else: contains(val, "(c\+\+)?(14|1y)") { 26 qtConfCommandlineSetInput("c++14", "yes") 27 qtConfCommandlineSetInput("c++1z", "no") 28 qtConfCommandlineSetInput("c++2a", "no") 29 } else: contains(val, "(c\+\+)?(17|1z)") { 30 qtConfCommandlineSetInput("c++14", "yes") 31 qtConfCommandlineSetInput("c++1z", "yes") 32 qtConfCommandlineSetInput("c++2a", "no") 33 } else: contains(val, "(c\+\+)?(2a)") { 34 qtConfCommandlineSetInput("c++14", "yes") 35 qtConfCommandlineSetInput("c++1z", "yes") 36 qtConfCommandlineSetInput("c++2a", "yes") 37 } else { 38 qtConfAddError("Invalid argument $$val to command line parameter $$arg") 39 } 40 } else { 41 qtConfAddError("Missing argument to command line parameter $$arg") 42 } 43} 44 45defineTest(qtConfCommandline_sanitize) { 46 arg = $${1} 47 val = $${2} 48 isEmpty(val): val = $$qtConfGetNextCommandlineArg() 49 !contains(val, "^-.*"):!isEmpty(val) { 50 equals(val, "address") { 51 qtConfCommandlineSetInput("sanitize_address", "yes") 52 } else: equals(val, "thread") { 53 qtConfCommandlineSetInput("sanitize_thread", "yes") 54 } else: equals(val, "memory") { 55 qtConfCommandlineSetInput("sanitize_memory", "yes") 56 } else: equals(val, "fuzzer-no-link") { 57 qtConfCommandlineSetInput("sanitize_fuzzer_no_link", "yes") 58 } else: equals(val, "undefined") { 59 qtConfCommandlineSetInput("sanitize_undefined", "yes") 60 } else { 61 qtConfAddError("Invalid argument $$val to command line parameter $$arg") 62 } 63 } else { 64 qtConfAddError("Missing argument to command line parameter $$arg") 65 } 66} 67 68defineTest(qtConfCommandline_coverage) { 69 arg = $${1} 70 val = $${2} 71 isEmpty(val): val = $$qtConfGetNextCommandlineArg() 72 !contains(val, "^-.*"):!isEmpty(val) { 73 equals(val, "trace-pc-guard") { 74 qtConfCommandlineSetInput("coverage_trace_pc_guard", "yes") 75 } else: equals(val, "source-based") { 76 qtConfCommandlineSetInput("coverage_source_based", "yes") 77 } else: { 78 qtConfAddError("Invalid argument $$val to command line parameter $$arg") 79 } 80 } else { 81 qtConfAddError("Missing argument to command line parameter $$arg") 82 } 83} 84 85# callbacks 86 87defineReplace(qtConfFunc_crossCompile) { 88 !isEmpty(config.input.xplatform): return(true) 89 !isEmpty(config.input.device-option): return(true) 90 !isEmpty(config.input.sysroot): return(true) 91 spec = $$[QMAKE_SPEC] 92 !equals(spec, $$[QMAKE_XSPEC]): return(true) 93 return(false) 94} 95 96defineReplace(qtConfFunc_licenseCheck) { 97 exists($$QT_SOURCE_TREE/LICENSE.LGPL3)|exists($$QT_SOURCE_TREE/LICENSE.GPL2)|exists($$QT_SOURCE_TREE/LICENSE.GPL3): \ 98 hasOpenSource = true 99 else: \ 100 hasOpenSource = false 101 exists($$QT_SOURCE_TREE/LICENSE.QT-LICENSE-AGREEMENT): \ 102 hasCommercial = true 103 else: \ 104 hasCommercial = false 105 106 commercial = $$config.input.commercial 107 isEmpty(commercial) { 108 $$hasOpenSource { 109 $$hasCommercial { 110 logn() 111 logn("Selecting Qt Edition.") 112 logn() 113 logn("Type 'c' if you want to use the Commercial Edition.") 114 logn("Type 'o' if you want to use the Open Source Edition.") 115 logn() 116 for(ever) { 117 val = $$lower($$prompt("Which edition of Qt do you want to use? ", false)) 118 equals(val, c) { 119 commercial = yes 120 QMAKE_SAVED_ARGS += -commercial 121 } else: equals(val, o) { 122 commercial = no 123 QMAKE_SAVED_ARGS += -opensource 124 } else { 125 next() 126 } 127 export(QMAKE_SAVED_ARGS) 128 break() 129 } 130 } else { 131 commercial = no 132 } 133 } else { 134 !$$hasCommercial: \ 135 qtConfFatalError("No license files. Cannot proceed. Try re-installing Qt.") 136 commercial = yes 137 } 138 } 139 140 equals(commercial, no) { 141 !$$hasOpenSource: \ 142 qtConfFatalError("This is the Qt Commercial Edition." \ 143 "Cannot proceed with -opensource.") 144 145 logn() 146 logn("This is the Qt Open Source Edition.") 147 148 EditionString = "Open Source" 149 config.input.qt_edition = OpenSource 150 export(config.input.qt_edition) 151 } else { 152 !$$hasCommercial: \ 153 qtConfFatalError("This is the Qt Open Source Edition." \ 154 "Cannot proceed with -commercial.") 155 156 !exists($$QT_SOURCE_TREE/.release-timestamp) { 157 # Build from git 158 159 logn() 160 logn("This is the Qt Commercial Edition.") 161 162 EditionString = "Commercial" 163 config.input.qt_edition = Commercial 164 export(config.input.qt_edition) 165 } else { 166 # Build from a released source package 167 168 equals(QMAKE_HOST.os, Linux) { 169 !equals(QMAKE_HOST.arch, x86_64): \ 170 Licheck = licheck32 171 else: \ 172 Licheck = licheck64 173 } else: equals(QMAKE_HOST.os, Darwin) { 174 Licheck = licheck_mac 175 } else: equals(QMAKE_HOST.os, Windows) { 176 Licheck = licheck.exe 177 } else { 178 qtConfFatalError("Host operating system not supported by this edition of Qt.") 179 } 180 181 !qtRunLoggedCommand("$$system_quote($$QT_SOURCE_TREE/bin/$$Licheck) \ 182 $$system_quote($$eval(config.input.confirm-license)) \ 183 $$system_quote($$QT_SOURCE_TREE) $$system_quote($$QT_BUILD_TREE) \ 184 $$[QMAKE_SPEC] $$[QMAKE_XSPEC]", \ 185 LicheckOutput, false): \ 186 return(false) 187 logn() 188 for (o, LicheckOutput) { 189 contains(o, "\\w+=.*"): \ 190 eval($$o) 191 else: \ 192 logn($$o) 193 } 194 config.input.qt_edition = $$Edition 195 config.input.qt_licheck = $$Licheck 196 config.input.qt_release_date = $$ReleaseDate 197 export(config.input.qt_edition) 198 export(config.input.qt_licheck) 199 export(config.input.qt_release_date) 200 return(true) 201 } 202 } 203 204 !isEmpty(config.input.confirm-license) { 205 logn() 206 logn("You have already accepted the terms of the $$EditionString license.") 207 return(true) 208 } 209 210 affix = the 211 equals(commercial, no) { 212 theLicense = "GNU Lesser General Public License (LGPL) version 3" 213 showWhat = "Type 'L' to view the GNU Lesser General Public License version 3 (LGPLv3)." 214 gpl2Ok = false 215 gpl3Ok = false 216 winrt { 217 notTheLicense = "Note: GPL version 2 is not available on WinRT." 218 } else: wasm { 219 gpl3Ok = true 220 theLicense = "GNU General Public License (GPL) version 3" 221 showWhat = "Type 'G' to view the GNU General Public License version 3 (GPLv3)." 222 } else: $$qtConfEvaluate("features.android-style-assets") { 223 notTheLicense = "Note: GPL version 2 is not available due to using Android style assets." 224 } else { 225 theLicense += "or the GNU General Public License (GPL) version 2" 226 showWhat += "Type 'G' to view the GNU General Public License version 2 (GPLv2)." 227 gpl2Ok = true 228 affix = either 229 } 230 } else { 231 theLicense = $$cat($$QT_SOURCE_TREE/LICENSE.QT-LICENSE-AGREEMENT, lines) 232 theLicense = $$first(theLicense) 233 showWhat = "Type '?' to view the $${theLicense}." 234 } 235 msg = \ 236 " " \ 237 "You are licensed to use this software under the terms of" \ 238 "the "$$theLicense"." \ 239 $$notTheLicense \ 240 " " \ 241 $$showWhat \ 242 "Type 'y' to accept this license offer." \ 243 "Type 'n' to decline this license offer." \ 244 " " 245 246 for(ever) { 247 logn($$join(msg, $$escape_expand(\\n))) 248 for(ever) { 249 val = $$lower($$prompt("Do you accept the terms of $$affix license? ", false)) 250 equals(val, y)|equals(val, yes) { 251 logn() 252 QMAKE_SAVED_ARGS += -confirm-license 253 export(QMAKE_SAVED_ARGS) 254 return(true) 255 } else: equals(val, n)|equals(val, no) { 256 return(false) 257 } else: equals(commercial, yes):equals(val, ?) { 258 licenseFile = $$QT_SOURCE_TREE/LICENSE.QT-LICENSE-AGREEMENT 259 } else: equals(commercial, no):equals(val, l) { 260 licenseFile = $$QT_SOURCE_TREE/LICENSE.LGPL3 261 } else: equals(commercial, no):equals(val, g):$$gpl2Ok { 262 licenseFile = $$QT_SOURCE_TREE/LICENSE.GPL2 263 } else: equals(commercial, no):equals(val, g):$$gpl3Ok { 264 licenseFile = $$QT_SOURCE_TREE/LICENSE.GPL3 265 } else { 266 next() 267 } 268 break() 269 } 270 system("more $$system_quote($$system_path($$licenseFile))") 271 logn() 272 logn() 273 } 274} 275 276# custom tests 277 278# this is meant for linux device specs only 279defineTest(qtConfTest_machineTuple) { 280 qtRunLoggedCommand("$$QMAKE_CXX -dumpmachine", $${1}.tuple)|return(false) 281 $${1}.cache += tuple 282 export($${1}.cache) 283 return(true) 284} 285 286defineTest(qtConfTest_verifySpec) { 287 qtConfTest_compile($$1): return(true) 288 qtConfFatalError("Cannot compile a minimal program. The toolchain or QMakeSpec is broken.", log) 289} 290 291defineTest(qtConfTest_architecture) { 292 !qtConfTest_compile($${1}): \ 293 error("Could not determine $$eval($${1}.label). See config.log for details.") 294 295 test = $$eval($${1}.test) 296 output = $$eval($${1}.output) 297 test_out_dir = $$OUT_PWD/$$basename(QMAKE_CONFIG_TESTS_DIR)/$$test 298 test_out_file = $$test_out_dir/$$cat($$test_out_dir/$${output}.target.txt) 299 exists($$test_out_file): \ 300 content = $$cat($$test_out_file, blob) 301 else: \ 302 error("$$eval($${1}.label) detection binary not found.") 303 content = $$cat($$test_out_file, blob) 304 305 arch_magic = ".*==Qt=magic=Qt== Architecture:([^\\0]*).*" 306 subarch_magic = ".*==Qt=magic=Qt== Sub-architecture:([^\\0]*).*" 307 buildabi_magic = ".*==Qt=magic=Qt== Build-ABI:([^\\0]*).*" 308 309 !contains(content, $$arch_magic)|!contains(content, $$subarch_magic)|!contains(content, $$buildabi_magic): \ 310 error("$$eval($${1}.label) detection binary does not contain expected data.") 311 312 $${1}.arch = $$replace(content, $$arch_magic, "\\1") 313 $${1}.subarch = $$replace(content, $$subarch_magic, "\\1") 314 $${1}.subarch = $$split($${1}.subarch, " ") 315 $${1}.buildabi = $$replace(content, $$buildabi_magic, "\\1") 316 export($${1}.arch) 317 export($${1}.subarch) 318 export($${1}.buildabi) 319 qtLog("Detected architecture: $$eval($${1}.arch) ($$eval($${1}.subarch))") 320 321 $${1}.cache += arch subarch buildabi 322 export($${1}.cache) 323 return(true) 324} 325 326defineTest(qtConfTest_gnumake) { 327 make = $$qtConfFindInPath("gmake") 328 isEmpty(make): make = $$qtConfFindInPath("make") 329 !isEmpty(make) { 330 qtRunLoggedCommand("$$make -v", version)|return(false) 331 contains(version, "^GNU Make.*"): return(true) 332 } 333 return(false) 334} 335 336defineTest(qtConfTest_detectPkgConfig) { 337 pkgConfig = $$getenv("PKG_CONFIG") 338 !isEmpty(pkgConfig): { 339 qtLog("Found pkg-config from environment variable: $$pkgConfig") 340 } else { 341 pkgConfig = $$QMAKE_PKG_CONFIG 342 343 !isEmpty(pkgConfig) { 344 qtLog("Found pkg-config from mkspec: $$pkgConfig") 345 } else { 346 pkgConfig = $$qtConfFindInPath("pkg-config") 347 348 isEmpty(pkgConfig): \ 349 return(false) 350 351 qtLog("Found pkg-config from path: $$pkgConfig") 352 } 353 } 354 355 $$qtConfEvaluate("features.cross_compile") { 356 # cross compiling, check that pkg-config is set up sanely 357 sysroot = $$config.input.sysroot 358 359 pkgConfigLibdir = $$getenv("PKG_CONFIG_LIBDIR") 360 isEmpty(pkgConfigLibdir) { 361 isEmpty(sysroot) { 362 qtConfAddWarning("Cross compiling without sysroot. Disabling pkg-config") 363 return(false) 364 } 365 !exists("$$sysroot/usr/lib/pkgconfig") { 366 qtConfAddWarning( \ 367 "Disabling pkg-config since PKG_CONFIG_LIBDIR is not set and" \ 368 "the host's .pc files would be used (even if you set PKG_CONFIG_PATH)." \ 369 "Set this variable to the directory that contains target .pc files" \ 370 "for pkg-config to function correctly when cross-compiling or" \ 371 "use -pkg-config to override this test.") 372 return(false) 373 } 374 375 pkgConfigLibdir = $$sysroot/usr/lib/pkgconfig:$$sysroot/usr/share/pkgconfig 376 machineTuple = $$eval($${currentConfig}.tests.machineTuple.tuple) 377 !isEmpty(machineTuple): \ 378 pkgConfigLibdir = "$$pkgConfigLibdir:$$sysroot/usr/lib/$$machineTuple/pkgconfig" 379 380 qtConfAddNote("PKG_CONFIG_LIBDIR automatically set to $$pkgConfigLibdir") 381 } 382 pkgConfigSysrootDir = $$getenv("PKG_CONFIG_SYSROOT_DIR") 383 isEmpty(pkgConfigSysrootDir) { 384 isEmpty(sysroot) { 385 qtConfAddWarning( \ 386 "Disabling pkg-config since PKG_CONFIG_SYSROOT_DIR is not set." \ 387 "Set this variable to your sysroot for pkg-config to function correctly when" \ 388 "cross-compiling or use -pkg-config to override this test.") 389 return(false) 390 } 391 392 pkgConfigSysrootDir = $$sysroot 393 qtConfAddNote("PKG_CONFIG_SYSROOT_DIR automatically set to $$pkgConfigSysrootDir") 394 } 395 $${1}.pkgConfigLibdir = $$pkgConfigLibdir 396 export($${1}.pkgConfigLibdir) 397 $${1}.pkgConfigSysrootDir = $$pkgConfigSysrootDir 398 export($${1}.pkgConfigSysrootDir) 399 $${1}.cache += pkgConfigLibdir pkgConfigSysrootDir 400 } 401 $${1}.pkgConfig = $$pkgConfig 402 export($${1}.pkgConfig) 403 $${1}.cache += pkgConfig 404 export($${1}.cache) 405 406 return(true) 407} 408 409defineTest(qtConfTest_buildParts) { 410 parts = $$config.input.make 411 isEmpty(parts) { 412 parts = libs examples 413 414 $$qtConfEvaluate("features.developer-build"): \ 415 parts += tests 416 !$$qtConfEvaluate("features.cross_compile"): \ 417 parts += tools 418 } 419 420 parts -= $$config.input.nomake 421 422 # always add libs, as it's required to build Qt 423 parts *= libs 424 425 $${1}.value = $$parts 426 export($${1}.value) 427 $${1}.cache = - 428 export($${1}.cache) 429 return(true) 430} 431 432defineTest(qtConfTest_x86Simd) { 433 simd = $$section(1, ".", -1) # last component 434 $${1}.args = CONFIG+=add_cflags DEFINES+=NO_ATTRIBUTE SIMD=$$simd 435 $${1}.test = x86_simd 436 qtConfTest_compile($${1}) 437} 438 439defineTest(qtConfTest_x86SimdAlways) { 440 configs = 441 fpfx = $${currentConfig}.features 442 tpfx = $${currentConfig}.tests 443 444 # Make a list of all passing features whose tests have type=x86Simd 445 for (f, $${tpfx}._KEYS_) { 446 !equals($${tpfx}.$${f}.type, "x86Simd"): \ 447 next() 448 qtConfCheckFeature($$f) 449 equals($${fpfx}.$${f}.available, true): configs += $$f 450 } 451 $${1}.literal_args = SIMD=$$join(configs, " ") 452 qtConfTest_compile($${1}) 453} 454 455# custom outputs 456 457# this reloads the qmakespec as completely as reasonably possible. 458defineTest(reloadSpec) { 459 bypassNesting() { 460 for (f, QMAKE_INTERNAL_INCLUDED_FILES) { 461 contains(f, .*/mkspecs/.*):\ 462 !contains(f, .*/(qt_build_config|qt_parts|qt_configure|configure_base)\\.prf): \ 463 discard_from($$f) 464 } 465 # nobody's going to try to re-load the features above, 466 # so don't bother with being selective. 467 QMAKE_INTERNAL_INCLUDED_FEATURES = \ 468 # loading it gets simulated below. 469 $$[QT_HOST_DATA/src]/mkspecs/features/device_config.prf \ 470 # must be delayed until qdevice.pri is ready. 471 $$[QT_HOST_DATA/src]/mkspecs/features/mac/toolchain.prf \ 472 $$[QT_HOST_DATA/src]/mkspecs/features/toolchain.prf 473 474 saved_variables = CONFIG QMAKE_CXXFLAGS 475 for (name, saved_variables): \ 476 _SAVED_$$name = $$eval($$name) 477 load(spec_pre) 478 # qdevice.pri gets written too late (and we can't write it early 479 # enough, as it's populated in stages, with later ones depending 480 # on earlier ones). so inject its variables manually. 481 for (l, $${currentConfig}.output.devicePro): \ 482 eval($$l) 483 include($$QMAKESPEC/qmake.conf) 484 load(spec_post) 485 for (name, saved_variables): \ 486 $$name += $$eval(_SAVED_$$name) 487 load(default_pre) 488 489 # ensure pristine environment for configuration. again. 490 discard_from($$[QT_HOST_DATA/get]/mkspecs/qconfig.pri) 491 discard_from($$[QT_HOST_DATA/get]/mkspecs/qmodule.pri) 492 } 493} 494 495defineTest(qtConfOutput_prepareSpec) { 496 device = $$eval(config.input.device) 497 !isEmpty(device) { 498 devices = $$files($$[QT_HOST_DATA/src]/mkspecs/devices/*$$device*) 499 isEmpty(devices): \ 500 qtConfFatalError("No device matching '$$device'.") 501 !count(devices, 1) { 502 err = "Multiple matches for device '$$device'. Candidates are:" 503 for (d, devices): \ 504 err += " $$basename(d)" 505 qtConfFatalError($$err) 506 } 507 XSPEC = $$relative_path($$devices, $$[QT_HOST_DATA/src]/mkspecs) 508 } 509 xspec = $$eval(config.input.xplatform) 510 !isEmpty(xspec) { 511 !exists($$[QT_HOST_DATA/src]/mkspecs/$$xspec/qmake.conf): \ 512 qtConfFatalError("Invalid target platform '$$xspec'.") 513 XSPEC = $$xspec 514 } 515 isEmpty(XSPEC): \ 516 XSPEC = $$[QMAKE_SPEC] 517 export(XSPEC) 518 QMAKESPEC = $$[QT_HOST_DATA/src]/mkspecs/$$XSPEC 519 export(QMAKESPEC) 520 521 notes = $$cat($$OUT_PWD/.config.notes, lines) 522 !isEmpty(notes): \ 523 qtConfAddNote("Also available for $$notes") 524 525 # deviceOptions() below contains conditionals coming form the spec, 526 # so this cannot be delayed for a batch reload. 527 reloadSpec() 528} 529 530defineTest(qtConfOutput_prepareOptions) { 531 $${currentConfig}.output.devicePro += \ 532 $$replace(config.input.device-option, "^([^=]+) *= *(.*)$", "\\1 = \\2") 533 darwin:!isEmpty(config.input.sdk) { 534 $${currentConfig}.output.devicePro += \ 535 "QMAKE_MAC_SDK = $$val_escape(config.input.sdk)" 536 } 537 android { 538 sdk_root = $$eval(config.input.android-sdk) 539 isEmpty(sdk_root): \ 540 sdk_root = $$getenv(ANDROID_SDK_ROOT) 541 isEmpty(sdk_root) { 542 for(ever) { 543 equals(QMAKE_HOST.os, Linux): \ 544 sdk_root = $$(HOME)/Android/Sdk 545 else: equals(QMAKE_HOST.os, Darwin): \ 546 sdk_root = $$(HOME)/Library/Android/sdk 547 else: \ 548 break() 549 !exists($$sdk_root): \ 550 sdk_root = 551 break() 552 } 553 } 554 isEmpty(sdk_root): \ 555 qtConfFatalError("Cannot find Android SDK." \ 556 "Please use -android-sdk option to specify one.") 557 558 ndk_root = $$eval(config.input.android-ndk) 559 isEmpty(ndk_root): \ 560 ndk_root = $$getenv(ANDROID_NDK_ROOT) 561 isEmpty(ndk_root) { 562 for(ever) { 563 exists($$sdk_root/ndk-bundle) { 564 ndk_root = $$sdk_root/ndk-bundle 565 break() 566 } 567 equals(QMAKE_HOST.os, Linux): \ 568 ndk_root = $$(HOME)/Android/Sdk/ndk-bundle 569 else: equals(QMAKE_HOST.os, Darwin): \ 570 ndk_root = $$(HOME)/Library/Android/sdk/ndk-bundle 571 else: \ 572 break() 573 !exists($$ndk_root): \ 574 ndk_root = 575 break() 576 } 577 } 578 isEmpty(ndk_root): \ 579 qtConfFatalError("Cannot find Android NDK." \ 580 "Please use -android-ndk option to specify one.") 581 582 ndk_tc_pfx = $$ndk_root/toolchains/llvm/prebuilt 583 ndk_host = $$eval(config.input.android-ndk-host) 584 isEmpty(ndk_host): \ 585 ndk_host = $$getenv(ANDROID_NDK_HOST) 586 isEmpty(ndk_host) { 587 equals(QMAKE_HOST.os, Linux) { 588 ndk_host_64 = linux-x86_64 589 ndk_host_32 = linux-x86 590 } else: equals(QMAKE_HOST.os, Darwin) { 591 ndk_host_64 = darwin-x86_64 592 ndk_host_32 = darwin-x86 593 } else: equals(QMAKE_HOST.os, Windows) { 594 ndk_host_64 = windows-x86_64 595 ndk_host_32 = windows 596 } else { 597 qtConfFatalError("Host operating system not supported by Android.") 598 } 599 !exists($$ndk_tc_pfx/$$ndk_host_64/*): ndk_host_64 = 600 !exists($$ndk_tc_pfx/$$ndk_host_32/*): ndk_host_32 = 601 equals(QMAKE_HOST.arch, x86_64):!isEmpty(ndk_host_64) { 602 ndk_host = $$ndk_host_64 603 } else: equals(QMAKE_HOST.arch, x86):!isEmpty(ndk_host_32) { 604 ndk_host = $$ndk_host_32 605 } else { 606 !isEmpty(ndk_host_64): \ 607 ndk_host = $$ndk_host_64 608 else: !isEmpty(ndk_host_32): \ 609 ndk_host = $$ndk_host_32 610 else: \ 611 qtConfFatalError("Cannot detect the Android host." \ 612 "Please use -android-ndk-host option to specify one.") 613 qtConfAddNote("Available Android host does not match host architecture.") 614 } 615 } else { 616 !exists($$ndk_tc_pfx/$$ndk_host/*) { 617 err = "Specified Android NDK host '$$ndk_host' is invalid. Expected files in the following directory to exist:" 618 err += '$${ndk_tc_pfx}/$${ndk_host}/' 619 qtConfFatalError($$err) 620 } 621 } 622 623 android_abis = $$eval(config.input.android-abis) 624 isEmpty(android_abis): \ 625 android_abis = $$eval(config.input.android-arch) 626 isEmpty(android_abis): \ 627 android_abis = armeabi-v7a,arm64-v8a,x86,x86_64 628 platform = $$eval(config.input.android-ndk-platform) 629 isEmpty(platform): \ 630 platform = android-21 631 632 android_javac_target = $$eval(config.input.android-javac-target) 633 android_javac_source = $$eval(config.input.android-javac-source) 634 635 $${currentConfig}.output.devicePro += \ 636 "DEFAULT_ANDROID_SDK_ROOT = $$val_escape(sdk_root)" \ 637 "DEFAULT_ANDROID_NDK_ROOT = $$val_escape(ndk_root)" \ 638 "DEFAULT_ANDROID_PLATFORM = $$platform" \ 639 "DEFAULT_ANDROID_NDK_HOST = $$ndk_host" \ 640 "DEFAULT_ANDROID_ABIS = $$split(android_abis, ',')" \ 641 "ANDROID_JAVAC_TARGET_VERSION = $$android_javac_target" \ 642 "ANDROID_JAVAC_SOURCE_VERSION = $$android_javac_source" 643 } 644 645 export($${currentConfig}.output.devicePro) 646 647 # if any settings were made, the spec will be reloaded later 648 # to make them take effect. 649} 650 651defineTest(qtConfOutput_machineTuple) { 652 $${currentConfig}.output.devicePro += \ 653 "GCC_MACHINE_DUMP = $$eval($${currentConfig}.tests.machineTuple.tuple)" 654 export($${currentConfig}.output.devicePro) 655 656 # for completeness, one could reload the spec here, 657 # but no downstream users actually need that. 658} 659 660defineTest(qtConfOutput_commitOptions) { 661 # qdevice.pri needs to be written early, because the compile tests require it. 662 write_file($$QT_BUILD_TREE/mkspecs/qdevice.pri, $${currentConfig}.output.devicePro)|error() 663} 664 665# type (empty or 'host'), option name, default value 666defineTest(processQtPath) { 667 out_var = config.rel_input.$${2} 668 path = $$eval(config.input.$${2}) 669 isEmpty(path) { 670 $$out_var = $$3 671 } else { 672 path = $$absolute_path($$path, $$OUT_PWD) 673 rel = $$relative_path($$path, $$eval(config.input.$${1}prefix)) 674 isEmpty(rel) { 675 $$out_var = . 676 } else: contains(rel, \.\..*) { 677 !equals(2, sysconfdir) { 678 PREFIX_COMPLAINTS += "-$$2 is not a subdirectory of -$${1}prefix." 679 export(PREFIX_COMPLAINTS) 680 !$$eval(have_$${1}prefix) { 681 PREFIX_REMINDER = true 682 export(PREFIX_REMINDER) 683 } 684 } 685 $$out_var = $$path 686 } else { 687 $$out_var = $$rel 688 } 689 } 690 export($$out_var) 691} 692 693defineTest(addConfStr) { 694 QT_CONFIGURE_STR_OFFSETS += " $$QT_CONFIGURE_STR_OFF," 695 QT_CONFIGURE_STRS += " \"$$1\\0\"" 696 QT_CONFIGURE_STR_OFF = $$num_add($$QT_CONFIGURE_STR_OFF, $$str_size($$1), 1) 697 export(QT_CONFIGURE_STR_OFFSETS) 698 export(QT_CONFIGURE_STRS) 699 export(QT_CONFIGURE_STR_OFF) 700} 701 702defineReplace(printInstallPath) { 703 val = $$eval(config.rel_input.$$2) 704 equals(val, $$3): return() 705 return("$$1=$$val") 706} 707 708defineReplace(printInstallPaths) { 709 ret = \ 710 $$printInstallPath(Documentation, docdir, doc) \ 711 $$printInstallPath(Headers, headerdir, include) \ 712 $$printInstallPath(Libraries, libdir, lib) \ 713 $$printInstallPath(LibraryExecutables, libexecdir, $$DEFAULT_LIBEXEC) \ 714 $$printInstallPath(Binaries, bindir, bin) \ 715 $$printInstallPath(Plugins, plugindir, plugins) \ 716 $$printInstallPath(Imports, importdir, imports) \ 717 $$printInstallPath(Qml2Imports, qmldir, qml) \ 718 $$printInstallPath(ArchData, archdatadir, .) \ 719 $$printInstallPath(Data, datadir, .) \ 720 $$printInstallPath(Translations, translationdir, translations) \ 721 $$printInstallPath(Examples, examplesdir, examples) \ 722 $$printInstallPath(Tests, testsdir, tests) 723 return($$ret) 724} 725 726defineReplace(printHostPaths) { 727 ret = \ 728 "HostPrefix=$$config.input.hostprefix" \ 729 $$printInstallPath(HostBinaries, hostbindir, bin) \ 730 $$printInstallPath(HostLibraries, hostlibdir, lib) \ 731 $$printInstallPath(HostData, hostdatadir, .) \ 732 "Sysroot=$$config.input.sysroot" \ 733 "SysrootifyPrefix=$$qmake_sysrootify" \ 734 "TargetSpec=$$XSPEC" \ 735 "HostSpec=$$[QMAKE_SPEC]" 736 return($$ret) 737} 738 739defineTest(qtConfOutput_preparePaths) { 740 isEmpty(config.input.prefix) { 741 $$qtConfEvaluate("features.developer-build") { 742 config.input.prefix = $$QT_BUILD_TREE # In Development, we use sandboxed builds by default 743 } else { 744 win32: \ 745 config.input.prefix = C:/Qt/Qt-$$[QT_VERSION] 746 else: \ 747 config.input.prefix = /usr/local/Qt-$$[QT_VERSION] 748 } 749 have_prefix = false 750 } else { 751 equals(XSPEC, $$[QMAKE_SPEC]) { 752 # Only make the user-specified prefix absolute if we're not cross-compiling. 753 config.input.prefix = $$absolute_path($$config.input.prefix, $$OUT_PWD) 754 } else { 755 # But we still must normalize path separators. 756 config.input.prefix = $$replace(config.input.prefix, \\\\, /) 757 } 758 have_prefix = true 759 } 760 761 isEmpty(config.input.extprefix) { 762 config.input.extprefix = $$config.input.prefix 763 !isEmpty(config.input.sysroot): \ 764 qmake_sysrootify = true 765 else: \ 766 qmake_sysrootify = false 767 } else { 768 config.input.extprefix = $$absolute_path($$config.input.extprefix, $$OUT_PWD) 769 qmake_sysrootify = false 770 } 771 772 isEmpty(config.input.hostprefix) { 773 $$qmake_sysrootify: \ 774 config.input.hostprefix = $$config.input.sysroot$$config.input.extprefix 775 else: \ 776 config.input.hostprefix = $$config.input.extprefix 777 have_hostprefix = false 778 } else { 779 isEqual(config.input.hostprefix, yes): \ 780 config.input.hostprefix = $$QT_BUILD_TREE 781 else: \ 782 config.input.hostprefix = $$absolute_path($$config.input.hostprefix, $$OUT_PWD) 783 have_hostprefix = true 784 } 785 786 equals(config.input.prefix, $$config.input.extprefix): \ 787 qmake_crossbuild = false 788 else: \ 789 qmake_crossbuild = true 790 791 PREFIX_COMPLAINTS = 792 PREFIX_REMINDER = false 793 win32: \ 794 DEFAULT_LIBEXEC = bin 795 else: \ 796 DEFAULT_LIBEXEC = libexec 797 darwin: \ 798 DEFAULT_SYSCONFDIR = /Library/Preferences/Qt 799 else: \ 800 DEFAULT_SYSCONFDIR = etc/xdg 801 802 processQtPath("", headerdir, include) 803 processQtPath("", libdir, lib) 804 processQtPath("", bindir, bin) 805 processQtPath("", datadir, .) 806 !equals(config.rel_input.datadir, .): \ 807 data_pfx = $$config.rel_input.datadir/ 808 processQtPath("", docdir, $${data_pfx}doc) 809 processQtPath("", translationdir, $${data_pfx}translations) 810 processQtPath("", examplesdir, $${data_pfx}examples) 811 processQtPath("", testsdir, tests) 812 processQtPath("", archdatadir, .) 813 !equals(config.rel_input.archdatadir, .): \ 814 archdata_pfx = $$config.rel_input.archdatadir/ 815 processQtPath("", libexecdir, $${archdata_pfx}$$DEFAULT_LIBEXEC) 816 processQtPath("", plugindir, $${archdata_pfx}plugins) 817 processQtPath("", importdir, $${archdata_pfx}imports) 818 processQtPath("", qmldir, $${archdata_pfx}qml) 819 processQtPath("", sysconfdir, $$DEFAULT_SYSCONFDIR) 820 $$have_hostprefix { 821 processQtPath(host, hostbindir, bin) 822 processQtPath(host, hostlibdir, lib) 823 processQtPath(host, hostdatadir, .) 824 } else { 825 processQtPath(host, hostbindir, $$config.rel_input.bindir) 826 processQtPath(host, hostlibdir, $$config.rel_input.libdir) 827 processQtPath(host, hostdatadir, $$config.rel_input.archdatadir) 828 } 829 830 win32:$$qtConfEvaluate("features.shared") { 831 # Windows DLLs are in the bin dir. 832 libloc_absolute_path = $$absolute_path($$config.rel_input.bindir, $$config.input.prefix) 833 } else { 834 libloc_absolute_path = $$absolute_path($$config.rel_input.libdir, $$config.input.prefix) 835 } 836 config.input.liblocation_to_prefix = $$relative_path($$config.input.prefix, $$libloc_absolute_path) 837 config.qtbase.features.shared.available = 838 export(config.qtbase.features.shared.available) 839 840 hostbindir_absolute_path = $$absolute_path($$config.rel_input.hostbindir, $$config.input.hostprefix) 841 config.input.hostbindir_to_hostprefix = $$relative_path($$config.input.hostprefix, $$hostbindir_absolute_path) 842 config.input.hostbindir_to_extprefix = $$relative_path($$config.input.extprefix, $$hostbindir_absolute_path) 843 844 !isEmpty(PREFIX_COMPLAINTS) { 845 PREFIX_COMPLAINTS = "$$join(PREFIX_COMPLAINTS, "$$escape_expand(\\n)Note: ")" 846 $$PREFIX_REMINDER: \ 847 PREFIX_COMPLAINTS += "Maybe you forgot to specify -prefix/-hostprefix?" 848 qtConfAddNote($$PREFIX_COMPLAINTS) 849 } 850 851 # populate qconfig.cpp (for qtcore) 852 853 QT_CONFIGURE_STR_OFF = 0 854 QT_CONFIGURE_STR_OFFSETS = 855 QT_CONFIGURE_STRS = 856 857 addConfStr($$config.rel_input.docdir) 858 addConfStr($$config.rel_input.headerdir) 859 addConfStr($$config.rel_input.libdir) 860 addConfStr($$config.rel_input.libexecdir) 861 addConfStr($$config.rel_input.bindir) 862 addConfStr($$config.rel_input.plugindir) 863 addConfStr($$config.rel_input.importdir) 864 addConfStr($$config.rel_input.qmldir) 865 addConfStr($$config.rel_input.archdatadir) 866 addConfStr($$config.rel_input.datadir) 867 addConfStr($$config.rel_input.translationdir) 868 addConfStr($$config.rel_input.examplesdir) 869 addConfStr($$config.rel_input.testsdir) 870 871 QT_CONFIGURE_STR_OFFSETS_ALL = $$QT_CONFIGURE_STR_OFFSETS 872 QT_CONFIGURE_STRS_ALL = $$QT_CONFIGURE_STRS 873 QT_CONFIGURE_STR_OFFSETS = 874 QT_CONFIGURE_STRS = 875 876 addConfStr($$config.input.sysroot) 877 addConfStr($$qmake_sysrootify) 878 addConfStr($$config.rel_input.hostbindir) 879 addConfStr($$config.rel_input.hostlibdir) 880 addConfStr($$config.rel_input.hostdatadir) 881 addConfStr($$XSPEC) 882 addConfStr($$[QMAKE_SPEC]) 883 884 $${currentConfig}.output.qconfigSource = \ 885 "/* Installation Info */" \ 886 "static const char qt_configure_prefix_path_str [12+256] = \"qt_prfxpath=$$config.input.prefix\";" \ 887 "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ 888 "static const char qt_configure_ext_prefix_path_str [12+256] = \"qt_epfxpath=$$config.input.extprefix\";" \ 889 "static const char qt_configure_host_prefix_path_str [12+256] = \"qt_hpfxpath=$$config.input.hostprefix\";" \ 890 "$${LITERAL_HASH}endif" \ 891 "" \ 892 "static const short qt_configure_str_offsets[] = {" \ 893 $$QT_CONFIGURE_STR_OFFSETS_ALL \ 894 "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ 895 $$QT_CONFIGURE_STR_OFFSETS \ 896 "$${LITERAL_HASH}endif" \ 897 "};" \ 898 "static const char qt_configure_strs[] =" \ 899 $$QT_CONFIGURE_STRS_ALL \ 900 "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ 901 $$QT_CONFIGURE_STRS \ 902 "$${LITERAL_HASH}endif" \ 903 ";" \ 904 "" \ 905 "$${LITERAL_HASH}define QT_CONFIGURE_SETTINGS_PATH \"$$config.rel_input.sysconfdir\"" \ 906 "$${LITERAL_HASH}define QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH \"$$config.input.liblocation_to_prefix\"" \ 907 "$${LITERAL_HASH}define QT_CONFIGURE_HOSTBINDIR_TO_EXTPREFIX_PATH \"$$config.input.hostbindir_to_extprefix\"" \ 908 "$${LITERAL_HASH}define QT_CONFIGURE_HOSTBINDIR_TO_HOSTPREFIX_PATH \"$$config.input.hostbindir_to_hostprefix\"" \ 909 "" \ 910 "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ 911 "$${LITERAL_HASH} define QT_CONFIGURE_SYSROOTIFY_PREFIX $$qmake_sysrootify" \ 912 "$${LITERAL_HASH} define QT_CONFIGURE_CROSSBUILD $$qmake_crossbuild" \ 913 "$${LITERAL_HASH}endif" \ 914 "" \ 915 "$${LITERAL_HASH}define QT_CONFIGURE_PREFIX_PATH qt_configure_prefix_path_str + 12" \ 916 "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ 917 "$${LITERAL_HASH} define QT_CONFIGURE_EXT_PREFIX_PATH qt_configure_ext_prefix_path_str + 12" \ 918 "$${LITERAL_HASH} define QT_CONFIGURE_HOST_PREFIX_PATH qt_configure_host_prefix_path_str + 12" \ 919 "$${LITERAL_HASH}endif" 920 export($${currentConfig}.output.qconfigSource) 921 922 # create bin/qt.conf. this doesn't use the regular file output 923 # mechanism, as the file is relied upon by configure tests. 924 925 cont = \ 926 "[EffectivePaths]" \ 927 "Prefix=.." \ 928 "[DevicePaths]" \ 929 "Prefix=$$config.input.prefix" \ 930 $$printInstallPaths() \ 931 "[Paths]" \ 932 "Prefix=$$config.input.extprefix" \ 933 $$printInstallPaths() \ 934 $$printHostPaths() 935 !equals(QT_SOURCE_TREE, $$QT_BUILD_TREE): \ 936 cont += \ 937 "[EffectiveSourcePaths]" \ 938 "Prefix=$$[QT_INSTALL_PREFIX/src]" 939 write_file($$QT_BUILD_TREE/bin/qt.conf, cont)|error() 940 reload_properties() 941 942 # if a sysroot was configured, the spec will be reloaded later, 943 # as some specs contain $$[SYSROOT] references. 944} 945 946defineTest(qtConfOutput_reloadSpec) { 947 !isEmpty($${currentConfig}.output.devicePro)| \ 948 !isEmpty(config.input.sysroot): \ 949 reloadSpec() 950 951 # toolchain.prf uses this. 952 dummy = $$qtConfEvaluate("features.cross_compile") 953 954 bypassNesting() { 955 QMAKE_INTERNAL_INCLUDED_FEATURES -= \ 956 $$[QT_HOST_DATA/src]/mkspecs/features/mac/toolchain.prf \ 957 $$[QT_HOST_DATA/src]/mkspecs/features/toolchain.prf 958 load(toolchain) 959 } 960} 961 962defineTest(qtConfOutput_shared) { 963 !$${2}: return() 964 965 # export this here, so later tests can use it 966 CONFIG += shared 967 export(CONFIG) 968} 969 970defineTest(qtConfOutput_sanitizer) { 971 !$${2}: return() 972 973 # Export this here, so that WebEngine can access it at configure time. 974 CONFIG += sanitizer 975 $$qtConfEvaluate("features.sanitize_address"): CONFIG += sanitize_address 976 $$qtConfEvaluate("features.sanitize_thread"): CONFIG += sanitize_thread 977 $$qtConfEvaluate("features.sanitize_memory"): CONFIG += sanitize_memory 978 $$qtConfEvaluate("features.sanitize_undefined"): CONFIG += sanitize_undefined 979 980 export(CONFIG) 981} 982 983defineTest(qtConfOutput_architecture) { 984 arch = $$qtConfEvaluate("tests.architecture.arch") 985 subarch = $$qtConfEvaluate('tests.architecture.subarch') 986 buildabi = $$qtConfEvaluate("tests.architecture.buildabi") 987 988 $$qtConfEvaluate("features.cross_compile") { 989 host_arch = $$qtConfEvaluate("tests.host_architecture.arch") 990 host_buildabi = $$qtConfEvaluate("tests.host_architecture.buildabi") 991 992 privatePro = \ 993 "host_build {" \ 994 " QT_CPU_FEATURES.$$host_arch = $$qtConfEvaluate('tests.host_architecture.subarch')" \ 995 "} else {" \ 996 " QT_CPU_FEATURES.$$arch = $$subarch" \ 997 "}" 998 publicPro = \ 999 "host_build {" \ 1000 " QT_ARCH = $$host_arch" \ 1001 " QT_BUILDABI = $$host_buildabi" \ 1002 " QT_TARGET_ARCH = $$arch" \ 1003 " QT_TARGET_BUILDABI = $$buildabi" \ 1004 "} else {" \ 1005 " QT_ARCH = $$arch" \ 1006 " QT_BUILDABI = $$buildabi" \ 1007 "}" 1008 1009 } else { 1010 privatePro = \ 1011 "QT_CPU_FEATURES.$$arch = $$subarch" 1012 publicPro = \ 1013 "QT_ARCH = $$arch" \ 1014 "QT_BUILDABI = $$buildabi" 1015 } 1016 1017 $${currentConfig}.output.publicPro += $$publicPro 1018 export($${currentConfig}.output.publicPro) 1019 $${currentConfig}.output.privatePro += $$privatePro 1020 export($${currentConfig}.output.privatePro) 1021 1022 # setup QT_ARCH and QT_CPU_FEATURES variables used by qtConfEvaluate 1023 QT_ARCH = $$arch 1024 export(QT_ARCH) 1025 QT_CPU_FEATURES.$$arch = $$subarch 1026 export(QT_CPU_FEATURES.$$arch) 1027} 1028 1029defineTest(qtConfOutput_qreal) { 1030 qreal = $$config.input.qreal 1031 isEmpty(qreal): qreal = "double" 1032 qreal_string = $$replace(qreal, [^a-zA-Z0-9], "_") 1033 qtConfOutputVar(assign, "privatePro", "QT_COORD_TYPE", $$qreal) 1034 !equals(qreal, "double") { 1035 qtConfOutputSetDefine("publicHeader", "QT_COORD_TYPE", $$qreal) 1036 qtConfOutputSetDefine("publicHeader", "QT_COORD_TYPE_STRING", "\"$$qreal_string\"") 1037 } 1038} 1039 1040defineTest(qtConfOutput_pkgConfig) { 1041 !$${2}: return() 1042 1043 PKG_CONFIG_EXECUTABLE = $$eval($${currentConfig}.tests.pkg-config.pkgConfig) 1044 qtConfOutputVar(assign, "privatePro", "PKG_CONFIG_EXECUTABLE", $$PKG_CONFIG_EXECUTABLE) 1045 export(PKG_CONFIG_EXECUTABLE) 1046 # this method also exports PKG_CONFIG_(LIB|SYSROOT)DIR, so that tests using pkgConfig will work correctly 1047 PKG_CONFIG_SYSROOT_DIR = $$eval($${currentConfig}.tests.pkg-config.pkgConfigSysrootDir) 1048 !isEmpty(PKG_CONFIG_SYSROOT_DIR) { 1049 qtConfOutputVar(assign, "publicPro", "PKG_CONFIG_SYSROOT_DIR", $$PKG_CONFIG_SYSROOT_DIR) 1050 export(PKG_CONFIG_SYSROOT_DIR) 1051 } 1052 PKG_CONFIG_LIBDIR = $$eval($${currentConfig}.tests.pkg-config.pkgConfigLibdir) 1053 !isEmpty(PKG_CONFIG_LIBDIR) { 1054 qtConfOutputVar(assign, "publicPro", "PKG_CONFIG_LIBDIR", $$PKG_CONFIG_LIBDIR) 1055 export(PKG_CONFIG_LIBDIR) 1056 } 1057} 1058 1059defineTest(qtConfOutput_crossCompile) { 1060 !$${2}: return() 1061 1062 # We need to preempt the output here, as subsequent tests rely on it 1063 CONFIG += cross_compile 1064 export(CONFIG) 1065} 1066 1067defineTest(qtConfOutput_useBFDLinker) { 1068 !$${2}: return() 1069 1070 # We need to preempt the output here, so that qtConfTest_linkerSupportsFlag can work properly in qtbase 1071 CONFIG += use_bfd_linker 1072 export(CONFIG) 1073} 1074 1075defineTest(qtConfOutput_useGoldLinker) { 1076 !$${2}: return() 1077 1078 # We need to preempt the output here, so that qtConfTest_linkerSupportsFlag can work properly in qtbase 1079 CONFIG += use_gold_linker 1080 export(CONFIG) 1081} 1082 1083defineTest(qtConfOutput_useLLDLinker) { 1084 !$${2}: return() 1085 1086 # We need to preempt the output here, so that qtConfTest_linkerSupportsFlag can work properly in qtbase 1087 CONFIG += use_lld_linker 1088 export(CONFIG) 1089} 1090 1091defineTest(qtConfOutput_debugAndRelease) { 1092 $$qtConfEvaluate("features.debug") { 1093 qtConfOutputVar(append, "publicPro", "CONFIG", "debug") 1094 $${2}: qtConfOutputVar(append, "publicPro", "QT_CONFIG", "release") 1095 qtConfOutputVar(append, "publicPro", "QT_CONFIG", "debug") 1096 } else { 1097 qtConfOutputVar(append, "publicPro", "CONFIG", "release") 1098 $${2}: qtConfOutputVar(append, "publicPro", "QT_CONFIG", "debug") 1099 qtConfOutputVar(append, "publicPro", "QT_CONFIG", "release") 1100 } 1101} 1102 1103defineTest(qtConfOutput_compilerFlags) { 1104 # this output also exports the variables locally, so that subsequent compiler tests can use them 1105 1106 output = 1107 !isEmpty(config.input.wflags) { 1108 wflags = $$join(config.input.wflags, " -W", "-W") 1109 QMAKE_CFLAGS_WARN_ON += $$wflags 1110 QMAKE_CXXFLAGS_WARN_ON += $$wflags 1111 export(QMAKE_CFLAGS_WARN_ON) 1112 export(QMAKE_CXXFLAGS_WARN_ON) 1113 output += \ 1114 "QMAKE_CFLAGS_WARN_ON += $$wflags" \ 1115 "QMAKE_CXXFLAGS_WARN_ON += $$wflags" 1116 } 1117 !isEmpty(config.input.defines) { 1118 EXTRA_DEFINES += $$config.input.defines 1119 export(EXTRA_DEFINES) 1120 output += "EXTRA_DEFINES += $$val_escape(config.input.defines)" 1121 } 1122 !isEmpty(config.input.includes) { 1123 EXTRA_INCLUDEPATH += $$config.input.includes 1124 export(EXTRA_INCLUDEPATH) 1125 output += "EXTRA_INCLUDEPATH += $$val_escape(config.input.includes)" 1126 } 1127 1128 !isEmpty(config.input.lpaths) { 1129 EXTRA_LIBDIR += $$config.input.lpaths 1130 export(EXTRA_LIBDIR) 1131 output += "EXTRA_LIBDIR += $$val_escape(config.input.lpaths)" 1132 } 1133 darwin:!isEmpty(config.input.fpaths) { 1134 EXTRA_FRAMEWORKPATH += $$config.input.fpaths 1135 export(EXTRA_FRAMEWORKPATH) 1136 output += "EXTRA_FRAMEWORKPATH += $$val_escape(config.input.fpaths)" 1137 } 1138 1139 $${currentConfig}.output.privatePro += $$output 1140 export($${currentConfig}.output.privatePro) 1141} 1142 1143defineTest(qtConfOutput_gccSysroot) { 1144 !$${2}: return() 1145 1146 # This variable also needs to be exported immediately, so the compilation tests 1147 # can pick it up. 1148 EXTRA_QMAKE_ARGS += \ 1149 "\"QMAKE_CFLAGS += --sysroot=$$config.input.sysroot\"" \ 1150 "\"QMAKE_CXXFLAGS += --sysroot=$$config.input.sysroot\"" \ 1151 "\"QMAKE_LFLAGS += --sysroot=$$config.input.sysroot\"" 1152 export(EXTRA_QMAKE_ARGS) 1153 1154 # This one is for qtConfToolchainSupportsFlag(). 1155 QMAKE_CXXFLAGS += --sysroot=$$config.input.sysroot 1156 export(QMAKE_CXXFLAGS) 1157 1158 output = \ 1159 "!host_build {" \ 1160 " QMAKE_CFLAGS += --sysroot=\$\$[QT_SYSROOT]" \ 1161 " QMAKE_CXXFLAGS += --sysroot=\$\$[QT_SYSROOT]" \ 1162 " QMAKE_LFLAGS += --sysroot=\$\$[QT_SYSROOT]" \ 1163 "}" 1164 $${currentConfig}.output.publicPro += $$output 1165 export($${currentConfig}.output.publicPro) 1166} 1167 1168defineTest(qtConfOutput_qmakeArgs) { 1169 !$${2}: return() 1170 1171 $${currentConfig}.output.privatePro += "!host_build|!cross_compile {" 1172 for (a, config.input.qmakeArgs) { 1173 $${currentConfig}.output.privatePro += " $$a" 1174 EXTRA_QMAKE_ARGS += $$system_quote($$a) 1175 } 1176 $${currentConfig}.output.privatePro += "}" 1177 export(EXTRA_QMAKE_ARGS) 1178 export($${currentConfig}.output.privatePro) 1179} 1180 1181defineReplace(qtConfOutputPostProcess_publicPro) { 1182 qt_version = $$[QT_VERSION] 1183 output = \ 1184 $$1 \ 1185 "QT_VERSION = $$qt_version" \ 1186 "QT_MAJOR_VERSION = $$section(qt_version, '.', 0, 0)" \ 1187 "QT_MINOR_VERSION = $$section(qt_version, '.', 1, 1)" \ 1188 "QT_PATCH_VERSION = $$section(qt_version, '.', 2, 2)" 1189 1190 #libinfix and namespace 1191 !isEmpty(config.input.qt_libinfix): output += "QT_LIBINFIX = $$config.input.qt_libinfix" 1192 !isEmpty(config.input.qt_namespace): output += "QT_NAMESPACE = $$config.input.qt_namespace" 1193 1194 !isEmpty(QMAKE_GCC_MAJOR_VERSION) { 1195 output += \ 1196 "QT_GCC_MAJOR_VERSION = $$QMAKE_GCC_MAJOR_VERSION" \ 1197 "QT_GCC_MINOR_VERSION = $$QMAKE_GCC_MINOR_VERSION" \ 1198 "QT_GCC_PATCH_VERSION = $$QMAKE_GCC_PATCH_VERSION" 1199 } 1200 !isEmpty(QMAKE_MAC_SDK_VERSION): \ 1201 output += "QT_MAC_SDK_VERSION = $$QMAKE_MAC_SDK_VERSION" 1202 !isEmpty(QMAKE_CLANG_MAJOR_VERSION) { 1203 output += \ 1204 "QT_CLANG_MAJOR_VERSION = $$QMAKE_CLANG_MAJOR_VERSION" \ 1205 "QT_CLANG_MINOR_VERSION = $$QMAKE_CLANG_MINOR_VERSION" \ 1206 "QT_CLANG_PATCH_VERSION = $$QMAKE_CLANG_PATCH_VERSION" 1207 } 1208 !isEmpty(QMAKE_APPLE_CLANG_MAJOR_VERSION) { 1209 output += \ 1210 "QT_APPLE_CLANG_MAJOR_VERSION = $$QMAKE_APPLE_CLANG_MAJOR_VERSION" \ 1211 "QT_APPLE_CLANG_MINOR_VERSION = $$QMAKE_APPLE_CLANG_MINOR_VERSION" \ 1212 "QT_APPLE_CLANG_PATCH_VERSION = $$QMAKE_APPLE_CLANG_PATCH_VERSION" 1213 } 1214 !isEmpty(QMAKE_MSC_VER) { 1215 output += \ 1216 "QT_MSVC_MAJOR_VERSION = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", "\\1")" \ 1217 "QT_MSVC_MINOR_VERSION = $$format_number($$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", "\\2"))" \ 1218 "QT_MSVC_PATCH_VERSION = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", "\\3")" 1219 } 1220 !isEmpty(QMAKE_ICC_VER) { 1221 output += \ 1222 "QT_ICC_MAJOR_VERSION = $$replace(QMAKE_ICC_VER, "(..)(..)", "\\1")" \ 1223 "QT_ICC_MINOR_VERSION = $$format_number($$replace(QMAKE_ICC_VER, "(..)(..)", "\\2"))" \ 1224 "QT_ICC_PATCH_VERSION = $$QMAKE_ICC_UPDATE_VER" 1225 } 1226 !isEmpty(QMAKE_GHS_VERSION) { 1227 output += \ 1228 "QT_GHS_MAJOR_VERSION = $$replace(QMAKE_GHS_VERSION, "(.*)(.)(.)", "\\1")" \ 1229 "QT_GHS_MINOR_VERSION = $$replace(QMAKE_GHS_VERSION, "(.*)(.)(.)", "\\2")" \ 1230 "QT_GHS_PATCH_VERSION = $$replace(QMAKE_GHS_VERSION, "(.*)(.)(.)", "\\3")" 1231 } 1232 1233 output += "QT_EDITION = $$config.input.qt_edition" 1234 !contains(config.input.qt_edition, "(OpenSource|Preview)") { 1235 output += \ 1236 "QT_LICHECK = $$config.input.qt_licheck" \ 1237 "QT_RELEASE_DATE = $$config.input.qt_release_date" 1238 } 1239 1240 wasm: { 1241 qt_emcc_version = $$qtSystemEmccVersion() 1242 output += \ 1243 "QT_EMCC_VERSION = $$qt_emcc_version" 1244 } 1245 1246 return($$output) 1247} 1248 1249defineReplace(qtConfOutputPostProcess_privatePro) { 1250 output = $$1 1251 1252 !isEmpty(config.input.external-hostbindir): \ 1253 output += "HOST_QT_TOOLS = $$val_escape(config.input.external-hostbindir)" 1254 1255 return($$output) 1256} 1257 1258defineReplace(qtConfOutputPostProcess_publicHeader) { 1259 qt_version = $$[QT_VERSION] 1260 output = \ 1261 $$1 \ 1262 "$${LITERAL_HASH}define QT_VERSION_STR \"$$qt_version\"" \ 1263 "$${LITERAL_HASH}define QT_VERSION_MAJOR $$section(qt_version, '.', 0, 0)" \ 1264 "$${LITERAL_HASH}define QT_VERSION_MINOR $$section(qt_version, '.', 1, 1)" \ 1265 "$${LITERAL_HASH}define QT_VERSION_PATCH $$section(qt_version, '.', 2, 2)" 1266 1267 !$$qtConfEvaluate("features.shared") { 1268 output += \ 1269 "/* Qt was configured for a static build */" \ 1270 "$${LITERAL_HASH}if !defined(QT_SHARED) && !defined(QT_STATIC)" \ 1271 "$${LITERAL_HASH} define QT_STATIC" \ 1272 "$${LITERAL_HASH}endif" 1273 } 1274 1275 !isEmpty(config.input.qt_libinfix): \ 1276 output += "$${LITERAL_HASH}define QT_LIBINFIX \"$$eval(config.input.qt_libinfix)\"" 1277 1278 wasm: { 1279 qt_emcc_version = $$qtSystemEmccVersion() 1280output += \ 1281 "$${LITERAL_HASH}define QT_EMCC_VERSION \"$$qt_emcc_version\"" 1282 } 1283 1284 return($$output) 1285} 1286 1287 1288# custom reporting 1289 1290defineTest(qtConfReport_buildParts) { 1291 qtConfReportPadded($${1}, $$qtConfEvaluate("tests.build_parts.value")) 1292} 1293 1294defineReplace(qtConfReportArch) { 1295 arch = $$qtConfEvaluate('tests.$${1}.arch') 1296 subarch = $$qtConfEvaluate('tests.$${1}.subarch') 1297 isEmpty(subarch): subarch = <none> 1298 return("$$arch, CPU features: $$subarch") 1299} 1300 1301defineReplace(qtConfReportCompiler) { 1302 clang_cl: { 1303 return("clang-cl $${QMAKE_CLANG_MAJOR_VERSION}.$${QMAKE_CLANG_MINOR_VERSION}.$${QMAKE_CLANG_PATCH_VERSION}") 1304 } else: clang { 1305 !isEmpty(QMAKE_APPLE_CLANG_MAJOR_VERSION) { 1306 return("clang (Apple) $${QMAKE_APPLE_CLANG_MAJOR_VERSION}.$${QMAKE_APPLE_CLANG_MINOR_VERSION}.$${QMAKE_APPLE_CLANG_PATCH_VERSION}") 1307 } else { 1308 return("clang $${QMAKE_CLANG_MAJOR_VERSION}.$${QMAKE_CLANG_MINOR_VERSION}.$${QMAKE_CLANG_PATCH_VERSION}") 1309 } 1310 } else: intel_icc { 1311 return("intel_icc $$QMAKE_ICC_VER") 1312 } else: intel_icl { 1313 return("intel_icl $$QMAKE_ICC_VER") 1314 } else: rim_qcc { 1315 return("rim_qcc $${QMAKE_GCC_MAJOR_VERSION}.$${QMAKE_GCC_MINOR_VERSION}.$${QMAKE_GCC_PATCH_VERSION}") 1316 } else: gcc { 1317 return("gcc $${QMAKE_GCC_MAJOR_VERSION}.$${QMAKE_GCC_MINOR_VERSION}.$${QMAKE_GCC_PATCH_VERSION}") 1318 } else: msvc { 1319 return("msvc $$QMAKE_MSC_FULL_VER") 1320 } else: ghs { 1321 return("ghs $$QMAKE_GHS_VERSION") 1322 } else { 1323 return("unknown ($$QMAKE_COMPILER)") 1324 } 1325} 1326 1327 1328defineTest(qtConfReport_buildTypeAndConfig) { 1329 !$$qtConfEvaluate("features.cross_compile") { 1330 qtConfAddReport("Build type: $$[QMAKE_SPEC] ($$qtConfReportArch(architecture))") 1331 qtConfAddReport("Compiler: $$qtConfReportCompiler()") 1332 } else { 1333 qtConfAddReport("Building on: $$[QMAKE_SPEC] ($$qtConfReportArch(host_architecture))") 1334 qtConfAddReport("Building for: $$[QMAKE_XSPEC] ($$qtConfReportArch(architecture))") 1335 qtConfAddReport("Target compiler: $$qtConfReportCompiler()") 1336 } 1337 1338 qtConfAddReport() 1339 qtConfAddReport("Configuration: $$eval($${currentConfig}.output.privatePro.append.CONFIG) $$eval($${currentConfig}.output.publicPro.append.QT_CONFIG)") 1340 qtConfAddReport() 1341} 1342 1343defineTest(qtConfReport_buildMode) { 1344 $$qtConfEvaluate("features.force_debug_info"): \ 1345 release = "release (with debug info)" 1346 else: \ 1347 release = "release" 1348 1349 $$qtConfEvaluate("features.debug") { 1350 build_mode = "debug" 1351 raw_build_mode = "debug" 1352 } else { 1353 build_mode = $$release 1354 raw_build_mode = "release" 1355 } 1356 1357 $$qtConfEvaluate("features.debug_and_release"): \ 1358 build_mode = "debug and $$release; default link: $$raw_build_mode" 1359 1360 $$qtConfEvaluate("features.release_tools"): \ 1361 build_mode = "$$build_mode; optimized tools" 1362 1363 qtConfReportPadded($$1, $$build_mode) 1364} 1365 1366defineTest(qtConfReport_emccVersion) { 1367 EMCC_VERSION = $$qtSystemEmccVersion() 1368 REQ_VERSION = $$qtEmccRecommendedVersion() 1369 !equals(EMCC_VERSION, $$REQ_VERSION) { 1370 qtConfAddReport("You should use the recommended Emscripten version $$REQ_VERSION with this Qt. You have $$EMCC_VERSION $$QT_EMCC_VERSION") 1371 } 1372} 1373 1374# ensure pristine environment for configuration 1375discard_from($$[QT_HOST_DATA/get]/mkspecs/qconfig.pri) 1376discard_from($$[QT_HOST_DATA/get]/mkspecs/qmodule.pri) 1377# ... and cause them to be reloaded afterwards 1378QMAKE_POST_CONFIGURE += \ 1379 "include(\$\$[QT_HOST_DATA/get]/mkspecs/qconfig.pri)" \ 1380 "include(\$\$[QT_HOST_DATA/get]/mkspecs/qmodule.pri)" 1381 1382defineTest(createConfigStatus) { 1383 $$QMAKE_REDO_CONFIG: return() 1384 cfg = $$relative_path($$_PRO_FILE_PWD_/configure, $$OUT_PWD) 1385 ext = 1386 equals(QMAKE_HOST.os, Windows) { 1387 ext = .bat 1388 cont = \ 1389 "$$system_quote($$system_path($$cfg)$$ext) -redo %*" 1390 } else { 1391 !contains(cfg, .*/.*): cfg = ./$$cfg 1392 cont = \ 1393 "$${LITERAL_HASH}!/bin/sh" \ 1394 "exec $$system_quote($$cfg) -redo \"$@\"" 1395 } 1396 write_file($$OUT_PWD/config.status$$ext, cont, exe)|error() 1397} 1398 1399QMAKE_POST_CONFIGURE += \ 1400 "createConfigStatus()" 1401