summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-12-01 20:13:08 +0100
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2018-12-03 11:25:56 +0000
commit521a85395da1a2728902816c072ec46bcb0ad380 (patch)
treecc3f0cd306563c9fe30f1518d8654e396e571a61
parent46a2b44b2b7f50ced7f2c0731cc6224478d960c7 (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.json2
-rw-r--r--mkspecs/features/qmake_use.prf1
-rw-r--r--mkspecs/features/qt_configure.prf171
-rw-r--r--mkspecs/features/qt_helper_lib.prf19
-rw-r--r--src/network/configure.json1
-rw-r--r--src/network/configure.pri6
-rw-r--r--src/plugins/sqldrivers/configure.pri50
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)
}