summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2016-08-25 15:45:44 +0200
committerLars Knoll <lars.knoll@qt.io>2016-09-10 14:04:01 +0000
commit60e5a1c8effd4099f7b1414107b5cbb67c266210 (patch)
tree6fbd85b8329c9fe67af1de55bbb10e6c327717d5
parent137e690ac76b6db59592f9a8f0b55e445d6f5ab1 (diff)
Modularize the new configure system (infrastructure part)
This change implements the required infrastructure to modularize the new configuration system. This requires a hierarchy of configuration files, both for handling multiple repositories and for individual modules inside the same repository. When configuring, they all need to get loaded first, as command line processing needs to know about all possible command line options. When the command line has been processed, the individual configuration files need to get processed one after the other and independently from each other. Configure is now automatically invoked when building the a project tree's "root" project; this works with both modular and top-level builds of Qt (the latter with an according change in the super repo). As an immediate consequence, the -skip option moves to the super repo with a different implementation, as configuration is now done after the repo list is determined. The option belongs there anyway. This commit also adds an optional testDir entry to the json file. Like this, we can still have all configure tests in qtbase/config.tests and the configuration file in, e.g., corelib can reference those. The files section can now be left out as long as a 'module' entry is present, specifying the module name. The names of the files to generate can then be deduced from that name. We still need to be able to specify names directly for the global configuration files. qtConfig() now also queries features which are module-specific. As it is sometimes necessary to query the configuration of modules which should not be actually linked (and cannot in the case of subdirs projects), the new variable QT_FOR_CONFIG which allows specifying configuration-only dependencies is introduced. Done-with: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> Change-Id: Id1b518a3aa34044748b87fb8fac14d79653f6b18 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
-rwxr-xr-xbin/syncqt.pl2
-rwxr-xr-xconfigure32
-rw-r--r--configure.json7
-rw-r--r--configure.pri96
-rw-r--r--mkspecs/features/configure.prf2
-rw-r--r--mkspecs/features/configure_base.prf2
-rw-r--r--mkspecs/features/qt_build_config.prf23
-rw-r--r--mkspecs/features/qt_configure.prf498
-rw-r--r--mkspecs/features/qt_functions.prf16
-rw-r--r--mkspecs/features/qt_module_headers.prf10
-rw-r--r--mkspecs/features/qt_module_pris.prf43
-rw-r--r--mkspecs/features/qt_parts.prf3
-rw-r--r--qtbase.pro1
-rw-r--r--tools/configure/configureapp.cpp22
-rw-r--r--tools/configure/configureapp.h1
-rw-r--r--tools/configure/main.cpp4
16 files changed, 486 insertions, 276 deletions
diff --git a/bin/syncqt.pl b/bin/syncqt.pl
index 43a033d8e1..b531dce374 100755
--- a/bin/syncqt.pl
+++ b/bin/syncqt.pl
@@ -935,6 +935,7 @@ foreach my $lib (@modules_to_sync) {
if (opendir DIR, $subdir) {
foreach my $t (sort { $b cmp $a } readdir(DIR)) {
next if ($t =~ /\.pri$/);
+ next if ($t =~ /^qt[a-z0-9]+-config(_p)?\.h$/);
my $file = "$subdir/$t";
if(-d $file) {
push @subdirs, $file unless($t eq "." || $t eq "..");
@@ -985,6 +986,7 @@ foreach my $lib (@modules_to_sync) {
#calc files and "copy" them
foreach my $subdir (@subdirs) {
my @headers = findFiles($subdir, "^[-a-z0-9_]*\\.h\$" , 0);
+ @headers = grep(!/^qt[a-z0-9]+-config(_p)?\.h$/, @headers);
if (defined $inject_headers{$subdir}) {
foreach my $if (@{$inject_headers{$subdir}}) {
@headers = grep(!/^\Q$if\E$/, @headers); #in case we configure'd previously
diff --git a/configure b/configure
index 85392bac92..81bf483634 100755
--- a/configure
+++ b/configure
@@ -1911,31 +1911,15 @@ done
set +f
IFS=$SAVED_IFS
-# redirect qmake's output to a dummy Makefile
-$CFG_QMAKE_PATH -o Makefile.cfg -qtconf "$QTCONFFILE" $relpath/configure.pri -- "$@" || exit 101
-rm Makefile.cfg
-
-#-------------------------------------------------------------------------------
-# give feedback on configuration
-#-------------------------------------------------------------------------------
-
-if [ -n "$PLATFORM_NOTES" ]; then
- echo
- echo "Platform notes:"
- echo "$PLATFORM_NOTES"
-else
- echo
-fi
-
#-------------------------------------------------------------------------------
-# build makefiles based on the configuration
+# configure and build top-level makefile
#-------------------------------------------------------------------------------
if [ -n "$CFG_TOPLEVEL" ]; then
cd ..
fi
-"$CFG_QMAKE_PATH" -qtconf "$QTCONFFILE" "$relpathMangled" || exit
+"$CFG_QMAKE_PATH" -qtconf "$QTCONFFILE" "$relpathMangled" -- "$@" || exit
#-------------------------------------------------------------------------------
# finally save the executed command to another script
@@ -1955,6 +1939,18 @@ if [ $CFG_REDO = no ]; then
chmod +x config.status
fi
+#-------------------------------------------------------------------------------
+# final notes for the user
+#-------------------------------------------------------------------------------
+
+if [ -n "$PLATFORM_NOTES" ]; then
+ echo
+ echo "Platform notes:"
+ echo "$PLATFORM_NOTES"
+else
+ echo
+fi
+
if [ -n "$PREFIX_COMPLAINTS" ]; then
echo
echo "$PREFIX_COMPLAINTS"
diff --git a/configure.json b/configure.json
index 830a19f13e..46f94573cf 100644
--- a/configure.json
+++ b/configure.json
@@ -162,7 +162,6 @@
"separate-debug-info": { "type": "boolean", "name": "separate_debug_info" },
"shared": "boolean",
"silent": "void",
- "skip": "addString",
"slog2": "boolean",
"sm": { "type": "boolean", "name": "sessionmanager" },
"sql-db2": "boolean",
@@ -857,9 +856,6 @@
"type": "compile",
"test": "unix/reduce_relocs"
},
- "skip_modules": {
- "type": "skipModules"
- },
"build_parts": {
"type": "buildParts"
},
@@ -2096,9 +2092,6 @@
"condition": "libs.host_dbus",
"output": [ { "type": "varAppend", "name": "QT_HOST_CFLAGS_DBUS", "value": "libs.host_dbus.cflags", "eval": "true" } ]
},
- "skip_modules": {
- "output": [ { "type": "varAssign", "name": "QT_SKIP_MODULES", "value": "tests.skip_modules.value" } ]
- },
"build_parts": {
"output": [ { "type": "varAppend", "name": "QT_BUILD_PARTS", "value": "tests.build_parts.value" } ]
},
diff --git a/configure.pri b/configure.pri
index 7447ec4428..03f8323f0d 100644
--- a/configure.pri
+++ b/configure.pri
@@ -195,34 +195,10 @@ defineTest(qtConfTest_detectPkgConfig) {
}
defineTest(qtConfTest_neon) {
- contains(config.tests.architecture.subarch, "neon"): return(true)
+ contains($${currentConfig}.tests.architecture.subarch, "neon"): return(true)
return(false)
}
-defineTest(qtConfTest_skipModules) {
- $${1}.cache = -
- export($${1}.cache)
-
- skip =
- uikit {
- skip += qtdoc qtmacextras qtserialport qtwebkit qtwebkit-examples
- !ios: skip += qtscript
- }
-
- for (m, config.input.skip) {
- # normalize the command line input
- m ~= s/^(qt)?/qt/
- !exists($$_PRO_FILE_PWD_/../$$m) {
- qtConfAddError("-skip command line argument called with non-existent module '$$m'.")
- return(false)
- }
- skip += $$m
- }
- $${1}.value = $$unique(skip)
- export($${1}.value)
- return(true)
-}
-
defineTest(qtConfTest_buildParts) {
parts = $$config.input.make
isEmpty(parts) {
@@ -491,10 +467,10 @@ defineTest(qtConfOutput_architecture) {
"QT_ARCH = $$arch"
}
- config.output.publicPro += $$publicPro
- export(config.output.publicPro)
- config.output.privatePro += $$privatePro
- export(config.output.privatePro)
+ $${currentConfig}.output.publicPro += $$publicPro
+ export($${currentConfig}.output.publicPro)
+ $${currentConfig}.output.privatePro += $$privatePro
+ export($${currentConfig}.output.privatePro)
# setup QT_ARCH variable used by qtConfEvaluate
QT_ARCH = $$arch
@@ -522,15 +498,15 @@ defineTest(qtConfOutput_qreal) {
defineTest(qtConfOutput_pkgConfig) {
!$${2}: return()
- PKG_CONFIG = $$eval(config.tests.pkg-config.pkgConfig)
+ PKG_CONFIG = $$eval($${currentConfig}.tests.pkg-config.pkgConfig)
export(PKG_CONFIG)
# this method also exports PKG_CONFIG_(LIB|SYSROOT)DIR, so that tests using pkgConfig will work correctly
- PKG_CONFIG_SYSROOT_DIR = $$eval(config.tests.pkg-config.pkgConfigSysrootDir)
+ 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(config.tests.pkg-config.pkgConfigLibdir)
+ 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)
@@ -560,20 +536,20 @@ defineTest(qtConfOutput_debugAndRelease) {
defineTest(qtConfOutput_compilerVersion) {
!$${2}: return()
- name = $$upper($$config.tests.compiler.compilerId)
- version = $$config.tests.compiler.compilerVersion
+ name = $$upper($$eval($${currentConfig}.tests.compiler.compilerId))
+ version = $$eval($${currentConfig}.tests.compiler.compilerVersion)
major = $$section(version, '.', 0, 0)
minor = $$section(version, '.', 1, 1)
patch = $$section(version, '.', 2, 2)
isEmpty(minor): minor = 0
isEmpty(patch): patch = 0
- config.output.publicPro += \
+ $${currentConfig}.output.publicPro += \
"QT_$${name}_MAJOR_VERSION = $$major" \
"QT_$${name}_MINOR_VERSION = $$minor" \
"QT_$${name}_PATCH_VERSION = $$patch"
- export(config.output.publicPro)
+ export($${currentConfig}.output.publicPro)
}
# should go away when qfeatures.txt is ported
@@ -581,17 +557,17 @@ defineTest(qtConfOutput_extraFeatures) {
isEmpty(config.input.extra_features): return()
# write to qconfig.pri
- config.output.publicPro += "$${LITERAL_HASH}ifndef QT_BOOTSTRAPPED"
+ $${currentConfig}.output.publicPro += "$${LITERAL_HASH}ifndef QT_BOOTSTRAPPED"
for (f, config.input.extra_features) {
feature = $$replace(f, "^no-", "")
FEATURE = $$upper($$replace(feature, -, _))
contains(f, "^no-.*") {
- config.output.publicPro += \
+ $${currentConfig}.output.publicPro += \
"$${LITERAL_HASH}ifndef QT_NO_$$FEATURE" \
"$${LITERAL_HASH}define QT_NO_$$FEATURE" \
"$${LITERAL_HASH}endif"
} else {
- config.output.publicPro += \
+ $${currentConfig}.output.publicPro += \
"$${LITERAL_HASH}if defined(QT_$$FEATURE) && defined(QT_NO_$$FEATURE)" \
"$${LITERAL_HASH}undef QT_$$FEATURE" \
"$${LITERAL_HASH}elif !defined(QT_$$FEATURE) && !defined(QT_NO_$$FEATURE)" \
@@ -599,8 +575,8 @@ defineTest(qtConfOutput_extraFeatures) {
"$${LITERAL_HASH}endif"
}
}
- config.output.publicPro += "$${LITERAL_HASH}endif"
- export(config.output.publicPro)
+ $${currentConfig}.output.publicPro += "$${LITERAL_HASH}endif"
+ export($${currentConfig}.output.publicPro)
# write to qmodule.pri
disabled_features =
@@ -649,8 +625,8 @@ defineTest(qtConfOutput_compilerFlags) {
output += "EXTRA_FRAMEWORKPATH += $$val_escape(config.input.fpaths)"
}
- config.output.privatePro += $$output
- export(config.output.privatePro)
+ $${currentConfig}.output.privatePro += $$output
+ export($${currentConfig}.output.privatePro)
}
defineTest(qtConfOutput_gccSysroot) {
@@ -670,21 +646,21 @@ defineTest(qtConfOutput_gccSysroot) {
" QMAKE_CXXFLAGS += --sysroot=\$\$[QT_SYSROOT]" \
" QMAKE_LFLAGS += --sysroot=\$\$[QT_SYSROOT]" \
"}"
- config.output.publicPro += $$output
- export(config.output.publicPro)
+ $${currentConfig}.output.publicPro += $$output
+ export($${currentConfig}.output.publicPro)
}
defineTest(qtConfOutput_qmakeArgs) {
!$${2}: return()
- config.output.privatePro = "!host_build {"
+ $${currentConfig}.output.privatePro = "!host_build {"
for (a, config.input.qmakeArgs) {
- config.output.privatePro += " $$a"
+ $${currentConfig}.output.privatePro += " $$a"
EXTRA_QMAKE_ARGS += $$system_quote($$a)
}
- config.output.privatePro += "}"
+ $${currentConfig}.output.privatePro += "}"
export(EXTRA_QMAKE_ARGS)
- export(config.output.privatePro)
+ export($${currentConfig}.output.privatePro)
}
defineTest(qtConfOutputPostProcess_publicPro) {
@@ -706,8 +682,8 @@ defineTest(qtConfOutputPostProcess_publicPro) {
"QT_RELEASE_DATE = $$config.input.qt_release_date"
}
- config.output.publicPro += $$output
- export(config.output.publicPro)
+ $${currentConfig}.output.publicPro += $$output
+ export($${currentConfig}.output.publicPro)
}
defineTest(qtConfOutputPostProcess_publicHeader) {
@@ -729,8 +705,8 @@ defineTest(qtConfOutputPostProcess_publicHeader) {
!isEmpty(config.input.qt_libinfix): \
output += "$${LITERAL_HASH}define QT_LIBINFIX \"$$eval(config.input.qt_libinfix)\""
- config.output.publicHeader += $$output
- export(config.output.publicHeader)
+ $${currentConfig}.output.publicHeader += $$output
+ export($${currentConfig}.output.publicHeader)
}
@@ -748,7 +724,7 @@ defineTest(qtConfReport_buildTypeAndConfig) {
qtConfAddReport("Building for: $$qtConfEvaluate('tests.architecture.arch')")
}
qtConfAddReport()
- qtConfAddReport("Configuration: $$config.output.privatePro.append.CONFIG $$config.output.publicPro.append.QT_CONFIG")
+ qtConfAddReport("Configuration: $$eval($${currentConfig}.output.privatePro.append.CONFIG) $$eval($${currentConfig}.output.publicPro.append.QT_CONFIG)")
qtConfAddReport()
}
@@ -775,10 +751,10 @@ defineTest(qtConfReport_buildMode) {
# 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)"
-# load and process input from configure
-exists("$$OUT_PWD/config.tests/configure.cfg") {
- include("$$OUT_PWD/config.tests/configure.cfg")
-}
-
-load(qt_configure)
+# load and process input from configure.sh/.exe
+include($$shadowed($$PWD)/config.tests/configure.cfg)
diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf
index bd53e31a04..f275e3ac06 100644
--- a/mkspecs/features/configure.prf
+++ b/mkspecs/features/configure.prf
@@ -1,5 +1,7 @@
load(configure_base)
+isEmpty(QMAKE_CONFIG_TESTS_DIR): QMAKE_CONFIG_TESTS_DIR = $$_PRO_FILE_PWD_/config.tests
+
# Try to build the test project in $$QMAKE_CONFIG_TESTS_DIR/$$1
# ($$_PRO_FILE_PWD_/config.tests/$$1 by default).
#
diff --git a/mkspecs/features/configure_base.prf b/mkspecs/features/configure_base.prf
index 08edba4b1c..dc630a3528 100644
--- a/mkspecs/features/configure_base.prf
+++ b/mkspecs/features/configure_base.prf
@@ -43,8 +43,6 @@ defineTest(qtRunLoggedCommand) {
return(true)
}
-isEmpty(QMAKE_CONFIG_TESTS_DIR): QMAKE_CONFIG_TESTS_DIR = $$_PRO_FILE_PWD_/config.tests
-
# Ensure that a cache is present. If none was found on startup, this will create
# one in the build directory of the project which loads this feature.
cache()
diff --git a/mkspecs/features/qt_build_config.prf b/mkspecs/features/qt_build_config.prf
index e0e8ef9f51..95e63ecae0 100644
--- a/mkspecs/features/qt_build_config.prf
+++ b/mkspecs/features/qt_build_config.prf
@@ -95,3 +95,26 @@ defineTest(qtNomakeTools) {
export($${d}.CONFIG)
}
}
+
+# This overloads the same function from qt_functions.prf.
+# This is not in qt_module.prf, as that gets loaded too late.
+defineTest(qtConfig) {
+ modules = $$QT $$QT_PRIVATE $$QT_FOR_PRIVATE $$QT_FOR_CONFIG
+ modules ~= s,-private$,_private,g
+ modules = $$resolve_depends(modules, "QT.", ".depends")
+ isEmpty(MODULE): \
+ MODULE = $$section($$list($$basename(_PRO_FILE_)), ., 0, 0)
+ exists($$OUT_PWD/qt$${MODULE}-config.pri) {
+ include($$OUT_PWD/qt$${MODULE}-config.pri)
+ modules += $${MODULE} $${MODULE}_private
+ }
+ modules += global global_private
+ modules = $$reverse(modules)
+ for (module, modules) {
+ contains(QT.$${module}.enabled_features, $$1): \
+ return(true)
+ contains(QT.$${module}.disabled_features, $$1): \
+ return(false)
+ }
+ error("Could not find feature $${1}.")
+}
diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf
index 2067829a10..79fede1525 100644
--- a/mkspecs/features/qt_configure.prf
+++ b/mkspecs/features/qt_configure.prf
@@ -1,8 +1,3 @@
-CONFIG -= qt debug_and_release
-load(configure_base)
-
-QMAKE_CONFIG_CACHE = $$dirname(_QMAKE_CACHE_)/config.cache
-QMAKE_CONFIG_CACHE_USE = all
QT_CONFIGURE_REPORT =
QT_CONFIGURE_NOTES =
@@ -36,8 +31,8 @@ defineTest(qtConfAddError) {
defineTest(qtConfCommandlineSetInput) {
arg = $${1}
val = $${2}
- !isEmpty(config.commandline.options.$${arg}.name): \
- arg = $$eval(config.commandline.options.$${arg}.name)
+ !isEmpty($${currentConfig}.commandline.options.$${arg}.name): \
+ arg = $$eval($${currentConfig}.commandline.options.$${arg}.name)
config.input.$$arg = $$val
export(config.input.$$arg)
@@ -74,7 +69,7 @@ defineTest(qtConfCommandline_void) {
return()
}
- val = $$eval(config.commandline.options.$${opt}.value)
+ val = $$eval($${currentConfig}.commandline.options.$${opt}.value)
isEmpty(val): val = yes
qtConfCommandlineSetInput($$opt, $$val)
@@ -86,11 +81,11 @@ defineTest(qtConfCommandline_enum) {
isEmpty(val): val = yes
# validate and map value
- mapped = $$eval(config.commandline.options.$${opt}.values.$${val})
+ mapped = $$eval($${currentConfig}.commandline.options.$${opt}.values.$${val})
isEmpty(mapped) {
# just a list of allowed values
- for (i, config.commandline.options.$${opt}.values._KEYS_) {
- equals(config.commandline.options.$${opt}.values.$${i}, $$val) {
+ for (i, $${currentConfig}.commandline.options.$${opt}.values._KEYS_) {
+ equals($${currentConfig}.commandline.options.$${opt}.values.$${i}, $$val) {
mapped = $$val
break()
}
@@ -108,12 +103,12 @@ defineTest(qtConfValidateValue) {
opt = $${1}
val = $${2}
- validValues = $$eval(config.commandline.options.$${opt}.values._KEYS_)
+ validValues = $$eval($${currentConfig}.commandline.options.$${opt}.values._KEYS_)
isEmpty(validValues): \
return(true)
for (i, validValues) {
- equals(config.commandline.options.$${opt}.values.$${i}, $$val): \
+ equals($${currentConfig}.commandline.options.$${opt}.values.$${i}, $$val): \
return(true)
}
@@ -169,20 +164,24 @@ defineTest(qtConfCommandline_addString) {
!qtConfValidateValue($$opt, $$val): \
return()
- !isEmpty(config.commandline.options.$${opt}.name): \
- opt = $$eval(config.commandline.options.$${opt}.name)
+ !isEmpty($${currentConfig}.commandline.options.$${opt}.name): \
+ opt = $$eval($${currentConfig}.commandline.options.$${opt}.name)
config.input.$$opt += $$val
export(config.input.$$opt)
}
defineTest(qtConfParseCommandLine) {
- custom = $$config.commandline.custom
- customCall =
- !isEmpty(custom) {
- customCall = qtConfCommandline_$$custom
- !defined($$customCall, test): \
- error("Custom command line callback '$$custom' is undefined.")
+ 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) {
@@ -212,15 +211,24 @@ defineTest(qtConfParseCommandLine) {
next()
}
- !isEmpty(customCall) {
- $${customCall}($$c): \
- next()
+ didCustomCall = false
+ for (customCall, customCalls) {
+ $${customCall}($$c) {
+ didCustomCall = true
+ break()
+ }
}
+ $$didCustomCall: \
+ next()
contains(c, "([A-Z_]+)=(.*)") {
opt = $$replace(c, "^([A-Z_]+)=(.*)", "\\1")
val = $$replace(c, "^([A-Z_]+)=(.*)", "\\2")
- var = $$eval(config.commandline.assignments.$${opt})
+ for (cc, allConfigs) {
+ var = $$eval($${cc}.commandline.assignments.$${opt})
+ !isEmpty(var): \
+ break()
+ }
isEmpty(var) {
qtConfAddError("Assigning unknown variable '$$opt' on command line.")
return()
@@ -254,20 +262,26 @@ defineTest(qtConfParseCommandLine) {
return()
}
- type = $$eval(config.commandline.options.$${opt})
- isEmpty(type): \
- type = $$eval(config.commandline.options.$${opt}.type)
- isEmpty(type) {
- # no match in the regular options, try matching the prefixes
- for (p, config.commandline.prefix._KEYS_) {
- e = "^-$${p}(.*)"
- contains(c, $$e) {
- opt = $$eval(config.commandline.prefix.$${p})
- val = $$replace(c, $$e, "\\1")
- type = "addString"
- break()
+ 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")
+ type = "addString"
+ break()
+ }
}
}
+ !isEmpty(type) {
+ currentConfig = $$cc
+ break()
+ }
}
# handle builtin [-no]-feature-xxx
isEmpty(type):contains(opt, "feature-(.*)") {
@@ -368,8 +382,8 @@ defineReplace(qtConfPrepareArgs) {
}
defineTest(qtConfSetupLibraries) {
- for (l, config.libraries._KEYS_) {
- lpfx = config.libraries.$${l}
+ 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 = $$l
@@ -396,8 +410,8 @@ defineTest(qtConfSetupLibraries) {
}
# reverse mapping for assignments on command line.
- for (a, config.commandline.assignments._KEYS_) {
- apfx = config.commandline.assignments.$${a}
+ for (a, $${currentConfig}.commandline.assignments._KEYS_) {
+ apfx = $${currentConfig}.commandline.assignments.$${a}
ra = config.commandline.rev_assignments.$$eval($$apfx)
$$ra = $$a
export($$ra)
@@ -570,10 +584,12 @@ defineTest(qtConfExportLibrary) {
qtConfOutputVar(assign, $$output, QMAKE_$${NAME}_VERSION_MINOR, $$member(version, 1))
qtConfOutputVar(assign, $$output, QMAKE_$${NAME}_VERSION_PATCH, $$member(version, 2))
}
+ !isEmpty($${currentConfig}.module): \
+ qtConfExtendVar($$output, "QT.$${currentModule}_private.libraries", $$2)
}
defineTest(qtConfHandleLibrary) {
- lpfx = config.libraries.$$1
+ lpfx = $${currentConfig}.libraries.$$1
defined($${lpfx}.result, var): return()
qtConfEnsureTestTypeDeps("library")
@@ -647,10 +663,10 @@ defineTest(qtConfTest_library) {
defineTest(qtConfTestPrepare_compile) {
for (u, $$list($$eval($${1}.use))) {
- !contains(config.libraries._KEYS_, $$u): \
+ !contains($${currentConfig}.libraries._KEYS_, $$u): \
error("Test $$1 tries to use undeclared library '$$u'")
qtConfHandleLibrary($$u)
- lpfx = config.libraries.$${u}
+ lpfx = $${currentConfig}.libraries.$${u}
isEmpty($${lpfx}.source): \
return(false)
$${1}.literal_args += $$qtConfLibraryArgs($${lpfx}.sources.$$eval($${lpfx}.source))
@@ -820,12 +836,12 @@ defineTest(qtConfIsBoolean) {
}
defineTest(qtConfSetupTestTypeDeps) {
- for (tt, config.testTypeDependencies._KEYS_) {
+ for (tt, $${currentConfig}.testTypeDependencies._KEYS_) {
!defined(qtConfTest_$${tt}, test): \
error("Declaring dependency for undefined test type '$$tt'.")
- for (f, config.testTypeDependencies.$${tt}._KEYS_) {
- feature = $$eval(config.testTypeDependencies.$${tt}.$${f})
- isEmpty(config.features.$${feature}._KEYS_): \
+ 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'.")
}
}
@@ -834,31 +850,31 @@ defineTest(qtConfSetupTestTypeDeps) {
# 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, config.testTypeAliases._KEYS_) {
+ for (tt, $${currentConfig}.testTypeAliases._KEYS_) {
!defined(qtConfTest_$${tt}, test): \
error("Aliasing undefined test type '$$tt'.")
- for (tta, config.testTypeAliases.$${tt}._KEYS_) {
- type = $$eval(config.testTypeAliases.$${tt}.$${tta})
+ for (tta, $${currentConfig}.testTypeAliases.$${tt}._KEYS_) {
+ type = $$eval($${currentConfig}.testTypeAliases.$${tt}.$${tta})
!defined(qtConfTest_$${type}, test): \
error("Aliasing '$$tt' to undefined test type '$$type'.")
- config.testTypeForwards.$${type} += $$tt
- export(config.testTypeForwards.$${type})
+ $${currentConfig}.testTypeForwards.$${type} += $$tt
+ export($${currentConfig}.testTypeForwards.$${type})
}
}
}
defineTest(qtConfEnsureTestTypeDeps) {
- depsn = config.testTypeDependencies.$${1}._KEYS_
+ depsn = $${currentConfig}.testTypeDependencies.$${1}._KEYS_
!isEmpty($$depsn) {
for (dep, $$depsn) {
- feature = $$eval(config.testTypeDependencies.$${1}.$${dep})
+ feature = $$eval($${currentConfig}.testTypeDependencies.$${1}.$${dep})
!qtConfCheckFeature($$feature): \
error("Test type '$$1' depends on non-emitted feature $${feature}.")
}
$$depsn =
export($$depsn)
}
- fwdsn = config.testTypeForwards.$${1}
+ fwdsn = $${currentConfig}.testTypeForwards.$${1}
!isEmpty($$fwdsn) {
for (fwd, $$fwdsn): \
qtConfEnsureTestTypeDeps($$fwd)
@@ -868,7 +884,7 @@ defineTest(qtConfEnsureTestTypeDeps) {
}
defineTest(qtRunSingleTest) {
- tpfx = config.tests.$${1}
+ tpfx = $${currentConfig}.tests.$${1}
defined($${tpfx}.result, var): \
return()
@@ -945,10 +961,10 @@ defineReplace(qtConfEvaluateSingleExpression) {
var = $$section(e, ".", 2, -1)
isEmpty(var): \
var = result
- !contains(config.tests._KEYS_, $$test): \
+ !contains($${currentConfig}.tests._KEYS_, $$test): \
error("Unknown test object $${test} in expression '$${1}'.")
qtRunSingleTest($$test)
- result = $$eval(config.tests.$${test}.$${var})
+ 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.")
@@ -956,22 +972,36 @@ defineReplace(qtConfEvaluateSingleExpression) {
var = $$section(e, ".", 2, -1)
isEmpty(var): \
var = result
- !contains(config.libraries._KEYS_, $$lib): \
+ !contains($${currentConfig}.libraries._KEYS_, $$lib): \
error("Unknown library object $${lib} in expression '$${1}'.")
qtConfHandleLibrary($$lib)
- !defined(config.libraries.$${lib}.$${var}, var): \
- var = sources.$$eval(config.libraries.$${lib}.$${source}).$$var
- result = $$eval(config.libraries.$${lib}.$${var})
+ !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(config.features._KEYS_, $$feature): \
+ !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(config.features.$${feature}.$${var})
+ result = $$eval($${currentConfig}.features.$${feature}.$${var})
} else: contains(e, "^config\..*") {
var = $$replace(e, "^config\.", "")
result = false
@@ -1059,7 +1089,7 @@ defineReplace(qtConfEvaluateSubExpression) {
}
defineReplace(qtIsFeatureEnabled) {
- enable = $$eval(config.features.$${1}.enable)
+ enable = $$eval($${currentConfig}.features.$${1}.enable)
!isEmpty(enable) {
$$qtConfEvaluate($$enable): \
return(true)
@@ -1072,7 +1102,7 @@ defineReplace(qtIsFeatureEnabled) {
}
defineReplace(qtIsFeatureDisabled) {
- disable = $$eval(config.features.$${1}.disable)
+ disable = $$eval($${currentConfig}.features.$${1}.disable)
!isEmpty(disable) {
$$qtConfEvaluate($$disable): \
return(true)
@@ -1100,7 +1130,7 @@ defineReplace(qtConfCheckSingleCondition) {
}
defineTest(qtConfCheckFeature) {
- fpfx = config.features.$${1}
+ fpfx = $${currentConfig}.features.$${1}
available = $$eval($${fpfx}.available)
!isEmpty(available): return(true)
@@ -1138,7 +1168,7 @@ defineTest(qtConfCheckFeature) {
$${fpfx}.available = $$result
export($${fpfx}.available)
- for (i, config.features.$${feature}.output._KEYS_): \
+ for (i, $${currentConfig}.features.$${feature}.output._KEYS_): \
qtConfProcessOneOutput($$feature, $$i)
return(true)
@@ -1146,7 +1176,7 @@ defineTest(qtConfCheckFeature) {
defineTest(qtConfProcessFeatures) {
- for (feature, config.features._KEYS_): \
+ for (feature, $${currentConfig}.features._KEYS_): \
qtConfCheckFeature($$feature)
}
@@ -1167,8 +1197,8 @@ defineTest(qtConfReportPadded) {
defineReplace(qtConfCollectFeatures) {
l =
for (feature, $$list($${1})) {
- $$eval(config.features.$${feature}.available): \
- l += $$eval(config.features.$${feature}.description)
+ $$eval($${currentConfig}.features.$${feature}.available): \
+ l += $$eval($${currentConfig}.features.$${feature}.description)
}
isEmpty(l): return("<none>")
@@ -1181,10 +1211,10 @@ defineTest(qtConfReport_featureList) {
defineReplace(qtConfFindFirstAvailableFeature) {
for (feature, $$list($${1})) {
- isEmpty(config.features.$${feature}._KEYS_): \
+ isEmpty($${currentConfig}.features.$${feature}._KEYS_): \
error("Asking for a report on undefined feature $${2}.")
- $$eval(config.features.$${feature}.available): \
- return($$eval(config.features.$${feature}.description))
+ $$eval($${currentConfig}.features.$${feature}.available): \
+ return($$eval($${currentConfig}.features.$${feature}.description))
}
return("<none>")
@@ -1195,14 +1225,14 @@ defineTest(qtConfReport_firstAvailableFeature) {
}
defineTest(qtConfReport_feature) {
- !contains(config.features._KEYS_, $$2): \
+ !contains($${currentConfig}.features._KEYS_, $$2): \
error("Asking for a report on undefined feature $${2}.")
# hide report for not emitted features
- isEmpty(config.features.$${2}.available): \
+ isEmpty($${currentConfig}.features.$${2}.available): \
return()
- $$eval(config.features.$${2}.available) {
+ $$eval($${currentConfig}.features.$${2}.available) {
result = "yes"
!isEmpty(3): result = "$${3}"
} else {
@@ -1210,7 +1240,7 @@ defineTest(qtConfReport_feature) {
!isEmpty(4): result = "$${4}"
}
- text = $$eval(config.features.$${2}.description)
+ text = $$eval($${currentConfig}.features.$${2}.description)
qtConfReportPadded($${1}$$text, $$result)
}
@@ -1270,17 +1300,15 @@ defineTest(qtConfCreateReportRecurse) {
}
defineTest(qtConfProcessEarlyChecks) {
- qtConfCreateReportRecurse(config.earlyReport, false)
- qtConfCheckErrors()
+ qtConfCreateReportRecurse($${currentConfig}.earlyReport, false)
}
-
defineTest(qtConfCreateReport) {
- qtConfCreateReportRecurse(config.report, false)
+ qtConfCreateReportRecurse($${currentConfig}.report, false)
}
defineTest(qtConfCreateSummary) {
- qtConfCreateReportRecurse(config.summary, "")
+ qtConfCreateReportRecurse($${currentConfig}.summary, "")
}
defineTest(qtConfPrintReport) {
@@ -1322,15 +1350,6 @@ defineTest(qtConfCheckErrors) {
# output generation
#
-defineReplace(qtConfOutputSelectProFile) {
- !isEmpty($${1}.public) {
- $$eval($${1}.public): \
- return(publicPro)
- }
- return(privatePro)
-}
-
-
# qtConfOutputVar(modifier, output, name, value)
defineTest(qtConfOutputVar) {
modifier = $$1
@@ -1338,35 +1357,53 @@ defineTest(qtConfOutputVar) {
name = $$3
value = $$val_escape(4)
- !isEmpty(config.output.$${output}.assign.$${name}): \
+ defined($${currentConfig}.output.$${output}.assign.$${name}, var): \
error("Trying to overwrite assigned variable '$$name' in '$$output' using modifier '$$modifier'.")
equals(modifier, assign) {
- !isEmpty(config.output.$${output}.append.$${name})|!isEmpty(config.output.$${output}.remove.$${name}): \
+ !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.")
- config.output.$${output}.assign.$${name} = $$value
+ $${currentConfig}.output.$${output}.assign.$${name} = $$value
} else: equals(modifier, append) {
- contains(config.output.$${output}.remove.$${name}, $$value): \
+ contains($${currentConfig}.output.$${output}.remove.$${name}, $$value): \
error("Trying to append removed '$$value' to variable '$$name' in '$$output'.")
- config.output.$${output}.append.$${name} += $$value
+ $${currentConfig}.output.$${output}.append.$${name} += $$value
} else: equals(modifier, remove) {
- contains(config.output.$${output}.append.$${name}, $$value): \
+ contains($${currentConfig}.output.$${output}.append.$${name}, $$value): \
error("Trying to remove appended '$$value' to variable '$$name' in '$$output'.")
- config.output.$${output}.remove.$${name} += $$value
+ $${currentConfig}.output.$${output}.remove.$${name} += $$value
} else {
error("Invalid modifier '$$modifier' passed to qtConfOutputVar.")
}
- config.output.$${output}.$${modifier}._KEYS_ *= $${name}
- export(config.output.$${output}.$${modifier}.$${name})
- export(config.output.$${output}.$${modifier}._KEYS_)
+ $${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()
- output = $$qtConfOutputSelectProFile($${2})
name = $$eval($${2}.name)
isEmpty(name): \
error("Output type 'var$$title($$1)' used in feature '$$eval($${2}.feature)' without a 'name' entry.")
@@ -1375,6 +1412,8 @@ defineTest(qtConfOutputVarHelper) {
!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) {
@@ -1392,6 +1431,8 @@ defineTest(qtConfOutput_varRemove) {
defineTest(qtConfOutputConfigVar) {
pro = $$3
var = $$4
+ modular = $$5
+
negative = $$eval($${1}.negative)
isEmpty(negative): negative = false
equals(2, $$negative): return()
@@ -1402,26 +1443,31 @@ defineTest(qtConfOutputConfigVar) {
$$negative: val = no-$$val
}
- qtConfOutputVar(append, $$pro, $$var, $$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")
+ qtConfOutputConfigVar($$1, $$2, "publicPro", "QT_CONFIG", true)
}
defineTest(qtConfOutput_publicConfig) {
- qtConfOutputConfigVar($$1, $$2, "publicPro", "CONFIG")
+ !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")
+ qtConfOutputConfigVar($$1, $$2, "privatePro", "CONFIG", false)
}
defineTest(qtConfOutputSetDefine) {
- config.output.$${1}.$${2} = $${3}
- config.output.$${1}._KEYS_ *= $${2}
- export(config.output.$${1}.$${2})
- export(config.output.$${1}._KEYS_)
+ $${currentConfig}.output.$${1}.$${2} = $${3}
+ $${currentConfig}.output.$${1}._KEYS_ *= $${2}
+ export($${currentConfig}.output.$${1}.$${2})
+ export($${currentConfig}.output.$${1}._KEYS_)
}
defineTest(qtConfOutput_define) {
@@ -1444,13 +1490,35 @@ defineTest(qtConfOutput_feature) {
name = $$eval($${1}.feature)
$${2} {
- qtConfOutputVar(append, "publicPro", "QT_CONFIG", $$name)
+ 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): \
@@ -1458,10 +1526,14 @@ defineTest(qtConfOutput_publicFeature) {
feature = $$replace(name, [-+.], _)
$${2} {
- qtConfOutputVar(append, "publicPro", "QT.global.enabled_features", $$name)
+ qtConfExtendVar("publicPro", "QT.$${currentModule}.enabled_features", $$name)
+ QT.$${currentModule}.enabled_features += $$name
+ export(QT.$${currentModule}.enabled_features)
qtConfOutputSetDefine("publicHeader", "QT_FEATURE_$$feature", 1)
} else {
- qtConfOutputVar(append, "publicPro", "QT.global.disabled_features", $$name)
+ qtConfExtendVar("publicPro", "QT.$${currentModule}.disabled_features", $$name)
+ QT.$${currentModule}.disabled_features += $$name
+ export(QT.$${currentModule}.disabled_features)
qtConfOutputSetDefine("publicHeader", "QT_FEATURE_$$feature", -1)
}
}
@@ -1476,17 +1548,21 @@ defineTest(qtConfOutput_privateFeature) {
feature = $$replace(name, [-+.], _)
$${2} {
- qtConfOutputVar(append, "privatePro", "QT.global.enabled_features", $$name)
+ 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 {
- qtConfOutputVar(append, "privatePro", "QT.global.disabled_features", $$name)
+ 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 = config.features.$${feature}
+ fpfx = $${currentConfig}.features.$${feature}
opfx = $${fpfx}.output.$${2}
condition = $$eval($${opfx}.condition)
@@ -1512,64 +1588,167 @@ defineTest(qtConfProcessOneOutput) {
}
defineTest(qtConfProcessOutput) {
+ !contains($${currentConfig}._KEYS_, "features"): \
+ return()
+
+ basedir = $$shadowed($$eval($${currentConfig}.dir))
+ module = $$eval($${currentConfig}.module)
+
# write it to the output files
- for (type, config.files._KEYS_) {
- file = $$OUT_PWD/$$eval(config.files.$${type})
+ isEmpty($${currentConfig}.files._KEYS_) {
+ # 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, config.output.$${type}.assign._KEYS_): \
- config.output.$$type += "$$k = $$eval(config.output.$${type}.assign.$$k)"
- for (k, config.output.$${type}.remove._KEYS_): \
- config.output.$$type += "$$k -= $$eval(config.output.$${type}.remove.$$k)"
- for (k, config.output.$${type}.append._KEYS_): \
- config.output.$$type += "$$k += $$eval(config.output.$${type}.append.$$k)"
+ 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 {
- for (define, config.output.$${type}._KEYS_) {
- value = $$eval(config.output.$${type}.$${define})
- config.output.$$type += "$${LITERAL_HASH}define $$define $$value"
+ for (define, $${currentConfig}.output.$${type}._KEYS_) {
+ value = $$eval($${currentConfig}.output.$${type}.$${define})
+ $${currentConfig}.output.$$type += "$${LITERAL_HASH}define $$define $$value"
}
}
- defined(qtConfOutputPostProcess_$${type}, test): \
- qtConfOutputPostProcess_$${type}()
- write_file($$file, config.output.$${type})|error()
+ ppScope =
+ !isEmpty(module): ppScope = $${module}_
+ defined(qtConfOutputPostProcess_$${ppScope}$${type}, test): \
+ qtConfOutputPostProcess_$${ppScope}$${type}()
+
+ file = $$eval($${currentConfig}.files.$${type})
+ fileCont.$$file += $$eval($${currentConfig}.output.$${type})
+ fileCont._KEYS_ *= $$file
}
+
+ for (file, fileCont._KEYS_): \
+ write_file($$basedir/$$file, fileCont.$$file)|error()
}
#
# tie it all together
#
-defineTest(qtConfigure) {
+cfgs =
+isEmpty(_QMAKE_SUPER_CACHE_)|equals(OUT_PWD, $$dirname(_QMAKE_SUPER_CACHE_)) {
+ c = $$basename(_PRO_FILE_PWD_)
+ config.$${c}.dir = $$_PRO_FILE_PWD_
+ cfgs += $$c
+ !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): \
+ return()
+
+load(configure_base)
+
+QMAKE_POST_CONFIGURE =
+allConfigs =
+for(ever) {
+ isEmpty(configsToProcess): \
+ break()
+
+ currentConfig = config.$$take_first(configsToProcess)
+ thisDir = $$eval($${currentConfig}.dir)
+ jsonFile = $$thisDir/configure.json
+ priFile = $$thisDir/configure.pri
+
+ allConfigs += $$currentConfig
+
# load configuration data
- configure_data = $$cat($${1}, blob)
- !parseJson(configure_data, config): \
- error("Invalid or non-existent file $${1}.")
+ configure_data = $$cat($$jsonFile, blob)
+ !parseJson(configure_data, $$currentConfig): \
+ error("Invalid or non-existent file $${jsonFile}.")
+ exists($$priFile): \
+ !include($$priFile): error()
+
+ # prepend all subconfigs to files to keep a depth first search order
+ subconfigs =
+ for(n, $${currentConfig}.subconfigs._KEYS_) {
+ subconfig = $$eval($${currentConfig}.subconfigs.$${n})
+ name = $$basename(subconfig)
+ config.$${name}.dir = $$thisDir/$$subconfig
+ subconfigs += $$name
+ }
+ configsToProcess = $$subconfigs $$configsToProcess
+}
+for (currentConfig, allConfigs): \
qtConfSetupLibraries()
- qtConfSetupTestTypeDeps()
- qtConfParseCommandLine()
+!isEmpty(_QMAKE_SUPER_CACHE_): \
+ QMAKE_CONFIG_CACHE = $$dirname(_QMAKE_SUPER_CACHE_)/config.cache
+else: \
+ QMAKE_CONFIG_CACHE = $$dirname(_QMAKE_CACHE_)/config.cache
+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
- }
- equals(QMAKE_CONFIG_CACHE_USE, none) {
- cont = \
- "cache.platform = $$[QMAKE_SPEC]" \
- "cache.xplatform = $$[QMAKE_XSPEC]"
- write_file($$QMAKE_CONFIG_CACHE, cont)
- }
+qtConfParseCommandLine()
+
+!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
+}
+equals(QMAKE_CONFIG_CACHE_USE, none) {
+ cont = \
+ "cache.platform = $$[QMAKE_SPEC]" \
+ "cache.xplatform = $$[QMAKE_XSPEC]"
+ write_file($$QMAKE_CONFIG_CACHE, cont)
+}
+for (currentConfig, allConfigs) {
+ qtConfSetModuleName()
+ qtConfSetupModuleOutputs()
# do early checks, mainly to validate the command line
qtConfProcessEarlyChecks()
+}
+qtConfCheckErrors()
- CONFIG += qt_conf_tests_allowed
- logn()
- logn("Running configuration tests...")
+CONFIG += qt_conf_tests_allowed
+logn()
+logn("Running configuration tests...")
+
+for (currentConfig, allConfigs) {
+ 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
+ !isEmpty($${currentConfig}.module) {
+ for (d, $${currentConfig}.depends._KEYS_) {
+ dep = $$replace($${currentConfig}.depends.$$d, -private$, _private)
+ dep *= $$replace(dep, _private$, )
+ QMAKE_CONFIG_DEPS += $$dep
+ }
+ }
# process all features
qtConfProcessFeatures()
@@ -1578,14 +1757,15 @@ defineTest(qtConfigure) {
qtConfProcessOutput()
qtConfCreateReport()
qtConfCreateSummary()
-
- logn("Done running configuration tests.")
- logn()
}
-qtConfigure($$_PRO_FILE_PWD_/configure.json)
+# these come from the pri files loaded above.
+for (p, QMAKE_POST_CONFIGURE): \
+ eval($$p)
-logn("Configure summary:")
+logn("Done running configuration tests.")
logn()
+logn("Configure summary:")
+logn()
qtConfPrintReport()
diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf
index 735ece45f2..efbf2fab1d 100644
--- a/mkspecs/features/qt_functions.prf
+++ b/mkspecs/features/qt_functions.prf
@@ -300,10 +300,16 @@ defineTest(prepareRecursiveTarget) {
}
defineTest(qtConfig) {
- contains(QT.global.enabled_features, $$1): \
- return(true)
- contains(QT.global.disabled_features, $$1): \
- return(false)
-
+ modules = $$QT $$QT_PRIVATE $$QT_FOR_CONFIG
+ modules ~= s,-private$,_private,g
+ modules = $$resolve_depends(modules, "QT.", ".depends")
+ modules += global global_private
+ modules = $$reverse(modules)
+ for (module, modules) {
+ contains(QT.$${module}.enabled_features, $$1): \
+ return(true)
+ contains(QT.$${module}.disabled_features, $$1): \
+ return(false)
+ }
error("Could not find feature $${1}.")
}
diff --git a/mkspecs/features/qt_module_headers.prf b/mkspecs/features/qt_module_headers.prf
index 9e0b21903f..229760068e 100644
--- a/mkspecs/features/qt_module_headers.prf
+++ b/mkspecs/features/qt_module_headers.prf
@@ -106,6 +106,16 @@ alien_syncqt: return()
MODULE_INC_OUTDIR = $$MODULE_BASE_OUTDIR/include/$$MODULE_INCNAME
+exists($$OUT_PWD/qt$${MODULE}-config.h) {
+ fwd_rel = $$relative_path($$OUT_PWD, $$MODULE_INC_OUTDIR)
+ SYNCQT.INJECTIONS += \
+ $$fwd_rel/qt$${MODULE}-config.h:qt$${MODULE}-config.h \
+ $$fwd_rel/qt$${MODULE}-config_p.h:$$MODULE_VERSION/$$MODULE_INCNAME/private/qt$${MODULE}-config_p.h
+ inst_rel = $$relative_path($$OUT_PWD, $$_PRO_FILE_PWD_)
+ SYNCQT.HEADER_FILES += $$inst_rel/qt$${MODULE}-config.h
+ SYNCQT.PRIVATE_HEADER_FILES += $$inst_rel/qt$${MODULE}-config_p.h
+}
+
for (injection, SYNCQT.INJECTIONS) {
injects = $$split(injection, :)
dst_hdr = $$absolute_path($$member(injects, 0), $$MODULE_INC_OUTDIR)
diff --git a/mkspecs/features/qt_module_pris.prf b/mkspecs/features/qt_module_pris.prf
index b67a56c7d5..9542a362d0 100644
--- a/mkspecs/features/qt_module_pris.prf
+++ b/mkspecs/features/qt_module_pris.prf
@@ -35,6 +35,41 @@ else: \
MODULE_PRI = $$mod_inst_pfx/qt_lib_$${MODULE_ID}.pri
MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri
+exists($$OUT_PWD/qt$${MODULE}-config.pri): \
+ include($$OUT_PWD/qt$${MODULE}-config.pri)
+
+defineReplace(qtGetFeaturesForModule) {
+ enabled = $$unique(QT.$${1}.enabled_features)
+ disabled = $$unique(QT.$${1}.disabled_features)
+ result = \
+ "QT.$${1}.enabled_features =$$join(enabled, " ", " ")" \
+ "QT.$${1}.disabled_features =$$join(disabled, " ", " ")"
+ return($$result)
+}
+
+defineReplace(qtGetExportsForModule) {
+ result =
+ for (var, QT.$${1}.exports): \
+ result += "$$var = $$val_escape($$var)"
+ return($$result)
+}
+
+defineReplace(qtExportLibsForModule) {
+ result =
+ for (lib, QT.$${1}.libraries) {
+ NAME = $$upper($$lib)
+ vars = \
+ QMAKE_LIBS_$$NAME QMAKE_LIBS_$${NAME}_DEBUG QMAKE_LIBS_$${NAME}_RELEASE \
+ QMAKE_CFLAGS_$$NAME QMAKE_INCDIR_$$NAME QMAKE_$${NAME}_VERSION \
+ QMAKE_$${NAME}_VERSION_MAJOR QMAKE_$${NAME}_VERSION_MINOR QMAKE_$${NAME}_VERSION_PATCH
+ for (var, vars) {
+ !isEmpty($$var): \
+ result += "$$var = $$val_escape($$var)"
+ }
+ }
+ return($$result)
+}
+
!build_pass {
# Create a module .pri file
@@ -102,6 +137,9 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri
"QT.$${MODULE_ID}.module_config =$$join(module_build_type, " ", " ")" \
$$module_config \
"QT.$${MODULE_ID}.DEFINES = $$val_escape(MODULE_DEFINES)" \
+ $$qtGetFeaturesForModule($$MODULE_ID) \
+ $$qtGetExportsForModule($$MODULE_ID) \
+ "QT_CONFIG +=$$join(QT.$${MODULE_ID}.QT_CONFIG, " ", " ")" \
"" \
"QT_MODULES += $$MODULE"
winrt: MODULE_PRI_CONT += \
@@ -126,7 +164,10 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri
"QT.$${MODULE}_private.includes = $$MODULE_PRIVATE_INCLUDES" \
"QT.$${MODULE}_private.frameworks =" \
"QT.$${MODULE}_private.depends = $$private_deps" \
- "QT.$${MODULE}_private.module_config =$$join(module_build_type, " ", " ")"
+ "QT.$${MODULE}_private.module_config =$$join(module_build_type, " ", " ")" \
+ $$qtGetFeaturesForModule($${MODULE}_private) \
+ "" \
+ $$qtExportLibsForModule($${MODULE}_private)
write_file($$MODULE_PRIVATE_PRI, MODULE_PRIVATE_PRI_CONT)|error()
}
MODULE_PRI_FILES = $$MODULE_PRI $$MODULE_PRIVATE_PRI
diff --git a/mkspecs/features/qt_parts.prf b/mkspecs/features/qt_parts.prf
index fa62f40e35..0accef6665 100644
--- a/mkspecs/features/qt_parts.prf
+++ b/mkspecs/features/qt_parts.prf
@@ -12,6 +12,8 @@
# Ensure that each module has a .qmake.cache when properly qmake'd.
cache()
+load(qt_configure)
+
load(qt_build_config)
TEMPLATE = subdirs
@@ -74,6 +76,7 @@ QT_BUILD_PARTS -= libs tools examples tests
QMAKE_DISTCLEAN += \
.qmake.cache \
+ config.cache \
config.log \
mkspecs/modules/*.pri \
mkspecs/modules-inst/*.pri
diff --git a/qtbase.pro b/qtbase.pro
index 0e44395f6f..fce2c9fa6c 100644
--- a/qtbase.pro
+++ b/qtbase.pro
@@ -24,7 +24,6 @@ DISTCLEAN_DEPS += qmake-clean
# config.status (and configure.cache, which is the same for Windows)
# are omitted for convenience of rebuilds.
QMAKE_DISTCLEAN += \
- config.cache \
config.summary \
config.tests/.qmake.cache \
mkspecs/qconfig.pri \
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index cc46fb99cb..bf2d7aa8a7 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -1015,35 +1015,21 @@ void Configure::configure()
QStringList args;
args << buildPath + "/bin/qmake"
- << "-o" << "Makefile.cfg"
- << sourcePath + "/configure.pri"
+ << sourcePathMangled
<< "--" << configCmdLine;
+ QString pwd = QDir::currentPath();
+ QDir::setCurrent(buildPathMangled);
if (int exitCode = Environment::execute(args, QStringList(), QStringList())) {
cout << "Qmake failed, return code " << exitCode << endl << endl;
dictionary[ "DONE" ] = "error";
}
+ QDir::setCurrent(pwd);
if ((dictionary["REDO"] != "yes") && (dictionary["DONE"] != "error"))
saveCmdLine();
}
-void Configure::generateMakefiles()
-{
- QString pwd = QDir::currentPath();
- {
- QStringList args;
- args << buildPath + "/bin/qmake" << sourcePathMangled;
-
- QDir::setCurrent(buildPathMangled);
- if (int exitCode = Environment::execute(args, QStringList(), QStringList())) {
- cout << "Qmake failed, return code " << exitCode << endl << endl;
- dictionary[ "DONE" ] = "error";
- }
- }
- QDir::setCurrent(pwd);
-}
-
bool Configure::showLicense(QString orgLicenseFile)
{
if (dictionary["LICENSE_CONFIRMED"] == "yes") {
diff --git a/tools/configure/configureapp.h b/tools/configure/configureapp.h
index 436c9307b1..b1c6ea9181 100644
--- a/tools/configure/configureapp.h
+++ b/tools/configure/configureapp.h
@@ -51,7 +51,6 @@ public:
void configure();
void generateHeaders();
- void generateMakefiles();
void generateQDevicePri();
void prepareConfigTests();
diff --git a/tools/configure/main.cpp b/tools/configure/main.cpp
index ac521f42e4..91a99c16c2 100644
--- a/tools/configure/main.cpp
+++ b/tools/configure/main.cpp
@@ -80,10 +80,6 @@ int runConfigure( int argc, char** argv )
if (!app.isOk())
return 3;
- app.generateMakefiles();
- if( !app.isOk() )
- return 2;
-
return 0;
}