# this must be done outside any function QT_SOURCE_TREE = $$PWD QT_BUILD_TREE = $$shadowed($$PWD) # custom command line handling defineTest(qtConfCommandline_qmakeArgs) { contains(1, QMAKE_[A-Z0-9_]+ *[-+]?=.*) { config.input.qmakeArgs += $$1 export(config.input.qmakeArgs) return(true) } return(false) } defineTest(qtConfCommandline_cxxstd) { arg = $${1} val = $${2} isEmpty(val): val = $$qtConfGetNextCommandlineArg() !contains(val, "^-.*"):!isEmpty(val) { contains(val, "(c\+\+)?11") { qtConfCommandlineSetInput("c++14", "no") qtConfCommandlineSetInput("c++1z", "no") qtConfCommandlineSetInput("c++2a", "no") } else: contains(val, "(c\+\+)?(14|1y)") { qtConfCommandlineSetInput("c++14", "yes") qtConfCommandlineSetInput("c++1z", "no") qtConfCommandlineSetInput("c++2a", "no") } else: contains(val, "(c\+\+)?(17|1z)") { qtConfCommandlineSetInput("c++14", "yes") qtConfCommandlineSetInput("c++1z", "yes") qtConfCommandlineSetInput("c++2a", "no") } else: contains(val, "(c\+\+)?(2a)") { qtConfCommandlineSetInput("c++14", "yes") qtConfCommandlineSetInput("c++1z", "yes") qtConfCommandlineSetInput("c++2a", "yes") } else { qtConfAddError("Invalid argument $$val to command line parameter $$arg") } } else { qtConfAddError("Missing argument to command line parameter $$arg") } } defineTest(qtConfCommandline_sanitize) { arg = $${1} val = $${2} isEmpty(val): val = $$qtConfGetNextCommandlineArg() !contains(val, "^-.*"):!isEmpty(val) { equals(val, "address") { qtConfCommandlineSetInput("sanitize_address", "yes") } else: equals(val, "thread") { qtConfCommandlineSetInput("sanitize_thread", "yes") } else: equals(val, "memory") { qtConfCommandlineSetInput("sanitize_memory", "yes") } else: equals(val, "undefined") { qtConfCommandlineSetInput("sanitize_undefined", "yes") } else { qtConfAddError("Invalid argument $$val to command line parameter $$arg") } } else { qtConfAddError("Missing argument to command line parameter $$arg") } } defineTest(qtConfCommandline_coverage) { arg = $${1} val = $${2} isEmpty(val): val = $$qtConfGetNextCommandlineArg() !contains(val, "^-.*"):!isEmpty(val) { equals(val, "trace-pc-guard") { qtConfCommandlineSetInput("coverage_trace_pc_guard", "yes") } else { qtConfAddError("Invalid argument $$val to command line parameter $$arg") } } else { qtConfAddError("Missing argument to command line parameter $$arg") } } # callbacks defineReplace(qtConfFunc_crossCompile) { !isEmpty(config.input.sysroot): return(true) spec = $$[QMAKE_SPEC] !equals(spec, $$[QMAKE_XSPEC]): return(true) return(false) } defineReplace(qtConfFunc_licenseCheck) { exists($$QT_SOURCE_TREE/LICENSE.LGPL3)|exists($$QT_SOURCE_TREE/LICENSE.GPL2)|exists($$QT_SOURCE_TREE/LICENSE.GPL3): \ hasOpenSource = true else: \ hasOpenSource = false exists($$QT_SOURCE_TREE/LICENSE.QT-LICENSE-AGREEMENT-4.0): \ hasCommercial = true else: \ hasCommercial = false commercial = $$config.input.commercial isEmpty(commercial) { $$hasOpenSource { $$hasCommercial { logn() logn("Selecting Qt Edition.") logn() logn("Type 'c' if you want to use the Commercial Edition.") logn("Type 'o' if you want to use the Open Source Edition.") logn() for(ever) { val = $$lower($$prompt("Which edition of Qt do you want to use? ", false)) equals(val, c) { commercial = yes QMAKE_SAVED_ARGS += -commercial } else: equals(val, o) { commercial = no QMAKE_SAVED_ARGS += -opensource } else { next() } export(QMAKE_SAVED_ARGS) break() } } else { commercial = no } } else { !$$hasCommercial: \ qtConfFatalError("No license files. Cannot proceed. Try re-installing Qt.") commercial = yes } } equals(commercial, no) { !$$hasOpenSource: \ qtConfFatalError("This is the Qt Commercial Edition." \ "Cannot proceed with -opensource.") logn() logn("This is the Qt Open Source Edition.") EditionString = "Open Source" config.input.qt_edition = OpenSource export(config.input.qt_edition) } else { !$$hasCommercial: \ qtConfFatalError("This is the Qt Open Source Edition." \ "Cannot proceed with -commercial.") !exists($$QT_SOURCE_TREE/.release-timestamp) { # Build from git logn() logn("This is the Qt Commercial Edition.") EditionString = "Commercial" config.input.qt_edition = Commercial export(config.input.qt_edition) } else { # Build from a released source package equals(QMAKE_HOST.os, Linux) { !equals(QMAKE_HOST.arch, x86_64): \ Licheck = licheck32 else: \ Licheck = licheck64 } else: equals(QMAKE_HOST.os, Darwin) { Licheck = licheck_mac } else: equals(QMAKE_HOST.os, Windows) { Licheck = licheck.exe } else { qtConfFatalError("Host operating system not supported by this edition of Qt.") } !qtRunLoggedCommand("$$system_quote($$QT_SOURCE_TREE/bin/$$Licheck) \ $$system_quote($$eval(config.input.confirm-license)) \ $$system_quote($$QT_SOURCE_TREE) $$system_quote($$QT_BUILD_TREE) \ $$[QMAKE_SPEC] $$[QMAKE_XSPEC]", \ LicheckOutput, false): \ return(false) logn() for (o, LicheckOutput) { contains(o, "\\w+=.*"): \ eval($$o) else: \ logn($$o) } config.input.qt_edition = $$Edition config.input.qt_licheck = $$Licheck config.input.qt_release_date = $$ReleaseDate export(config.input.qt_edition) export(config.input.qt_licheck) export(config.input.qt_release_date) return(true) } } !isEmpty(config.input.confirm-license) { logn() logn("You have already accepted the terms of the $$EditionString license.") return(true) } affix = the equals(commercial, no) { theLicense = "GNU Lesser General Public License (LGPL) version 3" showWhat = "Type 'L' to view the GNU Lesser General Public License version 3 (LGPLv3)." gpl2Ok = false gpl3Ok = false winrt { notTheLicense = "Note: GPL version 2 is not available on WinRT." } else: wasm { gpl3Ok = true theLicense = "GNU General Public License (GPL) version 3" showWhat = "Type 'G' to view the GNU General Public License version 3 (GPLv3)." } else: $$qtConfEvaluate("features.android-style-assets") { notTheLicense = "Note: GPL version 2 is not available due to using Android style assets." } else { theLicense += "or the GNU General Public License (GPL) version 2" showWhat += "Type 'G' to view the GNU General Public License version 2 (GPLv2)." gpl2Ok = true affix = either } } else { theLicense = $$cat($$QT_SOURCE_TREE/LICENSE.QT-LICENSE-AGREEMENT-4.0, lines) theLicense = $$first(theLicense) showWhat = "Type '?' to view the $${theLicense}." } msg = \ " " \ "You are licensed to use this software under the terms of" \ "the "$$theLicense"." \ $$notTheLicense \ " " \ $$showWhat \ "Type 'y' to accept this license offer." \ "Type 'n' to decline this license offer." \ " " for(ever) { logn($$join(msg, $$escape_expand(\\n))) for(ever) { val = $$lower($$prompt("Do you accept the terms of $$affix license? ", false)) equals(val, y)|equals(val, yes) { logn() QMAKE_SAVED_ARGS += -confirm-license export(QMAKE_SAVED_ARGS) return(true) } else: equals(val, n)|equals(val, no) { return(false) } else: equals(commercial, yes):equals(val, ?) { licenseFile = $$QT_SOURCE_TREE/LICENSE.QT-LICENSE-AGREEMENT-4.0 } else: equals(commercial, no):equals(val, l) { licenseFile = $$QT_SOURCE_TREE/LICENSE.LGPL3 } else: equals(commercial, no):equals(val, g):$$gpl2Ok { licenseFile = $$QT_SOURCE_TREE/LICENSE.GPL2 } else: equals(commercial, no):equals(val, g):$$gpl3Ok { licenseFile = $$QT_SOURCE_TREE/LICENSE.GPL3 } else { next() } break() } system("more $$system_quote($$system_path($$licenseFile))") logn() logn() } } # custom tests # this is meant for linux device specs only defineTest(qtConfTest_machineTuple) { qtRunLoggedCommand("$$QMAKE_CXX -dumpmachine", $${1}.tuple)|return(false) $${1}.cache += tuple export($${1}.cache) return(true) } defineTest(qtConfTest_verifySpec) { qtConfTest_compile($$1): return(true) qtConfFatalError("Cannot compile a minimal program. The toolchain or QMakeSpec is broken.", log) } defineTest(qtConfTest_architecture) { !qtConfTest_compile($${1}): \ error("Could not determine $$eval($${1}.label). See config.log for details.") test = $$eval($${1}.test) test_out_dir = $$OUT_PWD/$$basename(QMAKE_CONFIG_TESTS_DIR)/$$test unix:exists($$test_out_dir/arch): \ content = $$cat($$test_out_dir/arch, blob) else: win32:exists($$test_out_dir/arch.exe): \ content = $$cat($$test_out_dir/arch.exe, blob) else: android:exists($$test_out_dir/libarch.so): \ content = $$cat($$test_out_dir/libarch.so, blob) else: wasm:exists($$test_out_dir/arch.wasm): \ content = $$cat($$test_out_dir/arch.wasm, blob) else: wasm:exists($$test_out_dir/arch.o): \ content = $$cat($$test_out_dir/arch.o, blob) else: \ error("$$eval($${1}.label) detection binary not found.") arch_magic = ".*==Qt=magic=Qt== Architecture:([^\\0]*).*" subarch_magic = ".*==Qt=magic=Qt== Sub-architecture:([^\\0]*).*" buildabi_magic = ".*==Qt=magic=Qt== Build-ABI:([^\\0]*).*" !contains(content, $$arch_magic)|!contains(content, $$subarch_magic)|!contains(content, $$buildabi_magic): \ error("$$eval($${1}.label) detection binary does not contain expected data.") $${1}.arch = $$replace(content, $$arch_magic, "\\1") $${1}.subarch = $$replace(content, $$subarch_magic, "\\1") $${1}.subarch = $$split($${1}.subarch, " ") $${1}.buildabi = $$replace(content, $$buildabi_magic, "\\1") export($${1}.arch) export($${1}.subarch) export($${1}.buildabi) qtLog("Detected architecture: $$eval($${1}.arch) ($$eval($${1}.subarch))") $${1}.cache += arch subarch buildabi export($${1}.cache) return(true) } defineTest(qtConfTest_gnumake) { make = $$qtConfFindInPath("gmake") isEmpty(make): make = $$qtConfFindInPath("make") !isEmpty(make) { qtRunLoggedCommand("$$make -v", version)|return(false) contains(version, "^GNU Make.*"): return(true) } return(false) } defineTest(qtConfTest_detectPkgConfig) { pkgConfig = $$getenv("PKG_CONFIG") !isEmpty(pkgConfig): { qtLog("Found pkg-config from environment variable: $$pkgConfig") } else { pkgConfig = $$QMAKE_PKG_CONFIG !isEmpty(pkgConfig) { qtLog("Found pkg-config from mkspec: $$pkgConfig") } else { pkgConfig = $$qtConfFindInPath("pkg-config") isEmpty(pkgConfig): \ return(false) qtLog("Found pkg-config from path: $$pkgConfig") } } $$qtConfEvaluate("features.cross_compile") { # cross compiling, check that pkg-config is set up sanely sysroot = $$config.input.sysroot pkgConfigLibdir = $$getenv("PKG_CONFIG_LIBDIR") isEmpty(pkgConfigLibdir) { isEmpty(sysroot) { qtConfAddWarning("Cross compiling without sysroot. Disabling pkg-config") return(false) } !exists("$$sysroot/usr/lib/pkgconfig") { qtConfAddWarning( \ "Disabling pkg-config since PKG_CONFIG_LIBDIR is not set and" \ "the host's .pc files would be used (even if you set PKG_CONFIG_PATH)." \ "Set this variable to the directory that contains target .pc files" \ "for pkg-config to function correctly when cross-compiling or" \ "use -pkg-config to override this test.") return(false) } pkgConfigLibdir = $$sysroot/usr/lib/pkgconfig:$$sysroot/usr/share/pkgconfig machineTuple = $$eval($${currentConfig}.tests.machineTuple.tuple) !isEmpty(machineTuple): \ pkgConfigLibdir = "$$pkgConfigLibdir:$$sysroot/usr/lib/$$machineTuple/pkgconfig" qtConfAddNote("PKG_CONFIG_LIBDIR automatically set to $$pkgConfigLibdir") } pkgConfigSysrootDir = $$getenv("PKG_CONFIG_SYSROOT_DIR") isEmpty(pkgConfigSysrootDir) { isEmpty(sysroot) { qtConfAddWarning( \ "Disabling pkg-config since PKG_CONFIG_SYSROOT_DIR is not set." \ "Set this variable to your sysroot for pkg-config to function correctly when" \ "cross-compiling or use -pkg-config to override this test.") return(false) } pkgConfigSysrootDir = $$sysroot qtConfAddNote("PKG_CONFIG_SYSROOT_DIR automatically set to $$pkgConfigSysrootDir") } $${1}.pkgConfigLibdir = $$pkgConfigLibdir export($${1}.pkgConfigLibdir) $${1}.pkgConfigSysrootDir = $$pkgConfigSysrootDir export($${1}.pkgConfigSysrootDir) $${1}.cache += pkgConfigLibdir pkgConfigSysrootDir } $${1}.pkgConfig = $$pkgConfig export($${1}.pkgConfig) $${1}.cache += pkgConfig export($${1}.cache) return(true) } defineTest(qtConfTest_buildParts) { parts = $$config.input.make isEmpty(parts) { parts = libs examples $$qtConfEvaluate("features.developer-build"): \ parts += tests !$$qtConfEvaluate("features.cross_compile"): \ parts += tools } parts -= $$config.input.nomake # always add libs, as it's required to build Qt parts *= libs $${1}.value = $$parts export($${1}.value) $${1}.cache = - export($${1}.cache) return(true) } defineTest(qtConfTest_x86Simd) { simd = $$section(1, ".", -1) # last component $${1}.args = CONFIG+=add_cflags DEFINES+=NO_ATTRIBUTE SIMD=$$simd $${1}.test = x86_simd qtConfTest_compile($${1}) } defineTest(qtConfTest_x86SimdAlways) { configs = fpfx = $${currentConfig}.features tpfx = $${currentConfig}.tests # Make a list of all passing features whose tests have type=x86Simd for (f, $${tpfx}._KEYS_) { !equals($${tpfx}.$${f}.type, "x86Simd"): \ next() qtConfCheckFeature($$f) equals($${fpfx}.$${f}.available, true): configs += $$f } $${1}.literal_args = SIMD=$$join(configs, " ") qtConfTest_compile($${1}) } # custom outputs # this reloads the qmakespec as completely as reasonably possible. defineTest(reloadSpec) { bypassNesting() { for (f, QMAKE_INTERNAL_INCLUDED_FILES) { contains(f, .*/mkspecs/.*):\ !contains(f, .*/(qt_build_config|qt_parts|qt_configure|configure_base)\\.prf): \ discard_from($$f) } # nobody's going to try to re-load the features above, # so don't bother with being selective. QMAKE_INTERNAL_INCLUDED_FEATURES = \ # loading it gets simulated below. $$[QT_HOST_DATA/src]/mkspecs/features/device_config.prf \ # must be delayed until qdevice.pri is ready. $$[QT_HOST_DATA/src]/mkspecs/features/mac/toolchain.prf \ $$[QT_HOST_DATA/src]/mkspecs/features/toolchain.prf saved_variables = CONFIG QMAKE_CXXFLAGS for (name, saved_variables): \ _SAVED_$$name = $$eval($$name) load(spec_pre) # qdevice.pri gets written too late (and we can't write it early # enough, as it's populated in stages, with later ones depending # on earlier ones). so inject its variables manually. for (l, $${currentConfig}.output.devicePro): \ eval($$l) include($$QMAKESPEC/qmake.conf) load(spec_post) for (name, saved_variables): \ $$name += $$eval(_SAVED_$$name) load(default_pre) # ensure pristine environment for configuration. again. discard_from($$[QT_HOST_DATA/get]/mkspecs/qconfig.pri) discard_from($$[QT_HOST_DATA/get]/mkspecs/qmodule.pri) } } defineTest(qtConfOutput_prepareSpec) { device = $$eval(config.input.device) !isEmpty(device) { devices = $$files($$[QT_HOST_DATA/src]/mkspecs/devices/*$$device*) isEmpty(devices): \ qtConfFatalError("No device matching '$$device'.") !count(devices, 1) { err = "Multiple matches for device '$$device'. Candidates are:" for (d, devices): \ err += " $$basename(d)" qtConfFatalError($$err) } XSPEC = $$relative_path($$devices, $$[QT_HOST_DATA/src]/mkspecs) } xspec = $$eval(config.input.xplatform) !isEmpty(xspec) { !exists($$[QT_HOST_DATA/src]/mkspecs/$$xspec/qmake.conf): \ qtConfFatalError("Invalid target platform '$$xspec'.") XSPEC = $$xspec } isEmpty(XSPEC): \ XSPEC = $$[QMAKE_SPEC] export(XSPEC) QMAKESPEC = $$[QT_HOST_DATA/src]/mkspecs/$$XSPEC export(QMAKESPEC) notes = $$cat($$OUT_PWD/.config.notes, lines) !isEmpty(notes): \ qtConfAddNote("Also available for $$notes") # deviceOptions() below contains conditionals coming form the spec, # so this cannot be delayed for a batch reload. reloadSpec() } defineTest(qtConfOutput_prepareOptions) { $${currentConfig}.output.devicePro += \ $$replace(config.input.device-option, "^([^=]+) *= *(.*)$", "\\1 = \\2") darwin:!isEmpty(config.input.sdk) { $${currentConfig}.output.devicePro += \ "QMAKE_MAC_SDK = $$val_escape(config.input.sdk)" } android { sdk_root = $$eval(config.input.android-sdk) isEmpty(sdk_root): \ sdk_root = $$getenv(ANDROID_SDK_ROOT) isEmpty(sdk_root) { for(ever) { equals(QMAKE_HOST.os, Linux): \ sdk_root = $$(HOME)/Android/Sdk else: equals(QMAKE_HOST.os, Darwin): \ sdk_root = $$(HOME)/Library/Android/sdk else: \ break() !exists($$sdk_root): \ sdk_root = break() } } isEmpty(sdk_root): \ qtConfFatalError("Cannot find Android SDK." \ "Please use -android-sdk option to specify one.") ndk_root = $$eval(config.input.android-ndk) isEmpty(ndk_root): \ ndk_root = $$getenv(ANDROID_NDK_ROOT) isEmpty(ndk_root) { for(ever) { exists($$sdk_root/ndk-bundle) { ndk_root = $$sdk_root/ndk-bundle break() } equals(QMAKE_HOST.os, Linux): \ ndk_root = $$(HOME)/Android/Sdk/ndk-bundle else: equals(QMAKE_HOST.os, Darwin): \ ndk_root = $$(HOME)/Library/Android/sdk/ndk-bundle else: \ break() !exists($$ndk_root): \ ndk_root = break() } } isEmpty(ndk_root): \ qtConfFatalError("Cannot find Android NDK." \ "Please use -android-ndk option to specify one.") ndk_tc_ver = $$eval(config.input.android-toolchain-version) isEmpty(ndk_tc_ver): \ ndk_tc_ver = 4.9 !exists($$ndk_root/toolchains/arm-linux-androideabi-$$ndk_tc_ver/prebuilt/*): \ qtConfFatalError("Cannot detect Android NDK toolchain." \ "Please use -android-toolchain-version to specify it.") ndk_tc_pfx = $$ndk_root/toolchains/arm-linux-androideabi-$$ndk_tc_ver/prebuilt ndk_host = $$eval(config.input.android-ndk-host) isEmpty(ndk_host): \ ndk_host = $$getenv(ANDROID_NDK_HOST) isEmpty(ndk_host) { equals(QMAKE_HOST.os, Linux) { ndk_host_64 = linux-x86_64 ndk_host_32 = linux-x86 } else: equals(QMAKE_HOST.os, Darwin) { ndk_host_64 = darwin-x86_64 ndk_host_32 = darwin-x86 } else: equals(QMAKE_HOST.os, Windows) { ndk_host_64 = windows-x86_64 ndk_host_32 = windows } else { qtConfFatalError("Host operating system not supported by Android.") } !exists($$ndk_tc_pfx/$$ndk_host_64/*): ndk_host_64 = !exists($$ndk_tc_pfx/$$ndk_host_32/*): ndk_host_32 = equals(QMAKE_HOST.arch, x86_64):!isEmpty(ndk_host_64) { ndk_host = $$ndk_host_64 } else: equals(QMAKE_HOST.arch, x86):!isEmpty(ndk_host_32) { ndk_host = $$ndk_host_32 } else { !isEmpty(ndk_host_64): \ ndk_host = $$ndk_host_64 else: !isEmpty(ndk_host_32): \ ndk_host = $$ndk_host_32 else: \ qtConfFatalError("Cannot detect the Android host." \ "Please use -android-ndk-host option to specify one.") qtConfAddNote("Available Android host does not match host architecture.") } } else { !exists($$ndk_tc_pfx/$$ndk_host/*): \ qtConfFatalError("Specified Android NDK host is invalid.") } target_arch = $$eval(config.input.android-arch) isEmpty(target_arch): \ target_arch = armeabi-v7a platform = $$eval(config.input.android-ndk-platform) isEmpty(platform): \ platform = android-21 $${currentConfig}.output.devicePro += \ "DEFAULT_ANDROID_SDK_ROOT = $$val_escape(sdk_root)" \ "DEFAULT_ANDROID_NDK_ROOT = $$val_escape(ndk_root)" \ "DEFAULT_ANDROID_PLATFORM = $$platform" \ "DEFAULT_ANDROID_NDK_HOST = $$ndk_host" \ "DEFAULT_ANDROID_TARGET_ARCH = $$target_arch" \ "DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION = $$ndk_tc_ver" } export($${currentConfig}.output.devicePro) # if any settings were made, the spec will be reloaded later # to make them take effect. } defineTest(qtConfOutput_machineTuple) { $${currentConfig}.output.devicePro += \ "GCC_MACHINE_DUMP = $$eval($${currentConfig}.tests.machineTuple.tuple)" export($${currentConfig}.output.devicePro) # for completeness, one could reload the spec here, # but no downstream users actually need that. } defineTest(qtConfOutput_commitOptions) { # qdevice.pri needs to be written early, because the compile tests require it. write_file($$QT_BUILD_TREE/mkspecs/qdevice.pri, $${currentConfig}.output.devicePro)|error() } # type (empty or 'host'), option name, default value defineTest(processQtPath) { out_var = config.rel_input.$${2} path = $$eval(config.input.$${2}) isEmpty(path) { $$out_var = $$3 } else { path = $$absolute_path($$path, $$OUT_PWD) rel = $$relative_path($$path, $$eval(config.input.$${1}prefix)) isEmpty(rel) { $$out_var = . } else: contains(rel, \.\..*) { !equals(2, sysconfdir) { PREFIX_COMPLAINTS += "-$$2 is not a subdirectory of -$${1}prefix." export(PREFIX_COMPLAINTS) !$$eval(have_$${1}prefix) { PREFIX_REMINDER = true export(PREFIX_REMINDER) } } $$out_var = $$path } else { $$out_var = $$rel } } export($$out_var) } defineTest(addConfStr) { QT_CONFIGURE_STR_OFFSETS += " $$QT_CONFIGURE_STR_OFF," QT_CONFIGURE_STRS += " \"$$1\\0\"" QT_CONFIGURE_STR_OFF = $$num_add($$QT_CONFIGURE_STR_OFF, $$str_size($$1), 1) export(QT_CONFIGURE_STR_OFFSETS) export(QT_CONFIGURE_STRS) export(QT_CONFIGURE_STR_OFF) } defineReplace(printInstallPath) { val = $$eval(config.rel_input.$$2) equals(val, $$3): return() return("$$1=$$val") } defineReplace(printInstallPaths) { ret = \ $$printInstallPath(Documentation, docdir, doc) \ $$printInstallPath(Headers, headerdir, include) \ $$printInstallPath(Libraries, libdir, lib) \ $$printInstallPath(LibraryExecutables, libexecdir, $$DEFAULT_LIBEXEC) \ $$printInstallPath(Binaries, bindir, bin) \ $$printInstallPath(Plugins, plugindir, plugins) \ $$printInstallPath(Imports, importdir, imports) \ $$printInstallPath(Qml2Imports, qmldir, qml) \ $$printInstallPath(ArchData, archdatadir, .) \ $$printInstallPath(Data, datadir, .) \ $$printInstallPath(Translations, translationdir, translations) \ $$printInstallPath(Examples, examplesdir, examples) \ $$printInstallPath(Tests, testsdir, tests) return($$ret) } defineReplace(printHostPaths) { ret = \ "HostPrefix=$$config.input.hostprefix" \ $$printInstallPath(HostBinaries, hostbindir, bin) \ $$printInstallPath(HostLibraries, hostlibdir, lib) \ $$printInstallPath(HostData, hostdatadir, .) \ "Sysroot=$$config.input.sysroot" \ "SysrootifyPrefix=$$qmake_sysrootify" \ "TargetSpec=$$XSPEC" \ "HostSpec=$$[QMAKE_SPEC]" return($$ret) } defineTest(qtConfOutput_preparePaths) { isEmpty(config.input.prefix) { $$qtConfEvaluate("features.developer-build") { config.input.prefix = $$QT_BUILD_TREE # In Development, we use sandboxed builds by default } else { win32: \ config.input.prefix = C:/Qt/Qt-$$[QT_VERSION] else: \ config.input.prefix = /usr/local/Qt-$$[QT_VERSION] } have_prefix = false } else { config.input.prefix = $$absolute_path($$config.input.prefix, $$OUT_PWD) have_prefix = true } isEmpty(config.input.extprefix) { config.input.extprefix = $$config.input.prefix !isEmpty(config.input.sysroot): \ qmake_sysrootify = true else: \ qmake_sysrootify = false } else { config.input.extprefix = $$absolute_path($$config.input.extprefix, $$OUT_PWD) qmake_sysrootify = false } isEmpty(config.input.hostprefix) { $$qmake_sysrootify: \ config.input.hostprefix = $$config.input.sysroot$$config.input.extprefix else: \ config.input.hostprefix = $$config.input.extprefix have_hostprefix = false } else { isEqual(config.input.hostprefix, yes): \ config.input.hostprefix = $$QT_BUILD_TREE else: \ config.input.hostprefix = $$absolute_path($$config.input.hostprefix, $$OUT_PWD) have_hostprefix = true } PREFIX_COMPLAINTS = PREFIX_REMINDER = false win32: \ DEFAULT_LIBEXEC = bin else: \ DEFAULT_LIBEXEC = libexec darwin: \ DEFAULT_SYSCONFDIR = /Library/Preferences/Qt else: \ DEFAULT_SYSCONFDIR = etc/xdg processQtPath("", headerdir, include) processQtPath("", libdir, lib) processQtPath("", bindir, bin) processQtPath("", datadir, .) !equals(config.rel_input.datadir, .): \ data_pfx = $$config.rel_input.datadir/ processQtPath("", docdir, $${data_pfx}doc) processQtPath("", translationdir, $${data_pfx}translations) processQtPath("", examplesdir, $${data_pfx}examples) processQtPath("", testsdir, tests) processQtPath("", archdatadir, .) !equals(config.rel_input.archdatadir, .): \ archdata_pfx = $$config.rel_input.archdatadir/ processQtPath("", libexecdir, $${archdata_pfx}$$DEFAULT_LIBEXEC) processQtPath("", plugindir, $${archdata_pfx}plugins) processQtPath("", importdir, $${archdata_pfx}imports) processQtPath("", qmldir, $${archdata_pfx}qml) processQtPath("", sysconfdir, $$DEFAULT_SYSCONFDIR) $$have_hostprefix { processQtPath(host, hostbindir, bin) processQtPath(host, hostlibdir, lib) processQtPath(host, hostdatadir, .) } else { processQtPath(host, hostbindir, $$config.rel_input.bindir) processQtPath(host, hostlibdir, $$config.rel_input.libdir) processQtPath(host, hostdatadir, $$config.rel_input.archdatadir) } !isEmpty(PREFIX_COMPLAINTS) { PREFIX_COMPLAINTS = "$$join(PREFIX_COMPLAINTS, "$$escape_expand(\\n)Note: ")" $$PREFIX_REMINDER: \ PREFIX_COMPLAINTS += "Maybe you forgot to specify -prefix/-hostprefix?" qtConfAddNote($$PREFIX_COMPLAINTS) } # populate qconfig.cpp (for qtcore) QT_CONFIGURE_STR_OFF = 0 QT_CONFIGURE_STR_OFFSETS = QT_CONFIGURE_STRS = addConfStr($$config.rel_input.docdir) addConfStr($$config.rel_input.headerdir) addConfStr($$config.rel_input.libdir) addConfStr($$config.rel_input.libexecdir) addConfStr($$config.rel_input.bindir) addConfStr($$config.rel_input.plugindir) addConfStr($$config.rel_input.importdir) addConfStr($$config.rel_input.qmldir) addConfStr($$config.rel_input.archdatadir) addConfStr($$config.rel_input.datadir) addConfStr($$config.rel_input.translationdir) addConfStr($$config.rel_input.examplesdir) addConfStr($$config.rel_input.testsdir) QT_CONFIGURE_STR_OFFSETS_ALL = $$QT_CONFIGURE_STR_OFFSETS QT_CONFIGURE_STRS_ALL = $$QT_CONFIGURE_STRS QT_CONFIGURE_STR_OFFSETS = QT_CONFIGURE_STRS = addConfStr($$config.input.sysroot) addConfStr($$qmake_sysrootify) addConfStr($$config.rel_input.hostbindir) addConfStr($$config.rel_input.hostlibdir) addConfStr($$config.rel_input.hostdatadir) addConfStr($$XSPEC) addConfStr($$[QMAKE_SPEC]) $${currentConfig}.output.qconfigSource = \ "/* Installation date */" \ "static const char qt_configure_installation [12+11] = \"qt_instdate=2012-12-20\";" \ "" \ "/* Installation Info */" \ "static const char qt_configure_prefix_path_str [12+256] = \"qt_prfxpath=$$config.input.prefix\";" \ "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ "static const char qt_configure_ext_prefix_path_str [12+256] = \"qt_epfxpath=$$config.input.extprefix\";" \ "static const char qt_configure_host_prefix_path_str [12+256] = \"qt_hpfxpath=$$config.input.hostprefix\";" \ "$${LITERAL_HASH}endif" \ "" \ "static const short qt_configure_str_offsets[] = {" \ $$QT_CONFIGURE_STR_OFFSETS_ALL \ "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ $$QT_CONFIGURE_STR_OFFSETS \ "$${LITERAL_HASH}endif" \ "};" \ "static const char qt_configure_strs[] =" \ $$QT_CONFIGURE_STRS_ALL \ "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ $$QT_CONFIGURE_STRS \ "$${LITERAL_HASH}endif" \ ";" \ "" \ "$${LITERAL_HASH}define QT_CONFIGURE_SETTINGS_PATH \"$$config.rel_input.sysconfdir\"" \ "" \ "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ "$${LITERAL_HASH} define QT_CONFIGURE_SYSROOTIFY_PREFIX $$qmake_sysrootify" \ "$${LITERAL_HASH}endif" \ "" \ "$${LITERAL_HASH}define QT_CONFIGURE_PREFIX_PATH qt_configure_prefix_path_str + 12" \ "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ "$${LITERAL_HASH} define QT_CONFIGURE_EXT_PREFIX_PATH qt_configure_ext_prefix_path_str + 12" \ "$${LITERAL_HASH} define QT_CONFIGURE_HOST_PREFIX_PATH qt_configure_host_prefix_path_str + 12" \ "$${LITERAL_HASH}endif" export($${currentConfig}.output.qconfigSource) # create bin/qt.conf. this doesn't use the regular file output # mechanism, as the file is relied upon by configure tests. cont = \ "[EffectivePaths]" \ "Prefix=.." \ "[DevicePaths]" \ "Prefix=$$config.input.prefix" \ $$printInstallPaths() \ "[Paths]" \ "Prefix=$$config.input.extprefix" \ $$printInstallPaths() \ $$printHostPaths() !equals(QT_SOURCE_TREE, $$QT_BUILD_TREE): \ cont += \ "[EffectiveSourcePaths]" \ "Prefix=$$[QT_INSTALL_PREFIX/src]" write_file($$QT_BUILD_TREE/bin/qt.conf, cont)|error() reload_properties() # if a sysroot was configured, the spec will be reloaded later, # as some specs contain $$[SYSROOT] references. } defineTest(qtConfOutput_reloadSpec) { !isEmpty($${currentConfig}.output.devicePro)| \ !isEmpty(config.input.sysroot): \ reloadSpec() # toolchain.prf uses this. dummy = $$qtConfEvaluate("features.cross_compile") bypassNesting() { QMAKE_INTERNAL_INCLUDED_FEATURES -= \ $$[QT_HOST_DATA/src]/mkspecs/features/mac/toolchain.prf \ $$[QT_HOST_DATA/src]/mkspecs/features/toolchain.prf load(toolchain) } } defineTest(qtConfOutput_shared) { !$${2}: return() # export this here, so later tests can use it CONFIG += shared export(CONFIG) } defineTest(qtConfOutput_sanitizer) { !$${2}: return() # Export this here, so that WebEngine can access it at configure time. CONFIG += sanitizer $$qtConfEvaluate("features.sanitize_address"): CONFIG += sanitize_address $$qtConfEvaluate("features.sanitize_thread"): CONFIG += sanitize_thread $$qtConfEvaluate("features.sanitize_memory"): CONFIG += sanitize_memory $$qtConfEvaluate("features.sanitize_undefined"): CONFIG += sanitize_undefined export(CONFIG) } defineTest(qtConfOutput_architecture) { arch = $$qtConfEvaluate("tests.architecture.arch") subarch = $$qtConfEvaluate('tests.architecture.subarch') buildabi = $$qtConfEvaluate("tests.architecture.buildabi") $$qtConfEvaluate("features.cross_compile") { host_arch = $$qtConfEvaluate("tests.host_architecture.arch") host_buildabi = $$qtConfEvaluate("tests.host_architecture.buildabi") privatePro = \ "host_build {" \ " QT_CPU_FEATURES.$$host_arch = $$qtConfEvaluate('tests.host_architecture.subarch')" \ "} else {" \ " QT_CPU_FEATURES.$$arch = $$subarch" \ "}" publicPro = \ "host_build {" \ " QT_ARCH = $$host_arch" \ " QT_BUILDABI = $$host_buildabi" \ " QT_TARGET_ARCH = $$arch" \ " QT_TARGET_BUILDABI = $$buildabi" \ "} else {" \ " QT_ARCH = $$arch" \ " QT_BUILDABI = $$buildabi" \ "}" } else { privatePro = \ "QT_CPU_FEATURES.$$arch = $$subarch" publicPro = \ "QT_ARCH = $$arch" \ "QT_BUILDABI = $$buildabi" } $${currentConfig}.output.publicPro += $$publicPro export($${currentConfig}.output.publicPro) $${currentConfig}.output.privatePro += $$privatePro export($${currentConfig}.output.privatePro) # setup QT_ARCH and QT_CPU_FEATURES variables used by qtConfEvaluate QT_ARCH = $$arch export(QT_ARCH) QT_CPU_FEATURES.$$arch = $$subarch export(QT_CPU_FEATURES.$$arch) } defineTest(qtConfOutput_qreal) { qreal = $$config.input.qreal isEmpty(qreal): qreal = "double" qreal_string = $$replace(qreal, [^a-zA-Z0-9], "_") qtConfOutputVar(assign, "privatePro", "QT_COORD_TYPE", $$qreal) !equals(qreal, "double") { qtConfOutputSetDefine("publicHeader", "QT_COORD_TYPE", $$qreal) qtConfOutputSetDefine("publicHeader", "QT_COORD_TYPE_STRING", "\"$$qreal_string\"") } } defineTest(qtConfOutput_pkgConfig) { !$${2}: return() PKG_CONFIG_EXECUTABLE = $$eval($${currentConfig}.tests.pkg-config.pkgConfig) qtConfOutputVar(assign, "privatePro", "PKG_CONFIG_EXECUTABLE", $$PKG_CONFIG_EXECUTABLE) export(PKG_CONFIG_EXECUTABLE) # this method also exports PKG_CONFIG_(LIB|SYSROOT)DIR, so that tests using pkgConfig will work correctly PKG_CONFIG_SYSROOT_DIR = $$eval($${currentConfig}.tests.pkg-config.pkgConfigSysrootDir) !isEmpty(PKG_CONFIG_SYSROOT_DIR) { qtConfOutputVar(assign, "publicPro", "PKG_CONFIG_SYSROOT_DIR", $$PKG_CONFIG_SYSROOT_DIR) export(PKG_CONFIG_SYSROOT_DIR) } PKG_CONFIG_LIBDIR = $$eval($${currentConfig}.tests.pkg-config.pkgConfigLibdir) !isEmpty(PKG_CONFIG_LIBDIR) { qtConfOutputVar(assign, "publicPro", "PKG_CONFIG_LIBDIR", $$PKG_CONFIG_LIBDIR) export(PKG_CONFIG_LIBDIR) } } defineTest(qtConfOutput_crossCompile) { !$${2}: return() # We need to preempt the output here, as subsequent tests rely on it CONFIG += cross_compile export(CONFIG) } defineTest(qtConfOutput_useBFDLinker) { !$${2}: return() # We need to preempt the output here, so that qtConfTest_linkerSupportsFlag can work properly in qtbase CONFIG += use_bfd_linker export(CONFIG) } defineTest(qtConfOutput_useGoldLinker) { !$${2}: return() # We need to preempt the output here, so that qtConfTest_linkerSupportsFlag can work properly in qtbase CONFIG += use_gold_linker export(CONFIG) } defineTest(qtConfOutput_useLLDLinker) { !$${2}: return() # We need to preempt the output here, so that qtConfTest_linkerSupportsFlag can work properly in qtbase CONFIG += use_lld_linker export(CONFIG) } defineTest(qtConfOutput_debugAndRelease) { $$qtConfEvaluate("features.debug") { qtConfOutputVar(append, "publicPro", "CONFIG", "debug") $${2}: qtConfOutputVar(append, "publicPro", "QT_CONFIG", "release") qtConfOutputVar(append, "publicPro", "QT_CONFIG", "debug") } else { qtConfOutputVar(append, "publicPro", "CONFIG", "release") $${2}: qtConfOutputVar(append, "publicPro", "QT_CONFIG", "debug") qtConfOutputVar(append, "publicPro", "QT_CONFIG", "release") } } defineTest(qtConfOutput_compilerFlags) { # this output also exports the variables locally, so that subsequent compiler tests can use them output = !isEmpty(config.input.wflags) { wflags = $$join(config.input.wflags, " -W", "-W") QMAKE_CFLAGS_WARN_ON += $$wflags QMAKE_CXXFLAGS_WARN_ON += $$wflags export(QMAKE_CFLAGS_WARN_ON) export(QMAKE_CXXFLAGS_WARN_ON) output += \ "QMAKE_CFLAGS_WARN_ON += $$wflags" \ "QMAKE_CXXFLAGS_WARN_ON += $$wflags" } !isEmpty(config.input.defines) { EXTRA_DEFINES += $$config.input.defines export(EXTRA_DEFINES) output += "EXTRA_DEFINES += $$val_escape(config.input.defines)" } !isEmpty(config.input.includes) { EXTRA_INCLUDEPATH += $$config.input.includes export(EXTRA_INCLUDEPATH) output += "EXTRA_INCLUDEPATH += $$val_escape(config.input.includes)" } !isEmpty(config.input.lpaths) { EXTRA_LIBDIR += $$config.input.lpaths export(EXTRA_LIBDIR) output += "EXTRA_LIBDIR += $$val_escape(config.input.lpaths)" } darwin:!isEmpty(config.input.fpaths) { EXTRA_FRAMEWORKPATH += $$config.input.fpaths export(EXTRA_FRAMEWORKPATH) output += "EXTRA_FRAMEWORKPATH += $$val_escape(config.input.fpaths)" } $${currentConfig}.output.privatePro += $$output export($${currentConfig}.output.privatePro) } defineTest(qtConfOutput_gccSysroot) { !$${2}: return() # This variable also needs to be exported immediately, so the compilation tests # can pick it up. EXTRA_QMAKE_ARGS += \ "\"QMAKE_CFLAGS += --sysroot=$$config.input.sysroot\"" \ "\"QMAKE_CXXFLAGS += --sysroot=$$config.input.sysroot\"" \ "\"QMAKE_LFLAGS += --sysroot=$$config.input.sysroot\"" export(EXTRA_QMAKE_ARGS) # This one is for qtConfToolchainSupportsFlag(). QMAKE_CXXFLAGS += --sysroot=$$config.input.sysroot export(QMAKE_CXXFLAGS) output = \ "!host_build {" \ " QMAKE_CFLAGS += --sysroot=\$\$[QT_SYSROOT]" \ " QMAKE_CXXFLAGS += --sysroot=\$\$[QT_SYSROOT]" \ " QMAKE_LFLAGS += --sysroot=\$\$[QT_SYSROOT]" \ "}" $${currentConfig}.output.publicPro += $$output export($${currentConfig}.output.publicPro) } defineTest(qtConfOutput_qmakeArgs) { !$${2}: return() $${currentConfig}.output.privatePro += "!host_build|!cross_compile {" for (a, config.input.qmakeArgs) { $${currentConfig}.output.privatePro += " $$a" EXTRA_QMAKE_ARGS += $$system_quote($$a) } $${currentConfig}.output.privatePro += "}" export(EXTRA_QMAKE_ARGS) export($${currentConfig}.output.privatePro) } defineReplace(qtConfOutputPostProcess_publicPro) { qt_version = $$[QT_VERSION] output = \ $$1 \ "QT_VERSION = $$qt_version" \ "QT_MAJOR_VERSION = $$section(qt_version, '.', 0, 0)" \ "QT_MINOR_VERSION = $$section(qt_version, '.', 1, 1)" \ "QT_PATCH_VERSION = $$section(qt_version, '.', 2, 2)" #libinfix and namespace !isEmpty(config.input.qt_libinfix): output += "QT_LIBINFIX = $$config.input.qt_libinfix" !isEmpty(config.input.qt_namespace): output += "QT_NAMESPACE = $$config.input.qt_namespace" !isEmpty(QMAKE_GCC_MAJOR_VERSION) { output += \ "QT_GCC_MAJOR_VERSION = $$QMAKE_GCC_MAJOR_VERSION" \ "QT_GCC_MINOR_VERSION = $$QMAKE_GCC_MINOR_VERSION" \ "QT_GCC_PATCH_VERSION = $$QMAKE_GCC_PATCH_VERSION" } !isEmpty(QMAKE_MAC_SDK_VERSION): \ output += "QT_MAC_SDK_VERSION = $$QMAKE_MAC_SDK_VERSION" !isEmpty(QMAKE_CLANG_MAJOR_VERSION) { output += \ "QT_CLANG_MAJOR_VERSION = $$QMAKE_CLANG_MAJOR_VERSION" \ "QT_CLANG_MINOR_VERSION = $$QMAKE_CLANG_MINOR_VERSION" \ "QT_CLANG_PATCH_VERSION = $$QMAKE_CLANG_PATCH_VERSION" } !isEmpty(QMAKE_APPLE_CLANG_MAJOR_VERSION) { output += \ "QT_APPLE_CLANG_MAJOR_VERSION = $$QMAKE_APPLE_CLANG_MAJOR_VERSION" \ "QT_APPLE_CLANG_MINOR_VERSION = $$QMAKE_APPLE_CLANG_MINOR_VERSION" \ "QT_APPLE_CLANG_PATCH_VERSION = $$QMAKE_APPLE_CLANG_PATCH_VERSION" } !isEmpty(QMAKE_MSC_VER) { output += \ "QT_MSVC_MAJOR_VERSION = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", "\\1")" \ "QT_MSVC_MINOR_VERSION = $$format_number($$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", "\\2"))" \ "QT_MSVC_PATCH_VERSION = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", "\\3")" } !isEmpty(QMAKE_ICC_VER) { output += \ "QT_ICC_MAJOR_VERSION = $$replace(QMAKE_ICC_VER, "(..)(..)", "\\1")" \ "QT_ICC_MINOR_VERSION = $$format_number($$replace(QMAKE_ICC_VER, "(..)(..)", "\\2"))" \ "QT_ICC_PATCH_VERSION = $$QMAKE_ICC_UPDATE_VER" } !isEmpty(QMAKE_GHS_VERSION) { output += \ "QT_GHS_MAJOR_VERSION = $$replace(QMAKE_GHS_VERSION, "(.*)(.)(.)", "\\1")" \ "QT_GHS_MINOR_VERSION = $$replace(QMAKE_GHS_VERSION, "(.*)(.)(.)", "\\2")" \ "QT_GHS_PATCH_VERSION = $$replace(QMAKE_GHS_VERSION, "(.*)(.)(.)", "\\3")" } output += "QT_EDITION = $$config.input.qt_edition" !contains(config.input.qt_edition, "(OpenSource|Preview)") { output += \ "QT_LICHECK = $$config.input.qt_licheck" \ "QT_RELEASE_DATE = $$config.input.qt_release_date" } return($$output) } defineReplace(qtConfOutputPostProcess_privatePro) { output = $$1 !isEmpty(config.input.external-hostbindir): \ output += "HOST_QT_TOOLS = $$val_escape(config.input.external-hostbindir)" return($$output) } defineReplace(qtConfOutputPostProcess_publicHeader) { qt_version = $$[QT_VERSION] output = \ $$1 \ "$${LITERAL_HASH}define QT_VERSION_STR \"$$qt_version\"" \ "$${LITERAL_HASH}define QT_VERSION_MAJOR $$section(qt_version, '.', 0, 0)" \ "$${LITERAL_HASH}define QT_VERSION_MINOR $$section(qt_version, '.', 1, 1)" \ "$${LITERAL_HASH}define QT_VERSION_PATCH $$section(qt_version, '.', 2, 2)" !$$qtConfEvaluate("features.shared") { output += \ "/* Qt was configured for a static build */" \ "$${LITERAL_HASH}if !defined(QT_SHARED) && !defined(QT_STATIC)" \ "$${LITERAL_HASH} define QT_STATIC" \ "$${LITERAL_HASH}endif" } !isEmpty(config.input.qt_libinfix): \ output += "$${LITERAL_HASH}define QT_LIBINFIX \"$$eval(config.input.qt_libinfix)\"" return($$output) } # custom reporting defineTest(qtConfReport_buildParts) { qtConfReportPadded($${1}, $$qtConfEvaluate("tests.build_parts.value")) } defineReplace(qtConfReportArch) { arch = $$qtConfEvaluate('tests.$${1}.arch') subarch = $$qtConfEvaluate('tests.$${1}.subarch') isEmpty(subarch): subarch = <none> return("$$arch, CPU features: $$subarch") } defineReplace(qtConfReportCompiler) { clang_cl: { return("clang-cl $${QMAKE_CLANG_MAJOR_VERSION}.$${QMAKE_CLANG_MINOR_VERSION}.$${QMAKE_CLANG_PATCH_VERSION}") } else: clang { !isEmpty(QMAKE_APPLE_CLANG_MAJOR_VERSION) { return("clang (Apple) $${QMAKE_APPLE_CLANG_MAJOR_VERSION}.$${QMAKE_APPLE_CLANG_MINOR_VERSION}.$${QMAKE_APPLE_CLANG_PATCH_VERSION}") } else { return("clang $${QMAKE_CLANG_MAJOR_VERSION}.$${QMAKE_CLANG_MINOR_VERSION}.$${QMAKE_CLANG_PATCH_VERSION}") } } else: intel_icc { return("intel_icc $$QMAKE_ICC_VER") } else: intel_icl { return("intel_icl $$QMAKE_ICC_VER") } else: rim_qcc { return("rim_qcc $${QMAKE_GCC_MAJOR_VERSION}.$${QMAKE_GCC_MINOR_VERSION}.$${QMAKE_GCC_PATCH_VERSION}") } else: gcc { return("gcc $${QMAKE_GCC_MAJOR_VERSION}.$${QMAKE_GCC_MINOR_VERSION}.$${QMAKE_GCC_PATCH_VERSION}") } else: msvc { return("msvc $$QMAKE_MSC_FULL_VER") } else: ghs { return("ghs $$QMAKE_GHS_VERSION") } else { return("unknown ($$QMAKE_COMPILER)") } } defineTest(qtConfReport_buildTypeAndConfig) { !$$qtConfEvaluate("features.cross_compile") { qtConfAddReport("Build type: $$[QMAKE_SPEC] ($$qtConfReportArch(architecture))") qtConfAddReport("Compiler: $$qtConfReportCompiler()") } else { qtConfAddReport("Building on: $$[QMAKE_SPEC] ($$qtConfReportArch(host_architecture))") qtConfAddReport("Building for: $$[QMAKE_XSPEC] ($$qtConfReportArch(architecture))") qtConfAddReport("Target compiler: $$qtConfReportCompiler()") } qtConfAddReport() qtConfAddReport("Configuration: $$eval($${currentConfig}.output.privatePro.append.CONFIG) $$eval($${currentConfig}.output.publicPro.append.QT_CONFIG)") qtConfAddReport() } defineTest(qtConfReport_buildMode) { $$qtConfEvaluate("features.force_debug_info"): \ release = "release (with debug info)" else: \ release = "release" $$qtConfEvaluate("features.debug") { build_mode = "debug" raw_build_mode = "debug" } else { build_mode = $$release raw_build_mode = "release" } $$qtConfEvaluate("features.debug_and_release"): \ build_mode = "debug and $$release; default link: $$raw_build_mode" $$qtConfEvaluate("features.release_tools"): \ build_mode = "$$build_mode; optimized tools" qtConfReportPadded($$1, $$build_mode) } # ensure pristine environment for configuration discard_from($$[QT_HOST_DATA/get]/mkspecs/qconfig.pri) discard_from($$[QT_HOST_DATA/get]/mkspecs/qmodule.pri) # ... and cause them to be reloaded afterwards QMAKE_POST_CONFIGURE += \ "include(\$\$[QT_HOST_DATA/get]/mkspecs/qconfig.pri)" \ "include(\$\$[QT_HOST_DATA/get]/mkspecs/qmodule.pri)" defineTest(createConfigStatus) { $$QMAKE_REDO_CONFIG: return() cfg = $$relative_path($$_PRO_FILE_PWD_/configure, $$OUT_PWD) ext = equals(QMAKE_HOST.os, Windows) { ext = .bat cont = \ "$$system_quote($$system_path($$cfg)$$ext) -redo %*" } else { !contains(cfg, .*/.*): cfg = ./$$cfg cont = \ "$${LITERAL_HASH}!/bin/sh" \ "exec $$system_quote($$cfg) -redo \"$@\"" } write_file($$OUT_PWD/config.status$$ext, cont, exe)|error() } QMAKE_POST_CONFIGURE += \ "createConfigStatus()"