diff options
author | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-12-01 20:13:08 +0100 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2018-12-03 11:25:56 +0000 |
commit | 521a85395da1a2728902816c072ec46bcb0ad380 (patch) | |
tree | cc3f0cd306563c9fe30f1518d8654e396e571a61 | |
parent | 46a2b44b2b7f50ced7f2c0731cc6224478d960c7 (diff) |
configure: actually resolve libraries into full filepaths
this considerably speeds up failures, as no doomed build is attempted,
and produces more reliable results, as no second lookup (which would be
subject to environment changes) is done any more during the build.
in principle, this also opens up possibilities like selecting specific
variants of dependencies, automatically extracting rpaths, etc.
qt_helper_lib.prf also needs to create fully resolved library names now.
Change-Id: I65f13564b635433030e40fa017427bbc72d1c130
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
-rw-r--r-- | configure.json | 2 | ||||
-rw-r--r-- | mkspecs/features/qmake_use.prf | 1 | ||||
-rw-r--r-- | mkspecs/features/qt_configure.prf | 171 | ||||
-rw-r--r-- | mkspecs/features/qt_helper_lib.prf | 19 | ||||
-rw-r--r-- | src/network/configure.json | 1 | ||||
-rw-r--r-- | src/network/configure.pri | 6 | ||||
-rw-r--r-- | src/plugins/sqldrivers/configure.pri | 50 |
7 files changed, 173 insertions, 77 deletions
diff --git a/configure.json b/configure.json index 7c79b5c582..69e058e0c2 100644 --- a/configure.json +++ b/configure.json @@ -211,7 +211,7 @@ "verifySpec": [ "shared", "use_gold_linker", "compiler-flags", "qmakeargs", "commit" ], "compile": [ "verifyspec" ], "detectPkgConfig": [ "cross_compile", "machineTuple" ], - "library": [ "pkg-config" ], + "library": [ "pkg-config", "compiler-flags" ], "getPkgConfigVariable": [ "pkg-config" ] }, diff --git a/mkspecs/features/qmake_use.prf b/mkspecs/features/qmake_use.prf index f81d1cece4..dba45de92a 100644 --- a/mkspecs/features/qmake_use.prf +++ b/mkspecs/features/qmake_use.prf @@ -9,7 +9,6 @@ for(ever) { error("Library '$$name' is not defined.") !contains(use, nolink) { - QMAKE_LIBDIR += $$eval(QMAKE_LIBDIR_$$nu) debug: \ LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu) else: \ diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 65ee7df50b..44d8a3e639 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -365,9 +365,13 @@ defineTest(qtConfTest_linkerSupportsFlag) { } defineReplace(qtConfFindInPathList) { + # This nesting is consistent with Apple ld -search_paths_first, + # and presumably with GNU ld (no actual documentation found). for (dir, 2) { - exists("$$dir/$${1}"): \ - return("$$dir/$${1}") + for (file, 1) { + exists("$$dir/$$file"): \ + return("$$dir/$$file") + } } return() } @@ -488,6 +492,110 @@ defineTest(qtConfSetupLibraries) { } } +# libs-var, libs, in-paths, out-paths-var +defineTest(qtConfResolveLibs) { + ret = true + paths = $$3 + out = + copy = false + for (l, 2) { + $$copy { + copy = false + out += $$l + } else: equals(l, "-s") { + # em++ flag to link libraries from emscripten-ports; passed on literally. + copy = true + out += $$l + } else: contains(l, "^-L.*") { + lp = $$replace(l, "^-L", ) + !exists($$lp/.) { + qtLog("Library path $$val_escape(lp) is invalid.") + ret = false + } else { + paths += $$lp + } + } else: contains(l, "^-l.*") { + lib = $$replace(l, "^-l", ) + lcan = + unix { + # Under UNIX, we look for actual shared libraries, in addition + # to static ones. + lcan += \ + $${QMAKE_PREFIX_SHLIB}$${lib}.$${QMAKE_EXTENSION_SHLIB} \ + $${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB} + } else { + # Under Windows, we look only for static libraries, as even for DLLs + # one actually links against a static import library. + mingw { + lcan += \ + # MinGW supports UNIX-style library naming in addition to + # the MSVC style. + lib$${lib}.dll.a lib$${lib}.a \ + # Fun fact: prefix-less libraries are also supported. + $${lib}.dll.a $${lib}.a + } + lcan += $${lib}.lib + } + l = $$qtConfFindInPathList($$lcan, $$paths $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS) + isEmpty(l) { + qtLog("None of [$$val_escape(lcan)] found in [$$val_escape(paths)] and global paths.") + ret = false + } else { + out += $$l + } + } else { + out += $$l + } + } + $$1 = $$out + export($$1) + !isEmpty(4) { + $$4 = $$paths + export($$4) + } + return($$ret) +} + +# source-var +defineTest(qtConfResolveAllLibs) { + ret = true + !qtConfResolveLibs($${1}.libs, $$eval($${1}.libs), , $${1}.libdirs): \ + ret = false + for (b, $${1}.builds._KEYS_): \ + !qtConfResolveLibs($${1}.builds.$${b}, $$eval($${1}.builds.$${b}), $$eval($${1}.libdirs), ): \ + ret = false + return($$ret) +} + +# libs-var, in-paths, libs +defineTest(qtConfResolvePathLibs) { + ret = true + for (libdir, 2) { + !exists($$libdir/.) { + qtLog("Library path $$val_escape(libdir) is invalid.") + ret = false + } + } + !qtConfResolveLibs($$1, $$3, $$2): \ + ret = false + return($$ret) +} + +# includes-var, includes +defineTest(qtConfResolvePathIncs) { + ret = true + for (incdir, 2) { + !exists($$incdir/.) { + qtLog("Include path $$val_escape(incdir) is invalid.") + ret = false + } + } + 2 -= $$QMAKE_DEFAULT_INCDIRS + $$1 = $$2 + export($$1) + return($$ret) +} + # the library is specified inline in a 'libs' field. # overrides from the command line are accepted. defineTest(qtConfLibrary_inline) { @@ -517,7 +625,6 @@ defineTest(qtConfLibrary_inline) { 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 { @@ -532,35 +639,30 @@ defineTest(qtConfLibrary_inline) { 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) { + 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) { - $${1}.includedir = $$prefix/include - export($${1}.includedir) + includes += $$prefix/include $${1}.libs = -L$$prefix/lib $$eval($${1}.libs) - export($${1}.libs) - } - - incdir = $$eval(config.input.$${input}.incdir) - !isEmpty(incdir) { - $${1}.includedir = $$incdir - export($${1}.includedir) } libdir = $$eval(config.input.$${input}.libdir) - !isEmpty(libdir) { + !isEmpty(libdir): \ $${1}.libs = -L$$libdir $$eval($${1}.libs) - export($${1}.libs) - } + + !qtConfResolveAllLibs($$1): \ + return(false) + + !qtConfResolvePathIncs($${1}.includedir, $$includes): \ + return(false) return(true) } @@ -572,17 +674,13 @@ defineTest(qtConfLibrary_makeSpec) { isEmpty(spec): \ error("makeSpec source in library '$$eval($${1}.library)' does not specify 'spec'.") - $${1}.includedir = $$eval(QMAKE_INCDIR_$$spec) - export($${1}.includedir) - $${1}.libs = - for (l, QMAKE_LIBDIR_$$spec): \ - $${1}.libs += -L$$l - $${1}.libs += $$eval(QMAKE_LIBS_$$spec) - export($${1}.libs) + !qtConfResolvePathLibs($${1}.libs, $$eval(QMAKE_LIBDIR_$$spec), $$eval(QMAKE_LIBS_$$spec)): \ + return(false) - # the library definition is always in scope, so no point in exporting it. - $${1}.export = false - export($${1}.export) + !qtConfResolvePathIncs($${1}.includedir, $$eval(QMAKE_INCDIR_$$spec)): \ + return(false) + + # note that the object is re-exported, because we resolve the libraries. return(true) } @@ -602,13 +700,15 @@ defineTest(qtConfLibrary_pkgConfig) { } qtRunLoggedCommand("$$pkg_config --modversion $$args", version)|return(false) - qtRunLoggedCommand("$$pkg_config --libs-only-L $$args", libpaths)|return(false) - qtRunLoggedCommand("$$pkg_config --libs-only-l $$args", libs)|return(false) version ~= s/[^0-9.].*$// $${1}.version = $$first(version) export($${1}.version) - eval($${1}.libs = $$libpaths $$libs) - export($${1}.libs) + + 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) qtRunLoggedCommand("$$pkg_config --cflags $$args", $${1}.cflags)|return(false) # Split CFLAGS into stuff that goes into DEFINES, INCLUDEPATH, and other stuff. @@ -633,10 +733,11 @@ defineTest(qtConfLibrary_pkgConfig) { } !isEmpty(ignored): \ qtLog("Note: Dropped compiler flags '$$ignored'.") + !qtConfResolvePathIncs($${1}.includedir, $$includes): \ + return(false) $${1}.defines = $$defines export($${1}.defines) - $${1}.includedir = $$includes - export($${1}.includedir) + return(true) } diff --git a/mkspecs/features/qt_helper_lib.prf b/mkspecs/features/qt_helper_lib.prf index b3e49e4626..1a8446acb4 100644 --- a/mkspecs/features/qt_helper_lib.prf +++ b/mkspecs/features/qt_helper_lib.prf @@ -34,19 +34,30 @@ THE_TARGET = $$qt5LibraryTarget($$TARGET) MODULE_PRI = $$MODULE_QMAKE_OUTDIR/mkspecs/modules/qt_ext_$${MODULE}.pri ucmodule = $$upper($$MODULE) + win32|CONFIG(static, static|shared) { + prefix = $$QMAKE_PREFIX_STATICLIB + suffix = $$QMAKE_EXTENSION_STATICLIB + } else { + prefix = $$QMAKE_PREFIX_SHLIB + suffix = $$QMAKE_EXTENSION_SHLIB + } MODULE_PRI_CONT = \ "QMAKE_INCDIR_$${ucmodule} = $$val_escape(MODULE_INCLUDEPATH)" \ "QMAKE_DEFINES_$${ucmodule} = $$val_escape(MODULE_DEFINES)" debug_and_release { - win32: MODULE_DEBUG_LIBS = -L$$DESTDIR -l$${TARGET}d - darwin: MODULE_DEBUG_LIBS = -L$$DESTDIR -l$${TARGET}_debug - MODULE_RELEASE_LIBS = -L$$DESTDIR -l$$TARGET + win32: \ + MODULE_DEBUG_LIBS = $$DESTDIR/$$prefix$${TARGET}d.$$suffix + else: darwin: \ + MODULE_DEBUG_LIBS = $$DESTDIR/$$prefix$${TARGET}_debug.$$suffix + else: \ + error("'$$QMAKE_PLATFORM' does not do debug_and_release.") + MODULE_RELEASE_LIBS = $$DESTDIR/$$prefix$${TARGET}.$$suffix MODULE_PRI_CONT += \ "QMAKE_LIBS_$${ucmodule} =" \ # Needed for the module to be recognized. "QMAKE_LIBS_$${ucmodule}_DEBUG = $$val_escape(MODULE_DEBUG_LIBS)" \ "QMAKE_LIBS_$${ucmodule}_RELEASE = $$val_escape(MODULE_RELEASE_LIBS)" } else { - MODULE_LIBS = -L$$DESTDIR -l$$THE_TARGET + MODULE_LIBS = $$DESTDIR/$$prefix$${THE_TARGET}.$$suffix MODULE_PRI_CONT += \ "QMAKE_LIBS_$${ucmodule} = $$val_escape(MODULE_LIBS)" } diff --git a/src/network/configure.json b/src/network/configure.json index 327131ba11..019f8378c7 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -32,7 +32,6 @@ ] }, "network": { - "export": "", "sources": [ { "type": "makeSpec", "spec": "NETWORK" } ] diff --git a/src/network/configure.pri b/src/network/configure.pri index fa502db1d1..ad4d711cba 100644 --- a/src/network/configure.pri +++ b/src/network/configure.pri @@ -1,10 +1,10 @@ # custom tests defineTest(qtConfLibrary_openssl) { - libs = $$getenv("OPENSSL_LIBS") + eval(libs = $$getenv("OPENSSL_LIBS")) !isEmpty(libs) { - eval($${1}.libs = $$libs) - export($${1}.libs) + !qtConfResolveLibs($${1}.libs, $$libs): \ + return(false) return(true) } qtLog("$OPENSSL_LIBS is not set.") diff --git a/src/plugins/sqldrivers/configure.pri b/src/plugins/sqldrivers/configure.pri index 24954e9514..747a47e7b8 100644 --- a/src/plugins/sqldrivers/configure.pri +++ b/src/plugins/sqldrivers/configure.pri @@ -1,29 +1,16 @@ # custom tests -defineReplace(filterLibraryPath) { - str = $${1} - for (l, QMAKE_DEFAULT_LIBDIRS): \ - str -= "-L$$l" - - return($$str) -} - defineTest(qtConfLibrary_psqlConfig) { pg_config = $$config.input.psql_config isEmpty(pg_config): \ pg_config = $$qtConfFindInPath("pg_config") !win32:!isEmpty(pg_config) { qtRunLoggedCommand("$$pg_config --libdir", libdir)|return(false) + !qtConfResolvePathLibs($${1}.libs, $$libdir, -lpq): \ + return(false) qtRunLoggedCommand("$$pg_config --includedir", includedir)|return(false) - libdir -= $$QMAKE_DEFAULT_LIBDIRS - libs = - !isEmpty(libdir): libs += "-L$$libdir" - libs += "-lpq" - $${1}.libs = $$libs - includedir -= $$QMAKE_DEFAULT_INCDIRS - $${1}.includedir = $$includedir - export($${1}.libs) - export($${1}.includedir) + !qtConfResolvePathIncs($${1}.includedir, $$includedir): \ + return(false) return(true) } qtLog("pg_config not found.") @@ -34,8 +21,9 @@ defineTest(qtConfLibrary_psqlEnv) { # Respect PSQL_LIBS if set PSQL_LIBS = $$getenv(PSQL_LIBS) !isEmpty(PSQL_LIBS) { - eval($${1}.libs = $$PSQL_LIBS) - export($${1}.libs) + eval(libs = $$PSQL_LIBS) + !qtConfResolveLibs($${1}.libs, $$libs): \ + return(false) } else { !qtConfLibrary_inline($$1, $$2): \ return(false) @@ -58,7 +46,6 @@ defineTest(qtConfLibrary_mysqlConfig) { qtRunLoggedCommand("$$mysql_config $$query", libs)|return(false) qtRunLoggedCommand("$$mysql_config --include", includedir)|return(false) eval(libs = $$libs) - libs = $$filterLibraryPath($$libs) # -rdynamic should not be returned by mysql_config, but is on RHEL 6.6 libs -= -rdynamic equals($${1}.cleanlibs, true) { @@ -69,16 +56,15 @@ defineTest(qtConfLibrary_mysqlConfig) { } libs = $$cleanlibs } - $${1}.libs = $$libs + !qtConfResolveLibs($${1}.libs, $$libs): \ + return(false) eval(rawincludedir = $$includedir) rawincludedir ~= s/^-I//g includedir = for (id, rawincludedir): \ includedir += $$clean_path($$id) - includedir -= $$QMAKE_DEFAULT_INCDIRS - $${1}.includedir = $$includedir - export($${1}.libs) - export($${1}.includedir) + !qtConfResolvePathIncs($${1}.includedir, $$includedir): \ + return(false) return(true) } qtLog("mysql_config not found.") @@ -86,14 +72,14 @@ defineTest(qtConfLibrary_mysqlConfig) { } defineTest(qtConfLibrary_sybaseEnv) { - libs = + libdir = sybase = $$getenv(SYBASE) !isEmpty(sybase): \ - libs += "-L$${sybase}/lib" - eval(libs += $$getenv(SYBASE_LIBS)) - !isEmpty(libs) { - $${1}.libs = $$libs - export($${1}.libs) - } + libdir += $${sybase}/lib + eval(libs = $$getenv(SYBASE_LIBS)) + isEmpty(libs): \ + libs = $$eval($${1}.libs) + !qtConfResolvePathLibs($${1}.libs, $$libdir, $$libs): \ + return(false) return(true) } |