diff options
Diffstat (limited to 'mkspecs/features/qt_configure.prf')
-rw-r--r-- | mkspecs/features/qt_configure.prf | 182 |
1 files changed, 135 insertions, 47 deletions
diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index d8f5af5404..87190bc52a 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -1,3 +1,13 @@ +# +# 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 = @@ -378,6 +388,7 @@ defineReplace(qtConfFindInPathList) { defineReplace(qtConfFindInPath) { ensurePathEnv() + equals(QMAKE_HOST.os, Windows):!contains(1, .*\\.exe): 1 = $${1}.exe return($$qtConfFindInPathList($$1, $$2 $$QMAKE_PATH_ENV)) } @@ -428,12 +439,12 @@ defineTest(qtConfSetupLibraries) { 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 + $${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 = $$l + isEmpty(alias): alias = $$replace(l, -, _) $${lpfx}.alias = $$alias export($${lpfx}.alias) # make it easy to refer to the library by its export name. @@ -581,7 +592,43 @@ defineTest(qtConfResolvePathLibs) { return($$ret) } -# includes-var, includes +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 for (incdir, 2) { @@ -593,6 +640,24 @@ defineTest(qtConfResolvePathIncs) { 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) } @@ -655,13 +720,17 @@ defineTest(qtConfLibrary_inline) { } libdir = $$eval(config.input.$${input}.libdir) - !isEmpty(libdir): \ - $${1}.libs = -L$$libdir $$eval($${1}.libs) + !isEmpty(libdir) { + libs = + for (ld, libdir): \ + libs += -L$$ld + $${1}.libs = $$libs $$eval($${1}.libs) + } !qtConfResolveAllLibs($$1): \ return(false) - !qtConfResolvePathIncs($${1}.includedir, $$includes): \ + !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \ return(false) return(true) @@ -677,7 +746,7 @@ defineTest(qtConfLibrary_makeSpec) { !qtConfResolvePathLibs($${1}.libs, $$eval(QMAKE_LIBDIR_$$spec), $$eval(QMAKE_LIBS_$$spec)): \ return(false) - !qtConfResolvePathIncs($${1}.includedir, $$eval(QMAKE_INCDIR_$$spec)): \ + !qtConfResolvePathIncs($${1}.includedir, $$eval(QMAKE_INCDIR_$$spec), $$2): \ return(false) # note that the object is re-exported, because we resolve the libraries. @@ -740,7 +809,7 @@ defineTest(qtConfLibrary_pkgConfig) { } !isEmpty(ignored): \ qtLog("Note: Dropped compiler flags '$$ignored'.") - !qtConfResolvePathIncs($${1}.includedir, $$includes): \ + !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \ return(false) $${1}.defines = $$defines @@ -748,7 +817,7 @@ defineTest(qtConfLibrary_pkgConfig) { largs = $$qtConfAllLibraryArgs($$eval($${2}.dependencies)) for (la, largs): \ eval("$$la") - USES = $$eval($$list($$upper($$QMAKE_USE))) + 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) { @@ -781,7 +850,7 @@ defineTest(qtConfTest_getPkgConfigVariable) { } defineReplace(qtConfLibraryArgs) { - NAME = $$upper($$eval($${1}.library)) + 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})" @@ -797,8 +866,8 @@ defineReplace(qtConfLibraryArgs) { for (use, depends): \ dep_uses += $$section(use, :, 1, 1) qmake_args += \ - "QMAKE_DEPENDS_$${NAME}_CC = $$upper($$dep_uses)" \ - "QMAKE_DEPENDS_$${NAME}_LD = $$upper($$dep_uses)" + "QMAKE_DEPENDS_$${NAME}_CC = $$upper($$replace(dep_uses, -, _))" \ + "QMAKE_DEPENDS_$${NAME}_LD = $$upper($$replace(dep_uses, -, _))" } return($$qmake_args) } @@ -861,7 +930,7 @@ defineTest(qtConfExportLibrary) { !isEmpty(use_cfg): \ depends += $$upper($$eval($${use_cfg}.libraries.$${use_lib}.export)) else: \ - depends += $$upper($$use_lib) + depends += $$upper($$replace(use_lib, -, _)) } # we use suffixes instead of infixes, because $$resolve_depends() demands it. qtConfOutputVar(assign, $$output, QMAKE_DEPENDS_$${NAME}_CC, $$depends) @@ -930,7 +999,7 @@ defineTest(qtConfHandleLibrary) { export($${lpfx}.source) # if the library defines a test, use it to verify the source. - !isEmpty($${lpfx}.test)|!isEmpty($${lpfx}.test._KEYS_) { + defined($${lpfx}.test, var)|defined($${lpfx}.test._KEYS_, var) { $${lpfx}.resolved_uses = $$currentConfig:$$1 $${lpfx}.host = $$eval($${spfx}.host) !qtConfTest_compile($$lpfx) { @@ -1036,7 +1105,7 @@ defineTest(qtConfTestPrepare_compile) { } } isEmpty(libConfig) { - nu = $$upper($$u) + 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. @@ -1055,8 +1124,12 @@ defineTest(qtConfTestPrepare_compile) { defineTest(qtConfPrepareCompileTestSource) { test_dir = $$2 - test_lang = $$eval($${1}.lang) - isEmpty(test_lang): test_lang = "c++" + 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" @@ -1067,33 +1140,48 @@ defineTest(qtConfPrepareCompileTestSource) { # Create source code contents = "/* Generated by configure */" # Custom code before includes - for (ent, $$qtConfScalarOrList($${1}.head)): \ - contents += $$ent + for (test, tests): \ + for (ent, $$qtConfScalarOrList($${test}.test.head)): \ + contents += $$ent # Includes - for (ent, $$qtConfScalarOrList($${1}.include)): \ - contents += "$${LITERAL_HASH}include <$$ent>" + 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 (ent, $$qtConfScalarOrList($${1}.tail)): \ - contents += $$ent + 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 (ent, $$qtConfScalarOrList($${1}.main)): \ - contents += " $$ent" + 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 - for (ent, $$qtConfScalarOrList($${1}.qmake)): \ - contents += $$ent + 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() } @@ -1106,7 +1194,7 @@ defineTest(qtConfTest_compile) { isEmpty(test) { test_dir = $$test_base_out_dir/$$section(1, ".", -1) test_out_dir = $$test_dir - qtConfPrepareCompileTestSource($${1}.test, $$test_dir) + qtConfPrepareCompileTestSource($$1, $$test_dir) } else { test_dir = $$QMAKE_CONFIG_TESTS_DIR/$$test test_out_dir = $$test_base_out_dir/$$test @@ -1196,9 +1284,9 @@ defineTest(qtConfTest_files) { for(i, $${1}.files._KEYS_) { f = $$eval($${1}.files.$${i}) qtLog("Searching for file $${f}.") - contains(f, ".*\.h") { + contains(f, ".*\\.h") { file = $$qtConfFindInPathList($$f, $$EXTRA_INCLUDEPATH $$QMAKE_DEFAULT_INCDIRS) - } else: contains(f, ".*\.(lib|so|a)") { + } else: contains(f, ".*\\.(lib|so|a)") { file = $$qtConfFindInPathList($$f, $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS) } else { # assume we're looking for an executable @@ -1399,7 +1487,7 @@ defineReplace(qtConfEvaluate) { 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 @@ -1422,7 +1510,7 @@ defineReplace(qtConfEvaluateSingleExpression) { } else: contains(e, "^'.*'$") { # quoted literals result = $$replace(e, "^'(.*)'$", "\\1") - } else: contains(e, "^tests\..*") { + } 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) @@ -1433,7 +1521,7 @@ defineReplace(qtConfEvaluateSingleExpression) { error("Unknown test object $${test} in expression '$${1}'.") qtRunSingleTest($$test) result = $$eval($${currentConfig}.tests.$${test}.$${var}) - } else: contains(e, "^libs\..*") { + } 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) @@ -1446,7 +1534,7 @@ defineReplace(qtConfEvaluateSingleExpression) { !defined($${currentConfig}.libraries.$${lib}.$${var}, var): \ var = sources.$$eval($${currentConfig}.libraries.$${lib}.source).$$var result = $$eval($${currentConfig}.libraries.$${lib}.$${var}) - } else: contains(e, "^features\..*") { + } else: contains(e, "^features\\..*") { feature = $$section(e, ".", 1, 1) var = $$section(e, ".", 2, -1) isEmpty(var): \ @@ -1470,33 +1558,33 @@ defineReplace(qtConfEvaluateSingleExpression) { !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\.", "") + } else: contains(e, "^config\\..*") { + var = $$replace(e, "^config\\.", "") result = false contains(CONFIG, $$var): result = true - } else: contains(e, "^module\..*") { - var = $$replace(e, "^module\.", "") + } else: contains(e, "^module\\..*") { + var = $$replace(e, "^module\\.", "") result = false qtConfHaveModule($$var): result = true - } else: contains(e, "^arch\..*") { - var = $$replace(e, "^arch\.", "") + } 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\.", "") + } 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\..*") { + } else: contains(e, "^input\\..*") { result = $$eval(config.$$e) - } else: contains(e, "^var\..*") { - var = $$replace(e, "^var\.", "") + } else: contains(e, "^var\\..*") { + var = $$replace(e, "^var\\.", "") result = $$eval($$var) - } else: contains(e, "^call\..*") { - call = $$replace(e, "^call\.", "qtConfFunc_") + } 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"()) |