Implement proper dependencies for configuration tests

Some test types (like the compile tests) require that other
features have been checked before, so that the compile test
sets up the right environment. Implement this through a
'testTypeDependencies' section in the json file that explicitly
encodes those dependencies for certain test types.

This replaces the 'priority' field in the feature list.

Done-with: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Change-Id: I70e7c67a4f2c971149bcac090cecbbe9cfff3f57
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
This commit is contained in:
Lars Knoll 2016-08-12 10:14:51 +02:00 committed by Oswald Buddenhagen
parent c0cc505209
commit c8b46d3989
2 changed files with 81 additions and 32 deletions

View File

@ -742,6 +742,20 @@
}
},
"testTypeDependencies": {
"linkerSupportsFlag": [ "use_gold_linker" ],
"compile": [ "shared", "use_gold_linker", "compiler-flags", "gcc-sysroot" ],
"detectPkgConfig": [ "cross_compile" ],
"library": [ "pkg-config" ],
"getPkgConfigVariable": [ "pkg-config" ],
"neon": [ "architecture" ]
},
"testTypeAliases": {
"compile": [ "library", "architecture" ],
"getPkgConfigVariable": [ "xkbConfigRoot" ]
},
"tests": {
"architecture": {
"description": "target architecture",
@ -1173,8 +1187,7 @@
"publicConfig",
{ "type": "publicQtConfig", "negative": true, "name": "static" },
{ "type": "publicConfig", "negative": true, "name": "static" }
],
"priority": -3
]
},
"cross_compile": {
"description": "Cross compiling",
@ -1187,24 +1200,20 @@
"output": [ { "type": "publicConfig", "name": "c++11" } ]
},
"compiler-flags": {
"output": [ "compilerFlags" ],
"priority": -3
"output": [ "compilerFlags" ]
},
"gcc-sysroot": {
"output": [ "gccSysroot" ],
"condition": "input.sysroot != ''",
"priority": -3
"condition": "input.sysroot != ''"
},
"use_gold_linker": {
"description": "Using gold linker",
"condition": "tests.use_gold_linker",
"output": [ "privateConfig", "useGoldLinker" ],
"priority": -2
"output": [ "privateConfig", "useGoldLinker" ]
},
"architecture": {
"description": "Architecture",
"output": [ "architecture" ],
"priority": -1
"output": [ "architecture" ]
},
"pkg-config": {
"description": "Using pkg-config",
@ -1213,8 +1222,7 @@
"output": [
{ "type": "publicQtConfig", "negative": true },
"pkgConfig"
],
"priority": -1
]
},
"developer-build": {

View File

@ -468,6 +468,8 @@ defineTest(qtConfHandleLibrary) {
lpfx = config.libraries.$$1
defined($${lpfx}.result, var): return()
qtConfEnsureTestTypeDeps("library")
qtLogTestIntro($${lpfx})
msg = "looking for library $${1}"
write_file($$QMAKE_CONFIG_LOG, msg, append)
@ -517,6 +519,11 @@ defineTest(qtConfHandleLibrary) {
export($${lpfx}.result)
}
# 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) {
for (u, $$list($$eval($${1}.use))) {
!contains(config.libraries._KEYS_, $$u): \
@ -639,6 +646,54 @@ defineTest(qtConfIsBoolean) {
return(false)
}
defineTest(qtConfSetupTestTypeDeps) {
for (tt, config.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_): \
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, config.testTypeAliases._KEYS_) {
!defined(qtConfTest_$${tt}, test): \
error("Aliasing undefined test type '$$tt'.")
for (tta, config.testTypeAliases.$${tt}._KEYS_) {
type = $$eval(config.testTypeAliases.$${tt}.$${tta})
!defined(qtConfTest_$${type}, test): \
error("Aliasing '$$tt' to undefined test type '$$type'.")
config.testTypeForwards.$${type} += $$tt
export(config.testTypeForwards.$${type})
}
}
}
defineTest(qtConfEnsureTestTypeDeps) {
depsn = config.testTypeDependencies.$${1}._KEYS_
!isEmpty($$depsn) {
for (dep, $$depsn) {
feature = $$eval(config.testTypeDependencies.$${1}.$${dep})
!qtConfCheckFeature($$feature): \
error("Test type '$$1' depends on non-emitted feature $${feature}.")
}
$$depsn =
export($$depsn)
}
fwdsn = config.testTypeForwards.$${1}
!isEmpty($$fwdsn) {
for (fwd, $$fwdsn): \
qtConfEnsureTestTypeDeps($$fwd)
$$fwdsn =
export($$fwdsn)
}
}
defineTest(qtRunSingleTest) {
tpfx = config.tests.$${1}
defined($${tpfx}.result, var): \
@ -650,6 +705,8 @@ defineTest(qtRunSingleTest) {
!defined($$call, test): \
error("Configure test $${1} refers to nonexistent type $$type")
qtConfEnsureTestTypeDeps($$type)
preCall = "qtConfTestPrepare_$$type"
defined($$preCall, test): \
!$${preCall}($${tpfx}): result = false
@ -738,6 +795,8 @@ defineReplace(qtConfEvaluateSingleExpression) {
} else: contains(e, "^arch\..*") {
var = $$replace(e, "^arch\.", "")
result = false
isEmpty(QT_ARCH): \
qtConfCheckFeature(architecture)
contains(QT_ARCH, $$var): result = true
} else: contains(e, "^input\..*") {
result = $$eval(config.$$e)
@ -903,27 +962,8 @@ defineTest(qtConfCheckFeature) {
defineTest(qtConfProcessFeatures) {
priorities = 0
for (feature, config.features._KEYS_): \
priorities += $$eval(config.features.$${feature}.priority)
priorities = $$unique(priorities)
for (p, priorities): \
opriorities += $$format_number($$num_add($$p, 10000), width=5 zeropad)
opriorities = $$sorted(opriorities)
priorities =
for (op, opriorities): \
priorities += $$num_add($$op, -10000)
for (priority, priorities) {
for (feature, config.features._KEYS_) {
p = $$eval(config.features.$${feature}.priority)
isEmpty(p): p = 0
equals(p, $$priority): \
qtConfCheckFeature($$feature)
}
}
qtConfCheckFeature($$feature)
}
#
@ -1315,6 +1355,7 @@ defineTest(qtConfigure) {
error("Invalid or non-existent file $${1}.")
qtConfSetupLibraries()
qtConfSetupTestTypeDeps()
qtConfParseCommandLine()