summaryrefslogtreecommitdiffstats
path: root/mkspecs
diff options
context:
space:
mode:
Diffstat (limited to 'mkspecs')
-rw-r--r--mkspecs/common/msvc-based-version.conf32
-rw-r--r--mkspecs/common/msvc-version.conf10
-rw-r--r--mkspecs/features/data/dumpvcvars.bat44
-rw-r--r--mkspecs/features/egl.prf1
-rw-r--r--mkspecs/features/mac/asset_catalogs.prf2
-rw-r--r--mkspecs/features/mac/default_post.prf4
-rw-r--r--mkspecs/features/moc.prf2
-rw-r--r--mkspecs/features/qmake_use.prf6
-rw-r--r--mkspecs/features/qt.prf22
-rw-r--r--mkspecs/features/qt_common.prf24
-rw-r--r--mkspecs/features/qt_configure.prf182
-rw-r--r--mkspecs/features/qt_docs.prf2
-rw-r--r--mkspecs/features/qt_helper_lib.prf3
-rw-r--r--mkspecs/features/qt_module_headers.prf8
-rw-r--r--mkspecs/features/resources.prf9
-rw-r--r--mkspecs/features/static_runtime.prf4
-rw-r--r--mkspecs/features/toolchain.prf360
-rw-r--r--mkspecs/win32-clang-msvc/qmake.conf8
-rw-r--r--mkspecs/winrt-arm-msvc2015/qmake.conf1
-rw-r--r--mkspecs/winrt-arm-msvc2017/qmake.conf1
-rw-r--r--mkspecs/winrt-x64-msvc2015/qmake.conf1
-rw-r--r--mkspecs/winrt-x64-msvc2017/qmake.conf1
-rw-r--r--mkspecs/winrt-x86-msvc2015/qmake.conf1
-rw-r--r--mkspecs/winrt-x86-msvc2017/qmake.conf1
24 files changed, 515 insertions, 214 deletions
diff --git a/mkspecs/common/msvc-based-version.conf b/mkspecs/common/msvc-based-version.conf
new file mode 100644
index 0000000000..38aecbaf59
--- /dev/null
+++ b/mkspecs/common/msvc-based-version.conf
@@ -0,0 +1,32 @@
+#
+# qmake configuration for Compilers based on the Microsoft Visual Studio
+# C/C++ Compilers like win32-clang-msvc
+
+#
+# Version-specific changes
+#
+
+isEmpty(QMAKE_MSC_VER): error("msvc-based-version.conf loaded but QMAKE_MSC_VER isn't set")
+
+MSVC_VER = 14.0
+COMPAT_MKSPEC = win32-msvc2015
+
+# -utf-8 compiler option for Visual Studio 2015 Update 2
+greaterThan(QMAKE_MSC_FULL_VER, 190023918):!intel_icl {
+ isEmpty(QT_CLANG_MAJOR_VERSION)|!lessThan(QT_CLANG_MAJOR_VERSION, 4) {
+ QMAKE_CFLAGS_UTF8_SOURCE = -utf-8
+ }
+}
+
+greaterThan(QMAKE_MSC_VER, 1909) {
+ # Visual Studio 2017 (15.0) / Visual C++ 19.10 and up
+ MSVC_VER = 15.0
+ COMPAT_MKSPEC = win32-msvc2017
+}
+
+greaterThan(QMAKE_MSC_VER, 1910) {
+ # No compat spec past MSVC 2017
+ COMPAT_MKSPEC =
+}
+
+!isEmpty(COMPAT_MKSPEC):!$$COMPAT_MKSPEC: CONFIG += $$COMPAT_MKSPEC
diff --git a/mkspecs/common/msvc-version.conf b/mkspecs/common/msvc-version.conf
index 3fb55c9d81..de8ba56b7b 100644
--- a/mkspecs/common/msvc-version.conf
+++ b/mkspecs/common/msvc-version.conf
@@ -1,7 +1,6 @@
#
# qmake configuration for Microsoft Visual Studio C/C++ Compiler
-# This file is used by win32-msvc, win32-clang-msvc, and all
-# winrt-XXX-msvcXXX specs
+# This file is used by win32-msvc and all winrt-XXX-msvcXXX specs
#
#
@@ -70,11 +69,8 @@ greaterThan(QMAKE_MSC_VER, 1899) {
QMAKE_CXXFLAGS += -Zc:strictStrings -Zc:throwingNew
QMAKE_CXXFLAGS_WARN_ON += -w44456 -w44457 -w44458 -wd4577 -wd4467
- greaterThan(QMAKE_MSC_FULL_VER, 190023918):!intel_icl {
- isEmpty(QT_CLANG_MAJOR_VERSION)|!lessThan(QT_CLANG_MAJOR_VERSION, 4) {
- QMAKE_CFLAGS_UTF8_SOURCE = -utf-8
- }
- }
+ # -utf-8 compiler option for Visual Studio 2015 Update 2
+ greaterThan(QMAKE_MSC_FULL_VER, 190023918): QMAKE_CFLAGS_UTF8_SOURCE = -utf-8
}
greaterThan(QMAKE_MSC_VER, 1909) {
diff --git a/mkspecs/features/data/dumpvcvars.bat b/mkspecs/features/data/dumpvcvars.bat
new file mode 100644
index 0000000000..4721da2e39
--- /dev/null
+++ b/mkspecs/features/data/dumpvcvars.bat
@@ -0,0 +1,44 @@
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::
+:: Copyright (C) 2018 The Qt Company Ltd.
+:: Contact: https://www.qt.io/licensing/
+::
+:: This file is part of the tools applications of the Qt Toolkit.
+::
+:: $QT_BEGIN_LICENSE:GPL-EXCEPT$
+:: Commercial License Usage
+:: Licensees holding valid commercial Qt licenses may use this file in
+:: accordance with the commercial license agreement provided with the
+:: Software or, alternatively, in accordance with the terms contained in
+:: a written agreement between you and The Qt Company. For licensing terms
+:: and conditions see https://www.qt.io/terms-conditions. For further
+:: information use the contact form at https://www.qt.io/contact-us.
+::
+:: GNU General Public License Usage
+:: Alternatively, this file may be used under the terms of the GNU
+:: General Public License version 3 as published by the Free Software
+:: Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+:: included in the packaging of this file. Please review the following
+:: information to ensure the GNU General Public License requirements will
+:: be met: https://www.gnu.org/licenses/gpl-3.0.html.
+::
+:: $QT_END_LICENSE$
+::
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+@echo off
+
+REM We clear INCLUDE and LIB, because we want to obtain pristine values.
+REM PATH cannot be cleared, because then the script does not even run,
+REM and it would be counterproductive anyway (see toolchain.prf).
+set INCLUDE=
+set LIB=
+
+call %* || exit 1
+REM VS2015 does not set errorlevel in case of failure.
+if "%INCLUDE%" == "" exit 1
+
+echo =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
+echo %INCLUDE%
+echo %LIB%
+echo %PATH%
diff --git a/mkspecs/features/egl.prf b/mkspecs/features/egl.prf
index 9fa0c9e219..4577785576 100644
--- a/mkspecs/features/egl.prf
+++ b/mkspecs/features/egl.prf
@@ -2,6 +2,7 @@ INCLUDEPATH += $$QMAKE_INCDIR_EGL
LIBS_PRIVATE += $$QMAKE_LIBS_EGL
QMAKE_CFLAGS += $$QMAKE_CFLAGS_EGL
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_EGL
+DEFINES += $$QMAKE_DEFINES_EGL
LIBS += $$QMAKE_LFLAGS_EGL
for(p, QMAKE_LIBDIR_EGL) {
LIBS_PRIVATE += -L$$p
diff --git a/mkspecs/features/mac/asset_catalogs.prf b/mkspecs/features/mac/asset_catalogs.prf
index 123a0e0fcd..58211c13a2 100644
--- a/mkspecs/features/mac/asset_catalogs.prf
+++ b/mkspecs/features/mac/asset_catalogs.prf
@@ -110,7 +110,7 @@
# Backwards compatibility
for (bundle_data, QMAKE_BUNDLE_DATA) {
for (bundle_file, $${bundle_data}.files) {
- !contains(bundle_file, .*\.xcassets$): next()
+ !contains(bundle_file, .*\\.xcassets$): next()
warning("*.xcassets in QMAKE_BUNDLE_DATA is deprecated. Use QMAKE_ASSET_CATALOGS instead.")
!exists($$absolute_path($$bundle_file/AppIcon.appiconset, $$_PRO_FILE_PWD_)): next()
diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf
index c01e99fe8e..8e2c5e603a 100644
--- a/mkspecs/features/mac/default_post.prf
+++ b/mkspecs/features/mac/default_post.prf
@@ -1,7 +1,7 @@
load(default_post)
contains(TEMPLATE, .*app) {
- !macx-xcode {
+ !macx-xcode:if(isEmpty(BUILDS)|build_pass) {
# Detect changes to the platform SDK
QMAKE_EXTRA_VARIABLES += QMAKE_MAC_SDK QMAKE_MAC_SDK_VERSION QMAKE_XCODE_DEVELOPER_PATH
QMAKE_EXTRA_INCLUDES += $$shell_quote($$PWD/sdk.mk)
@@ -21,7 +21,7 @@ contains(TEMPLATE, .*app) {
!isEmpty($$list($$(QT_MAC_SDK_NO_VERSION_CHECK))): \
CONFIG += sdk_no_version_check
- QMAKE_MAC_SDK_MAJOR_MINOR_VERSION = $$replace(QMAKE_MAC_SDK_VERSION, "(\d+)(\.\d+)(\.\d+)?", \1\2)
+ QMAKE_MAC_SDK_MAJOR_MINOR_VERSION = $$replace(QMAKE_MAC_SDK_VERSION, "(\\d+)(\\.\\d+)(\\.\\d+)?", \\1\\2)
!sdk_no_version_check:!versionAtMost(QMAKE_MAC_SDK_MAJOR_MINOR_VERSION, $$QT_MAC_SDK_VERSION_MAX) {
warning("Qt has only been tested with version $$QT_MAC_SDK_VERSION_MAX"\
diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf
index 5c7745e5bb..d075183028 100644
--- a/mkspecs/features/moc.prf
+++ b/mkspecs/features/moc.prf
@@ -38,7 +38,7 @@ if(gcc|intel_icl|msvc):!rim_qcc:!uikit:!no_moc_predefs:if(!macos|count(QMAKE_APP
} else: error("Oops, I messed up")
moc_predefs.output = $$MOC_DIR/moc_predefs.h
moc_predefs.input = MOC_PREDEF_FILE
- silent: moc_predefs.commands = @echo generating $$moc_predefs.output$$escape_expand(\n\t)@$$moc_predefs.commands
+ silent: moc_predefs.commands = @echo generating $$moc_predefs.output$$escape_expand(\\n\\t)@$$moc_predefs.commands
QMAKE_EXTRA_COMPILERS += moc_predefs
MOC_PREDEF_FILE = $$[QT_HOST_DATA/src]/mkspecs/features/data/dummy.cpp
}
diff --git a/mkspecs/features/qmake_use.prf b/mkspecs/features/qmake_use.prf
index 8159e471a2..64faa4f215 100644
--- a/mkspecs/features/qmake_use.prf
+++ b/mkspecs/features/qmake_use.prf
@@ -5,14 +5,14 @@ for(ever) {
for (use, QMAKE_USE$${suffix}) {
use = $$split(use, /)
name = $$take_first(use)
- nu = $$upper($$name)
+ nu = $$upper($$replace(name, -, _))
!contains(use, linkonly): CC_USES += $$nu
!contains(use, nolink): LD_USES += $$nu
}
CC_USES = $$resolve_depends(CC_USES, QMAKE_DEPENDS_, _CC)
for (nu, CC_USES) {
!defined(QMAKE_LIBS_$$nu, var): \
- error("Library '$$lower($$nu)' is not defined.")
+ error("Library '$$lower($$replace(nu, _, -))' is not defined.")
DEFINES += $$eval(QMAKE_DEFINES_$${nu})
INCLUDEPATH += $$eval(QMAKE_INCDIR_$${nu})
@@ -20,7 +20,7 @@ for(ever) {
LD_USES = $$resolve_depends(LD_USES, QMAKE_DEPENDS_, _LD)
for (nu, LD_USES) {
!defined(QMAKE_LIBS_$$nu, var): \
- error("Library '$$lower($$nu)' is not defined.")
+ error("Library '$$lower($$replace(nu, _, -))' is not defined.")
debug: \
LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu)
diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf
index d16b3cf1be..5da82fdb5b 100644
--- a/mkspecs/features/qt.prf
+++ b/mkspecs/features/qt.prf
@@ -198,28 +198,6 @@ for(ever) {
MODULE_LIBS_ADD = $$MODULE_LIBS
MODULE_LIBS_ADD -= $$QMAKE_DEFAULT_LIBDIRS
- !contains(MODULE_CONFIG, v2) {
- # Backwards compatibility with pre-5.6 module .pri files
-
- contains(MODULE_CONFIG, lib_bundle) {
- MODULE_FRAMEWORKS = $$MODULE_LIBS
- inc = $$MODULE_LIBS/$${MODULE_NAME}.framework/Headers
- MODULE_INCLUDES = $$inc
- contains(MODULE_CONFIG, internal_module): \
- MODULE_INCLUDES += \
- $$inc/$$eval(QT.$${QTLIB}.VERSION) \
- $$inc/$$eval(QT.$${QTLIB}.VERSION)/$$MODULE_NAME
- } else {
- # Re-insert the major version in the library name (cf qt5LibraryTarget above)
- MODULE_NAME ~= s,^Qt,Qt$$QT_MAJOR_VERSION,
- }
-
- # Only link to this module if a libs directory is set, else this is just a module
- # to give access to sources or include files, and not for linking.
- !isEmpty(MODULE_LIBS):!contains(MODULE_CONFIG, no_link): \
- MODULE_MODULE = $${MODULE_NAME}$${QT_LIBINFIX}
- }
-
# Frameworks shouldn't need include paths, but much code does not use
# module-qualified #includes, so by default we add paths which point
# directly into the frameworks. Private modules have somewhat convoluted
diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf
index 4ad9946ae0..6cb2e78c1c 100644
--- a/mkspecs/features/qt_common.prf
+++ b/mkspecs/features/qt_common.prf
@@ -89,6 +89,14 @@ clang {
greaterThan(QT_GCC_MAJOR_VERSION, 5): QMAKE_CXXFLAGS_WARN_ON += -Wshift-overflow=2 -Wduplicated-cond
# GCC 7 has a lot of false positives relating to this, so disable completely
greaterThan(QT_GCC_MAJOR_VERSION, 6): QMAKE_CXXFLAGS_WARN_ON += -Wno-stringop-overflow
+ # GCC 9 has a lot of false positives relating to this, so disable completely
+ greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-deprecated-copy
+ # GCC 9 introduced this
+ greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-redundant-move
+ # GCC 9 introduced this
+ greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-format-overflow
+ # GCC 9 introduced this
+ greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-init-list-lifetime
}
warnings_are_errors:warning_clean {
@@ -104,16 +112,17 @@ warnings_are_errors:warning_clean {
QMAKE_CXXFLAGS_WARN_ON += -Werror -Wno-error=\\$${LITERAL_HASH}warnings -Wno-error=deprecated-declarations $$WERROR
}
} else:intel_icc:linux {
- # Intel CC 13.0 - 17.0, on Linux only
+ # Intel CC 13.0 - 18.0, on Linux only
ver = $${QT_ICC_MAJOR_VERSION}.$${QT_ICC_MINOR_VERSION}
- linux:contains(ver, "(1[3456]\\.|17\\.0)") {
+ linux:contains(ver, "(1[345678]\\.|19\\.0)") {
# 177: function "entity" was declared but never referenced
# (too aggressive; ICC reports even for functions created due to template instantiation)
# 1224: #warning directive
# 1478: function "entity" (declared at line N) was declared deprecated
+ # 1786: function "entity" (declared at line N of "file") was declared deprecated ("message")
# 1881: argument must be a constant null pointer value
# (NULL in C++ is usually a literal 0)
- QMAKE_CXXFLAGS_WARN_ON += -Werror -ww177,1224,1478,1881 $$WERROR
+ QMAKE_CXXFLAGS_WARN_ON += -Werror -ww177,1224,1478,1786,1881 $$WERROR
}
} else:gcc:!clang:!intel_icc:!rim_qcc {
# GCC 4.6-4.9, 5.x, ...
@@ -127,7 +136,14 @@ warnings_are_errors:warning_clean {
# GCC 7 includes -Wimplicit-fallthrough in -Wextra, but Qt is not yet free of implicit fallthroughs.
greaterThan(QT_GCC_MAJOR_VERSION, 6): QMAKE_CXXFLAGS_WARN_ON += -Wno-error=implicit-fallthrough
-
+ # GCC 9 has a lot of false positives relating to this, so disable completely
+ greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-deprecated-copy
+ # GCC 9 introduced this
+ greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-redundant-move
+ # GCC 9 introduced this
+ greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-format-overflow
+ # GCC 9 introduced this
+ greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-init-list-lifetime
# Work-around for bug https://code.google.com/p/android/issues/detail?id=58135
android: QMAKE_CXXFLAGS_WARN_ON += -Wno-error=literal-suffix
}
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"())
diff --git a/mkspecs/features/qt_docs.prf b/mkspecs/features/qt_docs.prf
index 3139c443c6..3b74cd4dd5 100644
--- a/mkspecs/features/qt_docs.prf
+++ b/mkspecs/features/qt_docs.prf
@@ -18,7 +18,7 @@ isEmpty(qtver.value): error("No version for documentation specified.")
qtmver.name = QT_VER
qtmver.value = $$replace(qtver.value, ^(\\d+\\.\\d+).*$, \\1)
qtvertag.name = QT_VERSION_TAG
-qtvertag.value = $$replace(qtver.value, \.,)
+qtvertag.value = $$replace(qtver.value, \\.,)
qtdocs.name = QT_INSTALL_DOCS
qtdocs.value = $$[QT_INSTALL_DOCS/src]
builddir.name = BUILDDIR
diff --git a/mkspecs/features/qt_helper_lib.prf b/mkspecs/features/qt_helper_lib.prf
index 05d3b941bd..2cb54fc547 100644
--- a/mkspecs/features/qt_helper_lib.prf
+++ b/mkspecs/features/qt_helper_lib.prf
@@ -31,6 +31,7 @@ THE_TARGET = $$qt5LibraryTarget($$TARGET)
!build_pass {
MODULE = $$replace(TARGET, ^qt, )
+ MODULE ~= s,-,_,
MODULE_PRI = $$MODULE_QMAKE_OUTDIR/mkspecs/modules/qt_ext_$${MODULE}.pri
ucmodule = $$upper($$MODULE)
@@ -46,7 +47,7 @@ THE_TARGET = $$qt5LibraryTarget($$TARGET)
for (use, QMAKE_USE) {
use = $$split(use, /)
name = $$take_first(use)
- nu = $$upper($$name)
+ nu = $$upper($$replace(name, -, _))
!contains(use, linkonly): CC_USES += $$nu
!contains(use, nolink): LD_USES += $$nu
}
diff --git a/mkspecs/features/qt_module_headers.prf b/mkspecs/features/qt_module_headers.prf
index 70d3520e5c..6b4b9143fa 100644
--- a/mkspecs/features/qt_module_headers.prf
+++ b/mkspecs/features/qt_module_headers.prf
@@ -239,6 +239,14 @@ headersclean:!internal_module {
gcc_ver = $${QT_GCC_MAJOR_VERSION}.$${QT_GCC_MINOR_VERSION}
versionAtLeast(gcc_ver, 4.5): hcleanFLAGS += -Wdouble-promotion
versionAtLeast(gcc_ver, 4.9): hcleanFLAGS += -Wfloat-conversion
+ # GCC 9 has a lot of false positives relating to this, so disable completely
+ greaterThan(QT_GCC_MAJOR_VERSION, 8): hcleanFLAGS += -Wno-deprecated-copy
+ # GCC 9 introduced this
+ greaterThan(QT_GCC_MAJOR_VERSION, 8): hcleanFLAGS += -Wno-redundant-move
+ # GCC 9 introduced this
+ greaterThan(QT_GCC_MAJOR_VERSION, 8): hcleanFLAGS += -Wno-format-overflow
+ # GCC 9 introduced this
+ greaterThan(QT_GCC_MAJOR_VERSION, 8): hcleanFLAGS += -Wno-init-list-lifetime
c++11 {
# only enabled for actual c++11 builds due to
diff --git a/mkspecs/features/resources.prf b/mkspecs/features/resources.prf
index a25846bd77..48e9f83885 100644
--- a/mkspecs/features/resources.prf
+++ b/mkspecs/features/resources.prf
@@ -73,17 +73,14 @@ for(resource, RESOURCES) {
}
!isEmpty(RESOURCES):contains(TEMPLATE, .*lib):plugin:static {
- pluginName = $$lower($$replace(_PRO_FILE_, .*/([^/.]+)\\.[^/.]+, \\1))
-
- resource_init_function = $${pluginName}_plugin_resource_init
+ resource_init_function = $$lower($$basename(TARGET))_plugin_resource_init
DEFINES += "QT_PLUGIN_RESOURCE_INIT_FUNCTION=$$resource_init_function"
-
- RESOURCE_INIT_CPP = $$OUT_PWD/$${pluginName}_plugin_resources.cpp
+ RESOURCE_INIT_CPP = $$OUT_PWD/$$lower($$basename(TARGET))_plugin_resources.cpp
GENERATED_SOURCES += $$RESOURCE_INIT_CPP
QMAKE_DISTCLEAN += $$RESOURCE_INIT_CPP
- !build_pass {
+ isEmpty(BUILDS)|build_pass {
RESOURCE_INIT_CONT = \
"// This file is autogenerated by qmake. It contains a function that" \
"// references all resources the plugin includes and the function is" \
diff --git a/mkspecs/features/static_runtime.prf b/mkspecs/features/static_runtime.prf
index 1af3236189..e20bfc4281 100644
--- a/mkspecs/features/static_runtime.prf
+++ b/mkspecs/features/static_runtime.prf
@@ -1,7 +1,7 @@
msvc {
# -MD becomes -MT, -MDd becomes -MTd
- QMAKE_CFLAGS ~= s,^-MD(d?)$,-MT\1,g
- QMAKE_CXXFLAGS ~= s,^-MD(d?)$,-MT\1,g
+ QMAKE_CFLAGS ~= s,^-MD(d?)$,-MT\\1,g
+ QMAKE_CXXFLAGS ~= s,^-MD(d?)$,-MT\\1,g
} else: mingw {
QMAKE_LFLAGS += -static
}
diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf
index 55295f271f..2a7cbabc54 100644
--- a/mkspecs/features/toolchain.prf
+++ b/mkspecs/features/toolchain.prf
@@ -1,28 +1,22 @@
-
-defineReplace(qtMakeExpand) {
- out = "$$1"
- for(ever) {
- m = $$replace(out, ".*\\$\\(EXPORT_([^)]+)\\).*", \\1)
- equals(m, $$out): \
- return($$out)
- out = $$replace(out, "\\$\\(EXPORT_$$m\\)", $$eval($$m))
- }
+defineTest(qtToolchainError) {
+ msg = \
+ $$1 \
+ "===================" \
+ $$2 \
+ "===================" \
+ $$3
+ error($$join(msg, $$escape_expand(\\n)))
}
-defineTest(qtCompilerErrror) {
+defineTest(qtCompilerError) {
!cross_compile: \
what =
else: host_build: \
what = " host"
else: \
what = " target"
- msg = \
- "Cannot run$$what compiler '$$1'. Output:" \
- "===================" \
- $$2 \
- "===================" \
- "Maybe you forgot to setup the environment?"
- error($$join(msg, $$escape_expand(\\n)))
+ qtToolchainError("Cannot run$$what compiler '$$1'. Output:", $$2, \
+ "Maybe you forgot to setup the environment?")
}
cross_compile:host_build: \
@@ -30,6 +24,142 @@ cross_compile:host_build: \
else: \
target_prefix = QMAKE_CXX
+#
+# Determine and cache the compiler version
+#
+
+defineReplace(qtVariablesFromMSVC) {
+ ret = $$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) 2>NUL", lines, ec)
+ !equals(ec, 0): qtCompilerError($$1, $$ret)
+ return($$ret)
+}
+
+defineReplace(qtVariablesFromGCC) {
+ ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) \
+ 2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec)
+ !equals(ec, 0): qtCompilerError($$1, $$ret)
+ return($$ret)
+}
+
+isEmpty($${target_prefix}.COMPILER_MACROS) {
+ msvc {
+ clang_cl {
+ # We need to obtain the cl.exe version first
+ vars = $$qtVariablesFromMSVC(cl)
+ for (v, vars) {
+ isEmpty(v)|contains(v, $${LITERAL_HASH}.*): next()
+ eval($$v)
+ }
+ isEmpty(QMAKE_MSC_FULL_VER): error("Could not determine the Visual Studio version")
+
+ QMAKE_CFLAGS_MSVC_COMPAT = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", \
+ "-fms-compatibility-version=\\1.\\2.\\3")
+ cache($${target_prefix}.QMAKE_CFLAGS_MSVC_COMPAT, set stash, QMAKE_CFLAGS_MSVC_COMPAT)
+ $${target_prefix}.COMPILER_MACROS += QMAKE_CFLAGS_MSVC_COMPAT
+ vars = $$qtVariablesFromMSVC($$QMAKE_CXX, $$QMAKE_CFLAGS_MSVC_COMPAT)
+ } else {
+ vars = $$qtVariablesFromMSVC($$QMAKE_CXX)
+ }
+ } else: gcc|ghs {
+ vars = $$qtVariablesFromGCC($$QMAKE_CXX)
+ }
+ for (v, vars) {
+ !contains(v, "[A-Z_]+ = .*"): next()
+ # Set both <varname> for the outer scope ...
+ eval($$v)
+ v ~= s/ .*//
+ isEmpty($$v): error("Compiler produced empty value for $${v}.")
+ # ... and save QMAKE_(HOST_)?CXX.<varname> in the cache.
+ cache($${target_prefix}.$$v, set stash, $$v)
+ $${target_prefix}.COMPILER_MACROS += $$v
+ }
+ cache($${target_prefix}.COMPILER_MACROS, set stash)
+} else {
+ # load from the cache
+ for (i, $${target_prefix}.COMPILER_MACROS): \
+ $$i = $$eval($${target_prefix}.$$i)
+}
+
+# Populate QMAKE_COMPILER_DEFINES and some compatibility variables.
+# The $$format_number() calls strip leading zeros to avoid misinterpretation as octal.
+QMAKE_COMPILER_DEFINES += __cplusplus=$$QT_COMPILER_STDCXX
+!isEmpty(QMAKE_MSC_VER): \
+ QMAKE_COMPILER_DEFINES += _MSC_VER=$$QMAKE_MSC_VER _MSC_FULL_VER=$$QMAKE_MSC_FULL_VER
+!isEmpty(QMAKE_ICC_VER): \
+ QMAKE_COMPILER_DEFINES += __INTEL_COMPILER=$$QMAKE_ICC_VER __INTEL_COMPILER_UPDATE=$$QMAKE_ICC_UPDATE_VER
+!isEmpty(QMAKE_APPLE_CC): \
+ QMAKE_COMPILER_DEFINES += __APPLE_CC__=$$QMAKE_APPLE_CC
+!isEmpty(QMAKE_APPLE_CLANG_MAJOR_VERSION): \
+ QMAKE_COMPILER_DEFINES += __clang__ \
+ __clang_major__=$$QMAKE_APPLE_CLANG_MAJOR_VERSION \
+ __clang_minor__=$$QMAKE_APPLE_CLANG_MINOR_VERSION \
+ __clang_patchlevel__=$$QMAKE_APPLE_CLANG_PATCH_VERSION
+!isEmpty(QMAKE_CLANG_MAJOR_VERSION): \
+ QMAKE_COMPILER_DEFINES += __clang__ \
+ __clang_major__=$$QMAKE_CLANG_MAJOR_VERSION \
+ __clang_minor__=$$QMAKE_CLANG_MINOR_VERSION \
+ __clang_patchlevel__=$$QMAKE_CLANG_PATCH_VERSION
+!isEmpty(QMAKE_GCC_MAJOR_VERSION): \
+ QMAKE_COMPILER_DEFINES += \
+ __GNUC__=$$QMAKE_GCC_MAJOR_VERSION \
+ __GNUC_MINOR__=$$QMAKE_GCC_MINOR_VERSION \
+ __GNUC_PATCHLEVEL__=$$QMAKE_GCC_PATCH_VERSION
+!isEmpty(QMAKE_GHS_VERSION): \
+ QMAKE_COMPILER_DEFINES += __ghs__ __GHS_VERSION_NUMBER=$$QMAKE_GHS_VERSION
+
+QMAKE_CFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT
+QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT
+
+clang_cl|intel_icl {
+ include(../common/msvc-based-version.conf)
+} else: msvc {
+ include(../common/msvc-version.conf)
+}
+
+#
+# Determine and cache the default search paths
+#
+
+defineReplace(qtMakeExpand) {
+ out = "$$1"
+ for(ever) {
+ m = $$replace(out, ".*\\$\\(EXPORT_([^)]+)\\).*", \\1)
+ equals(m, $$out): \
+ return($$out)
+ out = $$replace(out, "\\$\\(EXPORT_$$m\\)", $$eval($$m))
+ }
+}
+
+defineReplace(qtSplitPathList) {
+ paths = $$split(1, $$QMAKE_DIRLIST_SEP)
+ ret =
+ for (p, paths): \
+ ret += $$clean_path($$p)
+ return($$ret)
+}
+
+defineReplace(qtNmakePathList) {
+ paths =
+ for (p, 1): \
+ paths += $$shell_path($$p)
+ paths ~= s,$${LITERAL_HASH},^$${LITERAL_HASH},g
+ paths ~= s,\\$,\$\$,g
+ return($$join(paths, $$QMAKE_DIRLIST_SEP))
+}
+
+msvc {
+ arch = $$lower($$VCPROJ_ARCH)
+ equals(arch, x64): \ # may be "win32" or undefined
+ arch = amd64
+ else: !equals(arch, arm):!equals(arch, arm64): \ # may be "win32" or undefined
+ arch = x86
+ # Consider only WinRT and ARM64 desktop builds to be cross-builds -
+ # the host is assumed to be Intel and capable of running the target
+ # executables (so building for x64 on x86 will break).
+ winrt|equals(arch, arm64): \
+ CONFIG += msvc_cross
+}
+
isEmpty($${target_prefix}.INCDIRS) {
#
# Get default include and library paths from compiler
@@ -69,7 +199,7 @@ isEmpty($${target_prefix}.INCDIRS) {
cxx_flags += -E -v
output = $$system("$$cmd_prefix $$QMAKE_CXX $$qtMakeExpand($$cxx_flags) -xc++ - 2>&1 $$cmd_suffix", lines, ec)
- !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX, $$output)
+ !equals(ec, 0): qtCompilerError($$QMAKE_CXX, $$output)
rim_qcc {
for (line, output) {
@@ -129,7 +259,7 @@ isEmpty($${target_prefix}.INCDIRS) {
# What's more, -print-search-dirs can't be used on clang on Apple because it
# won't print all the library paths (only the clang-internal ones).
output = $$system("$$cmd_prefix $$QMAKE_LINK $$QMAKE_LFLAGS -print-search-dirs", lines, ec)
- !equals(ec, 0): qtCompilerErrror($$QMAKE_LINK, $$output)
+ !equals(ec, 0): qtCompilerError($$QMAKE_LINK, $$output)
for (line, output) {
contains(line, "^libraries: .*") {
@@ -149,7 +279,7 @@ isEmpty($${target_prefix}.INCDIRS) {
} else: ghs {
cmd = $$QMAKE_CXX $$QMAKE_CXXFLAGS -$${LITERAL_HASH} -o /tmp/fake_output /tmp/fake_input.cpp
output = $$system("$$cmd", blob, ec)
- !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX, $$output)
+ !equals(ec, 0): qtCompilerError($$QMAKE_CXX, $$output)
output ~= s/\\\\\\n {8}//g
output = $$split(output, $$escape_expand(\\n))
for (line, output) {
@@ -169,113 +299,121 @@ isEmpty($${target_prefix}.INCDIRS) {
}
}
}
+ } else: msvc_cross {
+ # Use a batch file, because %VAR% in the system() call expands to
+ # the pre-script-call value, and !VAR! cannot be enabled outside
+ # a batch file without invoking another shell instance.
+ cmd = $$system_quote($$system_path($$PWD/data/dumpvcvars.bat))
+
+ hostArch = $$QMAKE_HOST.arch
+ equals(hostArch, x86_64): \
+ hostArch = amd64
+ !equals(arch, $$hostArch): \
+ arch = $${hostArch}_$$arch
+
+ isEmpty(MSVC_VER): \
+ error("Mkspec does not specify MSVC_VER. Cannot continue.")
+ versionAtLeast(MSVC_VER, 15.0) {
+ dir = $$(VSINSTALLDIR)
+ isEmpty(dir): \
+ dir = $$read_registry(HKLM, \
+ "Software\\Microsoft\\VisualStudio\\SxS\\VS7\\$$MSVC_VER", 32)
+ isEmpty(dir): \
+ error("Failed to find the Visual Studio installation directory.")
+ cmd += $$system_quote($$dir\\VC\\Auxiliary\\Build\\vcvarsall.bat) $$arch
+ } else {
+ dir = $$(VCINSTALLDIR)
+ isEmpty(dir): \
+ dir = $$read_registry(HKLM, \
+ "Software\\Microsoft\\VisualStudio\\$$MSVC_VER\\Setup\\VC\\ProductDir", 32)
+ isEmpty(dir): \
+ error("Failed to find the Visual C installation directory.")
+ cmd += $$system_quote($$dir\\vcvarsall.bat) $$arch
+ }
+ winrt: cmd += store
+
+ isEmpty(WINSDK_VER): \
+ error("Mkspec does not specify WINSDK_VER. Cannot continue.")
+ # We prefer the environment variable, because that may work around
+ # a broken registry entry after uninstalling a newer SDK.
+ # However, we do that only if the major+minor SDK version matches
+ # the one requested by the mkspec, as we might be building for a
+ # newer target than the host.
+ winsdk_ver = $$(WindowsSDKVersion)
+ !isEmpty(winsdk_ver) {
+ winsdk_ver ~= s,\\\\$,, # Work around SDK breakage.
+ !equals(WINSDK_VER, $$replace(winsdk_ver, ^(\\d+\\.\\d+).*$, \\1)): \
+ winsdk_ver =
+ }
+ !isEmpty(winsdk_ver) {
+ cmd += $$winsdk_ver
+ } else {
+ winsdk_ver = $$read_registry(HKLM, \
+ "Software\\Microsoft\\Microsoft SDKs\\Windows\\v$$WINSDK_VER\\ProductVersion", 32)
+ isEmpty(winsdk_ver): \
+ error("Windows SDK $$WINSDK_VER requested by mkspec is not installed. Cannot continue.")
+ cmd += $${winsdk_ver}.0
+ }
+
+ output = $$system("$$cmd 2>&1", lines, ec)
+ !equals(ec, 0): \
+ qtToolchainError("SDK setup script failed. Output:", $$output, \
+ "Command was: $$cmd")
+ lines = $$output
+ for(ever) {
+ isEmpty(lines): \
+ break()
+ line = $$take_first(lines)
+ equals(line, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+="): \
+ break()
+ }
+ !count(lines, 3): \
+ qtToolchainError("SDK setup script returned unexpected output:", $$output, \
+ "Command was: $$cmd")
+
+ # These contain only paths for the target.
+ QMAKE_DEFAULT_INCDIRS = $$qtSplitPathList($$member(lines, 0))
+ QMAKE_DEFAULT_LIBDIRS = $$qtSplitPathList($$member(lines, 1))
+ # PATH is inherently for the host, and paths that are not shadowed
+ # by vcvarsall.bat are assumed to contain only tools that work for
+ # both host and target builds.
+ QMAKE_DEFAULT_PATH = $$qtSplitPathList($$member(lines, 2))
+ # We de-duplicate, because the script just prepends to the paths for
+ # the host, some of which are identical to the ones for the target.
+ QMAKE_DEFAULT_PATH = $$unique(QMAKE_DEFAULT_PATH)
} else: msvc {
- # This doesn't differentiate between host and target,
- # but neither do the compilers.
LIB = $$getenv("LIB")
QMAKE_DEFAULT_LIBDIRS = $$split(LIB, $$QMAKE_DIRLIST_SEP)
INCLUDE = $$getenv("INCLUDE")
QMAKE_DEFAULT_INCDIRS = $$split(INCLUDE, $$QMAKE_DIRLIST_SEP)
}
- unix {
+ unix:if(!cross_compile|host_build) {
isEmpty(QMAKE_DEFAULT_INCDIRS): QMAKE_DEFAULT_INCDIRS = /usr/include /usr/local/include
isEmpty(QMAKE_DEFAULT_LIBDIRS): QMAKE_DEFAULT_LIBDIRS = /lib /usr/lib
}
- cache($${target_prefix}.INCDIRS, set stash, QMAKE_DEFAULT_INCDIRS)
- cache($${target_prefix}.LIBDIRS, set stash, QMAKE_DEFAULT_LIBDIRS)
+ # cache() complains about undefined variables and doesn't persist empty ones.
+ !isEmpty(QMAKE_DEFAULT_INCDIRS): \
+ cache($${target_prefix}.INCDIRS, set stash, QMAKE_DEFAULT_INCDIRS)
+ !isEmpty(QMAKE_DEFAULT_LIBDIRS): \
+ cache($${target_prefix}.LIBDIRS, set stash, QMAKE_DEFAULT_LIBDIRS)
+ !isEmpty(QMAKE_DEFAULT_PATH): \
+ cache($${target_prefix}.PATH, set stash, QMAKE_DEFAULT_PATH)
} else {
QMAKE_DEFAULT_INCDIRS = $$eval($${target_prefix}.INCDIRS)
QMAKE_DEFAULT_LIBDIRS = $$eval($${target_prefix}.LIBDIRS)
+ QMAKE_DEFAULT_PATH = $$eval($${target_prefix}.PATH)
}
-#
-# Determine and cache the compiler version
-#
-
-defineReplace(qtVariablesFromMSVC) {
- ret = $$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) 2>NUL", lines, ec)
- !equals(ec, 0): qtCompilerErrror($$1, $$ret)
- return($$ret)
-}
-
-defineReplace(qtVariablesFromGCC) {
- ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) \
- 2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec)
- !equals(ec, 0): qtCompilerErrror($$1, $$ret)
- return($$ret)
-}
-
-isEmpty($${target_prefix}.COMPILER_MACROS) {
- msvc {
- clang_cl {
- # We need to obtain the cl.exe version first
- vars = $$qtVariablesFromMSVC(cl)
- for (v, vars) {
- isEmpty(v)|contains(v, $${LITERAL_HASH}.*): next()
- eval($$v)
- }
- isEmpty(QMAKE_MSC_FULL_VER): error("Could not determine the Visual Studio version")
-
- QMAKE_CFLAGS_MSVC_COMPAT = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", \
- "-fms-compatibility-version=\\1.\\2.\\3")
- cache($${target_prefix}.QMAKE_CFLAGS_MSVC_COMPAT, set stash, QMAKE_CFLAGS_MSVC_COMPAT)
- $${target_prefix}.COMPILER_MACROS += QMAKE_CFLAGS_MSVC_COMPAT
- vars = $$qtVariablesFromMSVC($$QMAKE_CXX, $$QMAKE_CFLAGS_MSVC_COMPAT)
- } else {
- vars = $$qtVariablesFromMSVC($$QMAKE_CXX)
- }
- } else: gcc|ghs {
- vars = $$qtVariablesFromGCC($$QMAKE_CXX)
- }
- for (v, vars) {
- !contains(v, "[A-Z_]+ = .*"): next()
- # Set both <varname> for the outer scope ...
- eval($$v)
- v ~= s/ .*//
- isEmpty($$v): error("Compiler produced empty value for $${v}.")
- # ... and save QMAKE_(HOST_)?CXX.<varname> in the cache.
- cache($${target_prefix}.$$v, set stash, $$v)
- $${target_prefix}.COMPILER_MACROS += $$v
- }
- cache($${target_prefix}.COMPILER_MACROS, set stash)
-} else {
- # load from the cache
- for (i, $${target_prefix}.COMPILER_MACROS): \
- $$i = $$eval($${target_prefix}.$$i)
+msvc_cross {
+ qmake_inc_exp.name = INCLUDE
+ qmake_inc_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_INCDIRS)
+ qmake_lib_exp.name = LIB
+ qmake_lib_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_LIBDIRS)
+ qmake_path_exp.name = PATH
+ qmake_path_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_PATH)
+ QMAKE_EXPORTED_VARIABLES += qmake_inc_exp qmake_lib_exp qmake_path_exp
}
unset(target_prefix)
-
-# Populate QMAKE_COMPILER_DEFINES and some compatibility variables.
-# The $$format_number() calls strip leading zeros to avoid misinterpretation as octal.
-QMAKE_COMPILER_DEFINES += __cplusplus=$$QT_COMPILER_STDCXX
-!isEmpty(QMAKE_MSC_VER): \
- QMAKE_COMPILER_DEFINES += _MSC_VER=$$QMAKE_MSC_VER _MSC_FULL_VER=$$QMAKE_MSC_FULL_VER
-!isEmpty(QMAKE_ICC_VER): \
- QMAKE_COMPILER_DEFINES += __INTEL_COMPILER=$$QMAKE_ICC_VER __INTEL_COMPILER_UPDATE=$$QMAKE_ICC_UPDATE_VER
-!isEmpty(QMAKE_APPLE_CC): \
- QMAKE_COMPILER_DEFINES += __APPLE_CC__=$$QMAKE_APPLE_CC
-!isEmpty(QMAKE_APPLE_CLANG_MAJOR_VERSION): \
- QMAKE_COMPILER_DEFINES += __clang__ \
- __clang_major__=$$QMAKE_APPLE_CLANG_MAJOR_VERSION \
- __clang_minor__=$$QMAKE_APPLE_CLANG_MINOR_VERSION \
- __clang_patchlevel__=$$QMAKE_APPLE_CLANG_PATCH_VERSION
-!isEmpty(QMAKE_CLANG_MAJOR_VERSION): \
- QMAKE_COMPILER_DEFINES += __clang__ \
- __clang_major__=$$QMAKE_CLANG_MAJOR_VERSION \
- __clang_minor__=$$QMAKE_CLANG_MINOR_VERSION \
- __clang_patchlevel__=$$QMAKE_CLANG_PATCH_VERSION
-!isEmpty(QMAKE_GCC_MAJOR_VERSION): \
- QMAKE_COMPILER_DEFINES += \
- __GNUC__=$$QMAKE_GCC_MAJOR_VERSION \
- __GNUC_MINOR__=$$QMAKE_GCC_MINOR_VERSION \
- __GNUC_PATCHLEVEL__=$$QMAKE_GCC_PATCH_VERSION
-!isEmpty(QMAKE_GHS_VERSION): \
- QMAKE_COMPILER_DEFINES += __ghs__ __GHS_VERSION_NUMBER=$$QMAKE_GHS_VERSION
-
-QMAKE_CFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT
-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT
-
-msvc:!intel_icl:!clang_cl: include(../common/msvc-version.conf)
diff --git a/mkspecs/win32-clang-msvc/qmake.conf b/mkspecs/win32-clang-msvc/qmake.conf
index ba9704e069..027f93ca6e 100644
--- a/mkspecs/win32-clang-msvc/qmake.conf
+++ b/mkspecs/win32-clang-msvc/qmake.conf
@@ -15,6 +15,14 @@ QMAKE_CFLAGS += -Wno-microsoft-enum-value
QMAKE_CXXFLAGS += -Wno-microsoft-enum-value
+QMAKE_LINK = lld-link
+QMAKE_LIB = llvm-lib /NOLOGO
+
+QMAKE_CFLAGS_LTCG = -flto
+QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
+# Leave QMAKE_LFLAGS_LTCG empty because lld-link doesn't need any additional parameters
+QMAKE_LFLAGS_LTCG =
+
# Precompiled headers are not supported yet by clang
CONFIG -= precompile_header
diff --git a/mkspecs/winrt-arm-msvc2015/qmake.conf b/mkspecs/winrt-arm-msvc2015/qmake.conf
index 8bca6f4af8..bc113d4954 100644
--- a/mkspecs/winrt-arm-msvc2015/qmake.conf
+++ b/mkspecs/winrt-arm-msvc2015/qmake.conf
@@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One
VCPROJ_ARCH = ARM
WINSDK_VER = 10.0
-WINTARGET_VER = winv10.0
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
WINRT_MANIFEST.architecture = arm
diff --git a/mkspecs/winrt-arm-msvc2017/qmake.conf b/mkspecs/winrt-arm-msvc2017/qmake.conf
index bf571d620c..1160d5766d 100644
--- a/mkspecs/winrt-arm-msvc2017/qmake.conf
+++ b/mkspecs/winrt-arm-msvc2017/qmake.conf
@@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One
VCPROJ_ARCH = ARM
WINSDK_VER = 10.0
-WINTARGET_VER = winv10.0
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
WINRT_MANIFEST.architecture = arm
diff --git a/mkspecs/winrt-x64-msvc2015/qmake.conf b/mkspecs/winrt-x64-msvc2015/qmake.conf
index d503399e3c..d1d1eb6513 100644
--- a/mkspecs/winrt-x64-msvc2015/qmake.conf
+++ b/mkspecs/winrt-x64-msvc2015/qmake.conf
@@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One
VCPROJ_ARCH = x64
WINSDK_VER = 10.0
-WINTARGET_VER = winv10.0
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
WINRT_MANIFEST.architecture = x64
diff --git a/mkspecs/winrt-x64-msvc2017/qmake.conf b/mkspecs/winrt-x64-msvc2017/qmake.conf
index cb2209fa23..dce896bd47 100644
--- a/mkspecs/winrt-x64-msvc2017/qmake.conf
+++ b/mkspecs/winrt-x64-msvc2017/qmake.conf
@@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One
VCPROJ_ARCH = x64
WINSDK_VER = 10.0
-WINTARGET_VER = winv10.0
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
WINRT_MANIFEST.architecture = x64
diff --git a/mkspecs/winrt-x86-msvc2015/qmake.conf b/mkspecs/winrt-x86-msvc2015/qmake.conf
index 37ce0e5525..06f059b600 100644
--- a/mkspecs/winrt-x86-msvc2015/qmake.conf
+++ b/mkspecs/winrt-x86-msvc2015/qmake.conf
@@ -14,6 +14,5 @@ QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib
QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib
VCPROJ_ARCH = Win32
WINSDK_VER = 10.0
-WINTARGET_VER = winv10.0
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
WINRT_MANIFEST.architecture = x86
diff --git a/mkspecs/winrt-x86-msvc2017/qmake.conf b/mkspecs/winrt-x86-msvc2017/qmake.conf
index 3c9506bbad..94fb68f6c0 100644
--- a/mkspecs/winrt-x86-msvc2017/qmake.conf
+++ b/mkspecs/winrt-x86-msvc2017/qmake.conf
@@ -14,6 +14,5 @@ QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib
QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib
VCPROJ_ARCH = Win32
WINSDK_VER = 10.0
-WINTARGET_VER = winv10.0
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
WINRT_MANIFEST.architecture = x86