summaryrefslogtreecommitdiffstats
path: root/mkspecs/features/qt_configure.prf
diff options
context:
space:
mode:
Diffstat (limited to 'mkspecs/features/qt_configure.prf')
-rw-r--r--mkspecs/features/qt_configure.prf2471
1 files changed, 0 insertions, 2471 deletions
diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf
deleted file mode 100644
index 4c18dbf953..0000000000
--- a/mkspecs/features/qt_configure.prf
+++ /dev/null
@@ -1,2471 +0,0 @@
-#
-# W A R N I N G
-# -------------
-#
-# This file is not part of the Qt API. It exists purely as an
-# implementation detail. It may change from version to version
-# without notice, or even be removed.
-#
-# We mean it.
-#
-
-QT_CONFIGURE_REPORT =
-QT_CONFIGURE_NOTES =
-QT_CONFIGURE_WARNINGS =
-QT_CONFIGURE_ERRORS =
-
-defineTest(qtConfAddReport) {
- QT_CONFIGURE_REPORT += "$$join(1, $$escape_expand(\\n))"
- export(QT_CONFIGURE_REPORT)
-}
-
-defineTest(qtConfAddNote) {
- QT_CONFIGURE_NOTES += "Note: $$join(1, $$escape_expand(\\n))"
- export(QT_CONFIGURE_NOTES)
-}
-
-defineTest(qtConfAddWarning) {
- QT_CONFIGURE_WARNINGS += "WARNING: $$join(1, $$escape_expand(\\n))"
- export(QT_CONFIGURE_WARNINGS)
-}
-
-defineTest(qtConfAddError) {
- QT_CONFIGURE_ERRORS += "ERROR: $$join(1, $$escape_expand(\\n))"
- export(QT_CONFIGURE_ERRORS)
- equals(2, log):qt_conf_tests_allowed {
- CONFIG += mention_config_log
- export(CONFIG)
- }
-}
-
-defineTest(qtConfFatalError) {
- qtConfAddError($$1, $$2)
- qtConfPrintReport()
- error()
-}
-
-# Return a string list for the specified JSON path, which may be either a
-# single string or an array of strings.
-# Note that this returns a variable name, so it can be directly iterated over.
-defineReplace(qtConfScalarOrList) {
- defined($$1, var): return($$1)
- vals = $$list()
- for (i, $${1}._KEYS_): \
- $$vals += $$eval($${1}.$$i)
- export($$vals)
- return($$vals)
-}
-
-defineTest(qtConfCommandlineSetInput) {
- arg = $${1}
- val = $${2}
- !isEmpty($${currentConfig}.commandline.options.$${arg}.name): \
- arg = $$eval($${currentConfig}.commandline.options.$${arg}.name)
- !isEmpty(config.input.$$arg) {
- oldval = $$eval(config.input.$$arg)
- equals(oldval, $$val): \
- qtConfAddNote("Option '$$arg' with value '$$val' was specified twice")
- else: \
- qtConfAddNote("Overriding option '$$arg' with '$$val' (was: '$$oldval')")
- }
-
- config.input.$$arg = $$val
- export(config.input.$$arg)
-}
-
-defineReplace(qtConfGetNextCommandlineArg) {
- c = $$take_first(QMAKE_EXTRA_ARGS)
- export(QMAKE_EXTRA_ARGS)
- return($$c)
-}
-
-defineReplace(qtConfPeekNextCommandlineArg) {
- return($$first(QMAKE_EXTRA_ARGS))
-}
-
-defineTest(qtConfCommandline_boolean) {
- opt = $${1}
- val = $${2}
- isEmpty(val): val = yes
-
- !equals(val, yes):!equals(val, no) {
- qtConfAddError("Invalid value given for boolean command line option '$$opt'.")
- return()
- }
-
- qtConfCommandlineSetInput($$opt, $$val)
-}
-
-defineTest(qtConfCommandline_void) {
- opt = $${1}
- val = $${2}
- !isEmpty(val) {
- qtConfAddError("Command line option '$$opt' expects no argument ('$$val' given).")
- return()
- }
-
- val = $$eval($${currentConfig}.commandline.options.$${opt}.value)
- isEmpty(val): val = yes
-
- qtConfCommandlineSetInput($$opt, $$val)
-}
-
-defineTest(qtConfCommandline_enum) {
- opt = $${1}
- val = $${2}
- isEmpty(val): val = yes
-
- # validate and map value
- mapped = $$eval($${currentConfig}.commandline.options.$${opt}.values.$${val})
- isEmpty(mapped) {
- # just a list of allowed values
- for (i, $${currentConfig}.commandline.options.$${opt}.values._KEYS_) {
- equals($${currentConfig}.commandline.options.$${opt}.values.$${i}, $$val) {
- mapped = $$val
- break()
- }
- }
- }
- isEmpty(mapped) {
- qtConfAddError("Invalid value '$$val' supplied to command line option '$$opt'.")
- return()
- }
-
- qtConfCommandlineSetInput($$opt, $$mapped)
-}
-
-defineTest(qtConfValidateValue) {
- opt = $${1}
- val = $${2}
-
- validValues = $$eval($${currentConfig}.commandline.options.$${opt}.values._KEYS_)
- isEmpty(validValues): \
- return(true)
-
- for (i, validValues) {
- equals($${currentConfig}.commandline.options.$${opt}.values.$${i}, $$val): \
- return(true)
- }
-
- qtConfAddError("Invalid value '$$val' supplied to command line option '$$opt'.")
- return(false)
-}
-
-defineTest(qtConfCommandline_string) {
- opt = $${1}
- val = $${2}
- nextok = $${3}
- isEmpty(val):$$nextok: val = $$qtConfGetNextCommandlineArg()
-
- # Note: Arguments which are variable assignments are legit here.
- contains(val, "^-.*")|isEmpty(val) {
- qtConfAddError("No value supplied to command line option '$$opt'.")
- return()
- }
-
- !qtConfValidateValue($$opt, $$val): \
- return()
-
- qtConfCommandlineSetInput($$opt, $$val)
-}
-
-defineTest(qtConfCommandline_optionalString) {
- opt = $${1}
- val = $${2}
- nextok = $${3}
- isEmpty(val) {
- $$nextok: val = $$qtConfPeekNextCommandlineArg()
- contains(val, "^-.*|[A-Z0-9_]+=.*")|isEmpty(val): \
- val = "yes"
- else: \
- val = $$qtConfGetNextCommandlineArg()
- }
-
- !qtConfValidateValue($$opt, $$val): \
- return()
-
- qtConfCommandlineSetInput($$opt, $$val)
-}
-
-
-defineTest(qtConfCommandline_addString) {
- opt = $${1}
- val = $${2}
- nextok = $${3}
- isEmpty(val):$$nextok: val = $$qtConfGetNextCommandlineArg()
-
- # Note: Arguments which are variable assignments are legit here.
- contains(val, "^-.*")|isEmpty(val) {
- qtConfAddError("No value supplied to command line option '$$opt'.")
- return()
- }
-
- !qtConfValidateValue($$opt, $$val): \
- return()
-
- !isEmpty($${currentConfig}.commandline.options.$${opt}.name): \
- opt = $$eval($${currentConfig}.commandline.options.$${opt}.name)
-
- config.input.$$opt += $$val
- export(config.input.$$opt)
-}
-
-defineTest(qtConfCommandline_redo) {
- !exists($$OUT_PWD/config.opt) {
- qtConfAddError("No config.opt present - cannot redo configuration.")
- return()
- }
- QMAKE_EXTRA_REDO_ARGS = $$cat($$OUT_PWD/config.opt, lines)
- export(QMAKE_EXTRA_REDO_ARGS) # just for config.log
- QMAKE_EXTRA_ARGS = $$QMAKE_EXTRA_REDO_ARGS $$QMAKE_EXTRA_ARGS
- export(QMAKE_EXTRA_ARGS)
- QMAKE_REDO_CONFIG = true
- export(QMAKE_REDO_CONFIG)
-}
-
-defineTest(qtConfParseCommandLine) {
- customCalls =
- for (cc, allConfigs) {
- custom = $$eval($${cc}.commandline.custom)
-
- !isEmpty(custom) {
- customCall = qtConfCommandline_$$custom
- !defined($$customCall, test): \
- error("Custom command line callback '$$custom' is undefined.")
- customCalls += $$customCall
- }
- }
-
- for (ever) {
- c = $$qtConfGetNextCommandlineArg()
- isEmpty(c): break()
-
- didCustomCall = false
- for (customCall, customCalls) {
- $${customCall}($$c) {
- didCustomCall = true
- break()
- }
- }
- $$didCustomCall: \
- next()
-
- contains(c, "([A-Z0-9_]+)=(.*)") {
- opt = $$replace(c, "^([A-Z0-9_]+)=(.*)", "\\1")
- val = $$replace(c, "^([A-Z0-9_]+)=(.*)", "\\2")
- for (cc, allConfigs) {
- var = $$eval($${cc}.commandline.assignments.$${opt})
- !isEmpty(var): \
- break()
- }
- isEmpty(var) {
- qtConfAddError("Assigning unknown variable '$$opt' on command line.")
- return()
- }
- config.input.$$var = $$val
- export(config.input.$$var)
- next()
- }
-
- # parse out opt and val
- nextok = false
- contains(c, "^--?enable-(.*)") {
- opt = $$replace(c, "^--?enable-(.*)", "\\1")
- val = yes
- } else: contains(c, "^--?(disable|no)-(.*)") {
- opt = $$replace(c, "^--?(disable|no)-(.*)", "\\2")
- val = no
- } else: contains(c, "^--([^=]+)=(.*)") {
- opt = $$replace(c, "^--([^=]+)=(.*)", "\\1")
- val = $$replace(c, "^--([^=]+)=(.*)", "\\2")
- } else: contains(c, "^--(.*)") {
- opt = $$replace(c, "^--(.*)", "\\1")
- val =
- } else: contains(c, "^-(.*)") {
- opt = $$replace(c, "^-(.*)", "\\1")
- val =
- nextok = true
- for (cc, allConfigs) {
- type = $$eval($${cc}.commandline.options.$${opt})
- !isEmpty(type): break()
- type = $$eval($${cc}.commandline.options.$${opt}.type)
- !isEmpty(type): break()
- }
- isEmpty(type):contains(opt, "(qt|system)-.*") {
- val = $$replace(opt, "(qt|system)-(.*)", "\\1")
- opt = $$replace(opt, "(qt|system)-(.*)", "\\2")
- }
- } else {
- qtConfAddError("Invalid command line parameter '$$c'.")
- return()
- }
-
- for (cc, allConfigs) {
- type = $$eval($${cc}.commandline.options.$${opt})
- isEmpty(type): \
- type = $$eval($${cc}.commandline.options.$${opt}.type)
- isEmpty(type) {
- # no match in the regular options, try matching the prefixes
- for (p, $${cc}.commandline.prefix._KEYS_) {
- e = "^-$${p}(.*)"
- contains(c, $$e) {
- opt = $$eval($${cc}.commandline.prefix.$${p})
- val = $$replace(c, $$e, "\\1")
- nextok = true
- type = "addString"
- break()
- }
- }
- }
- !isEmpty(type) {
- currentConfig = $$cc
- break()
- }
- }
- # handle builtin [-no]-feature-xxx
- isEmpty(type):contains(opt, "feature-(.*)") {
- opt ~= s,^feature-,,
- found = false
- for (cc, allConfigs) {
- contains($${cc}.features._KEYS_, $$opt) {
- found = true
- break()
- }
- }
- !$$found {
- qtConfAddError("Enabling/Disabling unknown feature '$$opt'.")
- return()
- }
- # this is a boolean enabling/disabling the corresponding feature
- type = boolean
- }
-
- # Skip the -qmake option.
- isEmpty(type):contains(opt, "qmake") {
- next()
- }
-
- isEmpty(type):contains(opt, "skip") {
- isEmpty(skipOptionWarningAdded) {
- qtConfAddWarning("Command line option -skip is only effective in top-level builds.")
- skipOptionWarningAdded = 1
- }
- val = $$qtConfGetNextCommandlineArg()
- next()
- }
-
- isEmpty(type) {
- qtConfAddError("Unknown command line option '$$c'.")
- equals(config.input.continue, yes): \
- next()
- else: \
- return()
- }
-
- call = "qtConfCommandline_$${type}"
- !defined($$call, test): \
- error("Command line option '$$c' has unknown type '$$type'.")
-
- # now that we have opt and value, process it
- $${call}($$opt, $$val, $$nextok)
- }
-}
-
-defineReplace(qtConfToolchainSupportsFlag) {
- test_out_dir = $$OUT_PWD/$$basename(QMAKE_CONFIG_TESTS_DIR)
- test_cmd_base = "$$QMAKE_CD $$system_quote($$system_path($$test_out_dir)) &&"
-
- conftest = "int main() { return 0; }"
- write_file("$$test_out_dir/conftest.cpp", conftest)|error()
-
- qtRunLoggedCommand("$$test_cmd_base $$QMAKE_CXX $$QMAKE_CXXFLAGS $${1} -o conftest-out conftest.cpp"): \
- return(true)
- return(false)
-}
-
-defineTest(qtConfTest_compilerSupportsFlag) {
- flag = $$eval($${1}.flag)
-
- return($$qtConfToolchainSupportsFlag($$flag))
-}
-
-defineTest(qtConfTest_linkerSupportsFlag) {
- flag = $$eval($${1}.flag)
-
- use_bfd_linker: \
- LFLAGS = -fuse-ld=bfd
- use_gold_linker: \
- LFLAGS = -fuse-ld=gold
- use_lld_linker: \
- LFLAGS = -fuse-ld=lld
-
- return($$qtConfToolchainSupportsFlag($$LFLAGS "-Wl,$$flag"))
-}
-
-defineReplace(qtConfFindInPathList) {
- # This nesting is consistent with Apple ld -search_paths_first,
- # and presumably with GNU ld (no actual documentation found).
- for (dir, 2) {
- for (file, 1) {
- exists("$$dir/$$file"): \
- return("$$dir/$$file")
- }
- }
- return()
-}
-
-defineReplace(qtConfFindInPath) {
- ensurePathEnv()
- equals(QMAKE_HOST.os, Windows):!contains(1, .*\\.exe): 1 = $${1}.exe
- return($$qtConfFindInPathList($$1, $$2 $$QMAKE_PATH_ENV))
-}
-
-defineReplace(qtConfPkgConfigEnv) {
- env =
- !isEmpty(PKG_CONFIG_SYSROOT_DIR): env = "$${SETENV_PFX}PKG_CONFIG_SYSROOT_DIR=$${PKG_CONFIG_SYSROOT_DIR}$${SETENV_SFX} "
- !isEmpty(PKG_CONFIG_LIBDIR): env = "$$env$${SETENV_PFX}PKG_CONFIG_LIBDIR=$${PKG_CONFIG_LIBDIR}$${SETENV_SFX} "
- return($$env)
-}
-
-defineReplace(qtConfPkgConfig) {
- host = $$1
- isEmpty(host): host = false
-
- $$host {
- pkg_config = $$qtConfFindInPath("pkg-config")
- } else {
- pkg_config = "$$qtConfPkgConfigEnv()$$PKG_CONFIG_EXECUTABLE"
- }
-
- return($$pkg_config)
-}
-
-defineTest(qtConfPkgConfigPackageExists) {
- isEmpty(1)|isEmpty(2): \
- return(false)
-
- !qtRunLoggedCommand("$${1} --exists --silence-errors $${2}"): \
- return(false)
-
- return(true)
-}
-
-defineReplace(qtSystemQuote) {
- args =
- for (a, 1): \
- args += $$system_quote($$a)
- return($$args)
-}
-
-defineReplace(qtConfPrepareArgs) {
- return($$qtSystemQuote($$split(1)))
-}
-
-defineTest(qtConfSetupLibraries) {
- asspfx = $${currentConfig}.commandline.assignments
- for (l, $${currentConfig}.libraries._KEYS_) {
- lpfx = $${currentConfig}.libraries.$${l}
- # 'export' may be omitted, in which case it falls back to the library's name
- !defined($${lpfx}.export, var) {
- $${lpfx}.export = $$replace(l, -, _)
- export($${lpfx}.export)
- }
- # 'export' may also be empty, but we need a derived identifier
- alias = $$eval($${lpfx}.export)
- isEmpty(alias): alias = $$replace(l, -, _)
- $${lpfx}.alias = $$alias
- export($${lpfx}.alias)
- # make it easy to refer to the library by its export name.
- $${currentConfig}.exports._KEYS_ += $$alias
- $${currentConfig}.exports.$$alias += $$l
- export($${currentConfig}.exports.$$alias)
- isEmpty($${lpfx}.sources._KEYS_): \
- error("Library $$l defines no sources")
- for (s, $${lpfx}.sources._KEYS_) {
- spfx = $${lpfx}.sources.$${s}
- # link back to parent object
- $${spfx}.library = $$l
- export($${spfx}.library)
- # a plain string is transformed into a structure
- isEmpty($${spfx}._KEYS_) {
- $${spfx}.libs = $$eval($${spfx})
- export($${spfx}.libs)
- }
- # if the type is missing (implicitly in the case of plain strings), assume 'inline'
- isEmpty($${spfx}.type) {
- $${spfx}.type = inline
- export($${spfx}.type)
- }
- }
- }
- $${currentConfig}.exports._KEYS_ = $$unique($${currentConfig}.exports._KEYS_)
- export($${currentConfig}.exports._KEYS_)
-
- for (alias, $${currentConfig}.exports._KEYS_) {
- ua = $$upper($$alias)
- $${asspfx}._KEYS_ += \
- $${ua}_PREFIX $${ua}_INCDIR $${ua}_LIBDIR \
- $${ua}_LIBS $${ua}_LIBS_DEBUG $${ua}_LIBS_RELEASE
- uapfx = $${asspfx}.$${ua}
- $${uapfx}_PREFIX = $${alias}.prefix
- $${uapfx}_INCDIR = $${alias}.incdir
- $${uapfx}_LIBDIR = $${alias}.libdir
- $${uapfx}_LIBS = $${alias}.libs
- $${uapfx}_LIBS_DEBUG = $${alias}.libs.debug
- $${uapfx}_LIBS_RELEASE = $${alias}.libs.release
- export($${uapfx}_PREFIX)
- export($${uapfx}_INCDIR)
- export($${uapfx}_LIBDIR)
- export($${uapfx}_LIBS)
- export($${uapfx}_LIBS_DEBUG)
- export($${uapfx}_LIBS_RELEASE)
- }
- export($${asspfx}._KEYS_)
-
- # reverse mapping for assignments on command line.
- for (a, $${asspfx}._KEYS_) {
- apfx = $${asspfx}.$${a}
- ra = config.commandline.rev_assignments.$$eval($$apfx)
- $$ra = $$a
- export($$ra)
- }
-}
-
-defineReplace(qtGccSysrootifiedPath) {
- return($$replace(1, ^=, $$[QT_SYSROOT]))
-}
-
-defineReplace(qtGccSysrootifiedPaths) {
- sysrootified =
- for (path, 1): \
- sysrootified += $$qtGccSysrootifiedPath($$path)
- return($$sysrootified)
-}
-
-# libs-var, libs, in-paths
-defineTest(qtConfResolveLibs) {
- for (path, 3): \
- pre_lflags += -L$$path
- $$1 = $$pre_lflags $$2
- export($$1)
- return(true)
-}
-
-# libs-var, in-paths, libs
-defineTest(qtConfResolvePathLibs) {
- ret = true
- gcc: \
- local_paths = $$qtGccSysrootifiedPaths($$2)
- else: \
- local_paths = $$2
- for (libdir, local_paths) {
- !exists($$libdir/.) {
- qtLog("Library path $$val_escape(libdir) is invalid.")
- ret = false
- }
- }
- !qtConfResolveLibs($$1, $$3, $$2): \
- ret = false
- return($$ret)
-}
-
-defineReplace(qtConfGetTestSourceList) {
- result =
- !isEmpty($${1}.test.inherit) {
- base = $$section(1, ., 0, -2)
- for (i, $${1}.test.inherit): \
- result += $$qtConfGetTestSourceList($${base}.$$i)
- }
- return($$result $$1)
-}
-
-defineReplace(qtConfGetTestIncludes) {
- defined($${1}._KEYS_, var) {
- 1st = $$first($${1}._KEYS_)
- equals(1st, 0) {
- # array; recurse for every element
- ret =
- for (k, $${1}._KEYS_): \
- ret += $$qtConfGetTestIncludes($${1}.$$k)
- return($$ret)
- }
- # object; try condition and recurse
- !defined($${1}.headers, var):!defined($${1}.headers._KEYS_, var): \ # just plain broken without it
- error("headers object '$$1' has no nested headers entry")
- cond = $$eval($${1}.condition)
- isEmpty(cond): \ # would be pointless otherwise
- error("headers object '$$1' has no condition")
- !$$qtConfEvaluate($$cond) {
- qtLog("header entry '$$1' failed condition '$$cond'.")
- return()
- }
- qtLog("header entry '$$1' passed condition.")
- return($$qtConfGetTestIncludes($${1}.headers))
- }
- return($$eval($$1)) # plain string - or nothing (can happen for top-level call only)
-}
-
-# includes-var, in-paths, test-object-var
-defineTest(qtConfResolvePathIncs) {
- ret = true
- gcc: \
- local_paths = $$qtGccSysrootifiedPaths($$2)
- else: \
- local_paths = $$2
- for (incdir, local_paths) {
- !exists($$incdir/.) {
- qtLog("Include path $$val_escape(incdir) is invalid.")
- ret = false
- }
- }
- 2 -= $$QMAKE_DEFAULT_INCDIRS
- $$1 = $$2
- export($$1)
- wasm {
- # FIXME: emcc downloads pre-built libraries and adds their include
- # path to the clang call dynamically. it would be possible to parse
- # the emcc -s USE_xyz=1 --cflags output to populate xzy_INCDIR and
- # thus make the code below work.
- return($$ret)
- }
- tests = $$qtConfGetTestSourceList($$3)
- hdrs =
- for (test, tests): \
- hdrs += $$qtConfGetTestIncludes($${test}.headers)
- for (hdr, hdrs) {
- h = $$qtConfFindInPathList($$hdr, $$2 $$EXTRA_INCLUDEPATH $$QMAKE_DEFAULT_INCDIRS)
- isEmpty(h) {
- qtLog("$$hdr not found in [$$val_escape(2)] and global paths.")
- ret = false
- }
- }
- return($$ret)
-}
-
-# the library is specified inline in a 'libs' field.
-# overrides from the command line are accepted.
-defineTest(qtConfLibrary_inline) {
- lib = $$eval($${1}.library)
- !defined($${1}.libs, var):isEmpty($${1}.builds._KEYS_): \
- error("'inline' source in library '$$lib' specifies neither 'libs' nor 'builds'.")
-
- # library lists are specified as strings in the json sources for
- # readability, but it's a pain to work with that, so expand it now.
- eval($${1}.libs = $$eval($${1}.libs))
- export($${1}.libs)
- for (b, $${1}.builds._KEYS_) {
- eval($${1}.builds.$${b} = $$eval($${1}.builds.$${b}))
- export($${1}.builds.$${b})
- }
-
- # if multiple libraries provide the same export, it makes sense
- # to make them recognize the same input variables.
- input = $$eval($${2}.alias)
-
- # build-specific direct libs. overwrites inline libs.
- vars =
- any = false
- all = true
- for (b, $$list(debug release)) {
- iv = $${input}.libs.$${b}
- vars += $$eval(config.commandline.rev_assignments.$${iv})
- defined(config.input.$${iv}, var) {
- eval($${1}.builds.$${b} = $$eval(config.input.$${iv}))
- export($${1}.builds.$${b})
- $${1}.builds._KEYS_ *= $${b}
- any = true
- } else {
- all = false
- }
- }
- $$any {
- !$$all {
- qtConfAddError("Either none or all of $$join(vars, ", ", [, ]) must be specified.")
- return(false)
- }
- export($${1}.builds._KEYS_)
- # we also reset the generic libs, to avoid surprises.
- $${1}.libs =
- export($${1}.libs)
- }
-
- # direct libs. overwrites inline libs.
- defined(config.input.$${input}.libs, var) {
- eval($${1}.libs = $$eval(config.input.$${input}.libs))
- export($${1}.libs)
- }
-
- includes = $$eval(config.input.$${input}.incdir)
-
- # prefix. prepends to (possibly overwritten) inline libs.
- prefix = $$eval(config.input.$${input}.prefix)
- !isEmpty(prefix) {
- includes += $$prefix/include
- $${1}.libs = -L$$prefix/lib $$eval($${1}.libs)
- export($${1}.libs)
- }
-
- libdir = $$eval(config.input.$${input}.libdir)
- !isEmpty(libdir) {
- libs =
- for (ld, libdir): \
- libs += -L$$ld
- $${1}.libs = $$libs $$eval($${1}.libs)
- export($${1}.libs)
- }
-
- !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \
- return(false)
-
- return(true)
-}
-
-# the library is provided by the qmake spec.
-# this source type cannot fail.
-defineTest(qtConfLibrary_makeSpec) {
- spec = $$eval($${1}.spec)
- isEmpty(spec): \
- error("makeSpec source in library '$$eval($${1}.library)' does not specify 'spec'.")
-
- !qtConfResolvePathLibs($${1}.libs, $$eval(QMAKE_LIBDIR_$$spec), $$eval(QMAKE_LIBS_$$spec)): \
- return(false)
-
- !qtConfResolvePathIncs($${1}.includedir, $$eval(QMAKE_INCDIR_$$spec), $$2): \
- return(false)
-
- !isEmpty(QMAKE_EXPORT_INCDIR_$$spec) {
- $${1}.exportincludedir = $$eval(QMAKE_EXPORT_INCDIR_$$spec)
- export($${1}.exportincludedir)
- }
-
- # note that the object is re-exported, because we resolve the libraries.
-
- return(true)
-}
-
-# the library is found via pkg-config.
-defineTest(qtConfLibrary_pkgConfig) {
- pkg_config = $$qtConfPkgConfig($$eval($${1}.host))
- isEmpty(pkg_config) {
- qtLog("pkg-config use disabled globally.")
- return(false)
- }
- args = $$qtConfPrepareArgs($$eval($${1}.args))
-
- !qtConfPkgConfigPackageExists($$pkg_config, $$args) {
- qtLog("pkg-config did not find package.")
- return(false)
- }
-
- qtRunLoggedCommand("$$pkg_config --modversion $$args", version)|return(false)
- version ~= s/[^0-9.].*$//
- $${1}.version = $$first(version)
- export($${1}.version)
-
- qtRunLoggedCommand("$$pkg_config --libs-only-L $$args", libpaths)|return(false)
- qtRunLoggedCommand("$$pkg_config --libs-only-l $$args", libs)|return(false)
- eval(libs = $$libpaths $$libs)
- !qtConfResolveLibs($${1}.libs, $$libs): \
- return(false)
- contains($${1}.libs, ".*\\.$${QMAKE_EXTENSION_STATICLIB}$") {
- qtRunLoggedCommand("$$pkg_config --static --libs $$args", libs)|return(false)
- # Split by space
- eval(libs = $$libs)
- !qtConfResolveLibs($${1}.libs, $$libs): \
- return(false)
- }
-
- qtRunLoggedCommand("$$pkg_config --cflags $$args", $${1}.cflags)|return(false)
- # Split CFLAGS into stuff that goes into DEFINES, INCLUDEPATH, and other stuff.
- # The compound variable is still set in case something wants to use it outside
- # regular library exports.
- defines =
- includes =
- ignored =
- eval(cflags = $$eval($${1}.cflags))
- for (i, cflags) {
- contains(i, "-I.*") {
- i ~= s/^-I//
- includes += $$i
- } else: contains(i, "-D.*") {
- i ~= s/^-D//
- defines += $$i
- } else {
- # Sometimes, pkg-config files include other flags
- # we really don't need and shouldn't add.
- ignored += $$i
- }
- }
- !isEmpty(ignored): \
- qtLog("Note: Dropped compiler flags '$$ignored'.")
- !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \
- return(false)
- $${1}.defines = $$defines
-
- # now remove the content of the transitive deps we know about.
- largs = $$qtConfAllLibraryArgs($$eval($${2}.dependencies))
- for (la, largs): \
- eval("$$la")
- USES = $$eval($$list($$upper($$replace(QMAKE_USE, -, _))))
- # _CC == _LD for configure's library sources, so pick first arbitrarily.
- DEPS = $$resolve_depends(USES, QMAKE_DEPENDS_, _CC)
- for (DEP, DEPS) {
- $${1}.libs -= $$eval(QMAKE_LIBS_$${DEP})
- $${1}.includedir -= $$eval(QMAKE_INCDIR_$${DEP})
- $${1}.defines -= $$eval(QMAKE_DEFINES_$${DEP})
- }
- export($${1}.libs)
- export($${1}.includedir)
- export($${1}.defines)
-
- return(true)
-}
-
-defineTest(qtConfTest_getPkgConfigVariable) {
- pkg_config = $$qtConfPkgConfig($$eval($${1}.host))
- isEmpty(pkg_config): \
- return(false)
- args = $$qtConfPrepareArgs($$eval($${1}.pkg-config-args))
-
- !qtConfPkgConfigPackageExists($$pkg_config, $$args): \
- return(false)
-
- variable = $$eval($${1}.pkg-config-variable)
- qtRunLoggedCommand("$$pkg_config --variable=$$variable $$args", $${1}.value)|return(false)
- export($${1}.value)
- $${1}.cache += value
- export($${1}.cache)
- return(true)
-}
-
-defineReplace(qtConfLibraryArgs) {
- NAME = $$upper($$replace($${1}.library, -, _))
- qmake_args = "QMAKE_LIBS_$${NAME} = $$val_escape($${1}.libs)"
- for (b, $${1}.builds._KEYS_): \
- qmake_args += "QMAKE_LIBS_$${NAME}_$$upper($$b) = $$val_escape($${1}.builds.$${b})"
- includedir = $$eval($${1}.includedir)
- !isEmpty(includedir): \
- qmake_args += "QMAKE_INCDIR_$${NAME} = $$val_escape(includedir)"
- defines = $$eval($${1}.defines)
- !isEmpty(defines): \
- qmake_args += "QMAKE_DEFINES_$${NAME} = $$val_escape(defines)"
- depends = $$eval($${2}.dependencies)
- !isEmpty(depends) {
- dep_uses =
- for (use, depends): \
- dep_uses += $$section(use, :, 1, 1)
- qmake_args += \
- "QMAKE_DEPENDS_$${NAME}_CC = $$upper($$replace(dep_uses, -, _))" \
- "QMAKE_DEPENDS_$${NAME}_LD = $$upper($$replace(dep_uses, -, _))"
- }
- return($$qmake_args)
-}
-
-defineReplace(qtConfAllLibraryArgs) {
- isEmpty(1): return()
- dep_uses =
- for (use, 1): \
- dep_uses += $$section(use, :, 1, 1)
- dep_args =
- seen =
- for(ever) {
- isEmpty(1): break()
- use = $$take_last(1)
- contains(seen, $$use): next()
- seen += $$use
- use_cfg = $$section(use, :, 0, 0)
- !isEmpty(use_cfg) {
- use_lib = $$section(use, :, 1, 1)
- lpfx = $${use_cfg}.libraries.$$use_lib
- dep_args += $$qtConfLibraryArgs($${lpfx}.sources.$$eval($${lpfx}.source), $$lpfx)
- 1 += $$eval($${lpfx}.dependencies)
- }
- }
- return("QMAKE_USE += $$dep_uses" $$dep_args)
-}
-
-defineTest(qtConfExportLibrary) {
- lpfx = $${currentConfig}.libraries.$$1
- alias = $$eval($${lpfx}.alias)
- $${currentConfig}.found.$$alias = $$1
- export($${currentConfig}.found.$$alias)
- name = $$eval($${lpfx}.export)
- isEmpty(name): return()
- spfx = $${lpfx}.sources.$$eval($${lpfx}.source)
- !$$qtConfEvaluate($$eval($${spfx}.export)): return()
-
- output = privatePro
- NAME = $$upper($$name)
- # LIBS is emitted even if empty, as this allows the library to be "seen".
- libs = $$eval($${spfx}.libs)
- qtConfOutputVar(assign, $$output, QMAKE_LIBS_$$NAME, $$libs)
- for (b, $${spfx}.builds._KEYS_) {
- blibs = $$eval($${spfx}.builds.$${b})
- qtConfOutputVar(assign, $$output, QMAKE_LIBS_$${NAME}_$$upper($$b), $$blibs)
- }
- defines = $$eval($${spfx}.defines)
- !isEmpty(defines): qtConfOutputVar(assign, $$output, QMAKE_DEFINES_$$NAME, $$defines)
- includes = $$eval($${spfx}.exportincludedir)
- !equals(includes, -) {
- isEmpty(includes): includes = $$eval($${spfx}.includedir)
- !isEmpty(includes): qtConfOutputVar(assign, $$output, QMAKE_INCDIR_$$NAME, $$includes)
- }
- uses = $$eval($${lpfx}.dependencies)
- !isEmpty(uses) {
- # FIXME: ideally, we would export transitive deps only for static
- # libs, to not extend the link interface unduly. however, the system
- # does currently not differentiate between public and private deps.
- depends =
- for (use, uses) {
- use_cfg = $$section(use, :, 0, 0)
- use_lib = $$section(use, :, 1, 1)
- !isEmpty(use_cfg): \
- depends += $$upper($$eval($${use_cfg}.libraries.$${use_lib}.export))
- else: \
- depends += $$upper($$replace(use_lib, -, _))
- }
- # we use suffixes instead of infixes, because $$resolve_depends() demands it.
- qtConfOutputVar(assign, $$output, QMAKE_DEPENDS_$${NAME}_CC, $$depends)
- qtConfOutputVar(assign, $$output, QMAKE_DEPENDS_$${NAME}_LD, $$depends)
- }
- !isEmpty($${currentConfig}.module): \
- qtConfExtendVar($$output, "QT.$${currentModule}_private.libraries", $$name)
-}
-
-defineTest(qtConfHandleLibrary) {
- lpfx = $${currentConfig}.libraries.$$1
- defined($${lpfx}.result, var): return()
-
- alias = $$eval($${lpfx}.alias)
- !isEmpty($${currentConfig}.found.$$alias) {
- # this happening indicates a logic error in the conditions
- # of the feature(s) referring to this library.
- # note that this does not look across module boundaries, as
- # multiple modules may know the same libraries; de-duplication
- # happens via the cache (obviously, this assumes identical
- # definitions and logic).
- error("A library exporting '$$alias' was already found.")
- }
-
- qtConfEnsureTestTypeDeps("library")
- !qtConfTestPrepare_compile($$lpfx) {
- $${lpfx}.result = false
- export($${lpfx}.result)
- return()
- }
- $${lpfx}.dependencies = $$eval($${lpfx}.resolved_uses)
- export($${lpfx}.dependencies)
-
- qtConfLoadResult($${lpfx}, $$1, "library") {
- $$eval($${lpfx}.result): \
- qtConfExportLibrary($$1)
- return()
- }
-
- qtLogTestIntro($${lpfx}, "looking for library $${1}")
- qtPersistLog()
-
- result = false
- for (s, $${lpfx}.sources._KEYS_) {
- spfx = $${lpfx}.sources.$${s}
-
- t = $$eval($${spfx}.type)
- call = qtConfLibrary_$$t
- !defined($$call, test): \
- error("Library $${1} source $${s} has unknown type '$$t'")
-
- qtLog("Trying source $$s (type $$t) of library $${1} ...")
-
- cond = $$eval($${spfx}.condition)
- !$$qtConfEvaluate($$cond) {
- qtLog(" => source failed condition '$$cond'.")
- next()
- }
-
- !$${call}($$spfx, $$lpfx) {
- qtLog(" => source produced no result.")
- next()
- }
-
- $${lpfx}.source = $$s
- export($${lpfx}.source)
-
- # if the library defines a test, use it to verify the source.
- defined($${lpfx}.test, var)|defined($${lpfx}.test._KEYS_, var) {
- $${lpfx}.resolved_uses = $$currentConfig:$$1
- $${lpfx}.host = $$eval($${spfx}.host)
- !qtConfTest_compile($$lpfx) {
- qtLog(" => source failed verification.")
- next()
- }
- }
-
- qtLog(" => source accepted.")
-
- $${lpfx}.cache += source
- for (v, $$list(libs includedir cflags version export)): \
- $${lpfx}.cache += sources.$${s}.$${v}
- for (b, $${spfx}.builds._KEYS_): \
- $${lpfx}.cache += sources.$${s}.builds.$${b}
-
- # immediately output the library as well.
- qtConfExportLibrary($$1)
-
- result = true
- break()
- }
-
- $${lpfx}.msgs = $$qtPersistedLog()
- export($${lpfx}.msgs)
-
- qtLogTestResult($${lpfx}, $$result)
-
- $${lpfx}.result = $$result
- export($${lpfx}.result)
- qtConfSaveResult($${lpfx}, $$1)
-}
-
-# This is a fake test type for the test dependency system.
-defineTest(qtConfTest_library) {
- error("The test type 'library' may not be instantiated.")
-}
-
-defineTest(qtConfTestPrepare_compile) {
- !isEmpty($${1}.use._KEYS_) {
- uses =
- for (k, $${1}.use._KEYS_) {
- use = $$eval($${1}.use.$${k}.lib)
- isEmpty(use): \
- error("'use' entry $$k in test $$1 lacks 'lib' field.")
- !$$qtConfEvaluate($$eval($${1}.use.$${k}.condition)): \
- next()
- uses += $$use
- }
- } else {
- uses = $$split($${1}.use)
- }
- for (u, uses) {
- libConfig =
- exports = $$eval($${currentConfig}.exports.$$u)
- !isEmpty(exports) {
- # using a local library by exported name.
- ru = $$eval($${currentConfig}.found.$$u)
- !isEmpty(ru) {
- # if it was already found, all is good.
- u = $$ru
- } else: count(exports, 1) {
- # otherwise, if there is only one option, ensure it's resolved.
- u = $$exports
- qtConfHandleLibrary($$u)
- } else {
- # otherwise, verify that all options were resolved.
- for (x, exports) {
- isEmpty($${currentConfig}.libraries.$${x}.result) {
- # the higher-level logic is in the features, which we cannot
- # infer from here. so the only option is failing.
- error("Test $$1 refers to yet unresolved library export '$$u'")
- }
- }
- return(false)
- }
- libConfig = $$currentConfig
- } else: contains($${currentConfig}.libraries._KEYS_, $$u) {
- # using a local library by real name. this should be the exception.
- qtConfHandleLibrary($$u)
- libConfig = $$currentConfig
- } else {
- for (d, QMAKE_LIBRARY_DEPS) {
- exports = $$eval($${d}.exports.$$u)
- !isEmpty(exports) {
- # using a foreign library by exported name.
- # foreign libraries may be external (if they are from a different
- # repository and the build is modular), and using these by real
- # name is impossible. so for consistency, uses by real name are
- # limited to local libraries.
- ru = $$eval($${d}.found.$$u)
- !isEmpty(ru) {
- u = $$ru
- libConfig = $$d
- break()
- }
- for (x, exports) {
- isEmpty($${d}.libraries.$${x}.result): \
- error("Test $$1 refers to unresolved library export '$$u' in '$$d'")
- }
- return(false)
- }
- }
- }
- isEmpty(libConfig) {
- nu = $$upper($$replace(u, -, _))
- !defined(QMAKE_LIBS_$$nu, var): \
- error("Test $$1 tries to use undeclared library '$$u'")
- # using an external library by exported name.
- $${1}.resolved_uses += :$$u
- } else {
- lpfx = $${libConfig}.libraries.$${u}
- !equals($${lpfx}.result, true): \
- return(false)
- $${1}.resolved_uses += $$libConfig:$$u
- }
- }
- export($${1}.resolved_uses)
- return(true)
-}
-
-defineTest(qtConfPrepareCompileTestSource) {
- test_dir = $$2
-
- tests = $$qtConfGetTestSourceList($$1)
-
- test_lang = "c++"
- for (test, tests): \
- test_lang += $$eval($${test}.test.lang)
- test_lang = $$last(test_lang) # Last non-empty, that is.
-
- equals(test_lang, "c++"): suffix = "cpp"
- else: equals(test_lang, "c"): suffix = "c"
- else: equals(test_lang, "objc"): suffix = "m"
- else: equals(test_lang, "objc++"): suffix = "mm"
- else: error("Unknown language '$$test_lang' in compile test $$1")
-
- # Create source code
- contents = "/* Generated by configure */"
- # Custom code before includes
- for (test, tests): \
- for (ent, $$qtConfScalarOrList($${test}.test.head)): \
- contents += $$ent
- # Includes
- for (test, tests) {
- hdrs = $$qtConfGetTestIncludes($${test}.test.include)
- isEmpty(hdrs): \
- hdrs = $$qtConfGetTestIncludes($${test}.headers)
- for (ent, hdrs): \
- contents += "$${LITERAL_HASH}include <$$ent>"
- }
- # Custom code after includes
- for (test, tests): \
- for (ent, $$qtConfScalarOrList($${test}.test.tail)): \
- contents += $$ent
- # And finally the custom code inside main()
- contents += \
- "int main(int argc, char **argv)" \
- "{" \
- " (void)argc; (void)argv;" \
- " /* BEGIN TEST: */"
- for (test, tests): \
- for (ent, $$qtConfScalarOrList($${test}.test.main)): \
- contents += " $$ent"
- contents += \
- " /* END TEST */" \
- " return 0;" \
- "}"
- write_file($$test_dir/main.$$suffix, contents)|error()
-
- for (test, tests) {
- for (file, $$qtConfScalarOrList($${test}.test.files._KEYS_)): \
- write_file($$test_dir/$$file, $$qtConfScalarOrList($${test}.test.files.$${file}))|error()
- }
-
- # Create stub .pro file
- contents = "SOURCES = main.$$suffix"
- # Custom project code
- pwd = $$val_escape($${currentConfig}.dir)
- for (test, tests): \
- for (ent, $$qtConfScalarOrList($${test}.test.qmake)): \
- contents += $$replace(ent, "@PWD@", $$pwd)
- write_file($$test_dir/$$basename(test_dir).pro, contents)|error()
-}
-
-defineTest(qtConfTest_compile) {
- test = $$eval($${1}.test)
- host = $$eval($${1}.host)
- isEmpty(host): host = false
-
- test_base_out_dir = $$OUT_PWD/$$basename(QMAKE_CONFIG_TESTS_DIR)
- isEmpty(test) {
- test_dir = $$test_base_out_dir/$$section(1, ".", -1)
- test_out_dir = $$test_dir
- qtConfPrepareCompileTestSource($$1, $$test_dir)
- } else {
- test_dir = $$QMAKE_CONFIG_TESTS_DIR/$$test
- test_out_dir = $$test_base_out_dir/$$test
- !isEmpty($${1}.pro): \
- test_dir = $$test_dir/$$eval($${1}.pro)
- }
- test_cmd_base = "$$QMAKE_CD $$system_quote($$system_path($$test_out_dir)) &&"
-
- qmake_args = $$qtConfPkgConfigEnv()$$system_quote($$system_path($$QMAKE_QMAKE))
- !isEmpty(QMAKE_QTCONF): \
- qmake_args += -qtconf $$system_quote($$QMAKE_QTCONF)
-
- # Disable qmake features which are typically counterproductive for tests
- qmake_args += "\"CONFIG -= qt debug_and_release app_bundle lib_bundle\""
-
- # allow tests to behave differently depending on the type of library
- # being built (shared/static). e.g. see config.tests/unix/icu
- shared: \
- qmake_configs = "shared"
- else: \
- qmake_configs = "static"
-
- use_bfd_linker: \
- qmake_configs += "use_bfd_linker"
- use_gold_linker: \
- qmake_configs += "use_gold_linker"
- use_lld_linker: \
- qmake_configs += "use_lld_linker"
-
- # disable warnings from the builds, since they're just noise at this point.
- qmake_configs += "warn_off"
-
- # add console to the CONFIG variable when running the tests, so that they
- # can work with a regular main() entry point on Windows.
- qmake_configs += "console"
-
- # for platforms with multiple architectures (macOS, iOS, tvOS, watchOS),
- # make sure tests are only built for a single architecture
- qmake_configs += "single_arch"
-
- qmake_args += "\"CONFIG += $$qmake_configs\""
-
- !$$host|!cross_compile {
- # add compiler flags, these are set for the target and should not be applied to host tests
- !isEmpty(EXTRA_DEFINES): \
- qmake_args += $$system_quote(DEFINES += $$val_escape(EXTRA_DEFINES))
- !isEmpty(EXTRA_LIBDIR): \
- qmake_args += $$system_quote(QMAKE_LIBDIR += $$val_escape(EXTRA_LIBDIR))
- !isEmpty(EXTRA_FRAMEWORKPATH): \
- qmake_args += $$system_quote(QMAKE_FRAMEWORKPATH += $$val_escape(EXTRA_FRAMEWORKPATH))
- !isEmpty(EXTRA_INCLUDEPATH): \
- qmake_args += $$system_quote(INCLUDEPATH += $$val_escape(EXTRA_INCLUDEPATH))
- qmake_args += $$EXTRA_QMAKE_ARGS
- }
-
- # make sure to make this the last override (because of -early)
- cross_compile {
- # must be done before loading default_pre.prf.
- qmake_args += -early "\"CONFIG += cross_compile\""
- }
-
- # Clean up after previous run
- exists($$test_out_dir/Makefile): \
- QMAKE_MAKE = "$$QMAKE_MAKE clean && $$QMAKE_MAKE"
-
- mkpath($$test_out_dir)|error()
- cont = "CONFIG += QTDIR_build"
- write_file($$test_base_out_dir/.qmake.cache, cont)|error()
-
- $${1}.literal_args += $$qtConfAllLibraryArgs($$eval($${1}.resolved_uses))
-
- # add possible command line args
- qmake_args += \
- $$qtConfPrepareArgs($$eval($${1}.args)) \
- $$qtSystemQuote($$eval($${1}.literal_args))
-
- qtRunLoggedCommand("$$test_cmd_base $$qmake_args $$system_quote($$test_dir)") {
- qtRunLoggedCommand("$$test_cmd_base $$QMAKE_MAKE"): \
- return(true)
- }
-
- return(false)
-}
-
-defineTest(qtConfTest_files) {
- for(i, $${1}.files._KEYS_) {
- f = $$eval($${1}.files.$${i})
- qtLog("Searching for file $${f}.")
- contains(f, ".*\\.h") {
- file = $$qtConfFindInPathList($$f, $$EXTRA_INCLUDEPATH $$QMAKE_DEFAULT_INCDIRS)
- } else: contains(f, ".*\\.(lib|so|a)") {
- file = $$qtConfFindInPathList($$f, $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS)
- } else {
- # assume we're looking for an executable
- file = $$qtConfFindInPath($$f, $$EXTRA_PATH)
- }
- isEmpty(file) {
- qtLog(" Not found.");
- return(false)
- }
- qtLog(" Found at $${file}.")
- }
- return(true)
-}
-
-defineTest(logn) {
- log("$${1}$$escape_expand(\\n)")
-}
-
-defineTest(qtLogTestIntro) {
- label = $$eval($${1}.label)
- isEmpty(label): return()
-
- isEmpty(3): log("Checking for $${label}... ")
- $$QMAKE_CONFIG_VERBOSE: log("$$escape_expand(\\n)")
- write_file($$QMAKE_CONFIG_LOG, 2, append)
-}
-
-defineTest(qtLogTestResult) {
- isEmpty($${1}.label): return()
-
- !isEmpty($${1}.log) {
- field = $$eval($${1}.log)
- log_msg = $$eval($${1}.$$field)
- msg = "test $$1 gave result $$log_msg"
- } else: $${2} {
- log_msg = yes
- msg = "test $$1 succeeded"
- } else {
- log_msg = no
- msg = "test $$1 FAILED"
- }
- $$QMAKE_CONFIG_VERBOSE: log_msg = $$msg
- isEmpty(3): logn("$$log_msg")
- write_file($$QMAKE_CONFIG_LOG, msg, append)
-}
-
-defineTest(qtConfSaveResult) {
- equals($${1}.cache, -): \
- return()
- keys = result msgs $$eval($${1}.cache)
- cont = "cache.$${2}._KEYS_ = $$keys"
- cache.$${2}._KEYS_ = $$keys
- export(cache.$${2}._KEYS_)
- for (k, keys) {
- cont += "cache.$${2}.$${k} = $$val_escape($${1}.$${k})"
- cache.$${2}.$${k} = $$eval($${1}.$${k})
- export(cache.$${2}.$${k})
- }
- write_file($$QMAKE_CONFIG_CACHE, cont, append)|error()
-}
-
-defineTest(qtConfLoadResult) {
- equals(QMAKE_CONFIG_CACHE_USE, none): \
- return(false)
- isEmpty(cache.$${2}._KEYS_): \
- return(false)
- equals(QMAKE_CONFIG_CACHE_USE, positive):!$$eval(cache.$${2}.result): \
- return(false)
- for (k, cache.$${2}._KEYS_) {
- $${1}.$${k} = $$eval(cache.$${2}.$${k})
- export($${1}.$${k})
- }
- # we could print the cached result, but that's basically just noise -
- # the explicitly generated summary is supposed to contain all relevant
- # information.
- qtLogTestIntro($$1, "loaded result for $$3 $$1", false)
- qtLog($$eval($${1}.msgs))
- qtLogTestResult($$1, $$eval($${1}.result), false)
- return(true)
-}
-
-defineTest(qtConfIsBoolean) {
- equals(1, "true")|equals(1, "false"): \
- return(true)
- return(false)
-}
-
-defineTest(qtConfSetupTestTypeDeps) {
- for (tt, $${currentConfig}.testTypeDependencies._KEYS_) {
- !defined(qtConfTest_$${tt}, test): \
- error("Declaring dependency for undefined test type '$$tt'.")
- for (f, $${currentConfig}.testTypeDependencies.$${tt}._KEYS_) {
- feature = $$eval($${currentConfig}.testTypeDependencies.$${tt}.$${f})
- isEmpty($${currentConfig}.features.$${feature}._KEYS_): \
- error("Test type '$$tt' depends on undefined feature '$$feature'.")
- }
- }
- # Test type aliasing means that one test type's callback is called by
- # another test type's callback. Put differently, one callback forwards
- # the call to another one. The former representation is more natural
- # (and concise) to write, while the latter is more efficient to process.
- # Hence, this function inverts the mapping.
- for (tt, $${currentConfig}.testTypeAliases._KEYS_) {
- !defined(qtConfTest_$${tt}, test): \
- error("Aliasing undefined test type '$$tt'.")
- for (tta, $${currentConfig}.testTypeAliases.$${tt}._KEYS_) {
- type = $$eval($${currentConfig}.testTypeAliases.$${tt}.$${tta})
- !defined(qtConfTest_$${type}, test): \
- error("Aliasing '$$tt' to undefined test type '$$type'.")
- $${currentConfig}.testTypeForwards.$${type} += $$tt
- export($${currentConfig}.testTypeForwards.$${type})
- }
- }
-}
-
-defineTest(qtConfEnsureTestTypeDepsOne) {
- depsn = $${currentConfig}.testTypeDependencies.$${1}._KEYS_
- !isEmpty($$depsn) {
- for (dep, $$depsn) {
- feature = $$eval($${currentConfig}.testTypeDependencies.$${1}.$${dep})
- !qtConfCheckFeature($$feature): \
- error("Test type '$$1' depends on non-emitted feature $${feature}.")
- }
- $$depsn =
- export($$depsn)
- }
- fwdsn = $${currentConfig}.testTypeForwards.$${1}
- !isEmpty($$fwdsn) {
- for (fwd, $$fwdsn): \
- qtConfEnsureTestTypeDepsOne($$fwd)
- $$fwdsn =
- export($$fwdsn)
- }
-}
-
-defineTest(qtConfEnsureTestTypeDeps) {
- qtConfEnsureTestTypeDepsOne($$1)
- currentConfig = config.builtins
- qtConfEnsureTestTypeDepsOne($$1)
-}
-
-defineTest(qtRunSingleTest) {
- tpfx = $${currentConfig}.tests.$${1}
- defined($${tpfx}.result, var): \
- return()
-
- type = $$eval($${tpfx}.type)
- call = "qtConfTest_$$type"
- !defined($$call, test): \
- error("Configure test $${1} refers to nonexistent type $$type")
-
- qtConfEnsureTestTypeDeps($$type)
-
- preCall = "qtConfTestPrepare_$$type"
- defined($$preCall, test):!$${preCall}($${tpfx}) {
- $${tpfx}.result = false
- export($${tpfx}.result)
- # don't cache the result; the pre-deps have their own caches.
- return()
- }
-
- # note: we do this only after resolving the dependencies and the
- # preparation (which may resolve libraries), so that caching does
- # not alter the execution order (and thus the output).
- qtConfLoadResult($${tpfx}, $$1, "config test"): \
- return()
-
- qtLogTestIntro($${tpfx}, "executing config test $${1}")
- qtPersistLog()
-
- result = false
- $${call}($${tpfx}): result = true
-
- $${tpfx}.msgs = $$qtPersistedLog()
- export($${tpfx}.msgs)
-
- qtLogTestResult($${tpfx}, $$result)
-
- $${tpfx}.result = $$result
- export($${tpfx}.result)
- qtConfSaveResult($${tpfx}, $$1)
-}
-
-defineTest(qtConfHaveModule) {
- module = $$replace(1, -, _)
- !isEmpty(QT.$${module}.skip):$$eval(QT.$${module}.skip): \
- return(false)
- !isEmpty(QT.$${module}.name): \
- return(true)
- return(false)
-}
-
-defineReplace(qtConfEvaluate) {
- isEmpty(1): return(true)
-
- 1 ~= s/$$escape_expand(\\t)/ /g
- 1 ~= s/$$escape_expand(\\r)//g
- 1 ~= s/$$escape_expand(\\n) */ /g
- expr = $${1}
- expr ~= s/&&/ && /g
- expr ~= s/\\|\\|/ || /g
- expr ~= s/!/ ! /g
- expr ~= s/\\(/ ( /g
- expr ~= s/\\)/ ) /g
- expr ~= s/ *== */==/g
- expr ~= s/ *! = */!=/g
- expr_list = $$eval($$list($$expr))
- return($$qtConfEvaluateSubExpression($${1}, $$expr_list, 0))
-}
-
-defineReplace(qtConfEvaluateSingleExpression) {
- e = $${2}
-
- equals(e, true) {
- result = true
- } else: equals(e, false) {
- result = false
- } else: contains(e, "^[0-9]+$") {
- # numbers
- result = $$e
- } else: contains(e, "^'.*'$") {
- # quoted literals
- result = $$replace(e, "^'(.*)'$", "\\1")
- } else: contains(e, "^tests\\..*") {
- !qt_conf_tests_allowed: \
- error("Expression '$${1}' refers to a test, which is not allowed at this stage of configuring.")
- test = $$section(e, ".", 1, 1)
- var = $$section(e, ".", 2, -1)
- isEmpty(var): \
- var = result
- !contains($${currentConfig}.tests._KEYS_, $$test): \
- error("Unknown test object $${test} in expression '$${1}'.")
- qtRunSingleTest($$test)
- result = $$eval($${currentConfig}.tests.$${test}.$${var})
- } else: contains(e, "^libs\\..*") {
- !qt_conf_tests_allowed: \
- error("Expression '$${1}' refers to a library, which is not allowed at this stage of configuring.")
- lib = $$section(e, ".", 1, 1)
- var = $$section(e, ".", 2, -1)
- isEmpty(var): \
- var = result
- !contains($${currentConfig}.libraries._KEYS_, $$lib): \
- error("Unknown library object $${lib} in expression '$${1}'.")
- qtConfHandleLibrary($$lib)
- !defined($${currentConfig}.libraries.$${lib}.$${var}, var): \
- var = sources.$$eval($${currentConfig}.libraries.$${lib}.source).$$var
- result = $$eval($${currentConfig}.libraries.$${lib}.$${var})
- } else: contains(e, "^features\\..*") {
- feature = $$section(e, ".", 1, 1)
- var = $$section(e, ".", 2, -1)
- isEmpty(var): \
- var = available
- !contains($${currentConfig}.features._KEYS_, $$feature) {
- # this is basically a copy of what qtConfig() in qt_build_config.prf
- # does, but we produce a nicer error message.
- for (module, QMAKE_CONFIG_DEPS) {
- contains(QT.$${module}.enabled_features, $$feature): \
- result = true
- else: contains(QT.$${module}.disabled_features, $$feature): \
- result = false
- else: \
- next()
- !equals(var, available): \
- error("Expression '$$1' is accessing field '$$var' of non-local feature $${feature}.")
- return($$result)
- }
- error("Unknown feature object $${feature} in expression '$${1}'.")
- }
- !qtConfCheckFeature($$feature): \
- error("Expression '$$1' is accessing non-emitted feature $${feature}.")
- result = $$eval($${currentConfig}.features.$${feature}.$${var})
- } else: contains(e, "^config\\..*") {
- var = $$replace(e, "^config\\.", "")
- result = false
- contains(CONFIG, $$var): result = true
- } else: contains(e, "^module\\..*") {
- var = $$replace(e, "^module\\.", "")
- result = false
- qtConfHaveModule($$var): result = true
- } else: contains(e, "^arch\\..*") {
- var = $$replace(e, "^arch\\.", "")
- result = false
- isEmpty(QT_ARCH): \
- qtConfCheckFeature(architecture)
- contains(QT_ARCH, $$var): result = true
- } else: contains(e, "^subarch\\..*") {
- var = $$replace(e, "^subarch\\.", "")
- result = false
- isEmpty(QT_ARCH): \
- qtConfCheckFeature(architecture)
- contains(QT_CPU_FEATURES.$$QT_ARCH, $$var): result = true
- } else: contains(e, "^input\\..*") {
- result = $$eval(config.$$e)
- } else: contains(e, "^var\\..*") {
- var = $$replace(e, "^var\\.", "")
- result = $$eval($$var)
- } else: contains(e, "^call\\..*") {
- call = $$replace(e, "^call\\.", "qtConfFunc_")
- !defined($$call, replace): \
- error("Call $$call referenced in expression '$${1}' does not exist")
- eval(result = \$\$"$$call"())
- } else {
- error("Unrecognized token $$e in expression '$${1}'")
- }
- return($$result)
-}
-
-defineReplace(qtConfEvaluateSubExpression) {
- expr_list = $${2}
- result = true
- negate = false
- runSubExpression = false
- nesting_level = 0
- for (n, $${3}..$$num_add($$size(expr_list), -1)) {
- e = $$member(expr_list, $$n)
- $$runSubExpression {
- runSubExpression = false
- result = $$qtConfEvaluateSubExpression($${1}, $$expr_list, $$n)
- } else: isEqual(e, "(") {
- isEqual(nesting_level, 0): runSubExpression = true
- nesting_level = $$num_add($$nesting_level, 1)
- next()
- } else: isEqual(e, ")") {
- nesting_level = $$num_add($$nesting_level, -1)
- lessThan(nesting_level, 0): break()
- next()
- } else: greaterThan(nesting_level, 0) {
- next()
- } else: isEqual(e, "!") {
- negate = true
- next()
- } else: isEqual(e, "&&") {
- !qtConfIsBoolean($$result): \
- error("Left hand side of && is non-boolean value '$$result' in expression '$${1}'")
- !$$result: return(false)
- } else: isEqual(e, "||") {
- !qtConfIsBoolean($$result): \
- error("Left hand side of || is non-boolean value '$$result' in expression '$${1}'")
- $$result: return(true)
- } else {
- contains(e, ".*==.*") {
- lhs = $$qtConfEvaluateSingleExpression($${1}, $$replace(e, "==.*", ""))
- rhs = $$qtConfEvaluateSingleExpression($${1}, $$replace(e, ".*==", ""))
- result = false
- equals(lhs, $$rhs): result = true
- } else: contains(e, ".*!=.*") {
- lhs = $$qtConfEvaluateSingleExpression($${1}, $$replace(e, "!=.*", ""))
- rhs = $$qtConfEvaluateSingleExpression($${1}, $$replace(e, ".*!=", ""))
- result = false
- !equals(lhs, $$rhs): result = true
- } else {
- result = $$qtConfEvaluateSingleExpression($${1}, $$e)
- }
- }
- $$negate {
- !qtConfIsBoolean($$result): \
- error("Attempting to negate a non-boolean value '$$result' in expression '$${1}'")
- $$result: \
- result = false
- else: \
- result = true
- negate = false
- }
- }
- return($$result)
-}
-
-defineReplace(qtIsFeatureEnabled) {
- enable = $$eval($${currentConfig}.features.$${1}.enable)
- !isEmpty(enable) {
- $$qtConfEvaluate($$enable): \
- return(true)
- } else {
- equals(config.input.$${1}, "yes"): \
- return(true)
- }
-
- return(false)
-}
-
-defineReplace(qtIsFeatureDisabled) {
- disable = $$eval($${currentConfig}.features.$${1}.disable)
- !isEmpty(disable) {
- $$qtConfEvaluate($$disable): \
- return(true)
- } else {
- equals(config.input.$${1}, "no"): \
- return(true)
- }
-
- return(false)
-}
-
-defineReplace(qtConfCheckSingleCondition) {
- result = $$qtConfEvaluate($$2)
-
- !qtConfIsBoolean($$result): \
- error("Evaluation of condition '$$2' yielded non-boolean value '$$result' in feature '$${1}'.")
-
- !$$result {
- $${3} {
- qtConfAddError("Feature '$${1}' was enabled, but the pre-condition '$$2' failed.", log)
- $$result = true
- }
- }
- return($$result)
-}
-
-defineTest(qtConfCheckFeature) {
- fpfx = $${currentConfig}.features.$${1}
-
- available = $$eval($${fpfx}.available)
- !isEmpty(available): return(true)
-
- # skip features that will not get emitted anyway
- emitIf = $$qtConfEvaluate($$eval($${fpfx}.emitIf))
- enabled = $$qtIsFeatureEnabled($$1)
- disabled = $$qtIsFeatureDisabled($$1)
-
- !$$emitIf {
- $$enabled|$$disabled: \
- qtConfAddWarning("Feature $${1} is insignificant in this configuration, ignoring related command line option(s).")
- return(false)
- }
-
- $$disabled {
- result = false
- } else: !$$enabled:!$$qtConfEvaluate($$eval($${fpfx}.autoDetect)) {
- # feature not auto-detected and not explicitly enabled
- result = false
- } else {
- result = true
- for (condition, $$qtConfScalarOrList($${fpfx}.condition)) {
- result = $$qtConfCheckSingleCondition($$1, $$condition, $$enabled)
- !$$result: break()
- }
- }
- $${fpfx}.available = $$result
- export($${fpfx}.available)
-
- for (i, $${fpfx}.output._KEYS_): \
- qtConfProcessOneOutput($${1}, $$i)
-
- return(true)
-}
-
-defineTest(qtConfCheckModuleCondition) {
- QT.$${currentModule}.skip = false
- !$$qtConfEvaluate($$eval($${currentConfig}.condition)): \
- QT.$${currentModule}.skip = true
- export(QT.$${currentModule}.skip)
-
- # ensure qtConfHaveModule() works
- QT.$${currentModule}.name = -
- export(QT.$${currentModule}.name)
-}
-
-
-defineTest(qtConfProcessFeatures) {
- for (feature, $${currentConfig}.features._KEYS_): \
- qtConfCheckFeature($$feature)
-}
-
-#
-# reporting
-#
-
-defineReplace(qtConfPadCols) {
- pad = $$num_add($$str_size($$2), -$$str_size($${1}))
- lessThan(pad, 0): pad = 0
- return("$$1 $$str_member($$2, 0, $$pad) $$3")
-}
-
-defineTest(qtConfReportPadded) {
- qtConfAddReport($$qtConfPadCols($$1, "........................................", $$2))
-}
-
-defineReplace(qtConfCollectFeatures) {
- l =
- for (feature, $$list($${1})) {
- $$eval($${currentConfig}.features.$${feature}.available): \
- l += $$eval($${currentConfig}.features.$${feature}.label)
- }
-
- isEmpty(l): return("<none>")
- return($$join(l, ' '))
-}
-
-defineTest(qtConfReport_featureList) {
- qtConfReportPadded($${1}, $$qtConfCollectFeatures($${2}))
-}
-
-defineReplace(qtConfFindFirstAvailableFeature) {
- for (feature, $$list($${1})) {
- isEmpty($${currentConfig}.features.$${feature}._KEYS_): \
- error("Asking for a report on undefined feature $${2}.")
- $$eval($${currentConfig}.features.$${feature}.available): \
- return($$eval($${currentConfig}.features.$${feature}.label))
- }
-
- return("<none>")
-}
-
-defineTest(qtConfReport_firstAvailableFeature) {
- qtConfReportPadded($${1}, $$qtConfFindFirstAvailableFeature($${2}))
-}
-
-defineTest(qtConfReport_feature) {
- !contains($${currentConfig}.features._KEYS_, $$2): \
- error("Asking for a report on undefined feature $${2}.")
-
- # hide report for not emitted features
- isEmpty($${currentConfig}.features.$${2}.available): \
- return()
-
- $$eval($${currentConfig}.features.$${2}.available) {
- result = "yes"
- !isEmpty(3): result = "$${3}"
- } else {
- result = "no"
- !isEmpty(4): result = "$${4}"
- }
-
- text = $$eval($${currentConfig}.features.$${2}.label)
-
- qtConfReportPadded($${1}$$text, $$result)
-}
-
-defineTest(qtConfReport_note) {
- qtConfAddNote($${1})
-}
-
-defineTest(qtConfReport_warning) {
- qtConfAddWarning($${1})
-}
-
-defineTest(qtConfReport_error) {
- qtConfAddError($${1}, log)
-}
-
-defineTest(qtConfReport_fatal) {
- qtConfFatalError($${1})
-}
-
-defineTest(qtConfCreateReportRecurse) {
- equals(2, false) {
- indent = ""
- recurse = false
- } else {
- indent = $${2}
- recurse = true
- }
-
- keys = $$eval($${1}._KEYS_)
- for (n, keys) {
- entry = $${1}.$$n
- subKeys = $$eval($${entry}._KEYS_)
- contains(subKeys, condition) {
- r = true
- for (condition, $$qtConfScalarOrList($${entry}.condition)) {
- r = $$qtConfEvaluate($$condition)
- !$$r: break()
- }
- !qtConfIsBoolean($$r): \
- error("Evaluation of condition '$$condition' in report entry $${entry} yielded non-boolean value '$$r'.")
- !$$r: next()
- }
- contains(subKeys, "section") {
- !$$recurse: \
- error("Report type 'section' is not allowed in '$$1'.")
- section = $$eval($${entry}.section)
- qtConfAddReport("$$indent$$section:")
- qtConfCreateReportRecurse("$${entry}.entries", "$$indent ")
- } else: !isEmpty($${entry}) {
- feature = $$eval($${entry})
- qtConfReport_feature($$indent, $$feature)
- } else {
- text = $$eval($${entry}.message)
- isEmpty($${entry}.type): \
- error("Report entry $${entry} doesn't define a type.")
- r = "qtConfReport_$$eval($${entry}.type)"
- !defined($$r, test): \
- error("Undefined report type $$eval($${entry}.type) used in report entry $${entry}.")
- args = $$eval($${entry}.args)
- $${r}($$indent$${text}, $$args)
- }
- }
-}
-
-defineTest(qtConfProcessEarlyChecks) {
- qtConfCreateReportRecurse($${currentConfig}.earlyReport, false)
-}
-
-defineTest(qtConfCreateReport) {
- qtConfCreateReportRecurse($${currentConfig}.report, false)
-}
-
-defineTest(qtConfCreateSummary) {
- qtConfCreateReportRecurse($${currentConfig}.summary, "")
-}
-
-defineTest(qtConfPrintReport) {
- blocks = \
- "$$join(QT_CONFIGURE_REPORT, $$escape_expand(\\n))" \
- "$$join(QT_CONFIGURE_NOTES, $$escape_expand(\\n\\n))" \
- "$$join(QT_CONFIGURE_WARNINGS, $$escape_expand(\\n\\n))"
-
- !isEmpty(QT_CONFIGURE_ERRORS) {
- blocks += "$$join(QT_CONFIGURE_ERRORS, $$escape_expand(\\n\\n))"
- mention_config_log:!$$QMAKE_CONFIG_VERBOSE: \
- blocks += "Check config.log for details."
- }
- blocks = "$$join(blocks, $$escape_expand(\\n\\n))"
- logn($$blocks)
- !isEmpty(QT_CONFIGURE_ERRORS):!equals(config.input.continue, yes): \
- error()
- write_file($$OUT_PWD/config.summary, blocks)|error()
-}
-
-defineTest(qtConfCheckErrors) {
- !isEmpty(QT_CONFIGURE_ERRORS):!equals(config.input.continue, yes): \
- qtConfPrintReport()
-}
-
-#
-# output generation
-#
-
-defineTest(qtConfOutput_libraryPaths) {
- qtLog("Global lib dirs: [$$val_escape(EXTRA_LIBDIR)] [$$val_escape(QMAKE_DEFAULT_LIBDIRS)]")
- qtLog("Global inc dirs: [$$val_escape(EXTRA_INCLUDEPATH)] [$$val_escape(QMAKE_DEFAULT_INCDIRS)]")
-}
-
-# qtConfOutputVar(modifier, output, name, value)
-defineTest(qtConfOutputVar) {
- modifier = $$1
- output = $$2
- name = $$3
- value = $$val_escape(4)
-
- defined($${currentConfig}.output.$${output}.assign.$${name}, var): \
- error("Trying to overwrite assigned variable '$$name' in '$$output' using modifier '$$modifier'.")
-
- equals(modifier, assign) {
- !isEmpty($${currentConfig}.output.$${output}.append.$${name})|!isEmpty($${currentConfig}.output.$${output}.remove.$${name}): \
- error("Trying to assign variable '$$name' in '$$output', which has already appended or removed parts.")
- $${currentConfig}.output.$${output}.assign.$${name} = $$value
- } else: equals(modifier, append) {
- contains($${currentConfig}.output.$${output}.remove.$${name}, $$value): \
- error("Trying to append removed '$$value' to variable '$$name' in '$$output'.")
- $${currentConfig}.output.$${output}.append.$${name} += $$value
- } else: equals(modifier, remove) {
- contains($${currentConfig}.output.$${output}.append.$${name}, $$value): \
- error("Trying to remove appended '$$value' to variable '$$name' in '$$output'.")
- $${currentConfig}.output.$${output}.remove.$${name} += $$value
- } else {
- error("Invalid modifier '$$modifier' passed to qtConfOutputVar.")
- }
- $${currentConfig}.output.$${output}.$${modifier}._KEYS_ *= $${name}
- export($${currentConfig}.output.$${output}.$${modifier}.$${name})
- export($${currentConfig}.output.$${output}.$${modifier}._KEYS_)
-}
-
-# qtConfExtendVar(output, name, value)
-defineTest(qtConfExtendVar) {
- output = $$1
- name = $$2
- value = $$val_escape(3)
-
- !defined($${currentConfig}.output.$${output}.assign.$${name}, var): \
- error("Trying to extend undefined variable '$$name' in '$$output'.")
-
- $${currentConfig}.output.$${output}.assign.$${name} += $$value
- export($${currentConfig}.output.$${output}.assign.$${name})
-}
-
-defineTest(qtConfOutputVarHelper) {
- !isEmpty($${2}.public):$$eval($${2}.public) {
- output = "publicPro"
- } else {
- output = "privatePro"
- }
-
- negative = $$eval($${2}.negative)
- isEmpty(negative): negative = false
- equals(3, $$negative): return()
-
- name = $$eval($${2}.name)
- isEmpty(name): \
- error("Output type 'var$$title($$1)' used in feature '$$eval($${2}.feature)' without a 'name' entry.")
-
- value = $$qtConfEvaluate($$eval($${2}.value))
- !isEmpty($${2}.eval):$$qtConfEvaluate($$eval($${2}.eval)): \
- eval(value = $$value)
- qtConfOutputVar($$1, $$output, $$name, $$value)
- equals(output, "publicPro"):!isEmpty($${currentConfig}.module): \
- qtConfExtendVar($$output, "QT.$${currentModule}.exports", $$name)
-}
-
-defineTest(qtConfOutput_varAssign) {
- qtConfOutputVarHelper(assign, $$1, $$2)
-}
-
-defineTest(qtConfOutput_varAppend) {
- qtConfOutputVarHelper(append, $$1, $$2)
-}
-
-defineTest(qtConfOutput_varRemove) {
- qtConfOutputVarHelper(remove, $$1, $$2)
-}
-
-defineTest(qtConfOutputConfigVar) {
- pro = $$3
- var = $$4
- modular = $$5
-
- negative = $$eval($${1}.negative)
- isEmpty(negative): negative = false
- equals(2, $$negative): return()
-
- val = $$eval($${1}.name)
- isEmpty(val) {
- val = $$eval($${1}.feature)
- $$negative: val = no-$$val
- }
-
- isEmpty($${currentConfig}.module)|!$$modular: \
- qtConfOutputVar(append, $$pro, $$var, $$val)
- else: \
- qtConfExtendVar($$pro, "QT.$${currentModule}.$$var", $$val)
-}
-
-defineTest(qtConfOutput_publicQtConfig) {
- qtConfOutputConfigVar($$1, $$2, "publicPro", "QT_CONFIG", true)
-}
-
-defineTest(qtConfOutput_publicConfig) {
- !isEmpty($${currentConfig}.module): \
- error("Cannot use output type 'publicConfig' in module-local feature '$$eval($${1}.feature)'.")
- qtConfOutputConfigVar($$1, $$2, "publicPro", "CONFIG", false)
-}
-
-defineTest(qtConfOutput_privateConfig) {
- qtConfOutputConfigVar($$1, $$2, "privatePro", "CONFIG", false)
-}
-
-defineTest(qtConfOutputSetDefine) {
- $${currentConfig}.output.$${1}.$${2} = $${3}
- $${currentConfig}.output.$${1}._KEYS_ *= $${2}
- export($${currentConfig}.output.$${1}.$${2})
- export($${currentConfig}.output.$${1}._KEYS_)
-}
-
-defineTest(qtConfOutput_define) {
- output = publicHeader
- define = $$eval($${1}.name)
- value = $$qtConfEvaluate($$eval($${1}.value))
- isEmpty(define): \
- error("Output type 'define' used in feature '$$eval($${1}.feature)' without a 'name' entry.")
-
- negative = $$eval($${1}.negative)
- isEmpty(negative): negative = false
- equals(2, $$negative): return()
-
- qtConfOutputSetDefine($$output, $$define, $$value)
-}
-
-defineTest(qtConfOutput_feature) {
- name = "$$eval($${1}.name)"
- isEmpty(name): \
- name = $$eval($${1}.feature)
-
- $${2} {
- isEmpty($${currentConfig}.module): \
- qtConfOutputVar(append, "publicPro", "QT_CONFIG", $$name)
- else: \
- qtConfExtendVar("publicPro", "QT.$${currentModule}.QT_CONFIG", $$name)
- } else {
- f = $$upper($$replace(name, -, _))
- qtConfOutputSetDefine("publicHeader", "QT_NO_$$f")
- }
-}
-
-defineTest(qtConfSetModuleName) {
- currentModule = $$eval($${currentConfig}.module)
- isEmpty(currentModule): \
- currentModule = global
- export(currentModule)
-}
-
-defineTest(qtConfSetupModuleOutputs) {
- qtConfOutputVar(assign, "publicPro", "QT.$${currentModule}.enabled_features", )
- qtConfOutputVar(assign, "publicPro", "QT.$${currentModule}.disabled_features", )
- qtConfOutputVar(assign, "privatePro", "QT.$${currentModule}_private.enabled_features", )
- qtConfOutputVar(assign, "privatePro", "QT.$${currentModule}_private.disabled_features", )
- !isEmpty($${currentConfig}.module) {
- qtConfOutputVar(assign, "publicPro", "QT.$${currentModule}.QT_CONFIG", )
- qtConfOutputVar(assign, "publicPro", "QT.$${currentModule}.exports", )
- qtConfOutputVar(assign, "privatePro", "QT.$${currentModule}_private.libraries", )
- }
-}
-
-defineTest(qtConfOutput_publicFeature) {
- name = "$$eval($${1}.name)"
- isEmpty(name): \
- name = $$eval($${1}.feature)
- feature = $$replace(name, [-+.], _)
-
- $${2} {
- qtConfExtendVar("publicPro", "QT.$${currentModule}.enabled_features", $$name)
- QT.$${currentModule}.enabled_features += $$name
- export(QT.$${currentModule}.enabled_features)
- qtConfOutputSetDefine("publicHeader", "QT_FEATURE_$$feature", 1)
- } else {
- qtConfExtendVar("publicPro", "QT.$${currentModule}.disabled_features", $$name)
- QT.$${currentModule}.disabled_features += $$name
- export(QT.$${currentModule}.disabled_features)
- qtConfOutputSetDefine("publicHeader", "QT_FEATURE_$$feature", -1)
- }
-}
-
-defineTest(qtConfOutput_privateFeature) {
- name = "$$eval($${1}.name)"
- isEmpty(name): \
- name = $$eval($${1}.feature)
- feature = $$replace(name, [-+.], _)
-
- $${2} {
- qtConfExtendVar("privatePro", "QT.$${currentModule}_private.enabled_features", $$name)
- QT.$${currentModule}_private.enabled_features += $$name
- export(QT.$${currentModule}_private.enabled_features)
- qtConfOutputSetDefine("privateHeader", "QT_FEATURE_$$feature", 1)
- } else {
- qtConfExtendVar("privatePro", "QT.$${currentModule}_private.disabled_features", $$name)
- QT.$${currentModule}_private.disabled_features += $$name
- export(QT.$${currentModule}_private.disabled_features)
- qtConfOutputSetDefine("privateHeader", "QT_FEATURE_$$feature", -1)
- }
-}
-
-defineTest(qtConfProcessOneOutput) {
- feature = $${1}
- fpfx = $${currentConfig}.features.$${feature}
- opfx = $${fpfx}.output.$${2}
-
- call = $$eval($${opfx}.type)
- isEmpty(call) {
- # output is just a string, not an object
- call = $$eval($$opfx)
- }
- !defined("qtConfOutput_$$call", test): \
- error("Undefined type '$$call' in output '$$2' of feature '$$feature'.")
-
- !$$qtConfEvaluate($$eval($${opfx}.condition)): \
- return()
-
- $${opfx}.feature = $$feature
- qtConfOutput_$${call}($$opfx, $$eval($${fpfx}.available))
-}
-
-defineTest(qtConfProcessOutput) {
- !contains($${currentConfig}._KEYS_, "features"): \
- return()
-
- basedir = $$shadowed($$eval($${currentConfig}.dir))
- module = $$eval($${currentConfig}.module)
-
- # write it to the output files
- !defined($${currentConfig}.files._KEYS_, var) {
- # set defaults that should work for most Qt modules
- isEmpty(module): \
- error("Neither module nor files section specified in configuration file.")
-
- $${currentConfig}.files._KEYS_ = publicPro privatePro publicHeader privateHeader
- $${currentConfig}.files.publicPro = qt$${module}-config.pri
- $${currentConfig}.files.privatePro = qt$${module}-config.pri # sic!
- $${currentConfig}.files.publicHeader = qt$${module}-config.h
- $${currentConfig}.files.privateHeader = qt$${module}-config_p.h
- }
-
- for (type, $${currentConfig}.files._KEYS_) {
- contains(type, ".*Pro") {
- for (k, $${currentConfig}.output.$${type}.assign._KEYS_): \
- $${currentConfig}.output.$$type += "$$k = $$eval($${currentConfig}.output.$${type}.assign.$$k)"
- for (k, $${currentConfig}.output.$${type}.remove._KEYS_): \
- $${currentConfig}.output.$$type += "$$k -= $$eval($${currentConfig}.output.$${type}.remove.$$k)"
- for (k, $${currentConfig}.output.$${type}.append._KEYS_): \
- $${currentConfig}.output.$$type += "$$k += $$eval($${currentConfig}.output.$${type}.append.$$k)"
- } else: contains(type, ".*Header") {
- for (define, $${currentConfig}.output.$${type}._KEYS_) {
- value = $$eval($${currentConfig}.output.$${type}.$${define})
- $${currentConfig}.output.$$type += "$${LITERAL_HASH}define $$define $$value"
- }
- }
-
- content = $$eval($${currentConfig}.output.$${type})
-
- !isEmpty(module): \
- call = qtConfOutputPostProcess_$${module}_$${type}
- else: \
- call = qtConfOutputPostProcess_$${type}
- defined($$call, replace): \
- eval(content = \$\$"$$call"(\$\$content))
-
- file = $$eval($${currentConfig}.files.$${type})
- fileCont.$$file += $$content
- fileCont._KEYS_ *= $$file
- }
-
- for (file, fileCont._KEYS_): \
- write_file($$basedir/$$file, fileCont.$$file)|error()
-}
-
-#
-# tie it all together
-#
-
-!isEmpty(_QMAKE_SUPER_CACHE_):!equals(OUT_PWD, $$dirname(_QMAKE_SUPER_CACHE_)) {
- # sub-repo within a top-level build; no need to configure anything.
- !isEmpty(QMAKE_EXTRA_ARGS) {
- # sub-projects don't get the extra args passed down automatically,
- # so we can use their presence to detect misguided attempts to
- # configure the repositories separately.
- # caveat: a plain qmake call is indistinguishable from a recursion
- # (by design), so we cannot detect this case.
- error("You cannot configure $$TARGET separately within a top-level build.")
- }
- return()
-}
-
-config.$${TARGET}.dir = $$_PRO_FILE_PWD_
-cfgs = $$TARGET
-!isEmpty(_QMAKE_SUPER_CACHE_) {
- for (s, SUBDIRS) {
- config.$${s}.dir = $$_PRO_FILE_PWD_/$${s}
- cfgs += $$s
- }
-}
-configsToProcess =
-for (c, cfgs) {
- s = $$eval(config.$${c}.dir)
- exists($$s/configure.json): \
- configsToProcess += $$c
-}
-isEmpty(configsToProcess) {
- !isEmpty(QMAKE_EXTRA_ARGS): \
- error("This module does not accept configure command line arguments.")
- return()
-}
-
-load(configure_base)
-
-QMAKE_POST_CONFIGURE =
-config.builtins.dir = $$PWD/data
-configsToProcess = builtins $$configsToProcess
-allConfigs =
-for(ever) {
- isEmpty(configsToProcess): \
- break()
-
- thisConfig = $$take_first(configsToProcess)
- currentConfig = config.$$thisConfig
- thisDir = $$eval($${currentConfig}.dir)
- jsonFile = $$thisDir/configure.json
- priFile = $$thisDir/configure.pri
-
- # load configuration data
- configure_data = $$cat($$jsonFile, blob)
- !parseJson(configure_data, $$currentConfig): \
- error("Invalid or non-existent file $${jsonFile}.")
- exists($$priFile): \
- !include($$priFile): error()
-
- # only configs which contain more than just subconfigs are saved for later.
- $${currentConfig}._KEYS_ -= subconfigs
- !isEmpty($${currentConfig}._KEYS_) {
- allConfigs += $$currentConfig
- contains($${currentConfig}._KEYS_, libraries) {
- qtConfSetupLibraries()
- # this ensures that references in QMAKE_LIBRARY_DEPS are unique.
- qtConfSetModuleName()
- ex = $$eval(config.modules.$${currentModule})
- !isEmpty(ex): \
- error("Module $$currentModule is claimed by both $$currentConfig and $${ex}.")
- config.modules.$${currentModule} = $$currentConfig
- }
- }
-
- # prepend all subconfigs to files to keep a depth first search order
- subconfigs =
- for(n, $${currentConfig}.subconfigs._KEYS_) {
- subconfig = $$eval($${currentConfig}.subconfigs.$${n})
- name = $${thisConfig}_$$basename(subconfig)
- ex = $$eval(config.$${name}.dir)
- !isEmpty(ex): \
- error("Basename clash between $$thisDir/$$subconfig and $${ex}.")
- config.$${name}.dir = $$thisDir/$$subconfig
- subconfigs += $$name
- }
- configsToProcess = $$subconfigs $$configsToProcess
-}
-# 'builtins' is used for command line parsing and test type dependency
-# injection, but its features must not be processed regularly.
-allModuleConfigs = $$member(allConfigs, 1, -1)
-
-QMAKE_SAVED_ARGS = $$QMAKE_EXTRA_ARGS
-QMAKE_REDO_CONFIG = false
-qtConfParseCommandLine()
-qtConfCheckErrors()
-
-!isEmpty(config.input.list-features) {
- all_ft =
- for (currentConfig, allModuleConfigs) {
- for (k, $${currentConfig}.features._KEYS_) {
- pp = $$eval($${currentConfig}.features.$${k}.purpose)
- !isEmpty(pp) {
- pfx = $$eval($${currentConfig}.features.$${k}.section)
- !isEmpty(pfx): pfx = "$$pfx: "
- all_ft += $$qtConfPadCols($$k, ".......................", \
- $$pfx$$section(pp, $$escape_expand(\\n), 0, 0))
- }
- }
- }
- all_ft = $$sorted(all_ft)
- logn()
- for (ft, all_ft): \
- logn($$ft)
- error()
-}
-
-!isEmpty(config.input.list-libraries) {
- logn()
- for (currentConfig, allModuleConfigs) {
- !isEmpty($${currentConfig}.exports._KEYS_) {
- !isEmpty($${currentConfig}.module): \
- logn($$eval($${currentConfig}.module):)
- else: \
- logn($$section(currentConfig, ., -1):)
- all_xp =
- for (xport, $${currentConfig}.exports._KEYS_) {
- libs = $$eval($${currentConfig}.exports.$$xport)
- isEqual($${currentConfig}.libraries.$$first(libs).export, "") { # not isEmpty()!
- !isEmpty(config.input.verbose): \
- all_xp += "$$xport!"
- } else {
- out = "$$xport"
- !isEmpty(config.input.verbose):!isEqual(xport, $$libs): \
- out += "($$libs)"
- all_xp += "$$out"
- }
- }
- all_xp = $$sorted(all_xp)
- all_xp ~= s,^([^!]*)!$,(\\1),g
- for (xp, all_xp): \
- logn(" $$xp")
- }
- }
- error()
-}
-
-QMAKE_CONFIG_VERBOSE = $$eval(config.input.verbose)
-isEmpty(QMAKE_CONFIG_VERBOSE): \
- QMAKE_CONFIG_VERBOSE = false
-QMAKE_CONFIG_LOG = $$OUT_PWD/config.log
-write_file($$QMAKE_CONFIG_LOG, "")
-qtLog("Command line: $$qtSystemQuote($$QMAKE_SAVED_ARGS)")
-$$QMAKE_REDO_CONFIG: \
- qtLog("config.opt: $$qtSystemQuote($$QMAKE_EXTRA_REDO_ARGS)")
-
-for (currentConfig, allModuleConfigs) {
- qtConfSetModuleName()
- qtConfSetupModuleOutputs()
- # do early checks, mainly to validate the command line
- qtConfProcessEarlyChecks()
-}
-qtConfCheckErrors()
-
-QMAKE_CONFIG_CACHE = $$OUT_PWD/config.cache
-QMAKE_CONFIG_CACHE_USE = $$eval(config.input.cache_use)
-cache_recheck = $$eval(config.input.cache_recheck)
-equals(cache_recheck, yes) {
- QMAKE_CONFIG_CACHE_USE = positive
- cache_recheck =
-}
-isEmpty(QMAKE_CONFIG_CACHE_USE): \
- QMAKE_CONFIG_CACHE_USE = all
-!equals(QMAKE_CONFIG_CACHE_USE, none) {
- include($$QMAKE_CONFIG_CACHE, , true)
- # this crudely determines when to discard the cache. this also catches the case
- # of no cache being there in the first place.
- !equals(cache.platform, $$[QMAKE_SPEC])|!equals(cache.xplatform, $$[QMAKE_XSPEC]) {
- QMAKE_CONFIG_CACHE_USE = none
- } else: !isEmpty(cache_recheck) {
- for (cr, $$list($$split(cache_recheck, ","))) {
- !isEmpty(cache.$${cr}._KEYS_) {
- cache.$${cr}._KEYS_ =
- } else {
- qtConfAddWarning("Attempting to discard non-cached result '$$cr'.")
- }
- }
- }
-}
-equals(QMAKE_CONFIG_CACHE_USE, none) {
- cont = \
- "cache.platform = $$[QMAKE_SPEC]" \
- "cache.xplatform = $$[QMAKE_XSPEC]"
- write_file($$QMAKE_CONFIG_CACHE, cont)
-}
-
-CONFIG += qt_conf_tests_allowed
-logn()
-logn("Running configuration tests...")
-
-for (currentConfig, allModuleConfigs) {
- tdir = $$eval($${currentConfig}.testDir)
- isEmpty(tdir): tdir = config.tests
- QMAKE_CONFIG_TESTS_DIR = $$absolute_path($$tdir, $$eval($${currentConfig}.dir))
-
- qtConfSetModuleName()
-
- qtConfSetupTestTypeDeps()
-
- # correctly setup dependencies
- QMAKE_CONFIG_DEPS = global global_private
- QMAKE_LIBRARY_DEPS = $$eval(config.modules.global)
- !isEmpty($${currentConfig}.module) {
- for (d, $${currentConfig}.depends._KEYS_) {
- dep = $$replace($${currentConfig}.depends.$$d, -private$, _private)
- gdep = $$replace(dep, _private$, )
- dep *= $$gdep
- QMAKE_CONFIG_DEPS += $$dep
- !isEqual(gdep, $$dep): \ # libraries are in the private module.
- QMAKE_LIBRARY_DEPS += $$eval(config.modules.$$gdep)
- }
- }
-
- qtConfCheckModuleCondition()
-
- qtConfHaveModule($$currentModule) {
- # process all features
- qtConfProcessFeatures()
- } else {
- qtConfOutputVar(assign, "privatePro", "QT.$${currentModule}.skip", "true")
- }
-
- # generate files and reports
- qtConfProcessOutput()
- qtConfHaveModule($$currentModule) {
- qtConfCreateReport()
- qtConfCreateSummary()
- } else {
- QT_CONFIGURE_SKIPPED_MODULES += " $$currentModule"
- }
-}
-
-!isEmpty(QT_CONFIGURE_SKIPPED_MODULES): \
- qtConfAddNote("The following modules are not being compiled in this configuration:" $$QT_CONFIGURE_SKIPPED_MODULES)
-
-logn("Done running configuration tests.")
-logn()
-
-!$$QMAKE_REDO_CONFIG {
- write_file($$OUT_PWD/config.opt, QMAKE_SAVED_ARGS)|error()
-}
-
-# these come from the pri files loaded above.
-for (p, QMAKE_POST_CONFIGURE): \
- eval($$p)
-
-logn("Configure summary:")
-logn()
-qtConfPrintReport()
-
-load(qt_prefix_build_check)
-
-# final notes for the user
-logn()
-logn("Qt is now configured for building. Just run '$$QMAKE_MAKE_NAME'.")
-pfx = $$[QT_INSTALL_PREFIX]
-qtIsPrefixBuild($$pfx) {
- logn("Once everything is built, you must run '$$QMAKE_MAKE_NAME install'.")
- logn("Qt will be installed into '$$system_path($$pfx)'.")
-} else {
- logn("Once everything is built, Qt is installed.")
- logn("You should NOT run '$$QMAKE_MAKE_NAME install'.")
- logn("Note that this build cannot be deployed to other machines or devices.")
-}
-logn()
-logn("Prior to reconfiguration, make sure you remove any leftovers from")
-logn("the previous build.")
-logn()