diff --git a/.gitignore b/.gitignore index a1079a33c6b..e0677a3a68a 100644 --- a/.gitignore +++ b/.gitignore @@ -120,6 +120,7 @@ config.opt config.status config.summary config.log +config.cache mkspecs/default mkspecs/default-host mkspecs/qconfig.pri @@ -127,12 +128,14 @@ mkspecs/qdevice.pri mkspecs/qfeatures.pri mkspecs/qhost.pri moc_*.cpp +qmake/qmake qmake/qmake.exe qmake/Makefile.bak qmake/qmake_pch.pch src/corelib/global/qconfig.cpp src/corelib/global/qconfig.h src/corelib/global/qconfig.h.qmake +src/corelib/global/qconfig_p.h src/corelib/global/qfeatures.h src/platformsupport/*_interface.* src/platformsupport/*_adaptor.* @@ -155,6 +158,9 @@ translations/*_untranslated.ts qrc_*.cpp *.version *.version.in +qt*-config.h +qt*-config_p.h +qt*-config.pri # Test generated files QObject.log diff --git a/config.tests/win/msvc_version.cpp b/config.tests/win/msvc_version.cpp deleted file mode 100644 index 3d7232e8e27..00000000000 --- a/config.tests/win/msvc_version.cpp +++ /dev/null @@ -1 +0,0 @@ -_MSC_FULL_VER diff --git a/configure b/configure index 82df73fb1b1..8827e63a78d 100755 --- a/configure +++ b/configure @@ -82,6 +82,11 @@ if [ x"$1" = x"-top-level" ]; then relpathMangled=`dirname "$relpath"` outpathPrefix=../ shift +else + if [ -f ../.qmake.super ]; then + echo >&2 "ERROR: You cannot configure qtbase separately within a top-level build." + exit 1 + fi fi OPT_CMDLINE= # expanded version for the script @@ -522,6 +527,16 @@ done if [ "$OPT_HELP" = "yes" ]; then cat $relpath/config_help.txt + if [ -n "$CFG_TOPLEVEL" ]; then + IFS=' +' + for i in $relpathMangled/qt*/config_help.txt; do + if [ x"$i" != x"$relpath/config_help.txt" ]; then + echo + cat "$i" + fi + done + fi exit 0 fi @@ -529,8 +544,8 @@ fi # platform detection #------------------------------------------------------------------------------- +PLATFORM_NOTES= if [ -z "$PLATFORM" ]; then - PLATFORM_NOTES= case "$UNAME_SYSTEM:$UNAME_RELEASE" in Darwin:*) PLATFORM=macx-clang @@ -540,9 +555,7 @@ if [ -z "$PLATFORM" ]; then #PLATFORM=aix-g++-64 PLATFORM=aix-xlc #PLATFORM=aix-xlc-64 - PLATFORM_NOTES=" - - Also available for AIX: aix-g++ aix-g++-64 aix-xlc-64 - " + PLATFORM_NOTES="AIX: aix-g++ aix-g++-64 aix-xlc-64" ;; GNU:*) PLATFORM=hurd-g++ @@ -559,14 +572,10 @@ if [ -z "$PLATFORM" ]; then FreeBSD:*) if [ "$(uname -r | cut -d. -f1)" -ge 10 ]; then PLATFORM=freebsd-clang - PLATFORM_NOTES=" - - Also available for FreeBSD: freebsd-g++ - " + PLATFORM_NOTES="FreeBSD: freebsd-g++" else PLATFORM=freebsd-g++ - PLATFORM_NOTES=" - - Also available for FreeBSD: freebsd-clang - " + PLATFORM_NOTES="FreeBSD: freebsd-clang" fi ;; OpenBSD:*) @@ -582,18 +591,14 @@ if [ -z "$PLATFORM" ]; then #PLATFORM=irix-g++ PLATFORM=irix-cc #PLATFORM=irix-cc-64 - PLATFORM_NOTES=" - - Also available for IRIX: irix-g++ irix-cc-64 - " + PLATFORM_NOTES="IRIX: irix-g++ irix-cc-64" ;; HP-UX:*) case "$UNAME_MACHINE" in ia64) #PLATFORM=hpuxi-acc-32 PLATFORM=hpuxi-acc-64 - PLATFORM_NOTES=" - - Also available for HP-UXi: hpuxi-acc-32 - " + PLATFORM_NOTES="HP-UXi: hpuxi-acc-32" ;; *) #PLATFORM=hpux-g++ @@ -601,39 +606,29 @@ if [ -z "$PLATFORM" ]; then #PLATFORM=hpux-acc-64 #PLATFORM=hpux-cc #PLATFORM=hpux-acc-o64 - PLATFORM_NOTES=" - - Also available for HP-UX: hpux-g++ hpux-acc-64 hpux-acc-o64 - " + PLATFORM_NOTES="HP-UX: hpux-g++ hpux-acc-64 hpux-acc-o64" ;; esac ;; OSF1:*) #PLATFORM=tru64-g++ PLATFORM=tru64-cxx - PLATFORM_NOTES=" - - Also available for Tru64: tru64-g++ - " + PLATFORM_NOTES="Tru64: tru64-g++" ;; Linux:*) PLATFORM=linux-g++ - PLATFORM_NOTES=" - - Also available for Linux: linux-clang linux-kcc linux-icc linux-cxx - " + PLATFORM_NOTES="Linux: linux-clang linux-kcc linux-icc linux-cxx" ;; SunOS:5*) #PLATFORM=solaris-g++ PLATFORM=solaris-cc #PLATFORM=solaris-cc64 - PLATFORM_NOTES=" - - Also available for Solaris: solaris-g++ solaris-cc-64 - " + PLATFORM_NOTES="Solaris: solaris-g++ solaris-cc-64" ;; ReliantUNIX-*:*|SINIX-*:*) PLATFORM=reliant-cds #PLATFORM=reliant-cds-64 - PLATFORM_NOTES=" - - Also available for Reliant UNIX: reliant-cds-64 - " + PLATFORM_NOTES="Reliant UNIX: reliant-cds-64" ;; CYGWIN*:*) PLATFORM=cygwin-g++ @@ -644,23 +639,17 @@ if [ -z "$PLATFORM" ]; then OpenUNIX:*) #PLATFORM=unixware-g++ PLATFORM=unixware-cc - PLATFORM_NOTES=" - - Also available for OpenUNIX: unixware-g++ - " + PLATFORM_NOTES="OpenUNIX: unixware-g++" ;; UnixWare:*) #PLATFORM=unixware-g++ PLATFORM=unixware-cc - PLATFORM_NOTES=" - - Also available for UnixWare: unixware-g++ - " + PLATFORM_NOTES="UnixWare: unixware-g++" ;; SCO_SV:*) #PLATFORM=sco-g++ PLATFORM=sco-cc - PLATFORM_NOTES=" - - Also available for SCO OpenServer: sco-g++ - " + PLATFORM_NOTES="SCO OpenServer: sco-g++" ;; UNIX_SV:*) PLATFORM=unixware-g++ @@ -678,6 +667,7 @@ if [ -z "$PLATFORM" ]; then exit 2 esac fi +echo "$PLATFORM_NOTES" > "${outpathPrefix}.config.notes" #------------------------------------------------------------------------------- # command line and environment validation @@ -895,11 +885,8 @@ Prefix=$relpath EOF fi -[ -z "$CFG_HOST_QT_TOOLS_PATH" ] && CFG_HOST_QT_TOOLS_PATH="$outpath/bin" -CFG_QMAKE_PATH="$CFG_HOST_QT_TOOLS_PATH/qmake" - #------------------------------------------------------------------------------- -# run configure tests +# configure and build top-level makefile #------------------------------------------------------------------------------- # recreate command line for qmake @@ -913,40 +900,12 @@ done set +f IFS=$SAVED_IFS -#------------------------------------------------------------------------------- -# configure and build top-level makefile -#------------------------------------------------------------------------------- - if [ -n "$CFG_TOPLEVEL" ]; then cd .. fi -"$CFG_QMAKE_PATH" -qtconf "$QTCONFFILE" "$relpathMangled" -- "$@" || exit - -#------------------------------------------------------------------------------- -# final notes for the user -#------------------------------------------------------------------------------- - -if [ -n "$PLATFORM_NOTES" ]; then - echo - echo "Platform notes:" - echo "$PLATFORM_NOTES" +if [ -n "$CFG_HOST_QT_TOOLS_PATH" ]; then + "$CFG_HOST_QT_TOOLS_PATH/qmake" -qtconf "$QTCONFFILE" "$relpathMangled" -- "$@" else - echo + "$outpath/bin/qmake" "$relpathMangled" -- "$@" fi - -QT_INSTALL_PREFIX=`sed -ne 's/^Prefix=//p' < "$outpath/qmake/builtin-qt.conf"` -MAKE=`basename "$MAKE"` -echo -echo Qt is now configured for building. Just run \'$MAKE\'. -if [ "$outpath" = "$QT_INSTALL_PREFIX" ]; then - echo Once everything is built, Qt is installed. - echo You should not run \'$MAKE install\'. -else - echo Once everything is built, you must run \'$MAKE install\'. - echo Qt will be installed into $QT_INSTALL_PREFIX -fi -echo -echo Prior to reconfiguration, make sure you remove any leftovers from -echo the previous build. -echo diff --git a/configure.bat b/configure.bat index 385b1e35565..7ce39e7ecf4 100644 --- a/configure.bat +++ b/configure.bat @@ -28,13 +28,40 @@ ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: @echo off -setlocal ENABLEEXTENSIONS +setlocal ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS set ARGS=%* set QTSRC=%~dp0 +set QTSRC=%QTSRC:~0,-1% set QTDIR=%CD% +rem Parse command line + +set TOPLEVEL=false +set TOPQTSRC=%QTSRC% +set TOPQTDIR=%QTDIR% +if /i not "%~1" == "-top-level" goto notoplevel +set ARGS=%ARGS:~10% +set TOPLEVEL=true +for %%P in ("%TOPQTSRC%") do set TOPQTSRC=%%~dpP +set TOPQTSRC=%TOPQTSRC:~0,-1% +for %%P in ("%QTDIR%") do set TOPQTDIR=%%~dpP +set TOPQTDIR=%TOPQTDIR:~0,-1% +goto wastoplevel +:notoplevel +if not exist ..\.qmake.super goto wastoplevel +echo ERROR: You cannot configure qtbase separately within a top-level build. >&2 +exit /b 1 +:wastoplevel + +set SYNCQT= +set PLATFORM= +set MAKE= +call :doargs %ARGS% +if errorlevel 1 exit /b +goto doneargs + :doargs - if "%~1" == "" goto doneargs + if "%~1" == "" exit /b if "%~1" == "/?" goto help if "%~1" == "-?" goto help @@ -44,25 +71,127 @@ set QTDIR=%CD% if /i "%~1" == "-help" goto help if /i "%~1" == "--help" goto help + if /i "%~1" == "-redo" goto redo + if /i "%~1" == "--redo" goto redo + + if /i "%~1" == "-platform" goto platform + if /i "%~1" == "--platform" goto platform + + if /i "%~1" == "-no-syncqt" goto nosyncqt + if /i "%~1" == "--no-syncqt" goto nosyncqt + + if /i "%~1" == "-make-tool" goto maketool + if /i "%~1" == "--make-tool" goto maketool + +:nextarg shift goto doargs + +:help + type %QTSRC%\config_help.txt + if %TOPLEVEL% == false exit /b 1 + for /d %%p in ("%TOPQTSRC%"\qt*) do ( + if not "%%p" == "%QTSRC%" ( + if exist "%%p\config_help.txt" ( + echo. + type "%%p\config_help.txt" + ) + ) + ) + exit /b 1 + +:redo + if not exist "%TOPQTDIR%\config.opt" goto redoerr + set rargs= + for /f "usebackq delims=" %%i in ("%TOPQTDIR%\config.opt") do set rargs=!rargs! "%%i" + call :doargs %rargs% + goto nextarg +:redoerr + echo No config.opt present - cannot redo configuration. >&2 + exit /b 1 + +:platform + shift + if "%~1" == "win32-msvc2012" goto msvc + if "%~1" == "win32-msvc2013" goto msvc + if "%~1" == "win32-msvc2015" goto msvc + if "%~1" == "win32-msvc2017" goto msvc + set PLATFORM=%~1 + goto nextarg +:msvc + echo. >&2 + echo Notice: re-mapping requested qmake spec to unified 'win32-msvc'. >&2 + echo. >&2 + set PLATFORM=win32-msvc + goto nextarg + +:nosyncqt + set SYNCQT=false + goto nextarg + +:maketool + shift + set MAKE=%~1 + goto nextarg + :doneargs -echo Please wait while bootstrapping configure ... - +rem Find various executables for %%C in (clang-cl.exe cl.exe icl.exe g++.exe perl.exe jom.exe) do set %%C=%%~$PATH:C -if "%perl.exe%" == "" ( - echo Perl not found in PATH. Aborting. >&2 +rem Determine host spec + +if "%PLATFORM%" == "" ( + if not "%icl.exe%" == "" ( + set PLATFORM=win32-icc + ) else if not "%clang-cl.exe%" == "" ( + set PLATFORM=win32-clang-msvc + ) else if not "%cl.exe%" == "" ( + set PLATFORM=win32-msvc + ) else if not "%g++.exe%" == "" ( + set PLATFORM=win32-g++ + ) else ( + echo Cannot detect host toolchain. Please use -platform. Aborting. >&2 + exit /b 1 + ) +) +if not exist "%QTSRC%\mkspecs\%PLATFORM%\qmake.conf" ( + echo Host platform '%PLATFORM%' is invalid. Aborting. >&2 exit /b 1 ) +if "%PLATFORM:win32-g++=%" == "%PLATFORM%" ( + if "%MAKE%" == "" ( + if not "%jom.exe%" == "" ( + set MAKE=jom + ) else ( + set MAKE=nmake + ) + ) + set tmpl=win32 +) else ( + if "%MAKE%" == "" ( + set MAKE=mingw32-make + ) + set tmpl=unix +) + +rem Prepare build dir + if not exist mkspecs ( md mkspecs - if errorlevel 1 goto exit + if errorlevel 1 exit /b +) +if not exist bin ( + md bin + if errorlevel 1 exit /b +) +if not exist qmake ( + md qmake + if errorlevel 1 exit /b ) rem Extract Qt's version from .qmake.conf -for /f "eol=# tokens=1,2,3,4 delims=.= " %%i in (%QTSRC%.qmake.conf) do ( +for /f "eol=# tokens=1,2,3,4 delims=.= " %%i in (%QTSRC%\.qmake.conf) do ( if %%i == MODULE_VERSION ( set QTVERMAJ=%%j set QTVERMIN=%%k @@ -71,69 +200,85 @@ for /f "eol=# tokens=1,2,3,4 delims=.= " %%i in (%QTSRC%.qmake.conf) do ( ) set QTVERSION=%QTVERMAJ%.%QTVERMIN%.%QTVERPAT% -perl %QTSRC%bin\syncqt.pl -minimal -version %QTVERSION% -module QtCore -outdir "%QTDIR%" %QTSRC% -if errorlevel 1 goto exit +rem Create forwarding headers -if not exist tools\configure ( - md tools\configure - if errorlevel 1 goto exit +if "%SYNCQT%" == "" ( + if exist "%QTSRC%\.git" ( + set SYNCQT=true + ) else ( + set SYNCQT=false + ) +) +if "%SYNCQT%" == "true" ( + if not "%perl.exe%" == "" ( + echo Running syncqt ... + "%perl.exe%" -w "%QTSRC%\bin\syncqt.pl" -minimal -version %QTVERSION% -module QtCore -outdir "%QTDIR%" %QTSRC% + if errorlevel 1 exit /b + ) else ( + echo Perl not found in PATH. Aborting. >&2 + exit /b 1 + ) ) -cd tools\configure -if errorlevel 1 goto exit -set make=nmake -if not "%jom.exe%" == "" set make=jom +rem Build qmake + +echo Bootstrapping qmake ... + +cd qmake +if errorlevel 1 exit /b echo #### Generated by configure.bat - DO NOT EDIT! ####> Makefile echo/>> Makefile -echo QTVERSION = %QTVERSION%>> Makefile -rem These must have trailing spaces to avoid misinterpretation as 5>>, etc. -echo QT_VERSION_MAJOR = %QTVERMAJ% >> Makefile -echo QT_VERSION_MINOR = %QTVERMIN% >> Makefile -echo QT_VERSION_PATCH = %QTVERPAT% >> Makefile -if not "%icl.exe%" == "" ( - echo CXX = icl>>Makefile - echo EXTRA_CXXFLAGS = /Qstd=c++11 /Zc:forScope>>Makefile - rem This must have a trailing space. - echo QTSRC = %QTSRC% >> Makefile - set tmpl=win32 -) else if not "%cl.exe%" == "" ( - echo CXX = cl>>Makefile - echo EXTRA_CXXFLAGS =>>Makefile - rem This must have a trailing space. - echo QTSRC = %QTSRC% >> Makefile - set tmpl=win32 -) else if not "%clang-cl.exe%" == "" ( - echo CXX = clang-cl>>Makefile - echo EXTRA_CXXFLAGS = -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value>>Makefile - rem This must have a trailing space. - echo QTSRC = %QTSRC% >> Makefile - set tmpl=win32 -) else if not "%g++.exe%" == "" ( - echo CXX = g++>>Makefile - echo EXTRA_CXXFLAGS =>>Makefile - rem This must NOT have a trailing space. - echo QTSRC = %QTSRC:\=/%>> Makefile - set tmpl=mingw - set make=mingw32-make +echo BUILD_PATH = ..>> Makefile +if "%tmpl%" == "win32" ( + echo SOURCE_PATH = %QTSRC%>> Makefile ) else ( - echo No suitable compiler found in PATH. Aborting. >&2 - cd ..\.. - exit /b 1 + echo SOURCE_PATH = %QTSRC:\=/%>> Makefile +) +if exist "%QTSRC%\.git" ( + echo INC_PATH = ../include>> Makefile +) else ( + echo INC_PATH = $^(SOURCE_PATH^)/include>> Makefile +) +echo QT_VERSION = %QTVERSION%>> Makefile +rem These must have trailing spaces to avoid misinterpretation as 5>>, etc. +echo QT_MAJOR_VERSION = %QTVERMAJ% >> Makefile +echo QT_MINOR_VERSION = %QTVERMIN% >> Makefile +echo QT_PATCH_VERSION = %QTVERPAT% >> Makefile +if "%tmpl%" == "win32" ( + echo QMAKESPEC = %PLATFORM%>> Makefile +) else ( + echo QMAKESPEC = $^(SOURCE_PATH^)/mkspecs/%PLATFORM%>> Makefile + echo CONFIG_CXXFLAGS = -std=c++11 -ffunction-sections>> Makefile + echo CONFIG_LFLAGS = -Wl,--gc-sections>> Makefile + type "%QTSRC%\qmake\Makefile.unix.win32" >> Makefile + type "%QTSRC%\qmake\Makefile.unix.mingw" >> Makefile ) echo/>> Makefile -type %QTSRC%tools\configure\Makefile.%tmpl% >> Makefile +type "%QTSRC%\qmake\Makefile.%tmpl%" >> Makefile -%make% -if errorlevel 1 (cd ..\.. & exit /b 1) +%MAKE% +if errorlevel 1 (cd .. & exit /b 1) -cd ..\.. +cd .. -:conf -configureapp.exe -srcdir %QTSRC% %ARGS% -goto exit +rem Generate qt.conf -:help -type %QTSRC%config_help.txt +> "%QTDIR%\bin\qt.conf" ( + @echo [EffectivePaths] + @echo Prefix=.. + @echo [Paths] + @echo TargetSpec=dummy + @echo HostSpec=%PLATFORM% +) +if not "%QTDIR%" == "%QTSRC%" ( + >> "%QTDIR%\bin\qt.conf" ( + @echo [EffectiveSourcePaths] + @echo Prefix=%QTSRC:\=/% + ) +) -:exit +rem Launch qmake-based configure + +cd "%TOPQTDIR%" +"%QTDIR%\bin\qmake.exe" "%TOPQTSRC%" -- %ARGS% diff --git a/configure.json b/configure.json index b424c8b0ca9..4030d359ae6 100644 --- a/configure.json +++ b/configure.json @@ -1,6 +1,5 @@ { "files": { - "builtinQtConf": "qmake/builtin-qt.conf", "qconfigSource": "src/corelib/global/qconfig.cpp", "publicHeader": "src/corelib/global/qconfig.h", "privateHeader": "src/corelib/global/qconfig_p.h", @@ -254,11 +253,6 @@ "type": "compile", "test": "common/c++98default" }, - "compiler": { - "label": "Compiler", - "type": "checkCompiler", - "log": "compilerDescription" - }, "precompile_header": { "label": "precompiled header support", "type": "compile", @@ -424,13 +418,14 @@ "features": { "prepare": { - "output": [ "prepareSpec", "prepareOptions", "preparePaths" ] + "output": [ "prepareSpec", "prepareOptions", "preparePaths", "reloadSpec" ] }, "machineTuple": { "condition": "!config.linux || config.android || tests.machineTuple", "output": [ "machineTuple" ] }, "commit": { + "condition": "features.machineTuple", "output": [ "commitOptions" ] }, "android-style-assets": { @@ -691,11 +686,6 @@ "condition": "features.c++14 && tests.c++1z", "output": [ "publicFeature", "publicQtConfig" ] }, - "compiler": { - "label": "Compiler version", - "condition": "tests.compiler", - "output": [ "compilerVersion" ] - }, "precompile_header": { "label": "Using precompiled headers", "condition": "config.msvc || tests.precompile_header", @@ -947,6 +937,18 @@ { "type": "publicQtConfig", "negative": true } ] }, + "network": { + "label": "Qt Network", + "output": [ "privateFeature" ] + }, + "sql": { + "label": "Qt Sql", + "output": [ "privateFeature" ] + }, + "testlib": { + "label": "Qt Testlib", + "output": [ "privateFeature" ] + }, "widgets": { "label": "Qt Widgets", "autoDetect": "!config.tvos && !config.watchos", @@ -957,6 +959,10 @@ { "type": "publicQtConfig", "negative": true } ] }, + "xml": { + "label": "Qt Xml", + "output": [ "privateFeature" ] + }, "libudev": { "label": "udev", "condition": "libs.libudev", @@ -1146,7 +1152,11 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5 "dbus", "dbus-linked", "gui", - "widgets" + "network", + "sql", + "testlib", + "widgets", + "xml" ] }, { "section": "Support enabled for", diff --git a/configure.pri b/configure.pri index 0dfe6cc719b..75e6927d8f4 100644 --- a/configure.pri +++ b/configure.pri @@ -397,50 +397,6 @@ defineTest(qtConfTest_buildParts) { return(true) } -defineTest(qtConfTest_checkCompiler) { - contains(QMAKE_CXX, ".*clang.*") { - qtRunLoggedCommand("$$QMAKE_CXX -v 2>&1", versionstr)|return(false) - versionstr = "$$versionstr" - contains(versionstr, "^Apple (clang|LLVM) version .*") { - $${1}.compilerDescription = "Apple Clang" - $${1}.compilerId = "apple_clang" - $${1}.compilerVersion = $$replace(versionstr, "^Apple (clang|LLVM) version ([0-9.]+).*$", "\\2") - } else: contains(versionstr, ".*clang version.*") { - $${1}.compilerDescription = "Clang" - $${1}.compilerId = "clang" - $${1}.compilerVersion = $$replace(versionstr, "^.*clang version ([0-9.]+).*", "\\1") - } else { - return(false) - } - } else: contains(QMAKE_CXX, ".*g\\+\\+.*") { - qtRunLoggedCommand("$$QMAKE_CXX -dumpversion", version)|return(false) - $${1}.compilerDescription = "GCC" - $${1}.compilerId = "gcc" - $${1}.compilerVersion = $$version - } else: contains(QMAKE_CXX, ".*icpc") { - qtRunLoggedCommand("$$QMAKE_CXX -dumpversion", version)|return(false) - $${1}.compilerDescription = "ICC" - $${1}.compilerId = "icc" - $${1}.compilerVersion = $$version - } else: msvc { - command = $$QMAKE_CXX /EP /nologo $$source $$system_quote($$QMAKE_CONFIG_TESTS_DIR/win/msvc_version.cpp) - qtRunLoggedCommand("$$command", version)|return(false) - version = "$$version" - $${1}.compilerDescription = "MSVC" - $${1}.compilerId = "cl" - $${1}.compilerVersion = $$replace(version, "^.*([0-9]{2})([0-9]{2})([0-9]{5}).*$", "\\1.\\2.\\3") - } else { - return(false) - } - $${1}.compilerDescription += $$eval($${1}.compilerVersion) - export($${1}.compilerDescription) - export($${1}.compilerId) - export($${1}.compilerVersion) - $${1}.cache += compilerDescription compilerId compilerVersion - export($${1}.cache) - return(true) -} - # custom outputs # this reloads the qmakespec as completely as reasonably possible. @@ -453,13 +409,15 @@ defineTest(reloadSpec) { } # nobody's going to try to re-load the features above, # so don't bother with being selective. - QMAKE_INTERNAL_INCLUDED_FEATURES = + QMAKE_INTERNAL_INCLUDED_FEATURES = \ + # loading it gets simulated below. + $$[QT_HOST_DATA/src]/mkspecs/features/device_config.prf \ + # must be delayed until qdevice.pri is ready. + $$[QT_HOST_DATA/src]/mkspecs/features/mac/toolchain.prf \ + $$[QT_HOST_DATA/src]/mkspecs/features/toolchain.prf _SAVED_CONFIG = $$CONFIG load(spec_pre) - load(device_config) # avoid that the spec loads it later. - # discard possible settings from an earlier configure run. - discard_from($$[QT_HOST_DATA/get]/mkspecs/qdevice.pri) # qdevice.pri gets written too late (and we can't write it early # enough, as it's populated in stages, with later ones depending # on earlier ones). so inject its variables manually. @@ -502,6 +460,10 @@ defineTest(qtConfOutput_prepareSpec) { QMAKESPEC = $$[QT_HOST_DATA/src]/mkspecs/$$XSPEC export(QMAKESPEC) + notes = $$cat($$OUT_PWD/.config.notes, lines) + !isEmpty(notes): \ + qtConfAddNote("Also available for $$notes") + # deviceOptions() below contains conditionals coming form the spec, # so this cannot be delayed for a batch reload. reloadSpec() @@ -623,9 +585,8 @@ defineTest(qtConfOutput_prepareOptions) { export($${currentConfig}.output.devicePro) - # reload the spec to make the settings actually take effect. - !isEmpty($${currentConfig}.output.devicePro): \ - reloadSpec() + # if any settings were made, the spec will be reloaded later + # to make them take effect. } defineTest(qtConfOutput_machineTuple) { @@ -710,6 +671,7 @@ defineReplace(printHostPaths) { $$printInstallPath(HostLibraries, hostlibdir, lib) \ $$printInstallPath(HostData, hostdatadir, .) \ "Sysroot=$$config.input.sysroot" \ + "SysrootifyPrefix=$$qmake_sysrootify" \ "TargetSpec=$$XSPEC" \ "HostSpec=$$[QMAKE_SPEC]" return($$ret) @@ -818,40 +780,56 @@ defineTest(qtConfOutput_preparePaths) { addConfStr($$config.rel_input.examplesdir) addConfStr($$config.rel_input.testsdir) + QT_CONFIGURE_STR_OFFSETS_ALL = $$QT_CONFIGURE_STR_OFFSETS + QT_CONFIGURE_STRS_ALL = $$QT_CONFIGURE_STRS + QT_CONFIGURE_STR_OFFSETS = + QT_CONFIGURE_STRS = + + addConfStr($$config.input.sysroot) + addConfStr($$qmake_sysrootify) + addConfStr($$config.rel_input.hostbindir) + addConfStr($$config.rel_input.hostlibdir) + addConfStr($$config.rel_input.hostdatadir) + addConfStr($$XSPEC) + addConfStr($$[QMAKE_SPEC]) + $${currentConfig}.output.qconfigSource = \ "/* Installation date */" \ "static const char qt_configure_installation [12+11] = \"qt_instdate=2012-12-20\";" \ "" \ "/* Installation Info */" \ "static const char qt_configure_prefix_path_str [12+256] = \"qt_prfxpath=$$config.input.prefix\";" \ + "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ + "static const char qt_configure_ext_prefix_path_str [12+256] = \"qt_epfxpath=$$config.input.extprefix\";" \ + "static const char qt_configure_host_prefix_path_str [12+256] = \"qt_hpfxpath=$$config.input.hostprefix\";" \ + "$${LITERAL_HASH}endif" \ "" \ "static const short qt_configure_str_offsets[] = {" \ + $$QT_CONFIGURE_STR_OFFSETS_ALL \ + "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ $$QT_CONFIGURE_STR_OFFSETS \ + "$${LITERAL_HASH}endif" \ "};" \ "static const char qt_configure_strs[] =" \ + $$QT_CONFIGURE_STRS_ALL \ + "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ $$QT_CONFIGURE_STRS \ + "$${LITERAL_HASH}endif" \ ";" \ "" \ "$${LITERAL_HASH}define QT_CONFIGURE_SETTINGS_PATH \"$$config.rel_input.sysconfdir\"" \ "" \ - "$${LITERAL_HASH}define QT_CONFIGURE_PREFIX_PATH qt_configure_prefix_path_str + 12" + "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ + "$${LITERAL_HASH} define QT_CONFIGURE_SYSROOTIFY_PREFIX $$qmake_sysrootify" \ + "$${LITERAL_HASH}endif" \ + "" \ + "$${LITERAL_HASH}define QT_CONFIGURE_PREFIX_PATH qt_configure_prefix_path_str + 12" \ + "$${LITERAL_HASH}ifdef QT_BUILD_QMAKE" \ + "$${LITERAL_HASH} define QT_CONFIGURE_EXT_PREFIX_PATH qt_configure_ext_prefix_path_str + 12" \ + "$${LITERAL_HASH} define QT_CONFIGURE_HOST_PREFIX_PATH qt_configure_host_prefix_path_str + 12" \ + "$${LITERAL_HASH}endif" export($${currentConfig}.output.qconfigSource) - # populate qmake/builtin-qt.conf - - $${currentConfig}.output.builtinQtConf = \ - " " \ - "===========================================================" \ - "==================== qt.conf beginning ====================" \ - "===========================================================" \ - "[Paths]" \ - "ExtPrefix=$$config.input.extprefix" \ - "Prefix=$$config.input.prefix" \ - $$printInstallPaths() \ - "Settings=$$config.rel_input.sysconfdir" \ - $$printHostPaths() - export($${currentConfig}.output.builtinQtConf) - # create bin/qt.conf. this doesn't use the regular file output # mechanism, as the file is relied upon by configure tests. @@ -871,6 +849,22 @@ defineTest(qtConfOutput_preparePaths) { "Prefix=$$QT_SOURCE_TREE" write_file($$QT_BUILD_TREE/bin/qt.conf, cont)|error() reload_properties() + + # if a sysroot was configured, the spec will be reloaded later, + # as some specs contain $$[SYSROOT] references. +} + +defineTest(qtConfOutput_reloadSpec) { + !isEmpty($${currentConfig}.output.devicePro)| \ + !isEmpty(config.input.sysroot): \ + reloadSpec() + + bypassNesting() { + QMAKE_INTERNAL_INCLUDED_FEATURES -= \ + $$[QT_HOST_DATA/src]/mkspecs/features/mac/toolchain.prf \ + $$[QT_HOST_DATA/src]/mkspecs/features/toolchain.prf + load(toolchain) + } } defineTest(qtConfOutput_shared) { @@ -968,25 +962,6 @@ defineTest(qtConfOutput_debugAndRelease) { } } -defineTest(qtConfOutput_compilerVersion) { - !$${2}: return() - - name = $$upper($$eval($${currentConfig}.tests.compiler.compilerId)) - version = $$eval($${currentConfig}.tests.compiler.compilerVersion) - major = $$section(version, '.', 0, 0) - minor = $$section(version, '.', 1, 1) - patch = $$section(version, '.', 2, 2) - isEmpty(minor): minor = 0 - isEmpty(patch): patch = 0 - - $${currentConfig}.output.publicPro += \ - "QT_$${name}_MAJOR_VERSION = $$major" \ - "QT_$${name}_MINOR_VERSION = $$minor" \ - "QT_$${name}_PATCH_VERSION = $$patch" - - export($${currentConfig}.output.publicPro) -} - defineTest(qtConfOutput_compilerFlags) { # this output also exports the variables locally, so that subsequent compiler tests can use them diff --git a/dist/changes-5.8.0 b/dist/changes-5.8.0 new file mode 100644 index 00000000000..8d938630870 --- /dev/null +++ b/dist/changes-5.8.0 @@ -0,0 +1,497 @@ +Qt 5.8 introduces many new features and improvements as well as bugfixes +over the 5.7.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + + http://doc.qt.io/qt-5/index.html + +The Qt version 5.8 series is binary compatible with the 5.7.x series. +Applications compiled for 5.7 will continue to run with 5.8. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +This release contains all fixes included in the Qt 5.7.1 release. + +**************************************************************************** +* License Changes * +**************************************************************************** + + Static libraries that are linked into executables (winmain and + qopenglextensions) are now licensed under BSD _and_ commercial licenses. + +**************************************************************************** +* Deprecation Notice * +**************************************************************************** + + - The following platforms or toolchains are deprecated and will be + removed as of Qt 5.9: + * Apple OS X Mavericks (v10.9) + * Apple iOS 7.x + + Deprecated platforms and toolchains continue to work until removed. + + - The Q_OBJECT_CHECK macro is deprecated and will be removed in Qt 6. The + internal, template function qt_check_for_QOBJECT_macro that it created in + QObject-derived classes will be removed in Qt 5.9. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - Support for the following platforms was removed in this version: + * Apple OS X Mountain Lion (v10.8) + * Apple iOS 6.x + +configure & build system +------------------------ + + - The configuration system has been rewritten almost from scratch. This + improved the consistency between builds on Unix and Windows, but some + subtle unintended behavior changes are also possible. Also, some + obsolete options have been entirely removed and will now cause errors. + - It is not permissible any more to manually #define QT_NO_ + anywhere. Instead, configure's -no-feature-* options must be used. + Note that this does not apply to defines which modify behavior rather + than entirely removing features. + - Configure test results are now cached. Use -recheck or -recheck-all + to discard them. + - [QTBUG-32530][QTBUG-42962] The Unix configure won't pick up CFLAGS and + related environment variables any more. Instead, it now accepts QMAKE_* + variable assignments on the command line. + - [QTBUG-52266] Configure won't pick up QMAKESPEC from the environment + any more. Use the -platform option instead. + - Device and simulator libraries are now combined on Apple device + platforms (iOS). This means that there will no longer be any + *_simulator.a libraries and the simulator architectures will simply + reside alongside the device architectures in a single Mach-O file. + - [Darwin] Project files may not override QMAKE_MAC_SDK any more. + +QtCore +------ + + - qFatal will now use std::abort to terminate the application on all + operating systems. Previously, ::abort() or ::exit(1) were called, + depending on the operating system. + - QLibraryInfo::licensee()/licensedProducts() were deprecated and + return empty strings now. + - Destroying a QThread which is still running will now result in + immediate and abnormal program termination. + +QtGui +----- + + - [QTBUG-54936] QFont::toString() and QFont::key() were modified to save + the font's style name if one is set, invalidating any stored font + identifiers. QFont::fromString() was also adjusted to accommodate the + change. + +QtNetwork +--------- + + - Proxies from system settings will now be used by default. Configure + with -no-system-proxies to disable. + - [QTBUG-53649] libproxy is now turned off by default. Configure with + -libproxy in order to enable it again. + +**************************************************************************** +* Library * +**************************************************************************** + +QtCore +------ + + - Disambiguated the relational operators comparing QByteArray with + QStringRef (and vice versa). + - Added qHash() overloads for QHash, QMultiHash. + - Added QDeadlineTimer, a counterpart to QElapsedTimer, used to mark a + time point in the future (a deadline) and determine whether such a + deadline has passed. + - Qt now relies on type traits from the C++11 standard library. + - [QTBUG-54981] Added Q_NAMESPACE, which can be used to add Q_ENUM_NS/ + Q_ENUMS, Q_FLAG_NS/Q_FLAGS and Q_CLASSINFO to a namespace. + - Q_IS_ENUM was deprecated. Use std::is_enum<>::value instead. + + - QChar: + * Added missing operator{<,>,<=,>=} comparing against QLatin1String and + QStringRef. + * Added missing operator{==,!=} comparing against QLatin1String. + + - QCommandLineOption: + * Added flags() and setFlags() methods. Added ShortOptionStyle and + HiddenFromHelp flags. + + - QDateTime: + * Introduced toSecsSinceEpoch, fromSecsSinceEpoch and setSecsSinceEpoch + functions, which use 64-bit integers to represent the number of + seconds. + * The toTime_t, fromTime_t and setTime_t functions are deprecated and + will be removed in Qt 6.0. For new code, use the equivalent functions + with "SecsSinceEpoch" in the name, or the equivalent ones with + millisecond accurancy that have existed since Qt 4.7. + * Added string formatting type Qt::ISODateWithMs. + + - QFileInfo: + * QFileInfo now reports file times with millisecond precision on Unix + systems. + + - QFileSystemWatcher: + * [QTBUG-55896] Fixed a bug that caused QFileSystemWatcher to mis-handle + file paths that contained non-US-ASCII characters on Apple platforms. + + - QJsonDocument: + * [QTBUG-39751] fromVariant can now take a QVariantHash argument. + * Fixed a number of bugs that could cause crashes when loading corrupt + binary JSON data. + + - QJsonValue: + * [QTBUG-43077] QJsonValue(Null).toVariant() now returns a QVariant of + type QMetaType::Nullptr instead of an invalid QVariant. + + - QLatin1String: + * Added at(), operator[](), mid(), right(), left(). + + - QLibraryInfo: + * Added QLibraryInfo::version(), which returns the current version of + the Qt library as a QVersionNumber object. + + - QLine/QLineF: + * Added center(). + + - QLockFile: + * Fixed a bug that caused QLockFile to over-sleep while waiting for the + lock file to become available. + + - QMetaType: + * std::nullptr_t is now a built-in Qt metatype. + + - QModelIndex: + * QModelIndex::child has been deprecated due to its lack of generality. + Use model->index(row, column, index) instead. + + - QMutex: + * QMutex now fully models the TimedLockable concept by providing the + try_lock, try_lock_for and try_lock_until functions, therefore making + it usable in Standard Library lock management classes and functions. + + - QObject: + * The QT_NO_NARROWING_CONVERSIONS_IN_CONNECT macro has been added. When + using the new connection syntax (PMF-based) this macro makes it + illegal to narrow the arguments carried by the signal, and/or to + perform floating point to integral implicit conversions on them. When + the macro is defined, depending on your compiler a QObject::connect() + statement triggering such conversions will now fail to compile. + + - QPersistentModelIndex: + * QPersistentModelIndex::child has been deprecated due to its lack of + generality. Use model->index(row, column, index) instead. + + - QStringList: + * Added join(QLatin1String) overload. + + - QStringRef: + * Added missing operator{<,>,<=,>=} comparing against QLatin1String and + QString. + + - QSysInfo: + * The output of QSysInfo::prettyProductName now includes the Windows + OS/kernel version number. In case of future versions of Windows, a + valid string is now returned. + + - QSettings: + * [QTBUG-56124] Fixed a bug that caused QSettings to fail on Apple + platforms when strings with embedded null (\0) bytes were present + + - QSharedPointer: + * [QTBUG-52369] Fixed a bug that caused QSharedPointer to fail to compile + if it was initialized with a nullptr literal. + * Fixed a bug that made QSharedPointer delete the pointer it held with the + wrong destructor if the type of the QSharedPointer and that of the object + passed on the constructor were different. Its behavior is now the same as + std::shared_ptr. + + - QStandardPaths: + * [QTBUG-55507] Fixed the QStandardPaths::FontsLocation on XDG systems to + be $XDG_DATA_DIR/fonts. + * Fixed handling of potential paths that do not exist on Windows. Now, + QStandardPaths may return storage locations that may not exist on all + platforms. + + - QTimer: + * Added support for std::chrono duration objects for QTimer methods, + like QTimer::singleShot and QTimer::setInterval. + + - QWaitCondition: + * Added notify_one() and notify_all() to make QWaitCondition be usable from + algorithms that use the Standard Library naming convention. + +QtDBus +------ + + - QDBusConnection: + * Fixed a bug that would cause QDBusConnection::connect() to return true + if a slot was already connected to the same D-Bus signal. QtDBus does + not support multiple connections. + +QtGui +----- + + - [QFileDialogOptions/QFontDialogOptions/QMessageDialogOptions/ + QColorDialogOptions] These classes no longer have value semantics, but + need to be held in QSharedPointer (as they always were). To copy an + instance, use the clone() method. + - QOpenGLTextureBlitter, a utility class to draw textured quads, has been + made public. + - [QTBUG-38825] Fixed QTextEdit to match undo functionality of QLineEdit + to group two sequential inserts into one undo action. + - [QTBUG-51844] Added rotation and uniqueId properties to + QTouchEvent::TouchPoint. This is mainly for the benefit of the TUIO + plugin so far: it now supports tracking physical objects (fiducials) + on the touchscreen surface, as long as the object's ID can fit in a + 64-bit integer. QPointingDeviceUniqueId is a wrapper for the ID, + designed to be extensible to support other types of IDs in the future. + - [QTBUG-52510] A stationary touchpoint event is delivered if its + velocity changes. This is to ensure that the application will be + notified when a TUIO fiducial object comes to rest. + - [QTBUG-53076] Add QGuiApplication::applicationDisplayNameChanged() + signal. + + - QAbstractTextDocumentLayout: + * Added imageAt() and formatAt() methods, which respectively can be used + to retrieve the source link of the image under the cursor, or the + QTextFormat of the text under the cursor. + + - QFont: + * [QTBUG-48043] The default value of QFont::stretch() is now 0 to + indicate any default stretch is acceptable. + + - QRegion: + * Is now iterable as a container of QRects: added {c,}{r,}{begin,end}(). + + - Text handling: + * [QTBUG-51411] Fixed performance hit from showing large QTextDocuments + in a QTextEdit or QTextBrowser. (Regression introduced in Qt 5.3.0) + * [QTBUG-50090] Fixed line spacing with some scalable fonts containing + bitmaps with the Freetype font engine. + * [QTBUG-56346] Fixed QStaticText when manually breaking lines and no + text width was set. + * [QTBUG-56659] Fixed a regression where raster fonts on Windows were + detected as smoothly scalable and thus rendering with said fonts in Qt + Quick would break. + * [QTBUG-51223] Fixed synthesized oblique for non-latin text on + platforms using the basic font database, such as Android. + * [QTBUG-56672] Fixed list of supported sizes for bitmap fonts on + Windows. + * [QTBUG-56714] Fixed a bug where a no-break space would sometimes cause + the first character of the containing line to not be displayed. + * [QTBUG-55856] Fixed rendering of large fonts when a device pixel ratio + is set and the Freetype engine is used. + +QtNetwork +--------- + + - Added QNetworkDatagram class, along with new function receiveDatagram() + in QUdpSocket that returns it, and an overload to writeDatagram() that + can accept it. + - Added QSctpServer and QSctpSocket classes. Note that these need to be + explicitly enabled via a configure option. + - [QTBUG-50956] Added support for HTTP/2 protocol + + - QSslSocket: + * [QTBUG-39077] TLS PSK ciphers are possible in server sockets. + * It is now possible to set custom Diffie-Hellman parameters for + QSslSocket-based servers. + + - QTcpServer: + * [QTBUG-51288] It is now possible to use QTcpServer with an externally + created QTcpSocket. + +QtSql +----- + + - QSqlDatabase: + * When connecting to a MySQL server whose version is 5.5.3 or higher, + the default connection charset is now utf8mb4 instead of utf8 to allow + 4-byte UTF-8 encodings. + + - SQLite: + * Added notification feature to SQLite driver + +QTestLib +-------- + + - [QTBUG-44030] Added QTest::createTouchDevice() for use in autotests + which generate touch events. + - Added ref-cycles perf counter. + - QFETCH variables can now be declared const (QFETCH(const T, name)). + - It is now possible to use variables of types with an explicit operator + bool in the QVERIFY macro. + +QtWidgets +--------- + + - QFormLayout: + * [QTBUG-15990] Added removeRow(), takeRow(). + + - QMainWindow: + * [QTBUG-56628] Fixed crash using takeCentralWidget when the central + widget was not set. + +**************************************************************************** +* Platform-specific Changes * +**************************************************************************** + + - Added technology preview support for Apple tvOS and Apple watchOS. + - Added initial support for Microsoft Visual Studio 2017, which uses the + mkspec "win32-msvc2017". Full support will happen after the final release + of that compiler. + +Android +------- + + - [QTBUG-48948] Show password while typing is now supported + - [QTBUG-55035][QTBUG-50759] Introduced a mechanism to forward + permission related callbacks on Activity objects to interested + parties. + +Apple platforms +--------------- + + - Added QImage::toCGImage() that returns a CGImage. + - Added functions that convert Qt types QPoint/QPointF, QRect/QRectF and + QSize/QSizeF to and from CGPoint, CGRect and CGSize. Note that QPoint, + QRect and QSize do not provide fromCGXxx functions since that would + silently lose precision. + +iOS +--- + + - Precompiled headers are now supported on iOS. + - Starting from iOS 10, Apple requires all apps that need access to photos + to have the key 'NSPhotoLibraryUsageDescription' in the Info.plist. + Therefore, to get the same support in Qt (when, e.g., using a file + dialog), the Info.plist assigned to QMAKE_INFO_PLIST will need this key + as well. + +macOS +----- + + - Speech to text dictation now works for Qt text input. + - [QTBUG-33708] Fixed underline position in font rendering. + +Linux +----- + + - [QTBUG-39959] QWidget-based applications running on the eglfs platform + plugin can now request 180 or 90 degrees rotated output by setting the + QT_QPA_EGLFS_ROTATION environment variable. + - KDE/Gnome themes now implement QPlatformTheme::fileIconPixmap(), showing + file icons. + +Windows +------- + + - [QTBUG-31476] QFactoryLoader now filters potential plugins by the + ".dll" suffix. + - [QTBUG-56239] 'What's this' button is now shown by default only for + QWidget dialogs. + - [QTBUG-53833] QProcess::startDetached() changed behavior on Windows: + it no longer creates a new console window unconditionally, instead it + passes the same creation flags to CreateProcess as QProcess::start(). + + - Text handling: + * [QTBUG-54740] Fixed embedding fonts in PDF when dpi scaling is active + or when the hinting preference was none or vertical hinting. + * [QTBUG-47485] Fix selecting non-regular fonts when using the Freetype + engine. + * [QTBUG-49346] Fixed rendering error when using the MingLiU fonts at + certain combinations of pixel size and scale. + +**************************************************************************** +* Tools * +**************************************************************************** + +configure & build system +------------------------ + + - The -no-feature-* option family was integrated with the rest of the + configuration system. Numerous existing features were made optional, + and build problems in various reduced configurations were fixed. + This is an ongoing effort known as "Qt Lite". + - Numerous Qt modules outside qtbase now support configure options. + In a module-by-module build, these can be passed to qmake itself, + after a -- option. + - Introduced the qtConfig() qmake function to replace the + patterns contains(QT_CONFIG, ) and load(qfeatures)+ + contains(QT_DISABLED_FEATURES, ). + Likewise, the C++ macro QT_CONFIG() was introduced to + replace the pattern !defined(QT_NO_). + The old methods are effectively deprecated and will stop working at + some point in the near future. + - Use of -sysroot will now trigger a cross-build even if -platform and + -xplatform are the same. + - The JPEG & GIF handlers and the SQL drivers are now always built as + plugins, even in static builds (static "plugins" in this case). + - [GCC] Include paths from system libraries are now marked as such, + resulting in fewer warnings the user cannot do anything about. + - [Windows] config.status.bat is now created, like on Unix. + - [QTBUG-46974] Fixed location of config.status in top-level builds. + - [QTBUG-38792][Unix] The -redo option is now accepted, like on Windows. + - It's now possible to add more arguments when -redo is used. Note that + these arguments are not saved in turn. Likewise for config.status. + - [QTBUG-32896][iOS/clang] Added missing CFBundleIdentifier to library + template. + - [QTBUG-47624] Fixed abort when some, but not all, XCB dependencies + are met. The feature is now disabled instead, as expected. + - [QTBUG-50838] The Raspberry Pi EGL detection now uses pkg-config. + - [QTBUG-52112][Android] Plugins now have a SONAME, as required by + Android 6+. + - [QTBUG-54438] Fixed launching tests, examples, and build tools in + some configurations. + - [QTBUG-56289][GCC@Windows] Fixed -separate-debug-info. + - [QTBUG-57086] Added support for Visual Studio 2017. + +qdbusxml2cpp +------------ + + - [QTBUG-34126] qdbusxml2cpp now supports the --verbose switch, which + provides more details when parsing invalid XML sources. + +qmake +----- + + - Added the $$take_first(), $$take_last(), $$num_add(), $$str_size(), + $$str_member(), and $$sorted() functions. + - The error() function can now be called without arguments to exit + silently. Use after write_file() and similar functions which already + print an error message. + - The $$system() function can return the command's exit code now. + - The $$prompt() function can now print the prompt verbatim. + - QMAKE_EXTRA_TARGETS will now consistently treat the target as a file + name (separator adjustment and quoting). + - [QTBUG-16904][VS] Fixed warning about circular dependencies when + Q_OBJECT is used in .cpp files. + - [QTBUG-36256] packageExists() and PKGCONFIG can now be used + regardless of whether Qt itself was built with pkg-config support. + - [QTBUG-43468][WinRT] Added option to use verbatim manifest files. + - [QTBUG-53905] Fixed OBJECTIVE_SOURCES being moc'd twice. + - [QTBUG-55591][VS2015] Added support for the /DEBUG:FASTLINK option. + - [QTBUG-56507] Fixed parallel builds when a lex source refers to a + file generated from a yacc source. + - [QTBUG-56594][MSVC] Fixed PDB files not being installed for static + libraries. + +moc +--- + + - [MSVC] qmake and moc now cooperate to use the Visual Studio environment + variables (set by the VCVARSALL.BAT script) to find system include + files. A possible consequence is that moc parses application headers + slightly differently, depending on #if conditions that depended on + macros that previous versions had not seen #define'd. Implementers of + other buildsystems are advised to pass the --compiler-flavor=msvc option + to moc. diff --git a/examples/corelib/ipc/ipc.pro b/examples/corelib/ipc/ipc.pro index 4cc5f3be56d..101552cea96 100644 --- a/examples/corelib/ipc/ipc.pro +++ b/examples/corelib/ipc/ipc.pro @@ -1,6 +1,6 @@ requires(qtHaveModule(widgets)) TEMPLATE = subdirs -# no QSharedMemory -!vxworks:!integrity: SUBDIRS = sharedmemory + +qtConfig(sharedmemory): SUBDIRS = sharedmemory qtHaveModule(network): SUBDIRS += localfortuneserver localfortuneclient diff --git a/examples/network/fortuneclient/client.cpp b/examples/network/fortuneclient/client.cpp index 205959936d5..c0043e246fa 100644 --- a/examples/network/fortuneclient/client.cpp +++ b/examples/network/fortuneclient/client.cpp @@ -122,8 +122,7 @@ Client::Client(QWidget *parent) //! [2] //! [3] connect(tcpSocket, &QIODevice::readyRead, this, &Client::readFortune); //! [2] //! [4] - typedef void (QAbstractSocket::*QAbstractSocketErrorSignal)(QAbstractSocket::SocketError); - connect(tcpSocket, static_cast(&QAbstractSocket::error), + connect(tcpSocket, QOverload::of(&QAbstractSocket::error), //! [3] this, &Client::displayError); //! [4] diff --git a/examples/opengl/paintedwindow/paintedwindow.cpp b/examples/opengl/paintedwindow/paintedwindow.cpp index 6e031e5cb73..799431a765e 100644 --- a/examples/opengl/paintedwindow/paintedwindow.cpp +++ b/examples/opengl/paintedwindow/paintedwindow.cpp @@ -95,9 +95,7 @@ PaintedWindow::PaintedWindow() connect(screen(), &QScreen::orientationChanged, this, &PaintedWindow::orientationChanged); connect(m_animation, &QAbstractAnimation::finished, this, &PaintedWindow::rotationDone); - typedef void (PaintedWindow::*PaintedWindowVoidSlot)(); - connect(this, &PaintedWindow::rotationChanged, - this, static_cast(&PaintedWindow::paint)); + connect(this, &PaintedWindow::rotationChanged, this, QOverload<>::of(&PaintedWindow::paint)); } void PaintedWindow::exposeEvent(QExposeEvent *) diff --git a/examples/opengl/qopenglwidget/mainwindow.cpp b/examples/opengl/qopenglwidget/mainwindow.cpp index f602c9995b1..1bb2aa2bf0e 100644 --- a/examples/opengl/qopenglwidget/mainwindow.cpp +++ b/examples/opengl/qopenglwidget/mainwindow.cpp @@ -61,8 +61,6 @@ #include "glwidget.h" -typedef void (QWidget::*QWidgetVoidSlot)(); - MainWindow::MainWindow() : m_nextX(1), m_nextY(1) { @@ -131,14 +129,11 @@ MainWindow::MainWindow() QMenu *helpMenu = menuBar()->addMenu("&Help"); helpMenu->addAction("About Qt", qApp, &QApplication::aboutQt); - connect(m_timer, &QTimer::timeout, - glwidget, static_cast(&QWidget::update)); + connect(m_timer, &QTimer::timeout, glwidget, QOverload<>::of(&QWidget::update)); connect(slider, &QAbstractSlider::valueChanged, glwidget, &GLWidget::setScaling); connect(transparent, &QCheckBox::toggled, glwidget, &GLWidget::setTransparent); - - typedef void (QSpinBox::*QSpinBoxIntSignal)(int); - connect(updateInterval, static_cast(&QSpinBox::valueChanged), + connect(updateInterval, QOverload::of(&QSpinBox::valueChanged), this, &MainWindow::updateIntervalChanged); connect(timerBased, &QCheckBox::toggled, this, &MainWindow::timerUsageChanged); connect(timerBased, &QCheckBox::toggled, updateInterval, &QWidget::setEnabled); @@ -162,7 +157,7 @@ void MainWindow::addNew() return; GLWidget *w = new GLWidget(this, false, qRgb(qrand() % 256, qrand() % 256, qrand() % 256)); m_glWidgets << w; - connect(m_timer, &QTimer::timeout, w, static_cast(&QWidget::update)); + connect(m_timer, &QTimer::timeout, w, QOverload<>::of(&QWidget::update)); m_layout->addWidget(w, m_nextY, m_nextX, 1, 1); if (m_nextX == 3) { m_nextX = 1; diff --git a/examples/opengl/qopenglwindow/main.cpp b/examples/opengl/qopenglwindow/main.cpp index 4287d42d243..4f008b45a65 100644 --- a/examples/opengl/qopenglwindow/main.cpp +++ b/examples/opengl/qopenglwindow/main.cpp @@ -173,8 +173,6 @@ void OpenGLWindow::keyPressEvent(QKeyEvent *e) void OpenGLWindow::setAnimating(bool enabled) { - typedef void (QPaintDeviceWindow::*QPaintDeviceWindowVoidSlot)(); - if (enabled) { // Animate continuously, throttled by the blocking swapBuffers() call the // QOpenGLWindow internally executes after each paint. Once that is done @@ -182,11 +180,11 @@ void OpenGLWindow::setAnimating(bool enabled) // obviously assumes that the swap interval (see // QSurfaceFormat::setSwapInterval()) is non-zero. connect(this, &QOpenGLWindow::frameSwapped, - this, static_cast(&QPaintDeviceWindow::update)); + this, QOverload<>::of(&QPaintDeviceWindow::update)); update(); } else { disconnect(this, &QOpenGLWindow::frameSwapped, - this, static_cast(&QPaintDeviceWindow::update)); + this, QOverload<>::of(&QPaintDeviceWindow::update)); } } diff --git a/examples/qtconcurrent/imagescaling/imagescaling.pro b/examples/qtconcurrent/imagescaling/imagescaling.pro index da237bd6afa..110f8f1b0ba 100644 --- a/examples/qtconcurrent/imagescaling/imagescaling.pro +++ b/examples/qtconcurrent/imagescaling/imagescaling.pro @@ -5,5 +5,3 @@ HEADERS += imagescaling.h target.path = $$[QT_INSTALL_EXAMPLES]/qtconcurrent/imagescaling INSTALLS += target - -wince: DEPLOYMENT_PLUGIN += qgif qjpeg diff --git a/examples/sql/sqlbrowser/sqlbrowser.pro b/examples/sql/sqlbrowser/sqlbrowser.pro index 539796fe714..1cc13d754f3 100644 --- a/examples/sql/sqlbrowser/sqlbrowser.pro +++ b/examples/sql/sqlbrowser/sqlbrowser.pro @@ -15,8 +15,3 @@ build_all:!build_pass { # install target.path = $$[QT_INSTALL_EXAMPLES]/sql/sqlbrowser INSTALLS += target - - -wince { - DEPLOYMENT_PLUGIN += qsqlite -} diff --git a/examples/sql/sqlwidgetmapper/sqlwidgetmapper.pro b/examples/sql/sqlwidgetmapper/sqlwidgetmapper.pro index 44815407d75..fe600a91241 100644 --- a/examples/sql/sqlwidgetmapper/sqlwidgetmapper.pro +++ b/examples/sql/sqlwidgetmapper/sqlwidgetmapper.pro @@ -7,6 +7,4 @@ QT += sql widgets target.path = $$[QT_INSTALL_EXAMPLES]/sql/sqlwidgetmapper INSTALLS += target -wince: DEPLOYMENT_PLUGIN += qsqlite - diff --git a/examples/widgets/desktop/screenshot/screenshot.cpp b/examples/widgets/desktop/screenshot/screenshot.cpp index 6438eb27cc0..80f26ae2822 100644 --- a/examples/widgets/desktop/screenshot/screenshot.cpp +++ b/examples/widgets/desktop/screenshot/screenshot.cpp @@ -70,8 +70,7 @@ Screenshot::Screenshot() delaySpinBox->setSuffix(tr(" s")); delaySpinBox->setMaximum(60); - typedef void (QSpinBox::*QSpinBoxIntSignal)(int); - connect(delaySpinBox, static_cast(&QSpinBox::valueChanged), + connect(delaySpinBox, QOverload::of(&QSpinBox::valueChanged), this, &Screenshot::updateCheckBox); hideThisWindowCheckBox = new QCheckBox(tr("Hide This Window"), optionsGroupBox); diff --git a/examples/widgets/desktop/systray/window.cpp b/examples/widgets/desktop/systray/window.cpp index ac05f163411..05944c92a7b 100644 --- a/examples/widgets/desktop/systray/window.cpp +++ b/examples/widgets/desktop/systray/window.cpp @@ -80,8 +80,7 @@ Window::Window() connect(showMessageButton, &QAbstractButton::clicked, this, &Window::showMessage); connect(showIconCheckBox, &QAbstractButton::toggled, trayIcon, &QSystemTrayIcon::setVisible); - typedef void (QComboBox::*QComboIntSignal)(int); - connect(iconComboBox, static_cast(&QComboBox::currentIndexChanged), + connect(iconComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &Window::setIcon); connect(trayIcon, &QSystemTrayIcon::messageClicked, this, &Window::messageClicked); connect(trayIcon, &QSystemTrayIcon::activated, this, &Window::iconActivated); diff --git a/examples/widgets/itemviews/basicsortfiltermodel/window.cpp b/examples/widgets/itemviews/basicsortfiltermodel/window.cpp index a8a8875f6bc..b45ee47ee2f 100644 --- a/examples/widgets/itemviews/basicsortfiltermodel/window.cpp +++ b/examples/widgets/itemviews/basicsortfiltermodel/window.cpp @@ -89,11 +89,9 @@ Window::Window() connect(filterPatternLineEdit, &QLineEdit::textChanged, this, &Window::filterRegExpChanged); - - typedef void (QComboBox::*QComboIntSignal)(int); - connect(filterSyntaxComboBox, static_cast(&QComboBox::currentIndexChanged), + connect(filterSyntaxComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &Window::filterRegExpChanged); - connect(filterColumnComboBox, static_cast(&QComboBox::currentIndexChanged), + connect(filterColumnComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &Window::filterColumnChanged); connect(filterCaseSensitivityCheckBox, &QAbstractButton::toggled, this, &Window::filterRegExpChanged); diff --git a/examples/widgets/itemviews/pixelator/mainwindow.cpp b/examples/widgets/itemviews/pixelator/mainwindow.cpp index a5a704a8644..2a5b5723443 100644 --- a/examples/widgets/itemviews/pixelator/mainwindow.cpp +++ b/examples/widgets/itemviews/pixelator/mainwindow.cpp @@ -113,10 +113,9 @@ MainWindow::MainWindow() connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit); connect(aboutAction, &QAction::triggered, this, &MainWindow::showAboutBox); //! [4] - typedef void (QSpinBox::*QSpinBoxIntSignal)(int); - connect(pixelSizeSpinBox, static_cast(&QSpinBox::valueChanged), + connect(pixelSizeSpinBox, QOverload::of(&QSpinBox::valueChanged), delegate, &PixelDelegate::setPixelSize); - connect(pixelSizeSpinBox, static_cast(&QSpinBox::valueChanged), + connect(pixelSizeSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &MainWindow::updateView); //! [4] diff --git a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp index a21a64bdd44..10e3dd045a7 100644 --- a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp +++ b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp @@ -282,23 +282,10 @@ void MainWindow::loadLayout() } } -class DockWidgetAreaCornerFunctor { -public: - explicit DockWidgetAreaCornerFunctor(QMainWindow *mw, Qt::Corner c, Qt::DockWidgetArea a) - : m_mainWindow(mw), m_area(a), m_corner(c) {} - - void operator()() const { m_mainWindow->setCorner(m_corner, m_area); } - -private: - QMainWindow *m_mainWindow; - Qt::DockWidgetArea m_area; - Qt::Corner m_corner; -}; - static QAction *addCornerAction(const QString &text, QMainWindow *mw, QMenu *menu, QActionGroup *group, Qt::Corner c, Qt::DockWidgetArea a) { - QAction *result = menu->addAction(text, mw, DockWidgetAreaCornerFunctor(mw, c, a)); + QAction *result = menu->addAction(text, mw, [=]() { mw->setCorner(c, a); }); result->setCheckable(true); group->addAction(result); return result; diff --git a/examples/widgets/mainwindows/mdi/mainwindow.cpp b/examples/widgets/mainwindows/mdi/mainwindow.cpp index 76b1c308cbf..188de1893ef 100644 --- a/examples/widgets/mainwindows/mdi/mainwindow.cpp +++ b/examples/widgets/mainwindows/mdi/mainwindow.cpp @@ -264,16 +264,6 @@ void MainWindow::updateMenus() #endif } -class ActiveMdiSubWindowFunctor { -public: - explicit ActiveMdiSubWindowFunctor(QMdiArea *mdiArea, QMdiSubWindow *activeWindow) : m_mdiArea(mdiArea), m_activeWindow(activeWindow) {} - void operator()() const { m_mdiArea->setActiveSubWindow(m_activeWindow); } - -private: - QMdiArea *m_mdiArea; - QMdiSubWindow *m_activeWindow; -}; - void MainWindow::updateWindowMenu() { windowMenu->clear(); @@ -302,7 +292,9 @@ void MainWindow::updateWindowMenu() text = tr("%1 %2").arg(i + 1) .arg(child->userFriendlyCurrentFile()); } - QAction *action = windowMenu->addAction(text, mdiSubWindow, ActiveMdiSubWindowFunctor(mdiArea, mdiSubWindow)); + QAction *action = windowMenu->addAction(text, mdiSubWindow, [this, mdiSubWindow]() { + mdiArea->setActiveSubWindow(mdiSubWindow); + }); action->setCheckable(true); action ->setChecked(child == activeMdiChild()); } diff --git a/examples/widgets/richtext/textedit/textedit.cpp b/examples/widgets/richtext/textedit/textedit.cpp index dec0b0bd356..140ae478ff4 100644 --- a/examples/widgets/richtext/textedit/textedit.cpp +++ b/examples/widgets/richtext/textedit/textedit.cpp @@ -342,13 +342,11 @@ void TextEdit::setupTextActions() comboStyle->addItem("Ordered List (Roman lower)"); comboStyle->addItem("Ordered List (Roman upper)"); - typedef void (QComboBox::*QComboIntSignal)(int); - connect(comboStyle, static_cast(&QComboBox::activated), this, &TextEdit::textStyle); + connect(comboStyle, QOverload::of(&QComboBox::activated), this, &TextEdit::textStyle); - typedef void (QComboBox::*QComboStringSignal)(const QString &); comboFont = new QFontComboBox(tb); tb->addWidget(comboFont); - connect(comboFont, static_cast(&QComboBox::activated), this, &TextEdit::textFamily); + connect(comboFont, QOverload::of(&QComboBox::activated), this, &TextEdit::textFamily); comboSize = new QComboBox(tb); comboSize->setObjectName("comboSize"); @@ -360,7 +358,7 @@ void TextEdit::setupTextActions() comboSize->addItem(QString::number(size)); comboSize->setCurrentIndex(standardSizes.indexOf(QApplication::font().pointSize())); - connect(comboSize, static_cast(&QComboBox::activated), this, &TextEdit::textSize); + connect(comboSize, QOverload::of(&QComboBox::activated), this, &TextEdit::textSize); } bool TextEdit::load(const QString &f) diff --git a/examples/widgets/tools/codecs/previewform.cpp b/examples/widgets/tools/codecs/previewform.cpp index e5ca13f011d..d19b9c08339 100644 --- a/examples/widgets/tools/codecs/previewform.cpp +++ b/examples/widgets/tools/codecs/previewform.cpp @@ -159,8 +159,7 @@ PreviewForm::PreviewForm(QWidget *parent) new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); okButton = buttonBox->button(QDialogButtonBox::Ok); - typedef void(QComboBox::*ComboBoxIntSignal)(int); - connect(encodingComboBox, static_cast(&QComboBox::activated), + connect(encodingComboBox, QOverload::of(&QComboBox::activated), this, &PreviewForm::updateTextEdit); connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); diff --git a/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp b/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp index f13240d06ff..7a67c763d8c 100644 --- a/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp +++ b/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp @@ -94,10 +94,10 @@ RegularExpressionDialog::RegularExpressionDialog(QWidget *parent) connect(optimizeOnFirstUsageOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); connect(dontAutomaticallyOptimizeOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); - connect(offsetSpinBox, static_cast(&QSpinBox::valueChanged), + connect(offsetSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &RegularExpressionDialog::refresh); - connect(matchTypeComboBox, static_cast(&QComboBox::currentIndexChanged), + connect(matchTypeComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &RegularExpressionDialog::refresh); connect(anchoredMatchOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh); diff --git a/examples/widgets/tools/settingseditor/locationdialog.cpp b/examples/widgets/tools/settingseditor/locationdialog.cpp index 4aa1e6073f9..5b6e2652bbb 100644 --- a/examples/widgets/tools/settingseditor/locationdialog.cpp +++ b/examples/widgets/tools/settingseditor/locationdialog.cpp @@ -106,10 +106,9 @@ LocationDialog::LocationDialog(QWidget *parent) buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - typedef void (QComboBox::*QComboIntSignal)(int); - connect(formatComboBox, static_cast(&QComboBox::activated), + connect(formatComboBox, QOverload::of(&QComboBox::activated), this, &LocationDialog::updateLocationsTable); - connect(scopeComboBox, static_cast(&QComboBox::activated), + connect(scopeComboBox, QOverload::of(&QComboBox::activated), this, &LocationDialog::updateLocationsTable); connect(organizationComboBox->lineEdit(), &QLineEdit::editingFinished, @@ -117,7 +116,7 @@ LocationDialog::LocationDialog(QWidget *parent) connect(applicationComboBox->lineEdit(), &QLineEdit::editingFinished, this, &LocationDialog::updateLocationsTable); - connect(applicationComboBox, static_cast(&QComboBox::activated), + connect(applicationComboBox, QOverload::of(&QComboBox::activated), this, &LocationDialog::updateLocationsTable); connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); diff --git a/examples/widgets/widgets/charactermap/mainwindow.cpp b/examples/widgets/widgets/charactermap/mainwindow.cpp index 8b406ba1ca8..5f17128a2f8 100644 --- a/examples/widgets/widgets/charactermap/mainwindow.cpp +++ b/examples/widgets/widgets/charactermap/mainwindow.cpp @@ -74,8 +74,7 @@ MainWindow::MainWindow() filterCombo->addItem(tr("Monospaced"), QVariant::fromValue(QFontComboBox::MonospacedFonts)); filterCombo->addItem(tr("Proportional"), QVariant::fromValue(QFontComboBox::ProportionalFonts)); filterCombo->setCurrentIndex(0); - typedef void (QComboBox::*QComboBoxIntSignal)(int); - connect(filterCombo, static_cast(&QComboBox::currentIndexChanged), + connect(filterCombo, QOverload::of(&QComboBox::currentIndexChanged), this, &MainWindow::filterChanged); QLabel *fontLabel = new QLabel(tr("Font:")); @@ -114,10 +113,9 @@ MainWindow::MainWindow() this, &MainWindow::findSizes); connect(fontCombo, &QFontComboBox::currentFontChanged, characterWidget, &CharacterWidget::updateFont); - typedef void (QComboBox::*QComboBoxStringSignal)(const QString &); - connect(sizeCombo, static_cast(&QComboBox::currentIndexChanged), + connect(sizeCombo, QOverload::of(&QComboBox::currentIndexChanged), characterWidget, &CharacterWidget::updateSize); - connect(styleCombo, static_cast(&QComboBox::currentIndexChanged), + connect(styleCombo, QOverload::of(&QComboBox::currentIndexChanged), characterWidget, &CharacterWidget::updateStyle); //! [4] //! [5] connect(characterWidget, &CharacterWidget::characterSelected, diff --git a/examples/widgets/widgets/icons/imagedelegate.cpp b/examples/widgets/widgets/icons/imagedelegate.cpp index 980013daeee..3c873f1e245 100644 --- a/examples/widgets/widgets/icons/imagedelegate.cpp +++ b/examples/widgets/widgets/icons/imagedelegate.cpp @@ -71,8 +71,7 @@ QWidget *ImageDelegate::createEditor(QWidget *parent, else if (index.column() == 2) comboBox->addItems(IconPreviewArea::iconStateNames()); - typedef void (QComboBox::*QComboBoxIntSignal)(int); - connect(comboBox, static_cast(&QComboBox::activated), + connect(comboBox, QOverload::of(&QComboBox::activated), this, &ImageDelegate::emitCommitData); return comboBox; diff --git a/examples/widgets/widgets/icons/mainwindow.cpp b/examples/widgets/widgets/icons/mainwindow.cpp index 5f3882de945..f704b8306f9 100644 --- a/examples/widgets/widgets/icons/mainwindow.cpp +++ b/examples/widgets/widgets/icons/mainwindow.cpp @@ -362,8 +362,7 @@ QWidget *MainWindow::createIconSizeGroupBox() sizeButtonGroup = new QButtonGroup(this); sizeButtonGroup->setExclusive(true); - typedef void (QButtonGroup::*QButtonGroupIntBoolSignal)(int, bool); - connect(sizeButtonGroup, static_cast(&QButtonGroup::buttonToggled), + connect(sizeButtonGroup, QOverload::of(&QButtonGroup::buttonToggled), this, &MainWindow::changeSize); QRadioButton *smallRadioButton = new QRadioButton; @@ -391,8 +390,7 @@ QWidget *MainWindow::createIconSizeGroupBox() //! [26] //! [27] - typedef void (QSpinBox::*QSpinBoxIntSignal)(int); - connect(otherSpinBox, static_cast(&QSpinBox::valueChanged), + connect(otherSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &MainWindow::triggerChangeSize); QHBoxLayout *otherSizeLayout = new QHBoxLayout; diff --git a/mkspecs/common/msvc-desktop.conf b/mkspecs/common/msvc-desktop.conf index b72cdff2526..02b8441547b 100644 --- a/mkspecs/common/msvc-desktop.conf +++ b/mkspecs/common/msvc-desktop.conf @@ -1,12 +1,11 @@ # # qmake configuration for Microsoft Visual Studio C/C++ Compiler -# This mkspec is used for all win32-msvcXXXX specs +# This mkspec is used by the win32-msvc and win32-clang-msvc specs # -isEmpty(MSC_VER)|isEmpty(MSVC_VER): error("Source mkspec must set both MSC_VER and MSVC_VER.") - # # Baseline: Visual Studio 2005 (8.0), VC++ 14.0 +# Version-specific settings go in msvc-version.conf (loaded by default_pre) # MAKEFILE_GENERATOR = MSVC.NET @@ -14,7 +13,7 @@ QMAKE_PLATFORM = win32 QMAKE_COMPILER = msvc CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe DEFINES += UNICODE WIN32 -QMAKE_COMPILER_DEFINES += _MSC_VER=$$MSC_VER _WIN32 +QMAKE_COMPILER_DEFINES += _WIN32 contains(QMAKE_TARGET.arch, x86_64) { DEFINES += WIN64 QMAKE_COMPILER_DEFINES += _WIN64 @@ -104,7 +103,4 @@ VCPROJ_EXTENSION = .vcproj VCSOLUTION_EXTENSION = .sln VCPROJ_KEYWORD = Qt4VSv1.0 -include(msvc-base.conf) include(windows-gles.conf) - -unset(MSC_VER) diff --git a/mkspecs/common/msvc-base.conf b/mkspecs/common/msvc-version.conf similarity index 54% rename from mkspecs/common/msvc-base.conf rename to mkspecs/common/msvc-version.conf index d37f10f88eb..664e48b042c 100644 --- a/mkspecs/common/msvc-base.conf +++ b/mkspecs/common/msvc-version.conf @@ -1,6 +1,6 @@ # # qmake configuration for Microsoft Visual Studio C/C++ Compiler -# This mkspec is used for all win32-msvcXXXX and +# This file is used by win32-msvc, win32-clang-msvc, and all # winrt-XXX-msvcXXX specs # @@ -8,14 +8,23 @@ # Version-specific changes # -greaterThan(MSC_VER, 1499) { +isEmpty(QMAKE_MSC_VER): error("msvc-version.conf loaded but QMAKE_MSC_VER isn't set") + +MSVC_VER = 8.0 +COMPAT_MKSPEC = win32-msvc2005 + +greaterThan(QMAKE_MSC_VER, 1499) { # Visual Studio 2008 (9.0) / Visual C++ 15.0 and up + MSVC_VER = 9.0 + COMPAT_MKSPEC = win32-msvc2008 QMAKE_CFLAGS_MP = -MP QMAKE_CXXFLAGS_MP = $$QMAKE_CFLAGS_MP } -greaterThan(MSC_VER, 1599) { +greaterThan(QMAKE_MSC_VER, 1599) { # Visual Studio 2010 (10.0) / Visual C++ 16.0 and up + MSVC_VER = 10.0 + COMPAT_MKSPEC = win32-msvc2010 MAKEFILE_GENERATOR = MSBUILD QMAKE_CFLAGS_AVX = -arch:AVX @@ -24,19 +33,23 @@ greaterThan(MSC_VER, 1599) { VCPROJ_EXTENSION = .vcxproj } -greaterThan(MSC_VER, 1699) { +greaterThan(QMAKE_MSC_VER, 1699) { # Visual Studio 2012 (11.0) / Visual C++ 17.0 and up + MSVC_VER = 11.0 + COMPAT_MKSPEC = win32-msvc2012 QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -D_HAS_EXCEPTIONS=0 QT_CONFIG += c++11 CONFIG += c++11 } -greaterThan(MSC_VER, 1799) { +greaterThan(QMAKE_MSC_VER, 1799) { # Visual Studio 2013 (12.0) / Visual C++ 18.0 and up + MSVC_VER = 12.0 + COMPAT_MKSPEC = win32-msvc2013 QMAKE_CFLAGS += -FS QMAKE_CXXFLAGS += -FS - equals(MSC_VER, 1800) { + equals(QMAKE_MSC_VER, 1800) { QMAKE_CFLAGS_RELEASE += -Zc:strictStrings QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -Zc:strictStrings QMAKE_CXXFLAGS_RELEASE += -Zc:strictStrings @@ -44,11 +57,26 @@ greaterThan(MSC_VER, 1799) { } } -greaterThan(MSC_VER, 1899) { +greaterThan(QMAKE_MSC_VER, 1899) { # Visual Studio 2015 (14.0) / Visual C++ 19.0 and up + MSVC_VER = 14.0 + COMPAT_MKSPEC = win32-msvc2015 QMAKE_CFLAGS += -Zc:strictStrings QMAKE_CFLAGS_WARN_ON += -w44456 -w44457 -w44458 QMAKE_CFLAGS_AVX2 = -arch:AVX2 QMAKE_CXXFLAGS += -Zc:strictStrings -Zc:throwingNew QMAKE_CXXFLAGS_WARN_ON += -w44456 -w44457 -w44458 -wd4577 -wd4467 } + +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/winrt_winphone/qmake.conf b/mkspecs/common/winrt_winphone/qmake.conf index 0c3af4a7a8f..818264c46b9 100644 --- a/mkspecs/common/winrt_winphone/qmake.conf +++ b/mkspecs/common/winrt_winphone/qmake.conf @@ -9,6 +9,7 @@ QMAKE_COMPILER = msvc QMAKE_PLATFORM = winrt win32 CONFIG = package_manifest $$CONFIG incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target rtti DEFINES += UNICODE WIN32 QT_LARGEFILE_SUPPORT Q_BYTE_ORDER=Q_LITTLE_ENDIAN +QMAKE_COMPILER_DEFINES += _WIN32 DEPLOYMENT_PLUGIN += qwinrt @@ -93,9 +94,6 @@ WINRT_ASSETS_PATH = $$PWD/assets WINRT_MANIFEST.capabilities = defaults WINRT_MANIFEST.capabilities_device = defaults -include(../msvc-base.conf) include(../windows-gles.conf) -unset(MSC_VER) - load(qt_config) diff --git a/mkspecs/devices/linux-drive-cx-g++/qmake.conf b/mkspecs/devices/linux-drive-cx-g++/qmake.conf index 985f8626add..a658f29deb2 100644 --- a/mkspecs/devices/linux-drive-cx-g++/qmake.conf +++ b/mkspecs/devices/linux-drive-cx-g++/qmake.conf @@ -16,8 +16,6 @@ include(../common/linux_device_pre.conf) -isEmpty(VIBRANTE_SDK_TOPDIR):error("You must pass -device-option VIBRANTE_SDK_TOPDIR=/path/to/sdk") - QMAKE_INCDIR += \ $${VIBRANTE_SDK_TOPDIR}/include \ $$[QT_SYSROOT]/usr/include @@ -43,4 +41,12 @@ COMPILER_FLAGS += -mtune=cortex-a57.cortex-a53 -march=armv8-a EGLFS_DEVICE_INTEGRATION = eglfs_kms_egldevice include(../common/linux_arm_device_post.conf) + +# override the default from linux_arm_device_post.conf +defineTest(qtConfSanitizeMkspec) { + isEmpty(VIBRANTE_SDK_TOPDIR): \ + error("You must pass -device-option VIBRANTE_SDK_TOPDIR=/path/to/sdk") + deviceSanityCheckCompiler() +} + load(qt_config) diff --git a/mkspecs/devices/linux-jetson-tk1-pro-g++/qmake.conf b/mkspecs/devices/linux-jetson-tk1-pro-g++/qmake.conf index 31aacad99fe..1f44c471519 100644 --- a/mkspecs/devices/linux-jetson-tk1-pro-g++/qmake.conf +++ b/mkspecs/devices/linux-jetson-tk1-pro-g++/qmake.conf @@ -14,8 +14,6 @@ include(../common/linux_device_pre.conf) -isEmpty(VIBRANTE_SDK_TOPDIR):error("You must pass -device-option VIBRANTE_SDK_TOPDIR=/path/to/sdk") - QMAKE_INCDIR += \ $${VIBRANTE_SDK_TOPDIR}/include \ $$[QT_SYSROOT]/usr/include @@ -38,4 +36,12 @@ COMPILER_FLAGS += -mtune=cortex-a15 -march=armv7-a -mfpu=neon-vfpv EGLFS_DEVICE_INTEGRATION = eglfs_kms_egldevice include(../common/linux_arm_device_post.conf) + +# override the default from linux_arm_device_post.conf +defineTest(qtConfSanitizeMkspec) { + isEmpty(VIBRANTE_SDK_TOPDIR): \ + error("You must pass -device-option VIBRANTE_SDK_TOPDIR=/path/to/sdk") + deviceSanityCheckCompiler() +} + load(qt_config) diff --git a/mkspecs/features/configure_base.prf b/mkspecs/features/configure_base.prf index 41f429e204e..a4464528b46 100644 --- a/mkspecs/features/configure_base.prf +++ b/mkspecs/features/configure_base.prf @@ -19,6 +19,7 @@ QMAKE_MAKE = $$(MAKE) } else { error("Configure tests are not supported with the $$MAKEFILE_GENERATOR Makefile generator.") } +QMAKE_MAKE_NAME = $$basename(QMAKE_MAKE) # Make sure we don't inherit MAKEFLAGS - -i in particular is fatal. QMAKE_MAKE = "$${SETENV_PFX}MAKEFLAGS=$$SETENV_SFX $$QMAKE_MAKE" diff --git a/mkspecs/features/data/configure.json b/mkspecs/features/data/configure.json index 8e5ff5f0a46..98ccde1ee3e 100644 --- a/mkspecs/features/data/configure.json +++ b/mkspecs/features/data/configure.json @@ -14,12 +14,5 @@ "redo": { "type": "redo" } } - - }, - - "features": { - "builtins": { - "output": [ "builtins" ] - } } } diff --git a/mkspecs/features/data/macros.cpp b/mkspecs/features/data/macros.cpp new file mode 100644 index 00000000000..88473fb980b --- /dev/null +++ b/mkspecs/features/data/macros.cpp @@ -0,0 +1,28 @@ +// Keep this file small. The pre-processed contents are eval'd by qmake. +#ifdef _MSC_VER +QMAKE_MSC_VER = _MSC_VER +QMAKE_MSC_FULL_VER = _MSC_FULL_VER +#endif +#ifdef __INTEL_COMPILER +QMAKE_ICC_VER = __INTEL_COMPILER +QMAKE_ICC_UPDATE_VER = __INTEL_COMPILER_UPDATE +#endif +#ifdef __APPLE_CC__ +QMAKE_APPLE_CC = __APPLE_CC__ +#endif +#ifdef __clang__ +#ifdef __APPLE_CC__ +QT_APPLE_CLANG_MAJOR_VERSION = __clang_major__ +QT_APPLE_CLANG_MINOR_VERSION = __clang_minor__ +QT_APPLE_CLANG_PATCH_VERSION = __clang_patchlevel__ +#else +QT_CLANG_MAJOR_VERSION = __clang_major__ +QT_CLANG_MINOR_VERSION = __clang_minor__ +QT_CLANG_PATCH_VERSION = __clang_patchlevel__ +#endif +#endif +#ifdef __GNUC__ +QT_GCC_MAJOR_VERSION = __GNUC__ +QT_GCC_MINOR_VERSION = __GNUC_MINOR__ +QT_GCC_PATCH_VERSION = __GNUC_PATCHLEVEL__ +#endif diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf index e7e9a5bd87f..7f5ab3a10cf 100644 --- a/mkspecs/features/default_post.prf +++ b/mkspecs/features/default_post.prf @@ -60,7 +60,7 @@ debug { } # disable special linker flags for host builds (no proper test for host support yet) -!host_build { +!host_build|!cross_compile { use_gold_linker: QMAKE_LFLAGS += $$QMAKE_LFLAGS_USE_GOLD enable_new_dtags: QMAKE_LFLAGS += $$QMAKE_LFLAGS_NEW_DTAGS } diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf index 1b2e5d5db4a..623a3486843 100644 --- a/mkspecs/features/mac/default_post.prf +++ b/mkspecs/features/mac/default_post.prf @@ -1,9 +1,5 @@ load(default_post) -# Ensure that we process sdk.prf first, as it will update QMAKE_CXX -# and friends that other features/extra compilers may depend on. -sdk: load(sdk) - !no_objective_c:CONFIG += objective_c qt { @@ -65,9 +61,9 @@ macx-xcode { only_active_arch.build = debug QMAKE_MAC_XCODE_SETTINGS += only_active_arch } else { - VALID_ARCHS = - device|!simulator: VALID_ARCHS += $$QMAKE_APPLE_DEVICE_ARCHS - simulator: VALID_ARCHS += $$QMAKE_APPLE_SIMULATOR_ARCHS + device|!simulator: VALID_DEVICE_ARCHS = $$QMAKE_APPLE_DEVICE_ARCHS + simulator: VALID_SIMULATOR_ARCHS = $$QMAKE_APPLE_SIMULATOR_ARCHS + VALID_ARCHS = $$VALID_DEVICE_ARCHS $$VALID_SIMULATOR_ARCHS isEmpty(VALID_ARCHS): \ error("QMAKE_APPLE_DEVICE_ARCHS or QMAKE_APPLE_SIMULATOR_ARCHS must contain at least one architecture") @@ -86,6 +82,78 @@ macx-xcode { QMAKE_LFLAGS += $$arch_flags QMAKE_PCH_ARCHS = $$VALID_ARCHS + + macos: deployment_target = $$QMAKE_MACOSX_DEPLOYMENT_TARGET + ios: deployment_target = $$QMAKE_IOS_DEPLOYMENT_TARGET + tvos: deployment_target = $$QMAKE_TVOS_DEPLOYMENT_TARGET + watchos: deployment_target = $$QMAKE_WATCHOS_DEPLOYMENT_TARGET + + # If we're doing a simulator_and_device build, device and simulator + # architectures use different paths and flags for the sysroot and + # deployment target switch, so we must multiplex them across multiple + # architectures using -Xarch. Otherwise we fall back to the simple path. + # This is not strictly necessary, but results in cleaner command lines + # and makes it easier for people to override EXPORT_VALID_ARCHS to limit + # individual rules to a different set of architecture(s) from the overall + # build (such as machtest in QtCore). + simulator_and_device { + QMAKE_XARCH_CFLAGS = + QMAKE_XARCH_LFLAGS = + QMAKE_EXTRA_VARIABLES += QMAKE_XARCH_CFLAGS QMAKE_XARCH_LFLAGS + + for (arch, VALID_ARCHS) { + contains(VALID_SIMULATOR_ARCHS, $$arch) { + sdk = $$simulator.sdk + version_identifier = $$simulator.deployment_identifier + } else { + sdk = $$device.sdk + version_identifier = $$device.deployment_identifier + } + + version_min_flags = \ + -Xarch_$${arch} \ + -m$${version_identifier}-version-min=$$deployment_target + QMAKE_XARCH_CFLAGS_$${arch} = $$version_min_flags \ + -Xarch_$${arch} \ + -isysroot$$xcodeSDKInfo(Path, $$sdk) + QMAKE_XARCH_LFLAGS_$${arch} = $$version_min_flags \ + -Xarch_$${arch} \ + -Wl,-syslibroot,$$xcodeSDKInfo(Path, $$sdk) + + QMAKE_XARCH_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS_$${arch}) + QMAKE_XARCH_LFLAGS += $(EXPORT_QMAKE_XARCH_LFLAGS_$${arch}) + + QMAKE_EXTRA_VARIABLES += \ + QMAKE_XARCH_CFLAGS_$${arch} \ + QMAKE_XARCH_LFLAGS_$${arch} + } + + QMAKE_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS) + QMAKE_CXXFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS) + QMAKE_LFLAGS += $(EXPORT_QMAKE_XARCH_LFLAGS) + } else { + simulator: \ + version_identifier = $$simulator.deployment_identifier + else: \ + version_identifier = $$device.deployment_identifier + version_min_flag = -m$${version_identifier}-version-min=$$deployment_target + QMAKE_CFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag + QMAKE_CXXFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag + QMAKE_LFLAGS += -Wl,-syslibroot,$$QMAKE_MAC_SDK_PATH $$version_min_flag + } + + # Enable precompiled headers for multiple architectures + QMAKE_CFLAGS_USE_PRECOMPILE = + for (arch, VALID_ARCHS) { + QMAKE_CFLAGS_USE_PRECOMPILE += \ + -Xarch_$${arch} \ + -include${QMAKE_PCH_OUTPUT_$${arch}} + } + QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE + QMAKE_OBJCFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE + QMAKE_OBJCXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE + + QMAKE_PCH_OUTPUT_EXT = _${QMAKE_PCH_ARCH}$${QMAKE_PCH_OUTPUT_EXT} } cache(QMAKE_XCODE_DEVELOPER_PATH, stash) diff --git a/mkspecs/features/mac/sdk.prf b/mkspecs/features/mac/sdk.prf index be885e52eef..68ab7e40530 100644 --- a/mkspecs/features/mac/sdk.prf +++ b/mkspecs/features/mac/sdk.prf @@ -47,89 +47,3 @@ for(tool, $$list(QMAKE_CC QMAKE_CXX QMAKE_FIX_RPATH QMAKE_AR QMAKE_RANLIB QMAKE_ $$tool = $$sysrooted $$member(value, 1, -1) cache($$tool_variable, set stash, $$tool) } - -!equals(MAKEFILE_GENERATOR, XCODE) { - macos: deployment_target = $$QMAKE_MACOSX_DEPLOYMENT_TARGET - ios: deployment_target = $$QMAKE_IOS_DEPLOYMENT_TARGET - tvos: deployment_target = $$QMAKE_TVOS_DEPLOYMENT_TARGET - watchos: deployment_target = $$QMAKE_WATCHOS_DEPLOYMENT_TARGET - - device|!simulator: device_archs = $$QMAKE_APPLE_DEVICE_ARCHS - simulator: simulator_archs = $$QMAKE_APPLE_SIMULATOR_ARCHS - archs = $$device_archs $$simulator_archs - - isEmpty(archs): \ - error("QMAKE_APPLE_DEVICE_ARCHS or QMAKE_APPLE_SIMULATOR_ARCHS must contain at least one architecture") - - single_arch { - device_archs = $$first(device_archs) - simulator_archs = $$first(simulator_archs) - archs = $$first(archs) - } - - # If we're doing a simulator and device build, device and simulator architectures - # use different paths and flags for the sysroot and deployment target switch, so we - # must multiplex them across multiple architectures using -Xarch. Otherwise we fall - # back to the simple path. This is not strictly necessary but results in cleaner - # command lines and makes it easier for people to override EXPORT_VALID_ARCHS to - # limit individual rules to a different set of architecture(s) from the overall - # build (such as machtest in QtCore). - simulator:device { - QMAKE_XARCH_CFLAGS = - QMAKE_XARCH_LFLAGS = - QMAKE_EXTRA_VARIABLES += QMAKE_XARCH_CFLAGS QMAKE_XARCH_LFLAGS - - for(arch, archs) { - contains(simulator_archs, $$arch) { - sdk = $$simulator.sdk - version_identifier = $$simulator.deployment_identifier - } else { - sdk = $$device.sdk - version_identifier = $$device.deployment_identifier - } - - version_min_flags = \ - -Xarch_$${arch} \ - -m$${version_identifier}-version-min=$$deployment_target - QMAKE_XARCH_CFLAGS_$${arch} = $$version_min_flags \ - -Xarch_$${arch} \ - -isysroot$$xcodeSDKInfo(Path, $$sdk) - QMAKE_XARCH_LFLAGS_$${arch} = $$version_min_flags \ - -Xarch_$${arch} \ - -Wl,-syslibroot,$$xcodeSDKInfo(Path, $$sdk) - - QMAKE_XARCH_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS_$${arch}) - QMAKE_XARCH_LFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS_$${arch}) - - QMAKE_EXTRA_VARIABLES += \ - QMAKE_XARCH_CFLAGS_$${arch} \ - QMAKE_XARCH_LFLAGS_$${arch} - } - - QMAKE_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS) - QMAKE_CXXFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS) - QMAKE_LFLAGS += $(EXPORT_QMAKE_XARCH_LFLAGS) - } else { - simulator: \ - version_identifier = $$simulator.deployment_identifier - else: \ - version_identifier = $$device.deployment_identifier - version_min_flag = -m$${version_identifier}-version-min=$$deployment_target - QMAKE_CFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag - QMAKE_CXXFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag - QMAKE_LFLAGS += -Wl,-syslibroot,$$QMAKE_MAC_SDK_PATH $$version_min_flag - } - - # Enable precompiled headers for multiple architectures - QMAKE_CFLAGS_USE_PRECOMPILE = - for(arch, archs) { - QMAKE_CFLAGS_USE_PRECOMPILE += \ - -Xarch_$${arch} \ - -include${QMAKE_PCH_OUTPUT_$${arch}} - } - QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE - QMAKE_OBJCFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE - QMAKE_OBJCXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE - - QMAKE_PCH_OUTPUT_EXT = _${QMAKE_PCH_ARCH}$${QMAKE_PCH_OUTPUT_EXT} -} diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 634757a6535..3ccbbe70616 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -45,6 +45,111 @@ qaxserver { QT += axserver } +!import_qpa_plugin { + warning("CONFIG-=import_qpa_plugin is deprecated. Use QTPLUGIN.platforms=- instead.") + QTPLUGIN.platforms = - +} else: qpa_minimal_plugin { + warning("CONFIG+=qpa_minimal_plugin is deprecated. Use QTPLUGIN.platforms=qminimal instead.") + QTPLUGIN.platforms = qminimal +} + +!force_import_plugins:!contains(TEMPLATE, ".*app"):!if(contains(TEMPLATE, ".*lib"):dll): \ + CONFIG -= import_plugins + +# qmake variables cannot contain dashes, so normalize the names first +CLEAN_QT = $$replace(QT, -private$, _private) +CLEAN_QT_PRIVATE = $$replace(QT_PRIVATE, -private$, _private) + +qt_module_deps = $$CLEAN_QT $$CLEAN_QT_PRIVATE +all_qt_module_deps = $$resolve_depends(qt_module_deps, "QT.", ".depends" ".run_depends") + +QTPLUGIN = $$unique($$list($$lower($$QTPLUGIN))) + +import_plugins:qtConfig(static) { + manualplugs = $$QTPLUGIN # User may specify plugins. Mostly legacy. + autoplugs = # Auto-added plugins. + # First round: explicitly specified modules. + plugin_deps = $$all_qt_module_deps + for(ever) { + # Automatically link the default plugins for the linked Qt modules. + for (qtmod, plugin_deps) { + for (ptype, QT.$${qtmod}.plugin_types) { + nptype = $$replace(ptype, [-/], _) + isEmpty(QTPLUGIN.$$nptype) { + for (plug, QT_PLUGINS) { + equals(QT_PLUGIN.$${plug}.TYPE, $$ptype) { + for (dep, QT_PLUGIN.$${plug}.EXTENDS) { + !contains(all_qt_module_deps, $$dep) { + plug = + break() + } + } + autoplugs += $$plug + } + } + } else { + plug = $$eval(QTPLUGIN.$$nptype) + !equals(plug, -): \ + autoplugs += $$plug + } + } + } + QTPLUGIN = $$manualplugs $$autoplugs + QTPLUGIN = $$unique(QTPLUGIN) + + # Obtain the plugins' Qt dependencies ... + plugin_deps = + for (plug, QTPLUGIN): \ + plugin_deps += $$eval(QT_PLUGIN.$${plug}.DEPENDS) + plugin_deps = $$resolve_depends(plugin_deps, "QT.", ".depends" ".run_depends") + plugin_deps -= $$all_qt_module_deps + isEmpty(plugin_deps): \ + break() + # ... and start over if any new Qt modules appeared, + # as these may want to load plugins in turn. + all_qt_module_deps += $$plugin_deps + } + extraplugs = $$manualplugs + manualplugs -= $$autoplugs + extraplugs -= $$manualplugs + !isEmpty(extraplugs): \ + warning("Redundant entries in QTPLUGIN: $$extraplugs") + + !isEmpty(QTPLUGIN) { + IMPORT_FILE_CONT = \ + "// This file is autogenerated by qmake. It imports static plugin classes for" \ + "// static plugins specified using QTPLUGIN and QT_PLUGIN_CLASS. variables." \ + "$${LITERAL_HASH}include " + for (plug, QTPLUGIN) { + plug_class = $$eval(QT_PLUGIN.$${plug}.CLASS_NAME) + !isEmpty(plug_class): \ + IMPORT_FILE_CONT += "Q_IMPORT_PLUGIN($$plug_class)" + else: \ + warning("Plugin class name could not be determined for plugin '$$plug'.") + } + IMPORT_CPP = $$OUT_PWD/$$lower($$basename(TARGET))_plugin_import.cpp + write_file($$IMPORT_CPP, IMPORT_FILE_CONT)|error() + GENERATED_SOURCES += $$IMPORT_CPP + QMAKE_DISTCLEAN += $$IMPORT_CPP + } +} + +# Only link against plugins in static builds +!isEmpty(QTPLUGIN):qtConfig(static) { + for (plug, QTPLUGIN) { + # Check if the plugin is known to Qt. We can use this to determine + # the plugin path. Unknown plugins must rely on the default link path. + plug_type = $$eval(QT_PLUGIN.$${plug}.TYPE) + !isEmpty(plug_type) { + plug_path = $$eval(QT_PLUGIN.$${plug}.PATH) + isEmpty(plug_path): \ + plug_path = $$[QT_INSTALL_PLUGINS/get] + LIBS += -L$$plug_path/$$plug_type + } + LIBS += -l$${plug}$$qtPlatformTargetSuffix() + } +} + # target variable, flag source variable defineTest(qtProcessModuleFlags) { for(flag, $$2) { @@ -59,8 +164,6 @@ defineTest(qtProcessModuleFlags) { unset(using_privates) var_sfx = for(ever) { - # qmake variables cannot contain dashes, so normalize the names first - CLEAN_QT$$var_sfx = $$replace(QT$$var_sfx, -private$, _private) # Topological resolution of modules based on their QT..depends variable FULL_QT$$var_sfx = $$resolve_depends(CLEAN_QT$$var_sfx, "QT.") # Finally actually add the modules @@ -164,11 +267,8 @@ for(ever) { message("This is not a bug, but a result of using Qt internals. You have been warned!") } -qt_module_deps = $$CLEAN_QT $$CLEAN_QT_PRIVATE -qt_module_deps = $$resolve_depends(qt_module_deps, "QT.") - !no_qt_rpath:!static:qtConfig(rpath):!qtConfig(static):\ - contains(qt_module_deps, core) { + contains(all_qt_module_deps, core) { relative_qt_rpath:!isEmpty(QMAKE_REL_RPATH_BASE):contains(INSTALLS, target):\ isEmpty(target.files):isEmpty(target.commands):isEmpty(target.extra) { # NOT the /dev property, as INSTALLS use host paths @@ -183,17 +283,17 @@ qt_module_deps = $$resolve_depends(qt_module_deps, "QT.") # libraries which were NOT specified on the command line. # This means that paths of direct dependencies (QT & QT_PRIVATE) # don't need to be listed, unlike their private dependencies' paths. - privdep = $$resolve_depends(qt_module_deps, "QT.", ".depends" ".run_depends") - privdep -= $$qt_module_deps + privdep = $$all_qt_module_deps + privdep -= $$resolve_depends(qt_module_deps, "QT.") rpaths = for(dep, privdep): \ rpaths += $$eval(QT.$${dep}.libs) QMAKE_RPATHLINKDIR *= $$unique(rpaths) } -# static builds: link qml import plugins into the app. -contains(qt_module_deps, qml): \ - qtConfig(static):contains(TEMPLATE, .*app):!host_build:!no_import_scan { +# static builds: link qml import plugins into the target. +contains(all_qt_module_deps, qml): \ + qtConfig(static):import_plugins:!host_build:!no_import_scan { exists($$[QT_INSTALL_QML/get]): \ QMLPATHS *= $$[QT_INSTALL_QML/get] @@ -238,140 +338,5 @@ contains(qt_module_deps, qml): \ write_file($$QML_IMPORT_CPP, IMPORT_FILE_CONT)|error() GENERATED_SOURCES += $$QML_IMPORT_CPP QMAKE_DISTCLEAN += $$QML_IMPORT_CPP - - # copy qml files. this part is platform spesific. - mac { - !shallow_bundle { - # Note: user can override QMAKE_BUNDLE_QML from pro file to change target bundle path - isEmpty(QMAKE_QML_BUNDLE_PATH):QMAKE_QML_BUNDLE_PATH = "Resources/qt_qml" - qmlTargetPath = $$OUT_PWD/$${TARGET}.app/Contents/$$QMAKE_QML_BUNDLE_PATH - qtconfTargetPath = $$OUT_PWD/$${TARGET}.app/Contents/Resources/qt.conf - } else { - # shallow bundle layout (no Contents/Resources) - isEmpty(QMAKE_QML_BUNDLE_PATH):QMAKE_QML_BUNDLE_PATH = "qt_qml" - qmlTargetPath = $CODESIGNING_FOLDER_PATH/$$QMAKE_QML_BUNDLE_PATH - qtconfTargetPath = $CODESIGNING_FOLDER_PATH/qt.conf - } - - # set import path in qt.conf to point to the bundeled qml: - QT_CONF_CONTENTS = \ - "[Paths]" \ - "Imports = $$QMAKE_QML_BUNDLE_PATH" \ - "Qml2Imports = $$QMAKE_QML_BUNDLE_PATH" - write_file("$$OUT_PWD/qt.conf", QT_CONF_CONTENTS)|error() - - # write qt.conf and copy each qml import dir into the bundle. - # But strip away archives and other files that are not needed: - !isEmpty(QMAKE_POST_LINK): QMAKE_POST_LINK += ";" - QMAKE_POST_LINK += \ - "cp $$shell_quote($$OUT_PWD/qt.conf) \"$$qtconfTargetPath\"; " \ - "test -d \"$$qmlTargetPath\" && rm -r \"$$qmlTargetPath\"; " \ - "mkdir -p \"$$qmlTargetPath\" && " \ - "for p in $$QMLPATHS; do" \ - "rsync -r --exclude='*.a' --exclude='*.prl' --exclude='*.qmltypes' " - macx-xcode: QMAKE_POST_LINK += "$p/ \"$$qmlTargetPath\"; done" - else: QMAKE_POST_LINK += "\$\$p/ \"$$qmlTargetPath\"; done" - } - } -} - -!import_qpa_plugin { - warning("CONFIG-=import_qpa_plugin is deprecated. Use QTPLUGIN.platforms=- instead.") - QTPLUGIN.platforms = - -} else: qpa_minimal_plugin { - warning("CONFIG+=qpa_minimal_plugin is deprecated. Use QTPLUGIN.platforms=qminimal instead.") - QTPLUGIN.platforms = qminimal -} - -contains(TEMPLATE, .*app) { - autoplugs = - for (qtmod, qt_module_deps) { - for (ptype, QT.$${qtmod}.plugin_types) { - nptype = $$replace(ptype, [-/], _) - isEmpty(QTPLUGIN.$$nptype) { - for (plug, QT_PLUGINS) { - equals(QT_PLUGIN.$${plug}.TYPE, $$ptype) { - for (dep, QT_PLUGIN.$${plug}.EXTENDS) { - !contains(qt_module_deps, $$dep) { - plug = - break() - } - } - autoplugs += $$plug - } - } - } else { - plug = $$eval(QTPLUGIN.$$nptype) - !equals(plug, -): \ - autoplugs += $$plug - } - } - } - manualplugs = $$QTPLUGIN - manualplugs -= $$autoplugs - QTPLUGIN -= $$manualplugs - !isEmpty(QTPLUGIN): \ - warning("Redundant entries in QTPLUGIN: $$QTPLUGIN") - QTPLUGIN = $$manualplugs $$autoplugs -} - -QT_PLUGIN_VERIFY = DEPLOYMENT_PLUGIN -qtConfig(static) { - QT_PLUGIN_VERIFY += QTPLUGIN - force_import_plugins|contains(TEMPLATE, .*app) { - import_plugins:!isEmpty(QTPLUGIN) { - IMPORT_FILE_CONT = \ - "// This file is autogenerated by qmake. It imports static plugin classes for" \ - "// static plugins specified using QTPLUGIN and QT_PLUGIN_CLASS. variables." \ - "$${LITERAL_HASH}include " - for(IMPORT_PLUG, $$list($$unique(QTPLUGIN))) { - PLUG_CLASS = $$eval(QT_PLUGIN.$${IMPORT_PLUG}.CLASS_NAME) - !isEmpty(PLUG_CLASS): \ - IMPORT_FILE_CONT += "Q_IMPORT_PLUGIN($$PLUG_CLASS)" - else: \ - warning("Plugin class name could not be determined for $$IMPORT_PLUG plugin.") - } - IMPORT_CPP = $$OUT_PWD/$$lower($$basename(TARGET))_plugin_import.cpp - write_file($$IMPORT_CPP, IMPORT_FILE_CONT)|error() - GENERATED_SOURCES += $$IMPORT_CPP - QMAKE_DISTCLEAN += $$IMPORT_CPP - } - } -} - -for(QT_CURRENT_VERIFY, $$list($$QT_PLUGIN_VERIFY)) { - for(QTPLUG, $$list($$lower($$unique($$QT_CURRENT_VERIFY)))) { - # Check if the plugin is known to Qt. We can use this to determine - # the plugin path. Unknown plugins must rely on the default link path. - QT_PLUGINPATH = $$eval(QT_PLUGIN.$${QTPLUG}.TYPE) - - # Generate the plugin linker line - QT_LINKAGE = -l$${QTPLUG}$$qtPlatformTargetSuffix() - - # Only link against plugin in static builds - isEqual(QT_CURRENT_VERIFY, QTPLUGIN) { - !isEmpty(QT_PLUGINPATH) { - plugpath = $$eval(QT_PLUGIN.$${QTPLUG}.PATH) - isEmpty(plugpath): \ - plugpath = $$[QT_INSTALL_PLUGINS/get] - LIBS *= -L$$plugpath/$$QT_PLUGINPATH - } - LIBS += $$QT_LINKAGE - # if the plugin is linked statically there is no need to deploy it - DEPLOYMENT_PLUGIN -= $$QT_CURRENT_VERIFY - } - - # The following block is currently broken, because qt_plugin_XXX.prf files - # are not generated for dynamic builds. - false:isEqual(QT_CURRENT_VERIFY, DEPLOYMENT_PLUGIN):shared:winrt { - QT_ITEM = - debug: QT_ITEM = $${QTPLUG}d4.dll - else: QT_ITEM = $${QTPLUG}4.dll - - qt_additional_plugin_$${QTPLUG}.files = $$[QT_INSTALL_PLUGINS/get]/$${QT_PLUGINPATH}/$${QT_ITEM} - qt_additional_plugin_$${QTPLUG}.path = $${QT_PLUGINPATH} - - INSTALLS *= qt_additional_plugin_$${QTPLUG} - } } } diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf index fefd36a7b85..c4c78554b3e 100644 --- a/mkspecs/features/qt_common.prf +++ b/mkspecs/features/qt_common.prf @@ -19,7 +19,7 @@ qtConfig(c++14): CONFIG += c++14 qtConfig(c++1z): CONFIG += c++1z contains(TEMPLATE, .*lib) { # module and plugins - !host_build:qtConfig(reduce_exports): CONFIG += hide_symbols + if(!host_build|!cross_compile):qtConfig(reduce_exports): CONFIG += hide_symbols unix:qtConfig(reduce_relocations): CONFIG += bsymbolic_functions qtConfig(separate_debug_info): CONFIG += separate_debug_info @@ -100,6 +100,9 @@ warnings_are_errors:warning_clean { # error: assuming signed overflow does not occur when assuming that (X + c) < X is always false QMAKE_CXXFLAGS_WARN_ON += -Wno-error=strict-overflow + # 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 + # 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 a620e94e97f..7d56a7474bc 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -183,7 +183,9 @@ defineTest(qtConfCommandline_redo) { qtConfAddError("No config.opt present - cannot redo configuration.") return() } - QMAKE_EXTRA_ARGS = $$cat($$OUT_PWD/config.opt, lines) $$QMAKE_EXTRA_ARGS + QMAKE_EXTRA_REDO_ARGS = $$cat($$OUT_PWD/config.opt, lines) + export(QMAKE_EXTRA_REDO_ARGS) # just for config.log + QMAKE_EXTRA_ARGS = $$QMAKE_EXTRA_REDO_ARGS $$QMAKE_EXTRA_ARGS export(QMAKE_EXTRA_ARGS) QMAKE_REDO_CONFIG = true export(QMAKE_REDO_CONFIG) @@ -241,8 +243,8 @@ defineTest(qtConfParseCommandLine) { opt = $$replace(c, "^--?(disable|no)-(.*)", "\\2") val = no } else: contains(c, "^--([^=]+)=(.*)") { - opt = $$replace(c, "^--?([^=]+)=(.*)", "\\1") - val = $$replace(c, "^--?([^=]+)=(.*)", "\\2") + opt = $$replace(c, "^--([^=]+)=(.*)", "\\1") + val = $$replace(c, "^--([^=]+)=(.*)", "\\2") } else: contains(c, "^--(.*)") { opt = $$replace(c, "^--(.*)", "\\1") val = yes @@ -387,14 +389,17 @@ defineTest(qtConfPkgConfigPackageExists) { return(true) } -defineReplace(qtConfPrepareArgs) { - arglist = $$split(1) +defineReplace(qtSystemQuote) { args = - for (a, arglist): \ + for (a, 1): \ args += $$system_quote($$a) return($$args) } +defineReplace(qtConfPrepareArgs) { + return($$qtSystemQuote($$split(1))) +} + defineTest(qtConfSetupLibraries) { for (l, $${currentConfig}.libraries._KEYS_) { lpfx = $${currentConfig}.libraries.$${l} @@ -503,12 +508,16 @@ defineTest(qtConfLibrary_makeSpec) { # the library is found via pkg-config. defineTest(qtConfLibrary_pkgConfig) { pkg_config = $$qtConfPkgConfig($$eval($${1}.host)) - isEmpty(pkg_config): \ + isEmpty(pkg_config) { + qtLog("pkg-config use disabled globally.") return(false) + } args = $$qtConfPrepareArgs($$eval($${1}.args)) - !qtConfPkgConfigPackageExists($$pkg_config, $$args): \ + !qtConfPkgConfigPackageExists($$pkg_config, $$args) { + qtLog("pkg-config did not find package.") return(false) + } qtRunLoggedCommand("$$pkg_config --modversion $$args", version)|return(false) qtRunLoggedCommand("$$pkg_config --libs-only-L --libs-only-l $$args", $${1}.libs)|return(false) @@ -619,8 +628,9 @@ defineTest(qtConfHandleLibrary) { qtLog("Trying source $$s (type $$t) of library $${1} ...") - !$$qtConfEvaluate($$eval($${spfx}.condition)) { - qtLog(" => source failed condition.") + cond = $$eval($${spfx}.condition) + !$$qtConfEvaluate($$cond) { + qtLog(" => source failed condition '$$cond'.") next() } @@ -1367,33 +1377,21 @@ defineTest(qtConfCreateSummary) { } defineTest(qtConfPrintReport) { - for (n, QT_CONFIGURE_REPORT): \ - logn($$n) - logn() - - for (n, QT_CONFIGURE_NOTES) { - logn($$n) - logn() - } - - for (w, QT_CONFIGURE_WARNINGS) { - logn($$w) - logn() - } + blocks = \ + "$$join(QT_CONFIGURE_REPORT, $$escape_expand(\\n))" \ + "$$join(QT_CONFIGURE_NOTES, $$escape_expand(\\n\\n))" \ + "$$join(QT_CONFIGURE_WARNINGS, $$escape_expand(\\n\\n))" !isEmpty(QT_CONFIGURE_ERRORS) { - for (e, QT_CONFIGURE_ERRORS) { - logn($$e) - logn() - } - mention_config_log:!$$QMAKE_CONFIG_VERBOSE { - logn("Check config.log for details.") - logn() - } - - !equals(config.input.continue, yes): \ - error() + blocks += "$$join(QT_CONFIGURE_ERRORS, $$escape_expand(\\n\\n))" + mention_config_log:!$$QMAKE_CONFIG_VERBOSE: \ + blocks += "Check config.log for details." } + blocks = "$$join(blocks, $$escape_expand(\\n\\n))" + logn($$blocks) + !isEmpty(QT_CONFIGURE_ERRORS):!equals(config.input.continue, yes): \ + error() + write_file($$OUT_PWD/config.summary, blocks)|error() } defineTest(qtConfCheckErrors) { @@ -1612,19 +1610,6 @@ defineTest(qtConfOutput_privateFeature) { } } -# command line built-ins post-processing -defineTest(qtConfOutput_builtins) { - QMAKE_CONFIG_VERBOSE = $$eval(config.input.verbose) - isEmpty(QMAKE_CONFIG_VERBOSE): \ - QMAKE_CONFIG_VERBOSE = false - export(QMAKE_CONFIG_VERBOSE) - - QMAKE_CONFIG_CACHE_USE = $$eval(config.input.cache_use) - isEmpty(QMAKE_CONFIG_CACHE_USE): \ - QMAKE_CONFIG_CACHE_USE = all - export(QMAKE_CONFIG_CACHE_USE) -} - defineTest(qtConfProcessOneOutput) { feature = $${1} fpfx = $${currentConfig}.features.$${feature} @@ -1709,16 +1694,25 @@ defineTest(qtConfProcessOutput) { # tie it all together # -cfgs = -isEmpty(_QMAKE_SUPER_CACHE_)|equals(OUT_PWD, $$dirname(_QMAKE_SUPER_CACHE_)) { - c = $$basename(_PRO_FILE_PWD_) - config.$${c}.dir = $$_PRO_FILE_PWD_ - cfgs += $$c - !isEmpty(_QMAKE_SUPER_CACHE_) { - for (s, SUBDIRS) { - config.$${s}.dir = $$_PRO_FILE_PWD_/$${s} - cfgs += $$s - } +!isEmpty(_QMAKE_SUPER_CACHE_):!equals(OUT_PWD, $$dirname(_QMAKE_SUPER_CACHE_)) { + # sub-repo within a top-level build; no need to configure anything. + !isEmpty(QMAKE_EXTRA_ARGS) { + # sub-projects don't get the extra args passed down automatically, + # so we can use their presence to detect misguided attempts to + # configure the repositories separately. + # caveat: a plain qmake call is indistinguishable from a recursion + # (by design), so we cannot detect this case. + error("You cannot configure $$TARGET separately within a top-level build.") + } + return() +} + +config.$${TARGET}.dir = $$_PRO_FILE_PWD_ +cfgs = $$TARGET +!isEmpty(_QMAKE_SUPER_CACHE_) { + for (s, SUBDIRS) { + config.$${s}.dir = $$_PRO_FILE_PWD_/$${s} + cfgs += $$s } } configsToProcess = @@ -1727,8 +1721,11 @@ for (c, cfgs) { exists($$s/configure.json): \ configsToProcess += $$c } -isEmpty(configsToProcess): \ +isEmpty(configsToProcess) { + !isEmpty(QMAKE_EXTRA_ARGS): \ + error("This module does not accept configure command line arguments.") return() +} load(configure_base) @@ -1771,6 +1768,7 @@ for (currentConfig, allConfigs): \ QMAKE_SAVED_ARGS = $$QMAKE_EXTRA_ARGS QMAKE_REDO_CONFIG = false qtConfParseCommandLine() +qtConfCheckErrors() for (currentConfig, allConfigs) { qtConfSetModuleName() @@ -1784,6 +1782,9 @@ qtConfCheckErrors() QMAKE_CONFIG_CACHE = $$dirname(_QMAKE_SUPER_CACHE_)/config.cache else: \ QMAKE_CONFIG_CACHE = $$dirname(_QMAKE_CACHE_)/config.cache +QMAKE_CONFIG_CACHE_USE = $$eval(config.input.cache_use) +isEmpty(QMAKE_CONFIG_CACHE_USE): \ + QMAKE_CONFIG_CACHE_USE = all !equals(QMAKE_CONFIG_CACHE_USE, none) { include($$QMAKE_CONFIG_CACHE, , true) # this crudely determines when to discard the cache. this also catches the case @@ -1798,9 +1799,17 @@ equals(QMAKE_CONFIG_CACHE_USE, none) { write_file($$QMAKE_CONFIG_CACHE, cont) } +QMAKE_CONFIG_VERBOSE = $$eval(config.input.verbose) +isEmpty(QMAKE_CONFIG_VERBOSE): \ + QMAKE_CONFIG_VERBOSE = false QMAKE_CONFIG_LOG = $$OUT_PWD/config.log !equals(QMAKE_CONFIG_CACHE_USE, all): \ write_file($$QMAKE_CONFIG_LOG, "") +else: \ + write_file($$QMAKE_CONFIG_LOG, $$list($$escape_expand(\\n)), append) +qtLog("Command line: $$qtSystemQuote($$QMAKE_SAVED_ARGS)") +$$QMAKE_REDO_CONFIG: \ + qtLog("config.opt: $$qtSystemQuote($$QMAKE_EXTRA_REDO_ARGS)") CONFIG += qt_conf_tests_allowed logn() @@ -1861,3 +1870,19 @@ for (p, QMAKE_POST_CONFIGURE): \ logn("Configure summary:") logn() qtConfPrintReport() + +# final notes for the user +logn() +logn("Qt is now configured for building. Just run '$$QMAKE_MAKE_NAME'.") +pfx = $$[QT_INSTALL_PREFIX] +equals(pfx, $$[QT_INSTALL_PREFIX/get]) { + logn("Once everything is built, Qt is installed.") + logn("You should NOT run '$$QMAKE_MAKE_NAME install'.") +} else { + logn("Once everything is built, you must run '$$QMAKE_MAKE_NAME install'.") + logn("Qt will be installed into '$$system_path($$pfx)'.") +} +logn() +logn("Prior to reconfiguration, make sure you remove any leftovers from") +logn("the previous build.") +logn() diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index 23d75182d0e..1f14dec0d4b 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -211,7 +211,10 @@ android: CONFIG += qt_android_deps no_linker_version_script } else { verscript_content = "Qt_$${QT_MAJOR_VERSION}_PRIVATE_API {" \ " qt_private_api_tag*;" - for(header, SYNCQT.PRIVATE_HEADER_FILES): \ + + private_api_headers = $$SYNCQT.PRIVATE_HEADER_FILES $$SYNCQT.QPA_HEADER_FILES + + for(header, private_api_headers): \ verscript_content += " @FILE:$${_PRO_FILE_PWD_}/$$header@" verscript_content += "};" @@ -232,7 +235,7 @@ android: CONFIG += qt_android_deps no_linker_version_script verscriptprocess.name = linker version script ${QMAKE_FILE_BASE} verscriptprocess.input = verscript_in verscriptprocess.CONFIG += no_link target_predeps - for(header, SYNCQT.PRIVATE_HEADER_FILES): \ + for(header, private_api_headers): \ verscriptprocess.depends += $${_PRO_FILE_PWD_}/$$header verscriptprocess.output = $$verscript verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < ${QMAKE_FILE_IN} > $@ diff --git a/mkspecs/features/qt_plugin.prf b/mkspecs/features/qt_plugin.prf index 265b4ea8a21..80d9c87e058 100644 --- a/mkspecs/features/qt_plugin.prf +++ b/mkspecs/features/qt_plugin.prf @@ -44,9 +44,13 @@ CONFIG(static, static|shared)|prefix_build { MODULE_FWD_PRI = $$mod_work_pfx/qt_plugin_$${MODULE}.pri !build_pass { + qt_plugin_deps = $$QT $$QT_PRIVATE + qt_plugin_deps = s,-private$,_private,g + MODULE_PRI_CONT = \ "QT_PLUGIN.$${MODULE}.TYPE = $$PLUGIN_TYPE" \ "QT_PLUGIN.$${MODULE}.EXTENDS =$$join(PLUGIN_EXTENDS, " ", " ")" \ + "QT_PLUGIN.$${MODULE}.DEPENDS = $$qt_plugin_deps" \ "QT_PLUGIN.$${MODULE}.CLASS_NAME = $$PLUGIN_CLASS_NAME" \ "QT_PLUGINS += $$MODULE" write_file($$MODULE_PRI, MODULE_PRI_CONT)|error() diff --git a/mkspecs/features/qt_targets.prf b/mkspecs/features/qt_targets.prf index 72429526a7e..cd76efdaf34 100644 --- a/mkspecs/features/qt_targets.prf +++ b/mkspecs/features/qt_targets.prf @@ -1,4 +1,4 @@ QMAKE_TARGET_COMPANY = The Qt Company Ltd -QMAKE_TARGET_PRODUCT = Qt5 -QMAKE_TARGET_DESCRIPTION = C++ application development framework. -QMAKE_TARGET_COPYRIGHT = Copyright (C) 2015 The Qt Company Ltd. +isEmpty(QMAKE_TARGET_PRODUCT): QMAKE_TARGET_PRODUCT = Qt5 +isEmpty(QMAKE_TARGET_DESCRIPTION): QMAKE_TARGET_DESCRIPTION = C++ application development framework. +QMAKE_TARGET_COPYRIGHT = Copyright (C) 2017 The Qt Company Ltd. diff --git a/mkspecs/features/resolve_target.prf b/mkspecs/features/resolve_target.prf index 8678c33ecd5..a9fe0d76d69 100644 --- a/mkspecs/features/resolve_target.prf +++ b/mkspecs/features/resolve_target.prf @@ -19,7 +19,6 @@ win32 { contains(TEMPLATE, .*lib) { !skip_target_version_ext:isEmpty(TARGET_VERSION_EXT):!isEmpty(VERSION) { TARGET_VERSION_EXT = $$section(VERSION, ., 0, 0) - isEqual(TARGET_VERSION_EXT, 0):unset(TARGET_VERSION_EXT) } static:TARGET_EXT = .lib else:TARGET_EXT = .dll diff --git a/mkspecs/features/resources.prf b/mkspecs/features/resources.prf index adc8e9a8ac9..de769b4b865 100644 --- a/mkspecs/features/resources.prf +++ b/mkspecs/features/resources.prf @@ -19,7 +19,7 @@ defineReplace(xml_escape) { RESOURCES += qmake_immediate for(resource, RESOURCES) { # Regular case of user qrc file - contains(resource, ".*\.qrc$"): \ + contains(resource, ".*\\.qrc$"): \ next() # Fallback for stand-alone files/directories diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index 0ef0fa8fc72..15b08292359 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -12,7 +12,12 @@ defineReplace(qtMakeExpand) { } } -isEmpty(QMAKE_DEFAULT_INCDIRS):!host_build { +cross_compile:host_build: \ + target_prefix = QMAKE_HOST_CXX +else: \ + target_prefix = QMAKE_CXX + +isEmpty($${target_prefix}.INCDIRS) { # # Get default include and library paths from compiler # @@ -44,6 +49,8 @@ isEmpty(QMAKE_DEFAULT_INCDIRS):!host_build { } QMAKE_DEFAULT_LIBDIRS = $$unique(QMAKE_DEFAULT_LIBDIRS) } 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") @@ -55,6 +62,101 @@ isEmpty(QMAKE_DEFAULT_INCDIRS):!host_build { isEmpty(QMAKE_DEFAULT_LIBDIRS): QMAKE_DEFAULT_LIBDIRS = /lib /usr/lib } - !isEmpty(QMAKE_DEFAULT_INCDIRS): cache(QMAKE_DEFAULT_INCDIRS, set stash) - !isEmpty(QMAKE_DEFAULT_LIBDIRS): cache(QMAKE_DEFAULT_LIBDIRS, set stash) + cache($${target_prefix}.INCDIRS, set stash, QMAKE_DEFAULT_INCDIRS) + cache($${target_prefix}.LIBDIRS, set stash, QMAKE_DEFAULT_LIBDIRS) +} else { + QMAKE_DEFAULT_INCDIRS = $$eval($${target_prefix}.INCDIRS) + QMAKE_DEFAULT_LIBDIRS = $$eval($${target_prefix}.LIBDIRS) } + +# +# Determine and cache the compiler version +# + +defineReplace(qtVariablesFromMSVC) { + return($$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) NUL", lines)) +} + +defineReplace(qtVariablesFromGCC) { + null_device = /dev/null + equals(QMAKE_HOST.os, Windows): null_device = NUL + return($$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) <$$null_device 2>$$null_device", lines)) +} + +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 { + vars = $$qtVariablesFromGCC($$QMAKE_CXX) + } + for (v, vars) { + isEmpty(v)|contains(v, $${LITERAL_HASH}.*): next() + # Set both for the outer scope ... + eval($$v) + v ~= s/ .*// + isEmpty($$v): error("Compiler produced empty value for $${v}.") + # ... and save QMAKE_(HOST_)?CXX. 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) +} + +unset(target_prefix) + +# Populate QMAKE_COMPILER_DEFINES and some compatibility variables. +# The $$format_number() calls strip leading zeros to avoid misinterpretation as octal. +!isEmpty(QMAKE_MSC_VER) { + QMAKE_COMPILER_DEFINES += _MSC_VER=$$QMAKE_MSC_VER _MSC_FULL_VER=$$QMAKE_MSC_FULL_VER + QT_MSVC_MAJOR_VERSION = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", "\\1") + QT_MSVC_MINOR_VERSION = $$format_number($$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", "\\2")) + QT_MSVC_PATCH_VERSION = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", "\\3")) +} +!isEmpty(QMAKE_ICC_VER) { + QMAKE_COMPILER_DEFINES += __INTEL_COMPILER=$$QMAKE_ICC_VER __INTEL_COMPILER_UPDATE=$$QMAKE_ICC_UPDATE_VER + QT_ICC_MAJOR_VERSION = $$replace(QMAKE_ICC_VER, "(..)(..)", "\\1") + QT_ICC_MINOR_VERSION = $$format_number($$replace(QMAKE_ICC_VER, "(..)(..)", "\\2")) + QT_ICC_PATCH_VERSION = $$QMAKE_ICC_UPDATE_VER +} +!isEmpty(QMAKE_APPLE_CC): \ + QMAKE_COMPILER_DEFINES += __APPLE_CC__=$$QMAKE_APPLE_CC +!isEmpty(QT_APPLE_CLANG_MAJOR_VERSION): \ + QMAKE_COMPILER_DEFINES += __clang__ \ + __clang_major__=$$QT_APPLE_CLANG_MAJOR_VERSION \ + __clang_minor__=$$QT_APPLE_CLANG_MINOR_VERSION \ + __clang_patchlevel__=$$QT_APPLE_CLANG_PATCH_VERSION +!isEmpty(QT_CLANG_MAJOR_VERSION): \ + QMAKE_COMPILER_DEFINES += __clang__ \ + __clang_major__=$$QT_CLANG_MAJOR_VERSION \ + __clang_minor__=$$QT_CLANG_MINOR_VERSION \ + __clang_patchlevel__=$$QT_CLANG_PATCH_VERSION +!isEmpty(QT_GCC_MAJOR_VERSION): \ + QMAKE_COMPILER_DEFINES += \ + __GNUC__=$$QT_GCC_MAJOR_VERSION \ + __GNUC_MINOR__=$$QT_GCC_MINOR_VERSION \ + __GNUC_PATCHLEVEL__=$$QT_GCC_PATCH_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/features/win32/default_pre.prf b/mkspecs/features/win32/default_pre.prf index 385184f632b..bdb72c0d897 100644 --- a/mkspecs/features/win32/default_pre.prf +++ b/mkspecs/features/win32/default_pre.prf @@ -1,3 +1,2 @@ CONFIG = rtti_off incremental_off windows $$CONFIG load(default_pre) - diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf index a1288367af4..8f4a7a6eab6 100644 --- a/mkspecs/features/winrt/package_manifest.prf +++ b/mkspecs/features/winrt/package_manifest.prf @@ -93,7 +93,7 @@ isEmpty(WINRT_MANIFEST.background): WINRT_MANIFEST.background = green isEmpty(WINRT_MANIFEST.foreground): WINRT_MANIFEST.foreground = light isEmpty(WINRT_MANIFEST.default_language): WINRT_MANIFEST.default_language = en - *-msvc2015 { + *-msvc2015|*-msvc2017 { isEmpty(WINRT_MANIFEST.minVersion): WINRT_MANIFEST.minVersion = $$(UCRTVersion) isEmpty(WINRT_MANIFEST.minVersion): error("No UCRTVersion found in environment.")) isEmpty(WINRT_MANIFEST.maxVersionTested): WINRT_MANIFEST.maxVersionTested = $$WINRT_MANIFEST.minVersion @@ -116,7 +116,7 @@ # All Windows 10 applications need to have internetClient. It is also not marked as additional # capability anymore and is assumed to be standard. - *-msvc2015: WINRT_MANIFEST.capabilities += internetClient + *-msvc2015|*-msvc2017: WINRT_MANIFEST.capabilities += internetClient contains(WINRT_MANIFEST.capabilities, defaults) { WINRT_MANIFEST.capabilities -= defaults @@ -143,7 +143,7 @@ } # Dependencies are given as a string list. The CRT dependency is added automatically above. - # For MSVC2015 the dependencies are added in conjunction with TargetDeviceFamily + # For MSVC2015/2017 the dependencies are added in conjunction with TargetDeviceFamily # Due to the hard coded dependency on "Windows.Universal" the tag # is already inside the MSVC2015 manifest. WINRT_MANIFEST.dependencies = $$unique(WINRT_MANIFEST.dependencies) diff --git a/mkspecs/win32-clang-msvc2015/qmake.conf b/mkspecs/win32-clang-msvc/qmake.conf similarity index 56% rename from mkspecs/win32-clang-msvc2015/qmake.conf rename to mkspecs/win32-clang-msvc/qmake.conf index 73cfdcbab9f..0041788ef9e 100644 --- a/mkspecs/win32-clang-msvc2015/qmake.conf +++ b/mkspecs/win32-clang-msvc/qmake.conf @@ -1,13 +1,9 @@ # -# qmake configuration for win32-clang-msvc2015 - +# qmake configuration for win32-clang-msvc # -# Written for Clang 3.8 with Microsoft Visual C++ 2015 Update 1 # Notice: this uses the clang-cl wrapper # -MSC_VER = 1900 -MSVC_VER = 14.0 include(../common/msvc-desktop.conf) QMAKE_COMPILER += clang_cl llvm @@ -15,7 +11,7 @@ QMAKE_COMPILER += clang_cl llvm QMAKE_CC = clang-cl QMAKE_CXX = $$QMAKE_CC -QMAKE_CFLAGS += -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value +QMAKE_CFLAGS += -Wno-microsoft-enum-value QMAKE_CXXFLAGS = $$QMAKE_CFLAGS # Precompiled headers are not supported yet by clang diff --git a/mkspecs/win32-msvc2008/qplatformdefs.h b/mkspecs/win32-clang-msvc/qplatformdefs.h similarity index 97% rename from mkspecs/win32-msvc2008/qplatformdefs.h rename to mkspecs/win32-clang-msvc/qplatformdefs.h index 9c598265551..8a3afa7630d 100644 --- a/mkspecs/win32-msvc2008/qplatformdefs.h +++ b/mkspecs/win32-clang-msvc/qplatformdefs.h @@ -37,4 +37,4 @@ ** ****************************************************************************/ -#include "../win32-msvc2005/qplatformdefs.h" +#include "../win32-msvc/qplatformdefs.h" diff --git a/mkspecs/win32-clang-msvc2015/qplatformdefs.h b/mkspecs/win32-clang-msvc2015/qplatformdefs.h deleted file mode 100644 index 7100e3aa41e..00000000000 --- a/mkspecs/win32-clang-msvc2015/qplatformdefs.h +++ /dev/null @@ -1,34 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../win32-msvc2005/qplatformdefs.h" diff --git a/mkspecs/win32-icc/qplatformdefs.h b/mkspecs/win32-icc/qplatformdefs.h index 9c598265551..8a3afa7630d 100644 --- a/mkspecs/win32-icc/qplatformdefs.h +++ b/mkspecs/win32-icc/qplatformdefs.h @@ -37,4 +37,4 @@ ** ****************************************************************************/ -#include "../win32-msvc2005/qplatformdefs.h" +#include "../win32-msvc/qplatformdefs.h" diff --git a/mkspecs/win32-msvc/qmake.conf b/mkspecs/win32-msvc/qmake.conf new file mode 100644 index 00000000000..1d8b8f0e97f --- /dev/null +++ b/mkspecs/win32-msvc/qmake.conf @@ -0,0 +1,8 @@ +# +# qmake configuration for win32-msvc +# +# Written for Microsoft Visual C++ (all desktop versions) +# + +include(../common/msvc-desktop.conf) +load(qt_config) diff --git a/mkspecs/win32-msvc2005/qplatformdefs.h b/mkspecs/win32-msvc/qplatformdefs.h similarity index 100% rename from mkspecs/win32-msvc2005/qplatformdefs.h rename to mkspecs/win32-msvc/qplatformdefs.h diff --git a/mkspecs/win32-msvc2005/qmake.conf b/mkspecs/win32-msvc2005/qmake.conf deleted file mode 100644 index 458f37cc047..00000000000 --- a/mkspecs/win32-msvc2005/qmake.conf +++ /dev/null @@ -1,10 +0,0 @@ -# -# qmake configuration for win32-msvc2005 -# -# Written for Microsoft Visual C++ 2005 -# - -MSC_VER = 1400 -MSVC_VER = 8.0 -include(../common/msvc-desktop.conf) -load(qt_config) diff --git a/mkspecs/win32-msvc2008/qmake.conf b/mkspecs/win32-msvc2008/qmake.conf deleted file mode 100644 index d1382ff2d43..00000000000 --- a/mkspecs/win32-msvc2008/qmake.conf +++ /dev/null @@ -1,10 +0,0 @@ -# -# qmake configuration for win32-msvc2008 -# -# Written for Microsoft Visual C++ 2008 -# - -MSC_VER = 1500 -MSVC_VER = 9.0 -include(../common/msvc-desktop.conf) -load(qt_config) diff --git a/mkspecs/win32-msvc2010/qmake.conf b/mkspecs/win32-msvc2010/qmake.conf deleted file mode 100644 index 3ad9d478ee3..00000000000 --- a/mkspecs/win32-msvc2010/qmake.conf +++ /dev/null @@ -1,10 +0,0 @@ -# -# qmake configuration for win32-msvc2010 -# -# Written for Microsoft Visual C++ 2010 -# - -MSC_VER = 1600 -MSVC_VER = 10.0 -include(../common/msvc-desktop.conf) -load(qt_config) diff --git a/mkspecs/win32-msvc2012/qmake.conf b/mkspecs/win32-msvc2012/qmake.conf deleted file mode 100644 index 3d9c5864af4..00000000000 --- a/mkspecs/win32-msvc2012/qmake.conf +++ /dev/null @@ -1,10 +0,0 @@ -# -# qmake configuration for win32-msvc2012 -# -# Written for Microsoft Visual C++ 2012 -# - -MSC_VER = 1700 -MSVC_VER = 11.0 -include(../common/msvc-desktop.conf) -load(qt_config) diff --git a/mkspecs/win32-msvc2013/qmake.conf b/mkspecs/win32-msvc2013/qmake.conf deleted file mode 100644 index 34108b2c328..00000000000 --- a/mkspecs/win32-msvc2013/qmake.conf +++ /dev/null @@ -1,10 +0,0 @@ -# -# qmake configuration for win32-msvc2013 -# -# Written for Microsoft Visual C++ 2013 -# - -MSC_VER = 1800 -MSVC_VER = 12.0 -include(../common/msvc-desktop.conf) -load(qt_config) diff --git a/mkspecs/win32-msvc2013/qplatformdefs.h b/mkspecs/win32-msvc2013/qplatformdefs.h deleted file mode 100644 index 9c598265551..00000000000 --- a/mkspecs/win32-msvc2013/qplatformdefs.h +++ /dev/null @@ -1,40 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** 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-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../win32-msvc2005/qplatformdefs.h" diff --git a/mkspecs/win32-msvc2015/qmake.conf b/mkspecs/win32-msvc2015/qmake.conf deleted file mode 100644 index ea654d42969..00000000000 --- a/mkspecs/win32-msvc2015/qmake.conf +++ /dev/null @@ -1,10 +0,0 @@ -# -# qmake configuration for win32-msvc2015 -# -# Written for Microsoft Visual C++ 2015 -# - -MSC_VER = 1900 -MSVC_VER = 14.0 -include(../common/msvc-desktop.conf) -load(qt_config) diff --git a/mkspecs/win32-msvc2015/qplatformdefs.h b/mkspecs/win32-msvc2015/qplatformdefs.h deleted file mode 100644 index 9c598265551..00000000000 --- a/mkspecs/win32-msvc2015/qplatformdefs.h +++ /dev/null @@ -1,40 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** 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-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../win32-msvc2005/qplatformdefs.h" diff --git a/mkspecs/win32-msvc2017/qmake.conf b/mkspecs/win32-msvc2017/qmake.conf deleted file mode 100644 index b8351eb3fec..00000000000 --- a/mkspecs/win32-msvc2017/qmake.conf +++ /dev/null @@ -1,10 +0,0 @@ -# -# qmake configuration for win32-msvc2017 -# -# Written for Microsoft Visual C++ 2017 -# - -MSC_VER = 1910 -MSVC_VER = 15.0 -include(../common/msvc-desktop.conf) -load(qt_config) diff --git a/mkspecs/win32-msvc2017/qplatformdefs.h b/mkspecs/win32-msvc2017/qplatformdefs.h deleted file mode 100644 index 7100e3aa41e..00000000000 --- a/mkspecs/win32-msvc2017/qplatformdefs.h +++ /dev/null @@ -1,34 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../win32-msvc2005/qplatformdefs.h" diff --git a/mkspecs/winrt-arm-msvc2015/qmake.conf b/mkspecs/winrt-arm-msvc2015/qmake.conf index 7a9375246d6..8bca6f4af89 100644 --- a/mkspecs/winrt-arm-msvc2015/qmake.conf +++ b/mkspecs/winrt-arm-msvc2015/qmake.conf @@ -4,9 +4,7 @@ # Written for Microsoft Visual C++ 2015 # -MSC_VER = 1900 include(../common/winrt_winphone/qmake.conf) -QMAKE_COMPILER_DEFINES += _MSC_VER=1900 DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PC_APP WINAPI_PARTITION_PHONE_APP=1 ARM __ARM__ __arm__ QMAKE_CFLAGS += -FS @@ -16,7 +14,6 @@ QMAKE_LFLAGS += /MACHINE:ARM /NODEFAULTLIB:kernel32.lib QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib VCPROJ_ARCH = ARM -MSVC_VER = 14.0 WINSDK_VER = 10.0 WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in diff --git a/mkspecs/winrt-x64-msvc2015/qmake.conf b/mkspecs/winrt-x64-msvc2015/qmake.conf index ca2dc88bf03..d503399e3c2 100644 --- a/mkspecs/winrt-x64-msvc2015/qmake.conf +++ b/mkspecs/winrt-x64-msvc2015/qmake.conf @@ -4,9 +4,7 @@ # Written for Microsoft Visual C++ 2015 # -MSC_VER = 1900 include(../common/winrt_winphone/qmake.conf) -QMAKE_COMPILER_DEFINES += _MSC_VER=1900 _WIN32 DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PC_APP WINAPI_PARTITION_PHONE_APP=1 X64 __X64__ __x64__ QMAKE_CFLAGS += -FS @@ -16,7 +14,6 @@ QMAKE_LFLAGS += /MACHINE:X64 /NODEFAULTLIB:kernel32.lib QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib VCPROJ_ARCH = x64 -MSVC_VER = 14.0 WINSDK_VER = 10.0 WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in diff --git a/mkspecs/winrt-x64-msvc2017/qmake.conf b/mkspecs/winrt-x64-msvc2017/qmake.conf new file mode 100644 index 00000000000..cb2209fa23b --- /dev/null +++ b/mkspecs/winrt-x64-msvc2017/qmake.conf @@ -0,0 +1,20 @@ +# +# qmake configuration for winrt-x64-msvc2017 +# +# Written for Microsoft Visual C++ 2017 +# + +include(../common/winrt_winphone/qmake.conf) +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PC_APP WINAPI_PARTITION_PHONE_APP=1 X64 __X64__ __x64__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /MACHINE:X64 /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib + +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/win32-msvc2012/qplatformdefs.h b/mkspecs/winrt-x64-msvc2017/qplatformdefs.h similarity index 97% rename from mkspecs/win32-msvc2012/qplatformdefs.h rename to mkspecs/winrt-x64-msvc2017/qplatformdefs.h index 9c598265551..2a1aef5e88c 100644 --- a/mkspecs/win32-msvc2012/qplatformdefs.h +++ b/mkspecs/winrt-x64-msvc2017/qplatformdefs.h @@ -37,4 +37,4 @@ ** ****************************************************************************/ -#include "../win32-msvc2005/qplatformdefs.h" +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-x86-msvc2015/qmake.conf b/mkspecs/winrt-x86-msvc2015/qmake.conf index 3b2681e93d4..37ce0e55250 100644 --- a/mkspecs/winrt-x86-msvc2015/qmake.conf +++ b/mkspecs/winrt-x86-msvc2015/qmake.conf @@ -4,9 +4,7 @@ # Written for Microsoft Visual C++ 2015 # -MSC_VER = 1900 include(../common/winrt_winphone/qmake.conf) -QMAKE_COMPILER_DEFINES += _MSC_VER=1900 _WIN32 DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PC_APP WINAPI_PARTITION_PHONE_APP=1 X86 __X86__ __x86__ QMAKE_CFLAGS += -FS @@ -15,7 +13,6 @@ QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib VCPROJ_ARCH = Win32 -MSVC_VER = 14.0 WINSDK_VER = 10.0 WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in diff --git a/mkspecs/winrt-x86-msvc2017/qmake.conf b/mkspecs/winrt-x86-msvc2017/qmake.conf new file mode 100644 index 00000000000..3c9506bbad0 --- /dev/null +++ b/mkspecs/winrt-x86-msvc2017/qmake.conf @@ -0,0 +1,19 @@ +# +# qmake configuration for winrt-x86-msvc2017 +# +# Written for Microsoft Visual C++ 2017 +# + +include(../common/winrt_winphone/qmake.conf) +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PC_APP WINAPI_PARTITION_PHONE_APP=1 X86 __X86__ __x86__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +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/win32-msvc2010/qplatformdefs.h b/mkspecs/winrt-x86-msvc2017/qplatformdefs.h similarity index 97% rename from mkspecs/win32-msvc2010/qplatformdefs.h rename to mkspecs/winrt-x86-msvc2017/qplatformdefs.h index 9c598265551..2a1aef5e88c 100644 --- a/mkspecs/win32-msvc2010/qplatformdefs.h +++ b/mkspecs/winrt-x86-msvc2017/qplatformdefs.h @@ -37,4 +37,4 @@ ** ****************************************************************************/ -#include "../win32-msvc2005/qplatformdefs.h" +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index de41e14e75f..982e4321714 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -16,7 +16,7 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qstring_compat.o qstringbuilder.o qtext qarraydata.o qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfiledevice.o qfile.o \ qfilesystementry.o qfilesystemengine.o qfsfileengine.o qfsfileengine_iterator.o qregexp.o qvector.o \ qbitarray.o qdir.o qdiriterator.o quuid.o qhash.o qfileinfo.o qdatetime.o qstringlist.o \ - qabstractfileengine.o qtemporaryfile.o qmap.o qmetatype.o qsettings.o qsystemerror.o qlibraryinfo.o \ + qabstractfileengine.o qtemporaryfile.o qmap.o qmetatype.o qsettings.o qsystemerror.o \ qvariant.o qvsnprintf.o qlocale.o qlocale_tools.o qlinkedlist.o qnumeric.o \ qcryptographichash.o qxmlstream.o qxmlutils.o qlogging.o qoperatingsystemversion.o \ qjson.o qjsondocument.o qjsonparser.o qjsonarray.o qjsonobject.o qjsonvalue.o \ @@ -33,6 +33,7 @@ DEPEND_SRC = \ $(QMKGENSRC)/projectgenerator.cpp $(QMKGENSRC)/makefile.cpp \ $(QMKGENSRC)/unix/unixmake.cpp $(QMKGENSRC)/unix/unixmake2.cpp \ $(QMKGENSRC)/mac/pbuilder_pbx.cpp \ + $(QMKGENSRC)/win32/registry.cpp \ $(QMKGENSRC)/win32/winmakefile.cpp \ $(QMKGENSRC)/win32/mingw_make.cpp $(QMKGENSRC)/win32/msvc_nmake.cpp \ $(QMKGENSRC)/mac/xmloutput.cpp \ @@ -84,7 +85,6 @@ DEPEND_SRC = \ $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp \ $(SOURCE_PATH)/src/corelib/global/qlogging.cpp \ $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp \ - $(SOURCE_PATH)/tools/shared/windows/registry.cpp \ $(SOURCE_PATH)/src/corelib/json/qjson.cpp \ $(SOURCE_PATH)/src/corelib/json/qjsondocument.cpp \ $(SOURCE_PATH)/src/corelib/json/qjsonparser.cpp \ @@ -100,7 +100,6 @@ CPPFLAGS = -g $(EXTRA_CPPFLAGS) \ -I$(INC_PATH)/QtCore/$(QT_VERSION) -I$(INC_PATH)/QtCore/$(QT_VERSION)/QtCore \ -I$(BUILD_PATH)/src/corelib/global \ -I$(QMAKESPEC) \ - -I$(SOURCE_PATH)/tools/shared \ -DQT_VERSION_STR=\"$(QT_VERSION)\" -DQT_VERSION_MAJOR=$(QT_MAJOR_VERSION) -DQT_VERSION_MINOR=$(QT_MINOR_VERSION) -DQT_VERSION_PATCH=$(QT_PATCH_VERSION) \ -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \ -DQT_NO_FOREACH @@ -110,19 +109,24 @@ LFLAGS = $(EXTRA_LFLAGS) $(CONFIG_LFLAGS) first all: $(BUILD_PATH)/bin/qmake$(EXEEXT) qmake: $(BUILD_PATH)/bin/qmake$(EXEEXT) +binary: $(BUILD_PATH)/qmake/qmake$(EXEEXT) -$(BUILD_PATH)/bin/qmake$(EXEEXT): $(OBJS) $(QOBJS) - $(CXX) -o "$@" $(OBJS) $(QOBJS) $(LFLAGS) +$(BUILD_PATH)/bin/qmake$(EXEEXT): $(OBJS) $(QOBJS) qlibraryinfo.o + $(CXX) -o "$@" $(OBJS) $(QOBJS) qlibraryinfo.o $(LFLAGS) + +$(BUILD_PATH)/qmake/qmake$(EXEEXT): $(OBJS) $(QOBJS) qlibraryinfo_final.o + $(CXX) -o "$@" $(OBJS) $(QOBJS) qlibraryinfo_final.o $(LFLAGS) Makefile: $(SOURCE_PATH)/qmake/Makefile.unix @echo "Out of date, please rerun configure" clean:: - $(RM_F) $(OBJS) $(QOBJS) + $(RM_F) $(OBJS) $(QOBJS) qlibraryinfo.o qlibraryinfo_final.o distclean:: clean $(RM_RF) .deps $(RM_F) $(BUILD_PATH)/bin/qmake$(EXEEXT) + $(RM_F) $(BUILD_PATH)/qmake/qmake$(EXEEXT) $(RM_F) Makefile depend: @@ -184,6 +188,9 @@ unixmake.o: $(QMKSRC)/generators/unix/unixmake.cpp unixmake2.o: $(QMKSRC)/generators/unix/unixmake2.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< +registry.o: $(QMKSRC)/generators/win32/registry.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $< + winmakefile.o: $(QMKSRC)/generators/win32/winmakefile.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< @@ -225,6 +232,9 @@ qsystemerror.o: $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp qlibraryinfo.o: $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp + $(CXX) -c -o $@ $(CXXFLAGS) -DQT_BUILD_QMAKE_BOOTSTRAP $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp + +qlibraryinfo_final.o: $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp $(BUILD_PATH)/src/corelib/global/qconfig.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp qnumeric.o: $(SOURCE_PATH)/src/corelib/global/qnumeric.cpp @@ -413,9 +423,6 @@ qlogging.o: $(SOURCE_PATH)/src/corelib/global/qlogging.cpp qsystemlibrary.o: $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp -registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp - $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp - qjson.o: $(SOURCE_PATH)/src/corelib/json/qjson.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjson.cpp diff --git a/qmake/Makefile.unix.win32 b/qmake/Makefile.unix.win32 index b2d8a0b1af9..c747eedcd01 100644 --- a/qmake/Makefile.unix.win32 +++ b/qmake/Makefile.unix.win32 @@ -18,4 +18,4 @@ QTSRCS = \ $(SOURCE_PATH)/src/corelib/io/qsettings_win.cpp \ $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp \ $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp \ - $(SOURCE_PATH)/tools/shared/windows/registry.cpp + $(SOURCE_PATH)/qmake/generators/win32/registry.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 6c1644004eb..74934cc38fe 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -14,35 +14,29 @@ QMKSRC = $(SOURCE_PATH)\qmake CXX = icl LINKER = link CFLAGS_EXTRA = /Zc:forScope /Qstd=c++11 -!elseif "$(QMAKESPEC)" == "win32-clang-msvc2015" +!elseif "$(QMAKESPEC)" == "win32-clang-msvc" CXX = clang-cl LINKER = link CFLAGS_EXTRA = -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value !else CXX = cl LINKER = link -! if "$(QMAKESPEC)" == "win32-msvc2013" -CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS $(CFLAGS_CRT) -! elseif "$(QMAKESPEC)" == "win32-msvc2015" || "$(QMAKESPEC)" == "win32-msvc2017" || "$(QMAKESPEC)" == "win32-clang-msvc2015" -CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS /Zc:strictStrings /w44456 /w44457 /w44458 /wd4577 $(CFLAGS_CRT) -! else -! error Unsupported compiler for this Makefile -! endif +CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS \ + /wd4577 $(CFLAGS_CRT) !endif # !win32-icc -!if "$(QMAKESPEC)" != "win32-clang-msvc2015" +!if "$(QMAKESPEC)" != "win32-clang-msvc" CFLAGS_PCH = -Yuqmake_pch.h -FIqmake_pch.h -Fpqmake_pch.pch PCH_OBJECT = qmake_pch.obj !endif CFLAGS_BARE = -c -Fo./ -Fdqmake.pdb \ - -W3 -nologo -O1 \ + -W2 -nologo -O1 \ $(CFLAGS_EXTRA) \ -I$(QMKSRC) -I$(QMKSRC)\library -I$(QMKSRC)\generators -I$(QMKSRC)\generators\unix -I$(QMKSRC)\generators\win32 -I$(QMKSRC)\generators\mac \ -I$(INC_PATH) -I$(INC_PATH)\QtCore -I$(INC_PATH)\QtCore\$(QT_VERSION) -I$(INC_PATH)\QtCore\$(QT_VERSION)\QtCore \ -I$(BUILD_PATH)\src\corelib\global \ -I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \ - -I$(SOURCE_PATH)\tools\shared \ -DQT_VERSION_STR=\"$(QT_VERSION)\" -DQT_VERSION_MAJOR=$(QT_MAJOR_VERSION) -DQT_VERSION_MINOR=$(QT_MINOR_VERSION) -DQT_VERSION_PATCH=$(QT_PATCH_VERSION) \ -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \ -DQT_NO_FOREACH -DUNICODE @@ -116,7 +110,6 @@ QTOBJS= \ quuid.obj \ qvector.obj \ qsettings.obj \ - qlibraryinfo.obj \ qvariant.obj \ qsettings_win.obj \ qmetatype.obj \ @@ -132,12 +125,16 @@ QTOBJS= \ qjsonvalue.obj first all: $(BUILD_PATH)\bin\qmake.exe +binary: $(BUILD_PATH)\qmake\qmake.exe -$(BUILD_PATH)\bin\qmake.exe: $(OBJS) $(QTOBJS) - $(LINKER) $(LFLAGS) /OUT:$(BUILD_PATH)\bin\qmake.exe $(OBJS) $(QTOBJS) $(PCH_OBJECT) $(LIBS) +$(BUILD_PATH)\bin\qmake.exe: $(OBJS) $(QTOBJS) qlibraryinfo.obj + $(LINKER) $(LFLAGS) /OUT:$(BUILD_PATH)\bin\qmake.exe $(OBJS) $(QTOBJS) qlibraryinfo.obj $(PCH_OBJECT) $(LIBS) + +$(BUILD_PATH)\qmake\qmake.exe: $(OBJS) $(QTOBJS) qlibraryinfo_final.obj + $(LINKER) $(LFLAGS) /OUT:$(BUILD_PATH)\qmake\qmake.exe $(OBJS) $(QTOBJS) qlibraryinfo_final.obj $(PCH_OBJECT) $(LIBS) clean:: - -del $(QTOBJS) + -del $(QTOBJS) qlibraryinfo.obj qlibraryinfo_final.obj -del $(OBJS) -del qmake_pch.obj -del qmake_pch.pch @@ -147,6 +144,7 @@ clean:: distclean:: clean -del $(BUILD_PATH)\bin\qmake.exe + -del $(BUILD_PATH)\qmake\qmake.exe -del Makefile .cpp.obj: @@ -156,6 +154,9 @@ $(OBJS): $(PCH_OBJECT) $(QTOBJS): $(PCH_OBJECT) +qlibraryinfo.obj: $(PCH_OBJECT) +qlibraryinfo_final.obj: $(PCH_OBJECT) + qmake_pch.obj: $(CXX) $(CXXFLAGS_BARE) -c -Yc -Fpqmake_pch.pch -TP $(QMKSRC)\qmake_pch.h @@ -204,9 +205,12 @@ qmake_pch.obj: {$(SOURCE_PATH)\src\corelib\json}.cpp{}.obj:: $(CXX) $(CXXFLAGS) $< -{$(SOURCE_PATH)\tools\shared\windows}.cpp{}.obj:: - $(CXX) $(CXXFLAGS) $< - # Make sure qstring_compat.obj isn't compiled with PCH enabled qstring_compat.obj: $(SOURCE_PATH)\src\corelib\tools\qstring_compat.cpp $(CXX) -c $(CXXFLAGS_BARE) $(SOURCE_PATH)\src\corelib\tools\qstring_compat.cpp + +qlibraryinfo.obj: $(SOURCE_PATH)\src\corelib\global\qlibraryinfo.cpp + $(CXX) $(CXXFLAGS) -DQT_BUILD_QMAKE_BOOTSTRAP $(SOURCE_PATH)\src\corelib\global\qlibraryinfo.cpp + +qlibraryinfo_final.obj: $(SOURCE_PATH)\src\corelib\global\qlibraryinfo.cpp $(BUILD_PATH)\src\corelib\global\qconfig.cpp + $(CXX) $(CXXFLAGS) -Foqlibraryinfo_final.obj $(SOURCE_PATH)\src\corelib\global\qlibraryinfo.cpp diff --git a/qmake/doc/snippets/code/doc_src_qmake-manual.pro b/qmake/doc/snippets/code/doc_src_qmake-manual.pro index c3b6e6595f9..8ba0aa07132 100644 --- a/qmake/doc/snippets/code/doc_src_qmake-manual.pro +++ b/qmake/doc/snippets/code/doc_src_qmake-manual.pro @@ -120,7 +120,7 @@ qmake -spec macx-g++ #! [14] -QMAKE_LFLAGS += -F/path/to/framework/directory/ +LIBS += -F/path/to/framework/directory/ #! [14] @@ -784,10 +784,6 @@ CONFIG(debug, debug|release) { } #! [127] -#! [142] -DEPLOYMENT_PLUGIN += qjpeg -#! [142] - #! [149] SUBDIRS += my_executable my_library my_executable.subdir = app diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index c3c878ebb8b..a8ccd199b4c 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -685,7 +685,7 @@ Directories other than the standard framework directory need to be specified to the build system, and this is achieved by appending linker options to the - \l{QMAKE_LFLAGS} variable, as shown in the following example: + \l{LIBS} variable, as shown in the following example: \snippet code/doc_src_qmake-manual.pro 14 @@ -960,6 +960,8 @@ \row \li c++14 \li C++14 support is enabled. This option has no effect if the compiler does not support C++14. By default, support is disabled. + \row \li depend_includepath \li Appending the value of INCLUDEPATH to + DEPENDPATH is enabled. Set by default. \endtable When you use the \c debug_and_release option (which is the default under @@ -1119,24 +1121,6 @@ Specifies a list of all directories to look in to resolve dependencies. This variable is used when crawling through \c included files. - \target DEPLOYMENT_PLUGIN - \section1 DEPLOYMENT_PLUGIN - - \note This variable is used only on the Windows CE platform. - - Specifies the Qt plugins that will be deployed. All plugins - available in Qt can be explicitly deployed to the device. See - \l{Static Plugins}{Static Plugins} for a complete list. - - \note No plugins will be deployed automatically to Windows CE devices. - If the application depends on plugins, these plugins have to be specified - manually. - - For example, the following definition uploads the jpeg imageformat plugin to - the plugins directory on the Windows CE device: - - \snippet code/doc_src_qmake-manual.pro 142 - \target DESTDIR \section1 DESTDIR diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 1ba2587bd0e..2845888dde1 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2254,12 +2254,17 @@ MakefileGenerator::writeDefaultVariables(QTextStream &t) t << "MOVE = " << var("QMAKE_MOVE") << endl; } -QString MakefileGenerator::buildArgs() +QString MakefileGenerator::buildArgs(bool withExtra) { QString ret; for (const QString &arg : qAsConst(Option::globals->qmake_args)) ret += " " + shellQuote(arg); + if (withExtra && !Option::globals->qmake_extra_args.isEmpty()) { + ret += " --"; + for (const QString &arg : qAsConst(Option::globals->qmake_extra_args)) + ret += " " + shellQuote(arg); + } return ret; } @@ -2278,7 +2283,7 @@ QString MakefileGenerator::build_args() ret += " " + escapeFilePath(fileFixify(project->projectFile())); // general options and arguments - ret += buildArgs(); + ret += buildArgs(true); return ret; } @@ -2442,7 +2447,7 @@ MakefileGenerator::writeSubTargetCall(QTextStream &t, if (!in_directory.isEmpty()) t << "\n\t" << mkdir_p_asstring(out_directory); pfx = "( " + chkexists.arg(out) + - + " $(QMAKE) -o " + out + ' ' + in + buildArgs() + + " $(QMAKE) -o " + out + ' ' + in + buildArgs(false) + " ) && "; } writeSubMakeCall(t, out_directory_cdin + pfx, makefilein); @@ -2513,7 +2518,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QListisEmpty("QMAKE_FAILED_REQUIREMENTS") && !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) { QStringList files = escapeFilePaths(fileFixify(Option::mkfile::project_files)); t << escapeDependencyPath(project->first("QMAKE_INTERNAL_PRL_FILE").toQString()) << ": \n\t" - << "@$(QMAKE) -prl " << files.join(' ') << ' ' << buildArgs() << endl; + << "@$(QMAKE) -prl " << files.join(' ') << ' ' << buildArgs(true) << endl; } QString qmake = build_args(); diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index 86fec748ebe..4ced3bd1219 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -178,7 +178,7 @@ protected: QString specdir(); //subclasses can use these to query information about how the generator was "run" - QString buildArgs(); + QString buildArgs(bool withExtra); virtual QStringList &findDependencies(const QString &file); virtual bool doDepends() const { return Option::mkfile::do_deps; } diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 3d12ffd65ce..5b56cac7843 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -659,11 +659,15 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "$(TARGETA): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) $(OBJCOMP)"; if(do_incremental) t << " $(INCREMENTAL_OBJECTS)"; - t << ' ' << depVar("POST_TARGETDEPS") << "\n\t" - << "-$(DEL_FILE) $(TARGETA) \n\t" + t << ' ' << depVar("POST_TARGETDEPS") << "\n\t"; + if (!project->isEmpty("QMAKE_PRE_LINK")) + t << var("QMAKE_PRE_LINK") << "\n\t"; + t << "-$(DEL_FILE) $(TARGETA) \n\t" << var("QMAKE_AR_CMD"); if(do_incremental) t << " $(INCREMENTAL_OBJECTS)"; + if (!project->isEmpty("QMAKE_POST_LINK")) + t << "\n\t" << var("QMAKE_POST_LINK"); if(!project->isEmpty("QMAKE_RANLIB")) t << "\n\t$(RANLIB) $(TARGETA)"; t << endl << endl; @@ -680,6 +684,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << " $(OBJECTS) $(OBJCOMP) " << depVar("POST_TARGETDEPS") << "\n\t"; if(!destdir.isEmpty()) t << mkdir_p_asstring(destdir, false) << "\n\t"; + if (!project->isEmpty("QMAKE_PRE_LINK")) + t << var("QMAKE_PRE_LINK") << "\n\t"; t << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t" << var("QMAKE_AR_CMD") << "\n"; if(!project->isEmpty("QMAKE_POST_LINK")) @@ -710,6 +716,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } if(!destdir.isEmpty()) t << mkdir_p_asstring(destdir, false) << "\n\t"; + if (!project->isEmpty("QMAKE_PRE_LINK")) + t << var("QMAKE_PRE_LINK") << "\n\t"; t << "-$(DEL_FILE) " << lib << "\n\t" << ar << "\n"; if(!project->isEmpty("QMAKE_POST_LINK")) @@ -732,7 +740,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } if(!meta_files.isEmpty()) t << escapeDependencyPaths(meta_files).join(" ") << ": \n\t" - << "@$(QMAKE) -prl " << escapeFilePath(project->projectFile()) << ' ' << buildArgs() << endl; + << "@$(QMAKE) -prl " << escapeFilePath(project->projectFile()) << ' ' << buildArgs(true) << endl; } if (!project->isEmpty("QMAKE_BUNDLE")) { diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index 3f789405b24..129fb28e014 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -176,7 +176,7 @@ const char _Optimization[] = "Optimization"; const char _OptimizeReferences[] = "OptimizeReferences"; const char _OutputDirectory[] = "OutputDirectory"; const char _OutputFile[] = "OutputFile"; -const char _PlatformToolSet[] = "PlatformToolSet"; +const char _PlatformToolSet[] = "PlatformToolset"; const char _PrecompiledHeader[] = "PrecompiledHeader"; const char _PrecompiledHeaderFile[] = "PrecompiledHeaderFile"; const char _PrecompiledHeaderOutputFile[] = "PrecompiledHeaderOutputFile"; @@ -406,7 +406,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) xml << decl("1.0", "utf-8") << tag("Project") << attrTag("DefaultTargets","Build") - << attrTag("ToolsVersion", "4.0") + << attrTagToolsVersion(tool.Configuration) << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003") << tag("ItemGroup") << attrTag("Label", "ProjectConfigurations"); @@ -550,7 +550,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) xmlFilter << decl("1.0", "utf-8") << tag("Project") - << attrTag("ToolsVersion", "4.0") + << attrTagToolsVersion(tool.Configuration) << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); xmlFilter << tag("ItemGroup"); @@ -587,6 +587,8 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) outputFilter(tempProj, xml, xmlFilter, tempProj.ExtraCompilers.at(x)); } + outputFilter(tempProj, xml, xmlFilter, "Root Files"); + xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets"); xml << tag("ImportGroup") @@ -603,13 +605,10 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) xml.setIndentString(" "); - const QString toolsVersion = (tool.SdkVersion == QLatin1String("10.0")) ? QStringLiteral("14.0") - : QStringLiteral("4.0"); - xml << decl("1.0", "utf-8") << tag("Project") << attrTag("DefaultTargets","Build") - << attrTag("ToolsVersion", toolsVersion) + << attrTagToolsVersion(tool.SingleProjects.first().Configuration) << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003") << tag("ItemGroup") << attrTag("Label", "ProjectConfigurations"); @@ -794,7 +793,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) xmlFilter << decl("1.0", "utf-8") << tag("Project") - << attrTag("ToolsVersion", "4.0") + << attrTagToolsVersion(tool.SingleProjects.first().Configuration) << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); xmlFilter << tag("ItemGroup"); @@ -2054,4 +2053,11 @@ QString VCXProjectWriter::generateCondition(const VCConfiguration &config) return QStringLiteral("'$(Configuration)|$(Platform)'=='") + config.Name + QLatin1Char('\''); } +XmlOutput::xml_output VCXProjectWriter::attrTagToolsVersion(const VCConfiguration &config) +{ + if (config.CompilerVersion >= NET2013) + return noxml(); + return attrTag("ToolsVersion", "4.0"); +} + QT_END_NAMESPACE diff --git a/qmake/generators/win32/msbuild_objectmodel.h b/qmake/generators/win32/msbuild_objectmodel.h index fe46430e60c..2e77537916b 100644 --- a/qmake/generators/win32/msbuild_objectmodel.h +++ b/qmake/generators/win32/msbuild_objectmodel.h @@ -182,6 +182,7 @@ private: bool fileAdded, bool hasCustomBuildStep); static void outputFileConfig(XmlOutput &xml, XmlOutput &xmlFilter, const QString &fileName, const QString &filterName); static QString generateCondition(const VCConfiguration &config); + static XmlOutput::xml_output attrTagToolsVersion(const VCConfiguration &config); friend class XTreeNode; friend class XFlatNode; diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 380ce60c5ba..c19c101d439 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -34,7 +34,7 @@ #include #include -#include +#include #include @@ -75,25 +75,44 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) QString arch = project->first("VCPROJ_ARCH").toQString().toLower(); QString compiler; QString compilerArch; - if (arch == QLatin1String("arm")) { - compiler = QStringLiteral("x86_arm"); - compilerArch = QStringLiteral("arm"); - } else if (arch == QLatin1String("x64")) { - const ProStringList hostArch = project->values("QMAKE_TARGET.arch"); - if (hostArch.contains("x86_64")) - compiler = QStringLiteral("amd64"); - else - compiler = QStringLiteral("x86_amd64"); - compilerArch = QStringLiteral("amd64"); - } else { - arch = QStringLiteral("x86"); - } - const QString msvcVer = project->first("MSVC_VER").toQString(); if (msvcVer.isEmpty()) { fprintf(stderr, "Mkspec does not specify MSVC_VER. Cannot continue.\n"); return false; } + + if (msvcVer == QStringLiteral("15.0")) { + const ProStringList hostArch = project->values("QMAKE_TARGET.arch"); + if (hostArch.contains("x86_64")) + compiler = QStringLiteral("HostX64/"); + else + compiler = QStringLiteral("HostX86/"); + if (arch == QLatin1String("arm")) { + compiler += QStringLiteral("arm"); + compilerArch = QStringLiteral("arm"); + } else if (arch == QLatin1String("x64")) { + compiler += QStringLiteral("x64"); + compilerArch = QStringLiteral("amd64"); + } else { + compiler += QStringLiteral("x86"); + compilerArch = QStringLiteral("amd64"); + } + } else { + if (arch == QLatin1String("arm")) { + compiler = QStringLiteral("x86_arm"); + compilerArch = QStringLiteral("arm"); + } else if (arch == QLatin1String("x64")) { + const ProStringList hostArch = project->values("QMAKE_TARGET.arch"); + if (hostArch.contains("x86_64")) + compiler = QStringLiteral("amd64"); + else + compiler = QStringLiteral("x86_amd64"); + compilerArch = QStringLiteral("amd64"); + } else { + arch = QStringLiteral("x86"); + } + } + const QString winsdkVer = project->first("WINSDK_VER").toQString(); if (winsdkVer.isEmpty()) { fprintf(stderr, "Mkspec does not specify WINSDK_VER. Cannot continue.\n"); @@ -106,7 +125,11 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) } #ifdef Q_OS_WIN - QString regKey = QStringLiteral("Software\\Microsoft\\VisualStudio\\") + msvcVer + ("\\Setup\\VC\\ProductDir"); + QString regKey; + if (msvcVer == QStringLiteral("15.0")) + regKey = QStringLiteral("Software\\Microsoft\\VisualStudio\\SxS\\VS7\\") + msvcVer; + else + regKey = QStringLiteral("Software\\Microsoft\\VisualStudio\\") + msvcVer + ("\\Setup\\VC\\ProductDir"); const QString vcInstallDir = qt_readRegistryKey(HKEY_LOCAL_MACHINE, regKey, KEY_WOW64_32KEY); if (vcInstallDir.isEmpty()) { fprintf(stderr, "Failed to find the Visual Studio installation directory.\n"); @@ -128,7 +151,46 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) QStringList incDirs; QStringList libDirs; QStringList binDirs; - if (msvcVer == QStringLiteral("14.0")) { + if (msvcVer == QStringLiteral("15.0")) { + const QString toolsInstallDir = qgetenv("VCToolsInstallDir"); + if (toolsInstallDir.isEmpty()) { + fprintf(stderr, "Failed to access tools installation dir.\n"); + return false; + } + + binDirs << toolsInstallDir + QStringLiteral("bin/") + compiler; + if (arch == QStringLiteral("x64")) + binDirs << toolsInstallDir + QStringLiteral("bin/HostX86/X86"); + binDirs << kitDir + QStringLiteral("bin/x86"); + binDirs << vcInstallDir + QStringLiteral("Common7/Tools"); + binDirs << vcInstallDir + QStringLiteral("Common7/ide"); + binDirs << vcInstallDir + QStringLiteral("MSBuild/15.0/bin"); + + incDirs << toolsInstallDir + QStringLiteral("include"); + incDirs << vcInstallDir + QStringLiteral("VC/Auxiliary/VS/include"); + + const QString crtVersion = qgetenv("UCRTVersion"); + if (crtVersion.isEmpty()) { + fprintf(stderr, "Failed to access CRT version.\n"); + return false; + } + const QString crtInclude = kitDir + QStringLiteral("Include/") + crtVersion; + const QString crtLib = kitDir + QStringLiteral("Lib/") + crtVersion; + incDirs << crtInclude + QStringLiteral("/ucrt"); + incDirs << crtInclude + QStringLiteral("/um"); + incDirs << crtInclude + QStringLiteral("/shared"); + incDirs << crtInclude + QStringLiteral("/winrt"); + + incDirs << kitDir + QStringLiteral("Extension SDKs/WindowsMobile/") + + crtVersion + QStringLiteral("/Include/WinRT"); + + libDirs << toolsInstallDir + QStringLiteral("lib/") + arch + QStringLiteral("/store"); + + libDirs << vcInstallDir + QStringLiteral("VC/Auxiliary/VS/lib/") + arch; + + libDirs << crtLib + QStringLiteral("/ucrt/") + arch; + libDirs << crtLib + QStringLiteral("/um/") + arch; + } else if (msvcVer == QStringLiteral("14.0")) { binDirs << vcInstallDir + QStringLiteral("bin/") + compiler; binDirs << vcInstallDir + QStringLiteral("bin/"); // Maybe remove for x86 again? binDirs << kitDir + QStringLiteral("bin/") + (arch == QStringLiteral("arm") ? QStringLiteral("x86") : arch); diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 33d96c146c7..60734b4d1bc 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -54,7 +54,8 @@ static DotNET vsVersionFromString(const char *versionString) "10.0", NET2010, "11.0", NET2012, "12.0", NET2013, - "14.0", NET2015 + "14.0", NET2015, + "15.0", NET2017 }; DotNET result = NETUnknown; for (const auto entry : mapping) { diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index b3da4db4c5f..3d5b80e06d4 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -670,6 +670,21 @@ bool VcprojGenerator::hasBuiltinCompiler(const QString &file) return false; } +void VcprojGenerator::createCustomBuildToolFakeFile(const QString &cbtFilePath, + const QString &realOutFilePath) +{ + QFile file(fileFixify(cbtFilePath, FileFixifyFromOutdir | FileFixifyAbsolute)); + if (file.exists()) + return; + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + warn_msg(WarnLogic, "Cannot create '%s'.", qPrintable(file.fileName())); + return; + } + file.write("This is a dummy file needed to create "); + file.write(qPrintable(realOutFilePath)); + file.write("\n"); +} + void VcprojGenerator::init() { is64Bit = (project->first("QMAKE_TARGET.arch") == "x86_64"); @@ -797,12 +812,14 @@ void VcprojGenerator::init() if (!hasBuiltinCompiler(file)) { extraCompilerSources[file] += quc.toQString(); } else { - // Use a fake file name foo.moc.cbt for the project view. + // Create a fake file foo.moc.cbt for the project view. // This prevents VS from complaining about a circular // dependency from foo.moc -> foo.moc. - QString out = Option::fixPathToTargetOS(replaceExtraCompilerVariables( - compiler_out, file, QString(), NoShell), false); - out += customBuildToolFilterFileSuffix; + QString realOut = replaceExtraCompilerVariables( + compiler_out, file, QString(), NoShell); + QString out = realOut + customBuildToolFilterFileSuffix; + createCustomBuildToolFakeFile(out, realOut); + out = Option::fixPathToTargetOS(out, false); extraCompilerSources[out] += quc.toQString(); extraCompilerOutputs[out] = file; } diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index e3e67d64b9a..4882296b463 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -130,6 +130,7 @@ private: bool isStandardSuffix(const QString &suffix) const; ProString firstInputFileName(const ProString &extraCompilerName) const; QString firstExpandedOutputFileName(const ProString &extraCompilerName); + void createCustomBuildToolFakeFile(const QString &cbtFilePath, const QString &realOutFilePath); friend class VCFilter; }; diff --git a/tools/shared/windows/registry.cpp b/qmake/generators/win32/registry.cpp similarity index 100% rename from tools/shared/windows/registry.cpp rename to qmake/generators/win32/registry.cpp diff --git a/tools/shared/windows/registry_p.h b/qmake/generators/win32/registry_p.h similarity index 100% rename from tools/shared/windows/registry_p.h rename to qmake/generators/win32/registry_p.h diff --git a/qmake/library/proitems.cpp b/qmake/library/proitems.cpp index 7862ab0e69d..ff1236f64a2 100644 --- a/qmake/library/proitems.cpp +++ b/qmake/library/proitems.cpp @@ -396,9 +396,12 @@ void ProStringList::removeAll(const char *str) void ProStringList::removeEach(const ProStringList &value) { - for (const ProString &str : value) + for (const ProString &str : value) { + if (isEmpty()) + break; if (!str.isEmpty()) removeAll(str); + } } void ProStringList::removeEmpty() diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 767528eb57e..4b3eeb4e7ae 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -152,6 +152,7 @@ void QMakeEvaluator::initStatics() statics.strhost_build = QLatin1String("host_build"); statics.strTEMPLATE = ProKey("TEMPLATE"); statics.strQMAKE_PLATFORM = ProKey("QMAKE_PLATFORM"); + statics.strQMAKE_DIR_SEP = ProKey("QMAKE_DIR_SEP"); statics.strQMAKESPEC = ProKey("QMAKESPEC"); #ifdef PROEVALUATOR_FULL statics.strREQUIRES = ProKey("REQUIRES"); @@ -938,11 +939,14 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProVariable( setTemplate(); else if (varName == statics.strQMAKE_PLATFORM) m_featureRoots = 0; + else if (varName == statics.strQMAKE_DIR_SEP) + m_dirSep = first(varName); else if (varName == statics.strQMAKESPEC) { if (!values(varName).isEmpty()) { QString spec = values(varName).first().toQString(); if (IoUtils::isAbsolutePath(spec)) { m_qmakespec = spec; + m_qmakespecName = IoUtils::fileName(m_qmakespec).toString(); m_featureRoots = 0; } } @@ -1205,8 +1209,6 @@ bool QMakeEvaluator::loadSpecInternal() // This also ensures that m_featureRoots is valid. if (evaluateFeatureFile(QLatin1String("spec_post.prf")) != ReturnTrue) return false; - // The MinGW and x-build specs may change the separator; $$shell_{path,quote}() need it - m_dirSep = first(ProKey("QMAKE_DIR_SEP")); return true; } diff --git a/qmake/library/qmakeevaluator_p.h b/qmake/library/qmakeevaluator_p.h index f444e0d0bed..42aaef70c36 100644 --- a/qmake/library/qmakeevaluator_p.h +++ b/qmake/library/qmakeevaluator_p.h @@ -78,6 +78,7 @@ struct QMakeStatics { QString strhost_build; ProKey strTEMPLATE; ProKey strQMAKE_PLATFORM; + ProKey strQMAKE_DIR_SEP; ProKey strQMAKESPEC; #ifdef PROEVALUATOR_FULL ProKey strREQUIRES; diff --git a/qmake/library/qmakeglobals.cpp b/qmake/library/qmakeglobals.cpp index b02bf4aaf86..b282b08d5ca 100644 --- a/qmake/library/qmakeglobals.cpp +++ b/qmake/library/qmakeglobals.cpp @@ -138,7 +138,7 @@ QMakeGlobals::ArgumentReturn QMakeGlobals::addCommandLineArguments( if (arg.startsWith(QLatin1Char('-'))) { if (arg == QLatin1String("--")) { state.extraargs = args.mid(*pos + 1); - *pos = args.size(); + args.erase(args.begin() + *pos, args.end()); return ArgumentsOk; } if (arg == QLatin1String("-after")) diff --git a/qmake/library/qmakeglobals.h b/qmake/library/qmakeglobals.h index 1bb86328831..86b1d28da47 100644 --- a/qmake/library/qmakeglobals.h +++ b/qmake/library/qmakeglobals.h @@ -105,7 +105,7 @@ public: QProcessEnvironment environment; #endif QString qmake_abslocation; - QStringList qmake_args; + QStringList qmake_args, qmake_extra_args; QString qtconf; QString qmakespec, xqmakespec; diff --git a/qmake/option.cpp b/qmake/option.cpp index b8102ecf06b..9dcd343c8a3 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -427,6 +427,7 @@ Option::init(int argc, char **argv) //return ret == QMAKE_CMDLINE_SHOW_USAGE ? usage(argv[0]) : false; } globals->qmake_args = args; + globals->qmake_extra_args = cmdstate.extraargs; } globals->commitCommandLineArguments(cmdstate); globals->debugLevel = Option::debug_level; @@ -638,11 +639,6 @@ qmakeAddCacheClear(qmakeCacheClearFunc func, void **data) cache_items.append(new QMakeCacheClearItem(func, data)); } -QString qmake_absoluteLocation() -{ - return Option::globals->qmake_abslocation; -} - QString qmake_libraryInfoFile() { if (!Option::globals->qtconf.isEmpty()) diff --git a/qmake/qmake-aux.pro b/qmake/qmake-aux.pro index 357ebc73674..f432fab05d5 100644 --- a/qmake/qmake-aux.pro +++ b/qmake/qmake-aux.pro @@ -9,14 +9,10 @@ win32: EXTENSION = .exe !build_pass { qmake_exe.target = $$OUT_PWD/qmake$$EXTENSION - qmake_exe.depends = ../bin/qmake$$EXTENSION builtin-qt.conf - equals(QMAKE_DIR_SEP, /): \ - qmake_exe.commands = cat ../bin/qmake$$EXTENSION builtin-qt.conf > qmake$$EXTENSION && chmod +x qmake$$EXTENSION - else: \ - qmake_exe.commands = copy /B ..\bin\qmake$$EXTENSION + builtin-qt.conf qmake$$EXTENSION + qmake_exe.commands = $(MAKE) binary + qmake_exe.CONFIG = phony QMAKE_EXTRA_TARGETS += qmake_exe - QMAKE_CLEAN += builtin-qt.conf QMAKE_DISTCLEAN += qmake$$EXTENSION first.depends += qmake_exe diff --git a/src/3rdparty/freetype/freetype.pro b/src/3rdparty/freetype/freetype.pro index 5b1eb92e324..390a6da749c 100644 --- a/src/3rdparty/freetype/freetype.pro +++ b/src/3rdparty/freetype/freetype.pro @@ -69,6 +69,7 @@ DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB include(../zlib_dependency.pri) DEFINES += FT_CONFIG_OPTION_USE_PNG +include($$OUT_PWD/../../gui/qtgui-config.pri) QMAKE_USE_PRIVATE += libpng DEFINES += TT_CONFIG_OPTION_SUBPIXEL_HINTING diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java index ce0ce3abc7e..759daf4393b 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java @@ -118,10 +118,12 @@ public class QtActivityLoader extends QtLoader { public void onCreate(Bundle savedInstanceState) { try { m_contextInfo = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), PackageManager.GET_META_DATA); + int theme = ((ActivityInfo)m_contextInfo).getThemeResource(); for (Field f : Class.forName("android.R$style").getDeclaredFields()) { - if (f.getInt(null) == ((ActivityInfo)m_contextInfo).getThemeResource()) { + if (f.getInt(null) == theme) { QT_ANDROID_THEMES = new String[] {f.getName()}; QT_ANDROID_DEFAULT_THEME = f.getName(); + break; } } } catch (Exception e) { diff --git a/src/angle/src/compiler/translator.pro b/src/angle/src/compiler/translator.pro index 2e5adaee961..398b9230cc9 100644 --- a/src/angle/src/compiler/translator.pro +++ b/src/angle/src/compiler/translator.pro @@ -189,7 +189,8 @@ QMAKE_EXTRA_COMPILERS += flex defineReplace(myDirName) { return($$dirname(1)) } bison.commands = $$addGnuPath(bison) --no-lines --skeleton=yacc.c --defines=${QMAKE_FILE_OUT} \ --output=${QMAKE_FUNC_FILE_OUT_myDirName}$$QMAKE_DIR_SEP${QMAKE_FILE_OUT_BASE}.cpp \ - ${QMAKE_FILE_NAME} + ${QMAKE_FILE_NAME}$$escape_expand(\\n\\t) \ + @echo // EOF>>${QMAKE_FUNC_FILE_OUT_myDirName}$$QMAKE_DIR_SEP${QMAKE_FILE_OUT_BASE}.cpp bison.output = $${BUILDSUBDIR}${QMAKE_FILE_BASE}_tab.h bison.input = BISON_SOURCES bison.dependency_type = TYPE_C @@ -204,6 +205,5 @@ bison_impl.output = $${BUILDSUBDIR}${QMAKE_FILE_BASE}_tab.cpp bison_impl.input = BISON_SOURCES bison_impl.commands = $$MAKEFILE_NOOP_COMMAND bison_impl.depends = $${BUILDSUBDIR}${QMAKE_FILE_BASE}_tab.h -bison_impl.output = $${BUILDSUBDIR}${QMAKE_FILE_BASE}_tab.cpp bison_impl.variable_out = GENERATED_SOURCES QMAKE_EXTRA_COMPILERS += bison_impl diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 662774b4849..8c189e92888 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -242,6 +242,7 @@ QUnifiedTimer *QUnifiedTimer::instance(bool create) inst = unifiedTimer() ? unifiedTimer()->localData() : 0; } #else + Q_UNUSED(create); static QUnifiedTimer unifiedTimer; inst = &unifiedTimer; #endif @@ -576,6 +577,7 @@ QAnimationTimer *QAnimationTimer::instance(bool create) inst = animationTimer() ? animationTimer()->localData() : 0; } #else + Q_UNUSED(create); static QAnimationTimer animationTimer; inst = &animationTimer; #endif diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp index 6e5b08c2959..9fd845bb93a 100644 --- a/src/corelib/animation/qpropertyanimation.cpp +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -269,10 +269,8 @@ void QPropertyAnimation::updateState(QAbstractAnimation::State newState, QPropertyAnimation *animToStop = 0; { -#ifndef QT_NO_THREAD static QBasicMutex mutex; QMutexLocker locker(&mutex); -#endif typedef QPair QPropertyAnimationPair; typedef QHash QPropertyAnimationHash; static QPropertyAnimationHash hash; diff --git a/src/corelib/configure.json b/src/corelib/configure.json index f84a13fa504..60248e9cd24 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -305,6 +305,7 @@ "label": "Mimetype handling", "purpose": "Provides MIME type handling.", "section": "Utilities", + "condition": "features.textcodec", "output": [ "publicFeature", "feature" ] }, "system-pcre2": { diff --git a/src/corelib/doc/src/filestorage.qdoc b/src/corelib/doc/src/filestorage.qdoc index c6a4a856461..e291ba1375a 100644 --- a/src/corelib/doc/src/filestorage.qdoc +++ b/src/corelib/doc/src/filestorage.qdoc @@ -75,7 +75,7 @@ by a Sun SPARC running Solaris. You can also use a data stream to read/write raw unencoded binary data. For more details on the datatypes that QDataStream can serialize, see -{Serializing Qt Data Types}. +\l{Serializing Qt Data Types}. The QTextStream class provides a convenient interface for reading and writing text. QTextStream can operate on a QIODevice, a QByteArray or diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 723611e1d87..a9922bb31d1 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -996,11 +996,20 @@ #ifdef __cplusplus # include # if defined(Q_OS_QNX) -// QNX: test if we are using libcpp (Dinkumware-based). -// Older versions (QNX 650) do not support C++11 features +// By default, QNX 7.0 uses libc++ (from LLVM) and +// QNX 6.X uses Dinkumware's libcpp. In all versions, +// it is also possible to use GNU libstdc++. + +// For Dinkumware, some features must be disabled +// (mostly because of library problems). +// Dinkumware is assumed when __GLIBCXX__ (GNU libstdc++) +// and _LIBCPP_VERSION (LLVM libc++) are both absent. +# if !defined(__GLIBCXX__) && !defined(_LIBCPP_VERSION) + +// Older versions of libcpp (QNX 650) do not support C++11 features // _HAS_* macros are set to 1 by toolchains that actually include // Dinkum C++11 libcpp. -# if !defined(__GLIBCXX__) + # if !defined(_HAS_CPP0X) || !_HAS_CPP0X // Disable C++11 features that depend on library support # undef Q_COMPILER_INITIALIZER_LISTS @@ -1017,7 +1026,7 @@ // Disable constexpr support on QNX even if the compiler supports it # undef Q_COMPILER_CONSTEXPR # endif // !_HAS_CONSTEXPR -# endif // !__GLIBCXX__ +# endif // !__GLIBCXX__ && !_LIBCPP_VERSION # endif // Q_OS_QNX # if (defined(Q_CC_CLANG) || defined(Q_CC_INTEL)) && defined(Q_OS_MAC) && defined(__GNUC_LIBSTD__) \ && ((__GNUC_LIBSTD__-0) * 100 + __GNUC_LIBSTD_MINOR__-0 <= 402) diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h index d0e45478cc4..d7849d4699c 100644 --- a/src/corelib/global/qconfig-bootstrapped.h +++ b/src/corelib/global/qconfig-bootstrapped.h @@ -83,11 +83,14 @@ #define QT_NO_TRANSLATION #define QT_FEATURE_translation -1 #define QT_NO_GEOM_VARIANT +#define QT_FEATURE_sharedmemory -1 +#define QT_FEATURE_systemsemaphore -1 -#if defined(QT_BUILD_QMAKE) || defined(QT_BUILD_CONFIGURE) +#ifdef QT_BUILD_QMAKE #define QT_FEATURE_commandlineparser -1 #define QT_NO_COMPRESS #define QT_JSON_READONLY +#define QT_NO_STANDARDPATHS #define QT_NO_TEXTCODEC #define QT_FEATURE_textcodec -1 #else @@ -97,8 +100,4 @@ #define QT_FEATURE_textcodec 1 #endif -#if defined(QT_BUILD_QMAKE) -#define QT_NO_STANDARDPATHS -#endif - #endif // QT_BOOTSTRAPPED diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index b34e8ec6592..010f2c18c42 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1515,6 +1515,13 @@ bool qSharedBuild() Q_DECL_NOTHROW C/C++, Intel C++ for Windows. */ +/*! + \macro Q_CC_CLANG + \relates + + Defined if the application is compiled using Clang. +*/ + /*! \macro Q_CC_BOR \relates diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index a020be7fb2d..e6d48484910 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -83,7 +83,7 @@ 1: The feature is available */ #define QT_CONFIG(feature) (1/QT_FEATURE_##feature == 1) -#define QT_REQUIRE_CONFIG(feature) Q_STATIC_ASSERT_X(QT_FEATURE_##feature == 1, "Required feature " #feature " for file " __FILE__ " not vailable.") +#define QT_REQUIRE_CONFIG(feature) Q_STATIC_ASSERT_X(QT_FEATURE_##feature == 1, "Required feature " #feature " for file " __FILE__ " not available.") #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) # define QT_NO_UNSHARABLE_CONTAINERS diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 87ee75fa455..0de8b509002 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -41,18 +41,15 @@ #include "qdir.h" #include "qstringlist.h" #include "qfile.h" -#include "qtemporaryfile.h" #include "qsettings.h" #include "qlibraryinfo.h" #include "qscopedpointer.h" #ifdef QT_BUILD_QMAKE QT_BEGIN_NAMESPACE -extern QString qmake_absoluteLocation(); extern QString qmake_libraryInfoFile(); QT_END_NAMESPACE #else -# include "qconfig.cpp" # include "qcoreapplication.h" #endif @@ -60,6 +57,10 @@ QT_END_NAMESPACE # include "private/qcore_mac_p.h" #endif +#ifndef QT_BUILD_QMAKE_BOOTSTRAP +# include "qconfig.cpp" +#endif + #include "archdetect.cpp" QT_BEGIN_NAMESPACE @@ -72,16 +73,9 @@ struct QLibrarySettings { QLibrarySettings(); void load(); -#ifdef QT_BUILD_QMAKE - void loadBuiltinValues(QSettings *config); -#endif QScopedPointer settings; #ifdef QT_BUILD_QMAKE - QString builtinValues[QLibraryInfo::LastHostPath + 1]; -# ifndef Q_OS_WIN - QString builtinSettingsPath; -# endif bool haveDevicePaths; bool haveEffectiveSourcePaths; bool haveEffectivePaths; @@ -113,25 +107,6 @@ public: ? ls->haveDevicePaths : ls->havePaths) : false; } - static bool sysrootify() - { - // This is actually bogus, as it does not consider post-configure settings. - QLibrarySettings *ls = qt_library_settings(); - return ls ? (!ls->builtinValues[QLibraryInfo::SysrootPath].isEmpty() - && ls->builtinValues[QLibraryInfo::ExtPrefixPath].isEmpty()) : false; - } - static QString builtinValue(int loc) - { - QLibrarySettings *ls = qt_library_settings(); - return ls ? ls->builtinValues[loc] : QString(); - } -# ifndef Q_OS_WIN - static QString builtinSettingsPath() - { - QLibrarySettings *ls = qt_library_settings(); - return ls ? ls->builtinSettingsPath : QString(); - } -# endif #endif static QSettings *configuration() { @@ -155,20 +130,6 @@ QLibrarySettings::QLibrarySettings() load(); } -#ifdef QT_BUILD_QMAKE -static QByteArray qtconfSeparator() -{ -# ifdef Q_OS_WIN - QByteArray header = QByteArrayLiteral("\r\n===========================================================\r\n"); -# else - QByteArray header = QByteArrayLiteral("\n===========================================================\n"); -# endif - QByteArray content = QByteArrayLiteral("==================== qt.conf beginning ===================="); - // Assemble from pieces to avoid that the string appears in a raw executable - return header + content + header; -} -#endif - void QLibrarySettings::load() { // If we get any settings here, those won't change when the application shows up. @@ -206,27 +167,6 @@ void QLibrarySettings::load() havePaths = false; #endif } - -#ifdef QT_BUILD_QMAKE - // Try to use an embedded qt.conf appended to the QMake executable. - QFile qmakeFile(qmake_absoluteLocation()); - if (!qmakeFile.open(QIODevice::ReadOnly)) - return; - qmakeFile.seek(qmakeFile.size() - 10000); - QByteArray tail = qmakeFile.read(10000); - QByteArray separator = qtconfSeparator(); - int qtconfOffset = tail.lastIndexOf(separator); - if (qtconfOffset < 0) - return; - tail.remove(0, qtconfOffset + separator.size()); - // If QSettings had a c'tor taking a QIODevice, we'd pass a QBuffer ... - QTemporaryFile tmpFile; - tmpFile.open(); - tmpFile.write(tail); - tmpFile.close(); - QSettings builtinSettings(tmpFile.fileName(), QSettings::IniFormat); - loadBuiltinValues(&builtinSettings); -#endif } QSettings *QLibraryInfoPrivate::findConfiguration() @@ -483,29 +423,17 @@ static const struct { { "Tests", "tests" }, #ifdef QT_BUILD_QMAKE { "Sysroot", "" }, + { "SysrootifyPrefix", "" }, { "HostBinaries", "bin" }, { "HostLibraries", "lib" }, { "HostData", "." }, { "TargetSpec", "" }, { "HostSpec", "" }, - { "ExtPrefix", "" }, { "HostPrefix", "" }, #endif }; #ifdef QT_BUILD_QMAKE -void QLibrarySettings::loadBuiltinValues(QSettings *config) -{ - config->beginGroup(QLatin1String("Paths")); - for (int i = 0; i <= QLibraryInfo::LastHostPath; i++) - builtinValues[i] = config->value(QLatin1String(qtConfEntries[i].key), - QLatin1String(qtConfEntries[i].value)).toString(); -# ifndef Q_OS_WIN - builtinSettingsPath = config->value(QLatin1String("Settings")).toString(); -# endif - config->endGroup(); -} - void QLibraryInfo::reload() { QLibraryInfoPrivate::reload(); @@ -522,13 +450,17 @@ QLibraryInfo::location(LibraryLocation loc) QString ret = rawLocation(loc, FinalPaths); // Automatically prepend the sysroot to target paths - if ((loc < SysrootPath || loc > LastHostPath) && QLibraryInfoPrivate::sysrootify()) { + if (loc < SysrootPath || loc > LastHostPath) { QString sysroot = rawLocation(SysrootPath, FinalPaths); - if (!sysroot.isEmpty() && ret.length() > 2 && ret.at(1) == QLatin1Char(':') - && (ret.at(2) == QLatin1Char('/') || ret.at(2) == QLatin1Char('\\'))) - ret.replace(0, 2, sysroot); // Strip out the drive on Windows targets - else - ret.prepend(sysroot); + if (!sysroot.isEmpty() + && QVariant::fromValue(rawLocation(SysrootifyPrefixPath, FinalPaths)).toBool()) { + if (ret.length() > 2 && ret.at(1) == QLatin1Char(':') + && (ret.at(2) == QLatin1Char('/') || ret.at(2) == QLatin1Char('\\'))) { + ret.replace(0, 2, sysroot); // Strip out the drive on Windows targets + } else { + ret.prepend(sysroot); + } + } } return ret; @@ -591,7 +523,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) if (loc == HostPrefixPath) ret = config->value(QLatin1String(qtConfEntries[PrefixPath].key), QLatin1String(qtConfEntries[PrefixPath].value)).toString(); - else if (loc == TargetSpecPath || loc == HostSpecPath) + else if (loc == TargetSpecPath || loc == HostSpecPath || loc == SysrootifyPrefixPath) fromConf = false; // The last case here is SysrootPath, which can be legitimately empty. // All other keys have non-empty fallbacks to start with. @@ -615,38 +547,36 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) } #endif // QT_NO_SETTINGS +#ifndef QT_BUILD_QMAKE_BOOTSTRAP if (!fromConf) { -#ifdef QT_BUILD_QMAKE - if ((unsigned)loc <= (unsigned)LastHostPath) { - if (loc == PrefixPath && group != DevicePaths) - ret = QLibraryInfoPrivate::builtinValue(ExtPrefixPath); - else - ret = QLibraryInfoPrivate::builtinValue(loc); -# ifndef Q_OS_WIN // On Windows we use the registry - } else if (loc == SettingsPath) { - ret = QLibraryInfoPrivate::builtinSettingsPath(); -# endif - } -#else // QT_BUILD_QMAKE const char * volatile path = 0; if (loc == PrefixPath) { - path = QT_CONFIGURE_PREFIX_PATH; + path = +# ifdef QT_BUILD_QMAKE + (group != DevicePaths) ? + QT_CONFIGURE_EXT_PREFIX_PATH : +# endif + QT_CONFIGURE_PREFIX_PATH; } else if (unsigned(loc) <= sizeof(qt_configure_str_offsets)/sizeof(qt_configure_str_offsets[0])) { path = qt_configure_strs + qt_configure_str_offsets[loc - 1]; #ifndef Q_OS_WIN // On Windows we use the registry } else if (loc == SettingsPath) { path = QT_CONFIGURE_SETTINGS_PATH; #endif +# ifdef QT_BUILD_QMAKE + } else if (loc == HostPrefixPath) { + path = QT_CONFIGURE_HOST_PREFIX_PATH; +# endif } if (path) ret = QString::fromLocal8Bit(path); -#endif } +#endif #ifdef QT_BUILD_QMAKE - // The specs need to be returned verbatim. - if (loc == TargetSpecPath || loc == HostSpecPath) + // These values aren't actually paths and thus need to be returned verbatim. + if (loc == TargetSpecPath || loc == HostSpecPath || loc == SysrootifyPrefixPath) return ret; #endif diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h index 9d794ce1da9..809813d99d9 100644 --- a/src/corelib/global/qlibraryinfo.h +++ b/src/corelib/global/qlibraryinfo.h @@ -91,12 +91,12 @@ public: #ifdef QT_BUILD_QMAKE // These are not subject to binary compatibility constraints SysrootPath, + SysrootifyPrefixPath, HostBinariesPath, HostLibrariesPath, HostDataPath, TargetSpecPath, HostSpecPath, - ExtPrefixPath, HostPrefixPath, LastHostPath = HostPrefixPath, #endif diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index dfecc3e2d3b..af485a18326 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -123,16 +123,14 @@ \value AA_PluginApplication Indicates that Qt is used to author a plugin. Depending on the operating system, it suppresses specific initializations that do not necessarily make sense in the plugin case. - For example on OS X, this includes avoiding loading our nib for the main menu and not taking possession of the native menu bar. Setting this attribute to true will also set the AA_DontUseNativeMenuBar attribute to true. It also disables native event filters. - This attribute has been added in Qt 5.7. It must be set before \l {QGuiApplication}{Q(Gui)Application} is constructed. - \value AA_MacPluginApplication This attribute has been deprecated. + \value AA_MacPluginApplication This attribute has been deprecated. Use AA_PluginApplication instead. \value AA_DontUseNativeMenuBar All menubars created while this attribute is @@ -166,7 +164,6 @@ \value AA_UseHighDpiPixmaps Make QIcon::pixmap() generate high-dpi pixmaps that can be larger than the requested size. Such pixmaps will have \l {QPixmap::devicePixelRatio}{devicePixelRatio()} set to a value higher than 1. - After setting this attribute, application code that uses pixmap sizes in layout geometry calculations should typically divide by \l {QPixmap::devicePixelRatio}{devicePixelRatio()} to get device-independent layout geometry. @@ -2660,7 +2657,7 @@ \value FontRole The font used for items rendered with the default delegate. (QFont) \value TextAlignmentRole The alignment of the text for items rendered with the - default delegate. (Qt::AlignmentFlag) + default delegate. (Qt::Alignment) \value BackgroundRole The background brush used for items rendered with the default delegate. (QBrush) \value BackgroundColorRole This role is obsolete. Use BackgroundRole instead. diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp index ae3a7c6abca..cb1ff93ad34 100644 --- a/src/corelib/io/qlockfile.cpp +++ b/src/corelib/io/qlockfile.cpp @@ -84,6 +84,9 @@ QT_BEGIN_NAMESPACE For the use case of protecting a resource over a long time, you should therefore call setStaleLockTime(0), and when tryLock() returns LockFailedError, inform the user that the document is locked, possibly using getLockInfo() for more details. + + \note On Windows, this class has problems detecting a stale lock if the + machine's hostname contains characters outside the US-ASCII character set. */ /*! diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index 82beb159123..3a80014c004 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -81,15 +81,6 @@ QT_BEGIN_NAMESPACE -static QByteArray localHostName() // from QHostInfo::localHostName(), modified to return a QByteArray -{ - QByteArray hostName(512, Qt::Uninitialized); - if (gethostname(hostName.data(), hostName.size()) == -1) - return QByteArray(); - hostName.truncate(strlen(hostName.data())); - return hostName; -} - // ### merge into qt_safe_write? static qint64 qt_write_loop(int fd, const char *data, qint64 len) { @@ -185,7 +176,7 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys() // Use operator% from the fast builder to avoid multiple memory allocations. QByteArray fileData = QByteArray::number(QCoreApplication::applicationPid()) % '\n' % QCoreApplication::applicationName().toUtf8() % '\n' - % localHostName() % '\n'; + % QSysInfo::machineHostName().toUtf8() % '\n'; const QByteArray lockFileName = QFile::encodeName(fileName); const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY | O_CREAT | O_EXCL, 0666); @@ -242,7 +233,7 @@ bool QLockFilePrivate::isApparentlyStale() const qint64 pid; QString hostname, appname; if (getLockInfo(&pid, &hostname, &appname)) { - if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) { + if (hostname.isEmpty() || hostname == QSysInfo::machineHostName()) { if (::kill(pid, 0) == -1 && errno == ESRCH) return true; // PID doesn't exist anymore const QString processName = processNameByPid(pid); diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index f2c2ba4476d..c27484acbe2 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -513,6 +513,9 @@ void QProcessPrivate::Channel::clear() You can also call error() to find the type of error that occurred last, and state() to find the current process state. + \note QProcess is not supported on VxWorks, iOS, tvOS, watchOS, + or the Universal Windows Platform. + \section1 Communicating via Channels Processes have two predefined output channels: The standard diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index c224b032aab..a6372b75f65 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -240,7 +240,7 @@ Only valid if RemovePath is not set. \value PreferLocalFile If the URL is a local file according to isLocalFile() and contains no query or fragment, a local file path is returned. - \value StripTrailingSlash The trailing slash is removed if one is present. + \value StripTrailingSlash The trailing slash is removed from the path, if one is present. \value NormalizePathSegments Modifies the path to remove redundant directory separators, and to resolve "."s and ".."s (as far as possible). diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp index e537793146c..7c306799d0b 100644 --- a/src/corelib/itemmodels/qidentityproxymodel.cpp +++ b/src/corelib/itemmodels/qidentityproxymodel.cpp @@ -496,15 +496,6 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QListpersistentIndexList(); - for (const QPersistentModelIndex &proxyPersistentIndex : proxyPersistentIndexes) { - proxyIndexes << proxyPersistentIndex; - Q_ASSERT(proxyPersistentIndex.isValid()); - const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex); - Q_ASSERT(srcPersistentIndex.isValid()); - layoutChangePersistentIndexes << srcPersistentIndex; - } - QList parents; parents.reserve(sourceParents.size()); for (const QPersistentModelIndex &parent : sourceParents) { @@ -518,6 +509,15 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QListlayoutAboutToBeChanged(parents, hint); + + const auto proxyPersistentIndexes = q->persistentIndexList(); + for (const QPersistentModelIndex &proxyPersistentIndex : proxyPersistentIndexes) { + proxyIndexes << proxyPersistentIndex; + Q_ASSERT(proxyPersistentIndex.isValid()); + const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex); + Q_ASSERT(srcPersistentIndex.isValid()); + layoutChangePersistentIndexes << srcPersistentIndex; + } } void QIdentityProxyModelPrivate::_q_sourceLayoutChanged(const QList &sourceParents, QAbstractItemModel::LayoutChangeHint hint) diff --git a/src/corelib/itemmodels/qitemselectionmodel.h b/src/corelib/itemmodels/qitemselectionmodel.h index 92c459a2439..2421610bce2 100644 --- a/src/corelib/itemmodels/qitemselectionmodel.h +++ b/src/corelib/itemmodels/qitemselectionmodel.h @@ -228,6 +228,24 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QItemSelectionModel::SelectionFlags) // dummy implentation of qHash() necessary for instantiating QList::toSet() with MSVC inline uint qHash(const QItemSelectionRange &) { return 0; } +#ifdef Q_CC_MSVC + +/* + ### Qt 6: + ### This needs to be removed for next releases of Qt. It is a workaround for vc++ because + ### Qt exports QItemSelection that inherits QList. +*/ + +# ifndef Q_TEMPLATE_EXTERN +# if defined(QT_BUILD_CORE_LIB) +# define Q_TEMPLATE_EXTERN +# else +# define Q_TEMPLATE_EXTERN extern +# endif +# endif +Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QList; +#endif // Q_CC_MSVC + class Q_CORE_EXPORT QItemSelection : public QList { public: diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index b0ddfa879dd..226a2401e1a 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -171,6 +171,7 @@ public: QRowsRemoval itemsBeingRemoved; QModelIndexPairList saved_persistent_indexes; + QList saved_layoutChange_parents; QHash::const_iterator create_mapping( const QModelIndex &source_parent) const; @@ -1331,23 +1332,23 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList parents; + saved_layoutChange_parents.clear(); for (const QPersistentModelIndex &parent : sourceParents) { if (!parent.isValid()) { - parents << QPersistentModelIndex(); + saved_layoutChange_parents << QPersistentModelIndex(); continue; } const QModelIndex mappedParent = q->mapFromSource(parent); // Might be filtered out. if (mappedParent.isValid()) - parents << mappedParent; + saved_layoutChange_parents << mappedParent; } // All parents filtered out. - if (!sourceParents.isEmpty() && parents.isEmpty()) + if (!sourceParents.isEmpty() && saved_layoutChange_parents.isEmpty()) return; - emit q->layoutAboutToBeChanged(parents); + emit q->layoutAboutToBeChanged(saved_layoutChange_parents); if (persistent.indexes.isEmpty()) return; @@ -1359,6 +1360,9 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged(const QList parents; - for (const QPersistentModelIndex &parent : sourceParents) { - if (!parent.isValid()) { - parents << QPersistentModelIndex(); - continue; - } - const QModelIndex mappedParent = q->mapFromSource(parent); - if (mappedParent.isValid()) - parents << mappedParent; - } - - if (!sourceParents.isEmpty() && parents.isEmpty()) - return; - - emit q->layoutChanged(parents); + emit q->layoutChanged(saved_layoutChange_parents); + saved_layoutChange_parents.clear(); } void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeInserted( @@ -1427,49 +1418,27 @@ void QSortFilterProxyModelPrivate::_q_sourceRowsRemoved( void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeMoved( const QModelIndex &sourceParent, int /* sourceStart */, int /* sourceEnd */, const QModelIndex &destParent, int /* dest */) { - Q_Q(QSortFilterProxyModel); // Because rows which are contiguous in the source model might not be contiguous // in the proxy due to sorting, the best thing we can do here is be specific about what // parents are having their children changed. // Optimize: Emit move signals if the proxy is not sorted. Will need to account for rows // being filtered out though. - saved_persistent_indexes.clear(); - QList parents; - parents << q->mapFromSource(sourceParent); + parents << sourceParent; if (sourceParent != destParent) - parents << q->mapFromSource(destParent); - emit q->layoutAboutToBeChanged(parents); - if (persistent.indexes.isEmpty()) - return; - saved_persistent_indexes = store_persistent_indexes(); + parents << destParent; + _q_sourceLayoutAboutToBeChanged(parents, QAbstractItemModel::NoLayoutChangeHint); } void QSortFilterProxyModelPrivate::_q_sourceRowsMoved( const QModelIndex &sourceParent, int /* sourceStart */, int /* sourceEnd */, const QModelIndex &destParent, int /* dest */) { - Q_Q(QSortFilterProxyModel); - - // Optimize: We only need to clear and update the persistent indexes which are children of - // sourceParent or destParent - qDeleteAll(source_index_mapping); - source_index_mapping.clear(); - - update_persistent_indexes(saved_persistent_indexes); - saved_persistent_indexes.clear(); - - if (dynamic_sortfilter && update_source_sort_column()) { - //update_source_sort_column might have created wrong mapping so we have to clear it again - qDeleteAll(source_index_mapping); - source_index_mapping.clear(); - } - QList parents; - parents << q->mapFromSource(sourceParent); + parents << sourceParent; if (sourceParent != destParent) - parents << q->mapFromSource(destParent); - emit q->layoutChanged(parents); + parents << destParent; + _q_sourceLayoutChanged(parents, QAbstractItemModel::NoLayoutChangeHint); } void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeInserted( @@ -1531,42 +1500,21 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsRemoved( void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeMoved( const QModelIndex &sourceParent, int /* sourceStart */, int /* sourceEnd */, const QModelIndex &destParent, int /* dest */) { - Q_Q(QSortFilterProxyModel); - - saved_persistent_indexes.clear(); - QList parents; - parents << q->mapFromSource(sourceParent); + parents << sourceParent; if (sourceParent != destParent) - parents << q->mapFromSource(destParent); - emit q->layoutAboutToBeChanged(parents); - - if (persistent.indexes.isEmpty()) - return; - saved_persistent_indexes = store_persistent_indexes(); + parents << destParent; + _q_sourceLayoutAboutToBeChanged(parents, QAbstractItemModel::NoLayoutChangeHint); } void QSortFilterProxyModelPrivate::_q_sourceColumnsMoved( const QModelIndex &sourceParent, int /* sourceStart */, int /* sourceEnd */, const QModelIndex &destParent, int /* dest */) { - Q_Q(QSortFilterProxyModel); - - qDeleteAll(source_index_mapping); - source_index_mapping.clear(); - - update_persistent_indexes(saved_persistent_indexes); - saved_persistent_indexes.clear(); - - if (dynamic_sortfilter && update_source_sort_column()) { - qDeleteAll(source_index_mapping); - source_index_mapping.clear(); - } - QList parents; - parents << q->mapFromSource(sourceParent); + parents << sourceParent; if (sourceParent != destParent) - parents << q->mapFromSource(destParent); - emit q->layoutChanged(parents); + parents << destParent; + _q_sourceLayoutChanged(parents, QAbstractItemModel::NoLayoutChangeHint); } /*! diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index b5756af994f..80058d91155 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -370,7 +370,7 @@ union qt_semun { }; #ifndef QT_POSIX_IPC -#ifndef QT_NO_SHAREDMEMORY +#if QT_CONFIG(sharedmemory) || QT_CONFIG(systemsemaphore) #ifndef Q_OS_ANDROID static inline key_t qt_safe_ftok(const QByteArray &filename, int proj_id) { @@ -379,7 +379,7 @@ static inline key_t qt_safe_ftok(const QByteArray &filename, int proj_id) return ::ftok(filename.constData(), qHash(filename, proj_id)); } #endif // !Q_OS_ANDROID -#endif // !QT_NO_SHAREDMEMORY +#endif // QT_CONFIG(sharedmemory) || QT_CONFIG(systemsemaphore) #endif // !QT_POSIX_IPC QT_END_NAMESPACE diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index fb86d0222e1..5623b085b87 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -207,8 +207,6 @@ struct DefinedTypesFilter { \enum QMetaType::Type These are the built-in types supported by QMetaType: - Read doc on QChar - Read doc on \l QChar \value Void \c void \value Bool \c bool diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h index 79c9c8303e6..1768e8ccc61 100644 --- a/src/corelib/kernel/qobjectdefs_impl.h +++ b/src/corelib/kernel/qobjectdefs_impl.h @@ -149,6 +149,20 @@ namespace QtPrivate { (o->*f)((*reinterpret_cast::Type *>(arg[II+1]))...), ApplyReturnValue(arg[0]); } }; +#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510 + template + struct FunctorCall, List, R, SlotRet (Obj::*)(SlotArgs...) noexcept> { + static void call(SlotRet (Obj::*f)(SlotArgs...) noexcept, Obj *o, void **arg) { + (o->*f)((*reinterpret_cast::Type *>(arg[II+1]))...), ApplyReturnValue(arg[0]); + } + }; + template + struct FunctorCall, List, R, SlotRet (Obj::*)(SlotArgs...) const noexcept> { + static void call(SlotRet (Obj::*f)(SlotArgs...) const noexcept, Obj *o, void **arg) { + (o->*f)((*reinterpret_cast::Type *>(arg[II+1]))...), ApplyReturnValue(arg[0]); + } + }; +#endif template struct FunctionPointer { @@ -187,6 +201,47 @@ namespace QtPrivate { } }; +#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510 + template struct FunctionPointer + { + typedef Obj Object; + typedef List Arguments; + typedef Ret ReturnType; + typedef Ret (Obj::*Function) (Args...) noexcept; + template struct ChangeClass { typedef Ret (Base:: *Type)(Args...) noexcept; }; + enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true}; + template + static void call(Function f, Obj *o, void **arg) { + FunctorCall::Value, SignalArgs, R, Function>::call(f, o, arg); + } + }; + template struct FunctionPointer + { + typedef Obj Object; + typedef List Arguments; + typedef Ret ReturnType; + typedef Ret (Obj::*Function) (Args...) const noexcept; + template struct ChangeClass { typedef Ret (Base:: *Type)(Args...) const noexcept; }; + enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true}; + template + static void call(Function f, Obj *o, void **arg) { + FunctorCall::Value, SignalArgs, R, Function>::call(f, o, arg); + } + }; + + template struct FunctionPointer + { + typedef List Arguments; + typedef Ret ReturnType; + typedef Ret (*Function) (Args...) noexcept; + enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = false}; + template + static void call(Function f, void *, void **arg) { + FunctorCall::Value, SignalArgs, R, Function>::call(f, arg); + } + }; +#endif + template struct Functor { template diff --git a/src/corelib/kernel/qsharedmemory_p.h b/src/corelib/kernel/qsharedmemory_p.h index 51f729cf233..95fe0d1083b 100644 --- a/src/corelib/kernel/qsharedmemory_p.h +++ b/src/corelib/kernel/qsharedmemory_p.h @@ -53,6 +53,8 @@ #include "qsharedmemory.h" +#include + #ifdef QT_NO_SHAREDMEMORY # ifndef QT_NO_SYSTEMSEMAPHORE namespace QSharedMemoryPrivate diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 4a4d5b92948..8a4ad8bbf3a 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1186,7 +1186,7 @@ Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names \snippet code/src_corelib_kernel_qvariant.cpp 1 QVariant can be extended to support other types than those - mentioned in the \l Type enum. See the \l QMetaType documentation + mentioned in the \l Type enum. See \l{Creating Custom Qt Types}{Creating Custom Qt Types} for details. \section1 A Note on GUI Types diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index 448e6117b1e..fda9f016436 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -108,12 +108,12 @@ QMimeType QMimeDatabasePrivate::mimeTypeForName(const QString &nameOrAlias) return provider()->mimeTypeForName(provider()->resolveAlias(nameOrAlias)); } -QStringList QMimeDatabasePrivate::mimeTypeForFileName(const QString &fileName, QString *foundSuffix) +QStringList QMimeDatabasePrivate::mimeTypeForFileName(const QString &fileName) { if (fileName.endsWith(QLatin1Char('/'))) return QStringList() << QLatin1String("inode/directory"); - QStringList matchingMimeTypes = provider()->findByFileName(QFileInfo(fileName).fileName(), foundSuffix); + QStringList matchingMimeTypes = provider()->findByFileName(QFileInfo(fileName).fileName()).m_matchingMimeTypes; matchingMimeTypes.sort(); // make it deterministic return matchingMimeTypes; } @@ -168,13 +168,17 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa *accuracyPtr = 0; // Pass 1) Try to match on the file name - QStringList candidatesByName = mimeTypeForFileName(fileName); - if (candidatesByName.count() == 1) { + QMimeGlobMatchResult candidatesByName; + if (fileName.endsWith(QLatin1Char('/'))) + candidatesByName.addMatch(QLatin1String("inode/directory"), 100, QString()); + else + candidatesByName = provider()->findByFileName(QFileInfo(fileName).fileName()); + if (candidatesByName.m_allMatchingMimeTypes.count() == 1) { *accuracyPtr = 100; - const QMimeType mime = mimeTypeForName(candidatesByName.at(0)); + const QMimeType mime = mimeTypeForName(candidatesByName.m_matchingMimeTypes.at(0)); if (mime.isValid()) return mime; - candidatesByName.clear(); + candidatesByName = {}; } // Extension is unknown, or matches multiple mimetypes. @@ -193,7 +197,7 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa // "for glob_match in glob_matches:" // "if glob_match is subclass or equal to sniffed_type, use glob_match" const QString sniffedMime = candidateByData.name(); - for (const QString &m : qAsConst(candidatesByName)) { + for (const QString &m : qAsConst(candidatesByName.m_matchingMimeTypes)) { if (inherits(m, sniffedMime)) { // We have magic + pattern pointing to this, so it's a pretty good match *accuracyPtr = 100; @@ -205,9 +209,10 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa } } - if (candidatesByName.count() > 1) { + if (candidatesByName.m_allMatchingMimeTypes.count() > 1) { + candidatesByName.m_matchingMimeTypes.sort(); // make it deterministic *accuracyPtr = 20; - const QMimeType mime = mimeTypeForName(candidatesByName.at(0)); + const QMimeType mime = mimeTypeForName(candidatesByName.m_matchingMimeTypes.at(0)); if (mime.isValid()) return mime; } @@ -455,9 +460,7 @@ QList QMimeDatabase::mimeTypesForFileName(const QString &fileName) co QString QMimeDatabase::suffixForFileName(const QString &fileName) const { QMutexLocker locker(&d->mutex); - QString foundSuffix; - d->mimeTypeForFileName(fileName, &foundSuffix); - return foundSuffix; + return d->provider()->findByFileName(QFileInfo(fileName).fileName()).m_foundSuffix; } /*! diff --git a/src/corelib/mimetypes/qmimedatabase_p.h b/src/corelib/mimetypes/qmimedatabase_p.h index 4ff5110a5b7..3f63f5f1034 100644 --- a/src/corelib/mimetypes/qmimedatabase_p.h +++ b/src/corelib/mimetypes/qmimedatabase_p.h @@ -90,7 +90,7 @@ public: QMimeType mimeTypeForName(const QString &nameOrAlias); QMimeType mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device, int *priorityPtr); QMimeType findByData(const QByteArray &data, int *priorityPtr); - QStringList mimeTypeForFileName(const QString &fileName, QString *foundSuffix = 0); + QStringList mimeTypeForFileName(const QString &fileName); mutable QMimeProviderBase *m_provider; const QString m_defaultMimeType; diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp index 568f9bf4dec..a4d2b046fa3 100644 --- a/src/corelib/mimetypes/qmimeglobpattern.cpp +++ b/src/corelib/mimetypes/qmimeglobpattern.cpp @@ -58,9 +58,13 @@ QT_BEGIN_NAMESPACE void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const QString &pattern) { - // Is this a lower-weight pattern than the last match? Skip this match then. - if (weight < m_weight) + if (m_allMatchingMimeTypes.contains(mimeType)) return; + // Is this a lower-weight pattern than the last match? Skip this match then. + if (weight < m_weight) { + m_allMatchingMimeTypes.append(mimeType); + return; + } bool replace = weight > m_weight; if (!replace) { // Compare the length of the match @@ -79,6 +83,7 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q } if (!m_matchingMimeTypes.contains(mimeType)) { m_matchingMimeTypes.append(mimeType); + m_allMatchingMimeTypes.append(mimeType); if (pattern.startsWith(QLatin1String("*."))) m_foundSuffix = pattern.mid(2); } @@ -201,35 +206,32 @@ void QMimeGlobPatternList::match(QMimeGlobMatchResult &result, } } -QStringList QMimeAllGlobPatterns::matchingGlobs(const QString &fileName, QString *foundSuffix) const +QMimeGlobMatchResult QMimeAllGlobPatterns::matchingGlobs(const QString &fileName) const { // First try the high weight matches (>50), if any. QMimeGlobMatchResult result; m_highWeightGlobs.match(result, fileName); - if (result.m_matchingMimeTypes.isEmpty()) { - // Now use the "fast patterns" dict, for simple *.foo patterns with weight 50 - // (which is most of them, so this optimization is definitely worth it) - const int lastDot = fileName.lastIndexOf(QLatin1Char('.')); - if (lastDot != -1) { // if no '.', skip the extension lookup - const int ext_len = fileName.length() - lastDot - 1; - const QString simpleExtension = fileName.right(ext_len).toLower(); - // (toLower because fast patterns are always case-insensitive and saved as lowercase) + // Now use the "fast patterns" dict, for simple *.foo patterns with weight 50 + // (which is most of them, so this optimization is definitely worth it) + const int lastDot = fileName.lastIndexOf(QLatin1Char('.')); + if (lastDot != -1) { // if no '.', skip the extension lookup + const int ext_len = fileName.length() - lastDot - 1; + const QString simpleExtension = fileName.right(ext_len).toLower(); + // (toLower because fast patterns are always case-insensitive and saved as lowercase) - const QStringList matchingMimeTypes = m_fastPatterns.value(simpleExtension); - const QString simplePattern = QLatin1String("*.") + simpleExtension; - for (const QString &mime : matchingMimeTypes) - result.addMatch(mime, 50, simplePattern); - // Can't return yet; *.tar.bz2 has to win over *.bz2, so we need the low-weight mimetypes anyway, - // at least those with weight 50. - } - - // Finally, try the low weight matches (<=50) - m_lowWeightGlobs.match(result, fileName); + const QStringList matchingMimeTypes = m_fastPatterns.value(simpleExtension); + const QString simplePattern = QLatin1String("*.") + simpleExtension; + for (const QString &mime : matchingMimeTypes) + result.addMatch(mime, 50, simplePattern); + // Can't return yet; *.tar.bz2 has to win over *.bz2, so we need the low-weight mimetypes anyway, + // at least those with weight 50. } - if (foundSuffix) - *foundSuffix = result.m_foundSuffix; - return result.m_matchingMimeTypes; + + // Finally, try the low weight matches (<=50) + m_lowWeightGlobs.match(result, fileName); + + return result; } void QMimeAllGlobPatterns::clear() diff --git a/src/corelib/mimetypes/qmimeglobpattern_p.h b/src/corelib/mimetypes/qmimeglobpattern_p.h index 3e4fdb50f6b..c8b70464fdc 100644 --- a/src/corelib/mimetypes/qmimeglobpattern_p.h +++ b/src/corelib/mimetypes/qmimeglobpattern_p.h @@ -68,7 +68,8 @@ struct QMimeGlobMatchResult void addMatch(const QString &mimeType, int weight, const QString &pattern); - QStringList m_matchingMimeTypes; + QStringList m_matchingMimeTypes; // only those with highest weight + QStringList m_allMatchingMimeTypes; int m_weight; int m_matchingPatternLength; QString m_foundSuffix; @@ -153,7 +154,7 @@ public: void addGlob(const QMimeGlobPattern &glob); void removeMimeType(const QString &mimeType); - QStringList matchingGlobs(const QString &fileName, QString *foundSuffix) const; + QMimeGlobMatchResult matchingGlobs(const QString &fileName) const; void clear(); PatternsMap m_fastPatterns; // example: "doc" -> "application/msword", "text/plain" diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp index 7e07f8acb9e..5bbf1bba9d6 100644 --- a/src/corelib/mimetypes/qmimemagicrule.cpp +++ b/src/corelib/mimetypes/qmimemagicrule.cpp @@ -161,7 +161,7 @@ bool QMimeMagicRule::matchNumber(const QByteArray &data) const //qDebug() << "mask" << QString::number(m_numberMask, 16); const char *p = data.constData() + m_startPos; - const char *e = data.constData() + qMin(data.size() - int(sizeof(T)), m_endPos + 1); + const char *e = data.constData() + qMin(data.size() - int(sizeof(T)), m_endPos); for ( ; p <= e; ++p) { if ((qFromUnaligned(p) & mask) == (value & mask)) return true; @@ -299,20 +299,30 @@ QMimeMagicRule::QMimeMagicRule(const QString &type, } break; case Big16: - case Host16: case Little16: if (m_number <= quint16(-1)) { m_number = m_type == Little16 ? qFromLittleEndian(m_number) : qFromBigEndian(m_number); + if (m_numberMask != 0) + m_numberMask = m_type == Little16 ? qFromLittleEndian(m_numberMask) : qFromBigEndian(m_numberMask); + } + Q_FALLTHROUGH(); + case Host16: + if (m_number <= quint16(-1)) { if (m_numberMask == 0) m_numberMask = quint16(-1); m_matchFunction = &QMimeMagicRule::matchNumber; } break; case Big32: - case Host32: case Little32: if (m_number <= quint32(-1)) { m_number = m_type == Little32 ? qFromLittleEndian(m_number) : qFromBigEndian(m_number); + if (m_numberMask != 0) + m_numberMask = m_type == Little32 ? qFromLittleEndian(m_numberMask) : qFromBigEndian(m_numberMask); + } + Q_FALLTHROUGH(); + case Host32: + if (m_number <= quint32(-1)) { if (m_numberMask == 0) m_numberMask = quint32(-1); m_matchFunction = &QMimeMagicRule::matchNumber; diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index 65b011b439e..959421bf52f 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -287,13 +287,13 @@ QMimeType QMimeBinaryProvider::mimeTypeForName(const QString &name) return mimeTypeForNameUnchecked(name); } -QStringList QMimeBinaryProvider::findByFileName(const QString &fileName, QString *foundSuffix) +QMimeGlobMatchResult QMimeBinaryProvider::findByFileName(const QString &fileName) { checkCache(); - if (fileName.isEmpty()) - return QStringList(); - const QString lowerFileName = fileName.toLower(); QMimeGlobMatchResult result; + if (fileName.isEmpty()) + return result; + const QString lowerFileName = fileName.toLower(); // TODO this parses in the order (local, global). Check that it handles "NOGLOBS" correctly. for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) { matchGlobList(result, cacheFile, cacheFile->getUint32(PosLiteralListOffset), fileName); @@ -305,9 +305,7 @@ QStringList QMimeBinaryProvider::findByFileName(const QString &fileName, QString if (result.m_matchingMimeTypes.isEmpty()) matchSuffixTree(result, cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true); } - if (foundSuffix) - *foundSuffix = result.m_foundSuffix; - return result.m_matchingMimeTypes; + return result; } void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName) @@ -728,12 +726,11 @@ QMimeType QMimeXMLProvider::mimeTypeForName(const QString &name) return m_nameMimeTypeMap.value(name); } -QStringList QMimeXMLProvider::findByFileName(const QString &fileName, QString *foundSuffix) +QMimeGlobMatchResult QMimeXMLProvider::findByFileName(const QString &fileName) { ensureLoaded(); - const QStringList matchingMimeTypes = m_mimeTypeGlobs.matchingGlobs(fileName, foundSuffix); - return matchingMimeTypes; + return m_mimeTypeGlobs.matchingGlobs(fileName); } QMimeType QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr) diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h index e6fc47bf80b..f410e622672 100644 --- a/src/corelib/mimetypes/qmimeprovider_p.h +++ b/src/corelib/mimetypes/qmimeprovider_p.h @@ -56,6 +56,7 @@ #ifndef QT_NO_MIMETYPE +#include "qmimeglobpattern_p.h" #include #include #include @@ -72,7 +73,7 @@ public: virtual bool isValid() = 0; virtual QMimeType mimeTypeForName(const QString &name) = 0; - virtual QStringList findByFileName(const QString &fileName, QString *foundSuffix) = 0; + virtual QMimeGlobMatchResult findByFileName(const QString &fileName) = 0; virtual QStringList parents(const QString &mime) = 0; virtual QString resolveAlias(const QString &name) = 0; virtual QStringList listAliases(const QString &name) = 0; @@ -99,7 +100,7 @@ public: virtual bool isValid() Q_DECL_OVERRIDE; virtual QMimeType mimeTypeForName(const QString &name) Q_DECL_OVERRIDE; - virtual QStringList findByFileName(const QString &fileName, QString *foundSuffix) Q_DECL_OVERRIDE; + virtual QMimeGlobMatchResult findByFileName(const QString &fileName) Q_DECL_OVERRIDE; virtual QStringList parents(const QString &mime) Q_DECL_OVERRIDE; virtual QString resolveAlias(const QString &name) Q_DECL_OVERRIDE; virtual QStringList listAliases(const QString &name) Q_DECL_OVERRIDE; @@ -142,7 +143,7 @@ public: virtual bool isValid() Q_DECL_OVERRIDE; virtual QMimeType mimeTypeForName(const QString &name) Q_DECL_OVERRIDE; - virtual QStringList findByFileName(const QString &fileName, QString *foundSuffix) Q_DECL_OVERRIDE; + virtual QMimeGlobMatchResult findByFileName(const QString &fileName) Q_DECL_OVERRIDE; virtual QStringList parents(const QString &mime) Q_DECL_OVERRIDE; virtual QString resolveAlias(const QString &name) Q_DECL_OVERRIDE; virtual QStringList listAliases(const QString &name) Q_DECL_OVERRIDE; diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index c09dc6c22b7..b8e18cc9a82 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -282,6 +282,7 @@ QObject *QFactoryLoader::instance(int index) const return 0; #ifndef QT_NO_LIBRARY + QMutexLocker lock(&d->mutex); if (index < d->libraryList.size()) { QLibraryPrivate *library = d->libraryList.at(index); if (library->instance || library->loadPlugin()) { @@ -297,6 +298,7 @@ QObject *QFactoryLoader::instance(int index) const return 0; } index -= d->libraryList.size(); + lock.unlock(); #endif QVector staticPlugins = QPluginLoader::staticPlugins(); diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 433f5956110..d7cdec9aac3 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -2024,7 +2024,9 @@ void QStateMachinePrivate::processEvents(EventProcessingMode processingMode) if (QThread::currentThread() == q->thread()) { _q_process(); break; - } // fallthrough -- processing must be done in the machine thread + } + // processing must be done in the machine thread, so: + Q_FALLTHROUGH(); case QueuedProcessing: processingScheduled = true; QMetaObject::invokeMethod(q, "_q_process", Qt::QueuedConnection); diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 9418813afd8..c28b1623051 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -79,7 +79,7 @@ class QFinalState; class QHistoryState; class QState; -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) class QAbstractAnimation; #endif @@ -123,7 +123,7 @@ public: // private slots void _q_start(); void _q_process(); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) void _q_animationFinished(); #endif void _q_startDelayedEventTimer(int id, int delay); @@ -152,7 +152,7 @@ public: const QList &statesToEnter_sorted, const QSet &statesForDefaultEntry, QHash > &propertyAssignmentsForState -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) , const QList &selectedAnimations #endif ); @@ -264,7 +264,7 @@ public: QSet pendingErrorStates; QSet pendingErrorStatesForDefaultEntry; -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) bool animated; struct InitializeAnimationResult { @@ -326,7 +326,9 @@ public: static const Handler *handler; }; +#if QT_CONFIG(animation) Q_DECLARE_SHARED(QStateMachinePrivate::InitializeAnimationResult) +#endif Q_CORE_EXPORT const QStateMachinePrivate::Handler *qcoreStateMachineHandler(); diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h index 410f642ca7a..45786537e20 100644 --- a/src/corelib/thread/qthread.h +++ b/src/corelib/thread/qthread.h @@ -140,10 +140,10 @@ public: static QThread* currentThread(); protected: - QThread(QThreadPrivate &dd, QObject *parent = 0); + QThread(QThreadPrivate &dd, QObject *parent = nullptr); private: - explicit QThread(QObject *parent = 0); + explicit QThread(QObject *parent = nullptr); static QThread *instance; friend class QCoreApplication; diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 621c8771743..65016933a04 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -1139,6 +1139,7 @@ end: } break; } } + Q_FALLTHROUGH(); case MonthSection: if (sn.count >= 3) { const int currentMonth = newCurrentValue.date().month(); @@ -1216,15 +1217,15 @@ end: } else { if (context == FromString) { // optimization - Q_ASSERT(getMaximum().date().toJulianDay() == 4642999); + Q_ASSERT(maximum.date().toJulianDay() == 4642999); if (newCurrentValue.date().toJulianDay() > 4642999) state = Invalid; } else { - if (newCurrentValue > getMaximum()) + if (newCurrentValue > maximum) state = Invalid; } - QDTPDEBUG << "not checking intermediate because newCurrentValue is" << newCurrentValue << getMinimum() << getMaximum(); + QDTPDEBUG << "not checking intermediate because newCurrentValue is" << newCurrentValue << minimum << maximum; } } StateNode node; @@ -1607,13 +1608,13 @@ bool QDateTimeParser::potentialValue(const QStringRef &str, int min, int max, in bool QDateTimeParser::skipToNextSection(int index, const QDateTime ¤t, const QStringRef &text) const { - Q_ASSERT(current >= getMinimum() && current <= getMaximum()); - const SectionNode &node = sectionNode(index); Q_ASSERT(text.size() < sectionMaxSize(index)); const QDateTime maximum = getMaximum(); const QDateTime minimum = getMinimum(); + Q_ASSERT(current >= minimum && current <= maximum); + QDateTime tmp = current; int min = absoluteMin(index); setDigit(tmp, index, min); @@ -1713,11 +1714,21 @@ bool QDateTimeParser::fromString(const QString &t, QDate *date, QTime *time) con QDateTime QDateTimeParser::getMinimum() const { + // Cache the most common case + if (spec == Qt::LocalTime) { + static const QDateTime localTimeMin(QDATETIMEEDIT_DATE_MIN, QDATETIMEEDIT_TIME_MIN, Qt::LocalTime); + return localTimeMin; + } return QDateTime(QDATETIMEEDIT_DATE_MIN, QDATETIMEEDIT_TIME_MIN, spec); } QDateTime QDateTimeParser::getMaximum() const { + // Cache the most common case + if (spec == Qt::LocalTime) { + static const QDateTime localTimeMax(QDATETIMEEDIT_DATE_MAX, QDATETIMEEDIT_TIME_MAX, Qt::LocalTime); + return localTimeMax; + } return QDateTime(QDATETIMEEDIT_DATE_MAX, QDATETIMEEDIT_TIME_MAX, spec); } diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 77f7ba963bd..cdda5292e70 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -334,33 +334,17 @@ QByteArray QLocalePrivate::bcp47Name(char separator) const return localeId.withLikelySubtagsRemoved().name(separator); } -const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLocale::Script script, QLocale::Country country) +static const QLocaleData *findLocaleDataById(const QLocaleId &localeId) { - QLocaleId localeId = QLocaleId::fromIds(language, script, country); - localeId = localeId.withLikelySubtagsAdded(); - - uint idx = locale_index[localeId.language_id]; + const uint idx = locale_index[localeId.language_id]; const QLocaleData *data = locale_data + idx; - if (idx == 0) // default language has no associated country + if (idx == 0) // default language has no associated script or country return data; Q_ASSERT(data->m_language_id == localeId.language_id); - if (localeId.script_id != QLocale::AnyScript && localeId.country_id != QLocale::AnyCountry) { - // both script and country are explicitly specified - do { - if (data->m_script_id == localeId.script_id && data->m_country_id == localeId.country_id) - return data; - ++data; - } while (data->m_language_id == localeId.language_id); - - // no match; try again with default script - localeId.script_id = QLocale::AnyScript; - data = locale_data + idx; - } - if (localeId.script_id == QLocale::AnyScript && localeId.country_id == QLocale::AnyCountry) return data; @@ -369,15 +353,72 @@ const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLoca if (data->m_country_id == localeId.country_id) return data; ++data; - } while (data->m_language_id == localeId.language_id); + } while (data->m_language_id && data->m_language_id == localeId.language_id); } else if (localeId.country_id == QLocale::AnyCountry) { do { if (data->m_script_id == localeId.script_id) return data; ++data; - } while (data->m_language_id == localeId.language_id); + } while (data->m_language_id && data->m_language_id == localeId.language_id); + } else { + do { + if (data->m_script_id == localeId.script_id && data->m_country_id == localeId.country_id) + return data; + ++data; + } while (data->m_language_id && data->m_language_id == localeId.language_id); } + return 0; +} + +const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLocale::Script script, QLocale::Country country) +{ + QLocaleId localeId = QLocaleId::fromIds(language, script, country); + localeId = localeId.withLikelySubtagsAdded(); + + const uint idx = locale_index[localeId.language_id]; + + // Try a straight match + if (const QLocaleData *const data = findLocaleDataById(localeId)) + return data; + QList tried; + tried.push_back(localeId); + + // No match; try again with likely country + localeId = QLocaleId::fromIds(language, script, QLocale::AnyCountry); + localeId = localeId.withLikelySubtagsAdded(); + if (!tried.contains(localeId)) { + if (const QLocaleData *const data = findLocaleDataById(localeId)) + return data; + tried.push_back(localeId); + } + + // No match; try again with any country + localeId = QLocaleId::fromIds(language, script, QLocale::AnyCountry); + if (!tried.contains(localeId)) { + if (const QLocaleData *const data = findLocaleDataById(localeId)) + return data; + tried.push_back(localeId); + } + + // No match; try again with likely script + localeId = QLocaleId::fromIds(language, QLocale::AnyScript, country); + localeId = localeId.withLikelySubtagsAdded(); + if (!tried.contains(localeId)) { + if (const QLocaleData *const data = findLocaleDataById(localeId)) + return data; + tried.push_back(localeId); + } + + // No match; try again with any script + localeId = QLocaleId::fromIds(language, QLocale::AnyScript, country); + if (!tried.contains(localeId)) { + if (const QLocaleData *const data = findLocaleDataById(localeId)) + return data; + tried.push_back(localeId); + } + + // No match; return data at original index return locale_data + idx; } @@ -1305,8 +1346,8 @@ float QLocale::toFloat(const QString &s, bool *ok) const If \a ok is not 0, reports failure by setting *ok to false and success by setting *ok to true. - Unlike QString::toDouble(), this function does not fall back to - the "C" locale if the string cannot be interpreted in this + Unlike QString::toDouble(), this function does not use + the 'C' locale if the string cannot be interpreted in this locale. \snippet code/src_corelib_tools_qlocale.cpp 3 diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 4dbf95c3154..5225b68d40f 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -982,11 +982,13 @@ QT_BEGIN_INCLUDE_NAMESPACE #include QT_END_INCLUDE_NAMESPACE +#ifndef Q_TEMPLATE_EXTERN #if defined(QT_BUILD_CORE_LIB) #define Q_TEMPLATE_EXTERN #else #define Q_TEMPLATE_EXTERN extern #endif +#endif Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector; Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector; #endif diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index f95cc3a15d6..da7557d7e8f 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -69,6 +69,10 @@ QT_BEGIN_NAMESPACE +#ifdef Q_OS_WIN +static void preventDllUnload(); +#endif + Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager) struct QDBusConnectionManager::ConnectionRequestData @@ -139,6 +143,10 @@ QDBusConnectionManager::QDBusConnectionManager() this, &QDBusConnectionManager::createServer, Qt::BlockingQueuedConnection); moveToThread(this); // ugly, don't do this in other projects +#ifdef Q_OS_WIN + // prevent the library from being unloaded on Windows. See comments in the function. + preventDllUnload(); +#endif defaultBuses[0] = defaultBuses[1] = Q_NULLPTR; start(); } @@ -1262,4 +1270,31 @@ QByteArray QDBusConnection::localMachineId() QT_END_NAMESPACE +#ifdef Q_OS_WIN +# include + +QT_BEGIN_NAMESPACE +static void preventDllUnload() +{ + // Thread termination is really wacky on Windows. For some reason we don't + // understand, exiting from the thread may try to unload the DLL. Since the + // QDBusConnectionManager thread runs until the DLL is unloaded, we've got + // a deadlock: the main thread is waiting for the manager thread to exit, + // but the manager thread is attempting to acquire a lock to unload the DLL. + // + // We work around the issue by preventing the unload from happening in the + // first place. + // + // For this trick, see + // https://blogs.msdn.microsoft.com/oldnewthing/20131105-00/?p=2733 + + static HMODULE self; + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_PIN, + reinterpret_cast(&self), // any address in this DLL + &self); +} +QT_END_NAMESPACE +#endif + #endif // QT_NO_DBUS diff --git a/src/dbus/qdbusxmlparser.cpp b/src/dbus/qdbusxmlparser.cpp index 3618c76a1d3..94223e15744 100644 --- a/src/dbus/qdbusxmlparser.cpp +++ b/src/dbus/qdbusxmlparser.cpp @@ -385,6 +385,11 @@ QDBusXmlParser::QDBusXmlParser(const QString& service, const QString& path, case QXmlStreamReader::Comment: // ignore comments and processing instructions break; + case QXmlStreamReader::Characters: + // ignore whitespace + if (xml.isWhitespace()) + break; + Q_FALLTHROUGH(); default: qDBusParserError() << "unknown token" << xml.name() << xml.tokenString(); break; diff --git a/src/gui/accessible/qaccessibleobject.cpp b/src/gui/accessible/qaccessibleobject.cpp index b67b8062ba8..2ef8502ad55 100644 --- a/src/gui/accessible/qaccessibleobject.cpp +++ b/src/gui/accessible/qaccessibleobject.cpp @@ -125,7 +125,7 @@ QAccessibleInterface *QAccessibleObject::childAt(int x, int y) const for (int i = 0; i < childCount(); ++i) { QAccessibleInterface *childIface = child(i); Q_ASSERT(childIface); - if (childIface->rect().contains(x,y)) + if (childIface->isValid() && childIface->rect().contains(x,y)) return childIface; } return 0; diff --git a/src/gui/configure.json b/src/gui/configure.json index 5ab0b98c69f..02032dee8f0 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -160,8 +160,8 @@ "test": "unix/libpng", "sources": [ { "type": "pkgConfig", "args": "libpng" }, - { "libs": "-llibpng", "condition": "config.msvc" }, - { "libs": "-lpng", "condition": "!config.msvc" } + { "libs": "-llibpng -lzdll", "condition": "config.msvc" }, + { "libs": "-lpng -lz", "condition": "!config.msvc" } ] }, "mirclient": { @@ -331,7 +331,7 @@ "use": "egl xcb_xlib" }, "egl-brcm": { - "label": "Broadcom EGL (Rasberry Pi)", + "label": "Broadcom EGL (Raspberry Pi)", "type": "compile", "test": "qpa/eglfs-brcm", "use": "egl bcm_host" @@ -432,6 +432,7 @@ }, "directfb": { "label": "DirectFB", + "section": "Platform plugins", "autoDetect": false, "condition": "libs.directfb", "output": [ "privateFeature" ] @@ -450,6 +451,7 @@ }, "direct2d": { "label": "Direct 2D", + "section": "Platform plugins", "condition": "config.win32 && !config.winrt && libs.direct2d", "output": [ "privateFeature" ] }, @@ -502,6 +504,7 @@ }, "integrityfb": { "label": "INTEGRITY framebuffer", + "section": "Platform plugins", "condition": "config.integrity", "output": [ "privateFeature" ] }, @@ -528,11 +531,13 @@ }, "linuxfb": { "label": "LinuxFB", + "section": "Platform plugins", "condition": "tests.linuxfb", "output": [ "privateFeature" ] }, "mirclient": { "label": "Mir client", + "section": "Platform plugins", "condition": "libs.mirclient", "output": [ "privateFeature" ] }, @@ -608,12 +613,13 @@ }, "eglfs": { "label": "EGLFS", + "section": "Platform plugins", "autoDetect": "!config.android && !config.win32", "condition": "features.egl", "output": [ "privateFeature" ] }, "eglfs_brcm": { - "label": "EGLFS Rasberry Pi", + "label": "EGLFS Raspberry Pi", "condition": "features.eglfs && tests.egl-brcm", "output": [ "privateFeature" ] }, @@ -644,6 +650,7 @@ }, "gif": { "label": "GIF", + "condition": "features.imageformatplugin", "output": [ "privateFeature", { "type": "define", "negative": true, "name": "QT_NO_IMAGEFORMAT_GIF" } @@ -651,11 +658,13 @@ }, "ico": { "label": "ICO", + "condition": "features.imageformatplugin", "output": [ "privateFeature", "feature" ] }, "jpeg": { "label": "JPEG", "disable": "input.libjpeg == 'no'", + "condition": "features.imageformatplugin", "output": [ "privateFeature", { "type": "define", "negative": true, "name": "QT_NO_IMAGEFORMAT_JPEG" } @@ -705,6 +714,7 @@ }, "xcb": { "label": "XCB", + "section": "Platform plugins", "autoDetect": "!config.darwin", "condition": "libs.xcb", "output": [ "privateFeature" ] diff --git a/src/gui/doc/src/dnd.qdoc b/src/gui/doc/src/dnd.qdoc index 03b3cbfa24a..945c4857058 100644 --- a/src/gui/doc/src/dnd.qdoc +++ b/src/gui/doc/src/dnd.qdoc @@ -343,9 +343,7 @@ Applications can also communicate with each other by putting data on the clipboard. To access this, you need to obtain a QClipboard object - from the QApplication object: - - \snippet ../widgets/widgets/charactermap/mainwindow.cpp 3 + from the QApplication object. The QMimeData class is used to represent data that is transferred to and from the clipboard. To put data on the clipboard, you can use the diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 3438fc0dcd0..2faf9708553 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -757,6 +757,14 @@ void QGuiApplicationPrivate::updateBlockedStatus(QWindow *window) updateBlockedStatusRecursion(window, shouldBeBlocked); } +// Return whether the window needs to be notified about window blocked events. +// As opposed to QGuiApplication::topLevelWindows(), embedded windows are +// included in this list (QTBUG-18099). +static inline bool needsWindowBlockedEvent(const QWindow *w) +{ + return w->isTopLevel() && w->type() != Qt::Desktop; +} + void QGuiApplicationPrivate::showModalWindow(QWindow *modal) { self->modalWindowList.prepend(modal); @@ -774,10 +782,8 @@ void QGuiApplicationPrivate::showModalWindow(QWindow *modal) } } - QWindowList windows = QGuiApplication::topLevelWindows(); - for (int i = 0; i < windows.count(); ++i) { - QWindow *window = windows.at(i); - if (!window->d_func()->blockedByModalWindow) + for (QWindow *window : qAsConst(QGuiApplicationPrivate::window_list)) { + if (needsWindowBlockedEvent(window) && !window->d_func()->blockedByModalWindow) updateBlockedStatus(window); } @@ -788,10 +794,8 @@ void QGuiApplicationPrivate::hideModalWindow(QWindow *window) { self->modalWindowList.removeAll(window); - QWindowList windows = QGuiApplication::topLevelWindows(); - for (int i = 0; i < windows.count(); ++i) { - QWindow *window = windows.at(i); - if (window->d_func()->blockedByModalWindow) + for (QWindow *window : qAsConst(QGuiApplicationPrivate::window_list)) { + if (needsWindowBlockedEvent(window) && window->d_func()->blockedByModalWindow) updateBlockedStatus(window); } } diff --git a/src/gui/kernel/qinputdevicemanager_p.h b/src/gui/kernel/qinputdevicemanager_p.h index 11bbaae592a..db9d0596b6c 100644 --- a/src/gui/kernel/qinputdevicemanager_p.h +++ b/src/gui/kernel/qinputdevicemanager_p.h @@ -79,7 +79,7 @@ public: void setCursorPos(const QPoint &pos); signals: - void deviceListChanged(DeviceType type); + void deviceListChanged(QInputDeviceManager::DeviceType type); void cursorPositionChangeRequested(const QPoint &pos); }; diff --git a/src/gui/kernel/qplatformsystemtrayicon.cpp b/src/gui/kernel/qplatformsystemtrayicon.cpp index 30db966df7a..973b9980594 100644 --- a/src/gui/kernel/qplatformsystemtrayicon.cpp +++ b/src/gui/kernel/qplatformsystemtrayicon.cpp @@ -40,6 +40,9 @@ #include "qplatformsystemtrayicon.h" +#include +#include + #ifndef QT_NO_SYSTEMTRAYICON QT_BEGIN_NAMESPACE @@ -158,11 +161,10 @@ QPlatformSystemTrayIcon::~QPlatformSystemTrayIcon() */ /*! - This method is called in case there is no QPlatformMenu available when - updating the menu. This allows the abstraction to provide a menu for the - system tray icon even if normally a non-native menu is used. - - The default implementation returns a null pointer. + This method allows platforms to use a different QPlatformMenu for system + tray menus than what would normally be used for e.g. menu bars. The default + implementation falls back to a platform menu created by the platform theme, + which may be null on platforms without native menus. \sa updateMenu() \since 5.3 @@ -170,7 +172,7 @@ QPlatformSystemTrayIcon::~QPlatformSystemTrayIcon() QPlatformMenu *QPlatformSystemTrayIcon::createMenu() const { - return Q_NULLPTR; + return QGuiApplicationPrivate::platformTheme()->createPlatformMenu(); } QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp index 931c784d08b..878f656f2e7 100644 --- a/src/gui/kernel/qplatformtheme.cpp +++ b/src/gui/kernel/qplatformtheme.cpp @@ -80,6 +80,10 @@ QT_BEGIN_NAMESPACE \value MouseDoubleClickInterval (int) Mouse double click interval in ms, overriding QPlatformIntegration::styleHint. + \value MouseDoubleClickDistance (int) The maximum distance in logical pixels which the mouse can travel + between clicks in order for the click sequence to be handled as a double click. + The default value is 5 logical pixels. + \value MousePressAndHoldInterval (int) Mouse press and hold interval in ms, overriding QPlatformIntegration::styleHint. @@ -89,6 +93,9 @@ QT_BEGIN_NAMESPACE \value StartDragTime (int) Start drag time in ms, overriding QPlatformIntegration::styleHint. + \value WheelScrollLines (int) The number of lines to scroll a widget, when the mouse wheel is rotated. + The default value is 3. \sa QApplication::wheelScrollLines() + \value KeyboardAutoRepeatRate (int) Keyboard auto repeat rate, overriding QPlatformIntegration::styleHint. diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 2f8a678c38c..6fd2afb1aae 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -60,7 +60,7 @@ QPlatformWindow::QPlatformWindow(QWindow *window) , d_ptr(new QPlatformWindowPrivate) { Q_D(QPlatformWindow); - d->rect = window->geometry(); + d->rect = QHighDpi::toNativePixels(window->geometry(), window); } /*! diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp index a6ce04dc349..fc622733259 100644 --- a/src/gui/kernel/qsimpledrag.cpp +++ b/src/gui/kernel/qsimpledrag.cpp @@ -53,6 +53,8 @@ #include "qdir.h" #include "qimagereader.h" #include "qimagewriter.h" +#include "qplatformscreen.h" +#include "qplatformwindow.h" #include #include @@ -316,6 +318,25 @@ void QBasicDrag::updateCursor(Qt::DropAction action) updateAction(action); } + +static inline QPoint fromNativeGlobalPixels(const QPoint &point) +{ +#ifndef QT_NO_HIGHDPISCALING + QPoint res = point; + if (QHighDpiScaling::isActive()) { + for (const QScreen *s : qAsConst(QGuiApplicationPrivate::screen_list)) { + if (s->handle()->geometry().contains(point)) { + res = QHighDpi::fromNativePixels(point, s); + break; + } + } + } + return res; +#else + return point; +#endif +} + /*! \class QSimpleDrag \brief QSimpleDrag implements QBasicDrag for Drag and Drop operations within the Qt Application itself. @@ -344,7 +365,7 @@ void QSimpleDrag::startDrag() QBasicDrag::startDrag(); m_current_window = topLevelAt(QCursor::pos()); if (m_current_window) { - QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_current_window, drag()->mimeData(), QCursor::pos(), drag()->supportedActions()); + QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_current_window, drag()->mimeData(), QHighDpi::toNativePixels(QCursor::pos(), m_current_window), drag()->supportedActions()); setCanDrop(response.isAccepted()); updateCursor(response.acceptedAction()); } else { @@ -363,15 +384,15 @@ void QSimpleDrag::cancel() } } -void QSimpleDrag::move(const QPoint &globalPos) +void QSimpleDrag::move(const QPoint &nativeGlobalPos) { - //### not high-DPI aware + QPoint globalPos = fromNativeGlobalPixels(nativeGlobalPos); moveShapedPixmapWindow(globalPos); QWindow *window = topLevelAt(globalPos); if (!window) return; - const QPoint pos = globalPos - window->geometry().topLeft(); + const QPoint pos = nativeGlobalPos - window->handle()->geometry().topLeft(); const QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(window, drag()->mimeData(), pos, drag()->supportedActions()); @@ -379,16 +400,16 @@ void QSimpleDrag::move(const QPoint &globalPos) setCanDrop(qt_response.isAccepted()); } -void QSimpleDrag::drop(const QPoint &globalPos) +void QSimpleDrag::drop(const QPoint &nativeGlobalPos) { - //### not high-DPI aware + QPoint globalPos = fromNativeGlobalPixels(nativeGlobalPos); - QBasicDrag::drop(globalPos); + QBasicDrag::drop(nativeGlobalPos); QWindow *window = topLevelAt(globalPos); if (!window) return; - const QPoint pos = globalPos - window->geometry().topLeft(); + const QPoint pos = nativeGlobalPos - window->handle()->geometry().topLeft(); const QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(window, drag()->mimeData(),pos, drag()->supportedActions()); if (response.isAccepted()) { diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 813b0f72bb8..b273682b976 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -962,6 +962,13 @@ Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *window, const QPointF &local, con QWindowSystemInterface::handleMouseEvent(window, timestamp, local * factor, global * factor, b, mods); } +// Wrapper for compatibility with Qt < 5.6 +// ### Qt6: Remove +Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier) +{ + qt_handleMouseEvent(w, local, global, b, mods, QWindowSystemInterfacePrivate::eventTime.elapsed()); +} + Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *window, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1) { QWindowSystemInterface::handleKeyEvent(window, t, k, mods, text, autorep, count); diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp index e61473cb7b6..7e663d48bb1 100644 --- a/src/gui/opengl/qopengl.cpp +++ b/src/gui/opengl/qopengl.cpp @@ -65,6 +65,10 @@ typedef const GLubyte * (QOPENGLF_APIENTRYP qt_glGetStringi)(GLenum, GLuint); QOpenGLExtensionMatcher::QOpenGLExtensionMatcher() { QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (!ctx) { + qWarning("QOpenGLExtensionMatcher::QOpenGLExtensionMatcher: No context"); + return; + } QOpenGLFunctions *funcs = ctx->functions(); const char *extensionStr = 0; @@ -80,19 +84,17 @@ QOpenGLExtensionMatcher::QOpenGLExtensionMatcher() // clear error state while (funcs->glGetError()) {} - if (ctx) { - qt_glGetStringi glGetStringi = (qt_glGetStringi)ctx->getProcAddress("glGetStringi"); + qt_glGetStringi glGetStringi = (qt_glGetStringi)ctx->getProcAddress("glGetStringi"); - if (!glGetStringi) - return; + if (!glGetStringi) + return; - GLint numExtensions = 0; - funcs->glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); + GLint numExtensions = 0; + funcs->glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); - for (int i = 0; i < numExtensions; ++i) { - const char *str = reinterpret_cast(glGetStringi(GL_EXTENSIONS, i)); - m_extensions.insert(str); - } + for (int i = 0; i < numExtensions; ++i) { + const char *str = reinterpret_cast(glGetStringi(GL_EXTENSIONS, i)); + m_extensions.insert(str); } #endif // QT_OPENGL_3 } diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index e4e7c6d1b50..ad8b19a2bcb 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -2196,9 +2196,10 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *c) #ifndef QT_OPENGL_ES_2 // setup fallbacks in case some methods couldn't get resolved - if (!f.ClearDepthf) + bool es = QOpenGLContext::currentContext()->isOpenGLES(); + if (!f.ClearDepthf || !es) f.ClearDepthf = qopenglfSpecialClearDepthf; - if (!f.DepthRangef) + if (!f.DepthRangef || !es) f.DepthRangef = qopenglfSpecialDepthRangef; if (!f.GetShaderPrecisionFormat) f.GetShaderPrecisionFormat = qopenglfSpecialGetShaderPrecisionFormat; diff --git a/src/gui/opengl/qopenglversionfunctions.cpp b/src/gui/opengl/qopenglversionfunctions.cpp index 54df2e57342..a3d3bb6bd18 100644 --- a/src/gui/opengl/qopenglversionfunctions.cpp +++ b/src/gui/opengl/qopenglversionfunctions.cpp @@ -74,15 +74,21 @@ QOpenGLVersionFunctionsStorage::QOpenGLVersionFunctionsStorage() QOpenGLVersionFunctionsStorage::~QOpenGLVersionFunctionsStorage() { +#ifndef QT_OPENGL_ES if (backends) { - for (int i = 0; i < QOpenGLVersionFunctionsBackend::OpenGLVersionBackendCount; ++i) { - if (backends[i] && !--backends[i]->refs) { - // deleting the base class is ok, as the derived classes don't have a destructor - delete backends[i]; - } - } + + int i = 0; + +#define DELETE_BACKEND(X) \ + if (backends[i] && !--backends[i]->refs) \ + delete static_cast(backends[i]); \ + ++i; + + QT_OPENGL_VERSIONS(DELETE_BACKEND) +#undef DELETE_BACKEND delete[] backends; } +#endif } QOpenGLVersionFunctionsBackend *QOpenGLVersionFunctionsStorage::backend(QOpenGLContext *context, QOpenGLVersionFunctionsBackend::Version v) diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp index babe52aa830..02625382506 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.cpp +++ b/src/gui/opengl/qopenglvertexarrayobject.cpp @@ -197,33 +197,59 @@ void QOpenGLVertexArrayObjectPrivate::destroy() { Q_Q(QOpenGLVertexArrayObject); + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + QOpenGLContext *oldContext = 0; + QSurface *oldContextSurface = 0; + QScopedPointer offscreenSurface; + if (context && context != ctx) { + oldContext = ctx; + oldContextSurface = ctx ? ctx->surface() : 0; + // Cannot just make the current surface current again with another context. + // The format may be incompatible and some platforms (iOS) may impose + // restrictions on using a window with different contexts. Create an + // offscreen surface (a pbuffer or a hidden window) instead to be safe. + offscreenSurface.reset(new QOffscreenSurface); + offscreenSurface->setFormat(context->format()); + offscreenSurface->create(); + if (context->makeCurrent(offscreenSurface.data())) { + ctx = context; + } else { + qWarning("QOpenGLVertexArrayObject::destroy() failed to make VAO's context current"); + ctx = 0; + } + } + if (context) { QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed())); context = 0; } - if (!vao) - return; - - switch (vaoFuncsType) { + if (vao) { + switch (vaoFuncsType) { #ifndef QT_OPENGL_ES_2 - case Core_3_2: - vaoFuncs.core_3_2->glDeleteVertexArrays(1, &vao); - break; - case Core_3_0: - vaoFuncs.core_3_0->glDeleteVertexArrays(1, &vao); - break; + case Core_3_2: + vaoFuncs.core_3_2->glDeleteVertexArrays(1, &vao); + break; + case Core_3_0: + vaoFuncs.core_3_0->glDeleteVertexArrays(1, &vao); + break; #endif - case ARB: - case APPLE: - case OES: - vaoFuncs.helper->glDeleteVertexArrays(1, &vao); - break; - default: - break; + case ARB: + case APPLE: + case OES: + vaoFuncs.helper->glDeleteVertexArrays(1, &vao); + break; + default: + break; + } + + vao = 0; } - vao = 0; + if (oldContext && oldContextSurface) { + if (!oldContext->makeCurrent(oldContextSurface)) + qWarning("QOpenGLVertexArrayObject::destroy() failed to restore current context"); + } } /*! @@ -354,37 +380,7 @@ QOpenGLVertexArrayObject::QOpenGLVertexArrayObject(QOpenGLVertexArrayObjectPriva */ QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() { - QOpenGLContext* ctx = QOpenGLContext::currentContext(); - - Q_D(QOpenGLVertexArrayObject); - QOpenGLContext *oldContext = 0; - QSurface *oldContextSurface = 0; - QScopedPointer offscreenSurface; - if (d->context && ctx && d->context != ctx) { - oldContext = ctx; - oldContextSurface = ctx->surface(); - // Cannot just make the current surface current again with another context. - // The format may be incompatible and some platforms (iOS) may impose - // restrictions on using a window with different contexts. Create an - // offscreen surface (a pbuffer or a hidden window) instead to be safe. - offscreenSurface.reset(new QOffscreenSurface); - offscreenSurface->setFormat(d->context->format()); - offscreenSurface->create(); - if (d->context->makeCurrent(offscreenSurface.data())) { - ctx = d->context; - } else { - qWarning("QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() failed to make VAO's context current"); - ctx = 0; - } - } - - if (ctx) - destroy(); - - if (oldContext) { - if (!oldContext->makeCurrent(oldContextSurface)) - qWarning("QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() failed to restore current context"); - } + destroy(); } /*! diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 6a8091bf8b3..9e1785c11d1 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -545,12 +545,8 @@ static QStringList get_colornames() \section1 The HSL Color Model - HSL is similar to HSV. Instead of value parameter from HSV, - HSL has the lightness parameter. - The lightness parameter goes from black to color and from color to white. - If you go outside at the night its black or dark gray. At day its colorful but - if you look in a really strong light a things they are going to white and - wash out. + HSL is similar to HSV, however instead of the Value parameter, HSL + specifies a Lightness parameter. \section1 The CMYK Color Model diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm index 34dfd51204c..2f09037cfe7 100644 --- a/src/gui/painting/qcoregraphics.mm +++ b/src/gui/painting/qcoregraphics.mm @@ -473,6 +473,8 @@ QMacCGContext::QMacCGContext(QPaintDevice *paintDevice) : context(0) context = CGBitmapContextCreate(image->bits(), image->width(), image->height(), 8, image->bytesPerLine(), colorspace, flags); CGContextTranslateCTM(context, 0, image->height()); + const qreal devicePixelRatio = paintDevice->devicePixelRatioF(); + CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio); CGContextScaleCTM(context, 1, -1); } diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 8a9f8b8bdc0..7cf0dd7f039 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -3004,8 +3004,8 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co FetchPixelFunc fetch = qFetchPixel[layout->bpp]; uint sbuf1[buffer_size]; uint sbuf2[buffer_size]; - QRgba64 buf1[buffer_size]; - QRgba64 buf2[buffer_size]; + quint64 buf1[buffer_size]; + quint64 buf2[buffer_size]; QRgba64 *b = buffer; while (length) { int len = qMin(length, buffer_size / 2); @@ -3081,9 +3081,9 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co fx += fdx; } - layout->convertToARGB64PM(buf1, sbuf1, len * 2, clut, 0); + layout->convertToARGB64PM((QRgba64 *)buf1, sbuf1, len * 2, clut, 0); if (disty) - layout->convertToARGB64PM(buf2, sbuf2, len * 2, clut, 0); + layout->convertToARGB64PM((QRgba64 *)buf2, sbuf2, len * 2, clut, 0); for (int i = 0; i < len; ++i) { int distx = (fracX & 0x0000ffff); @@ -3101,7 +3101,7 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8)); _mm_storel_epi64((__m128i*)(b+i), vt); #else - b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty); + b[i] = interpolate_4_pixels_rgb64((QRgba64 *)buf1 + i*2, (QRgba64 *)buf2 + i*2, distx, disty); #endif fracX += fdx; } @@ -3112,8 +3112,8 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co FetchPixelFunc fetch = qFetchPixel[layout->bpp]; uint sbuf1[buffer_size]; uint sbuf2[buffer_size]; - QRgba64 buf1[buffer_size]; - QRgba64 buf2[buffer_size]; + quint64 buf1[buffer_size]; + quint64 buf2[buffer_size]; QRgba64 *end = buffer + length; QRgba64 *b = buffer; @@ -3221,13 +3221,13 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co fx += fdx; fy += fdy; } - layout->convertToARGB64PM(buf1, sbuf1, len * 2, clut, 0); - layout->convertToARGB64PM(buf2, sbuf2, len * 2, clut, 0); + layout->convertToARGB64PM((QRgba64 *)buf1, sbuf1, len * 2, clut, 0); + layout->convertToARGB64PM((QRgba64 *)buf2, sbuf2, len * 2, clut, 0); for (int i = 0; i < len; ++i) { int distx = (fracX & 0x0000ffff); int disty = (fracY & 0x0000ffff); - b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty); + b[i] = interpolate_4_pixels_rgb64((QRgba64 *)buf1 + i*2, (QRgba64 *)buf2 + i*2, distx, disty); fracX += fdx; fracY += fdy; } @@ -3244,8 +3244,8 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co FetchPixelFunc fetch = qFetchPixel[layout->bpp]; uint sbuf1[buffer_size]; uint sbuf2[buffer_size]; - QRgba64 buf1[buffer_size]; - QRgba64 buf2[buffer_size]; + quint64 buf1[buffer_size]; + quint64 buf2[buffer_size]; QRgba64 *b = buffer; int distxs[buffer_size / 2]; @@ -3293,13 +3293,13 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64(QRgba64 *buffer, co fw += fdw; } - layout->convertToARGB64PM(buf1, sbuf1, len * 2, clut, 0); - layout->convertToARGB64PM(buf2, sbuf2, len * 2, clut, 0); + layout->convertToARGB64PM((QRgba64 *)buf1, sbuf1, len * 2, clut, 0); + layout->convertToARGB64PM((QRgba64 *)buf2, sbuf2, len * 2, clut, 0); for (int i = 0; i < len; ++i) { int distx = distxs[i]; int disty = distys[i]; - b[i] = interpolate_4_pixels_rgb64(buf1 + i*2, buf2 + i*2, distx, disty); + b[i] = interpolate_4_pixels_rgb64((QRgba64 *)buf1 + i*2, (QRgba64 *)buf2 + i*2, distx, disty); } length -= len; @@ -3846,7 +3846,7 @@ void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData) return blend_color_generic(count, spans, userData); } - QRgba64 buffer[buffer_size]; + quint64 buffer[buffer_size]; const QRgba64 color = data->solid.color; while (count--) { @@ -3854,7 +3854,7 @@ void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData) int length = spans->len; while (length) { int l = qMin(buffer_size, length); - QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans->y, l); + QRgba64 *dest = op.destFetch64((QRgba64 *)buffer, data->rasterBuffer, x, spans->y, l); op.funcSolid64(dest, l, color, spans->coverage); op.destStore64(data->rasterBuffer, x, spans->y, dest, l); length -= l; @@ -4035,11 +4035,11 @@ public: } }; -class BlendSrcGenericRGB64 : public QBlendBase +class BlendSrcGenericRGB64 : public QBlendBase { public: BlendSrcGenericRGB64(QSpanData *d, const Operator &o) - : QBlendBase(d, o) + : QBlendBase(d, o) { } @@ -4048,20 +4048,20 @@ public: return op.func64 && op.destFetch64 && op.destStore64; } - const QRgba64 *fetch(int x, int y, int len) + const quint64 *fetch(int x, int y, int len) { - dest = op.destFetch64(buffer, data->rasterBuffer, x, y, len); - return op.srcFetch64(src_buffer, &op, data, y, x, len); + dest = (quint64 *)op.destFetch64((QRgba64 *)buffer, data->rasterBuffer, x, y, len); + return (const quint64 *)op.srcFetch64((QRgba64 *)src_buffer, &op, data, y, x, len); } - void process(int, int, int len, int coverage, const QRgba64 *src, int offset) + void process(int, int, int len, int coverage, const quint64 *src, int offset) { - op.func64(dest + offset, src + offset, len, coverage); + op.func64((QRgba64 *)dest + offset, (const QRgba64 *)src + offset, len, coverage); } void store(int x, int y, int len) { - op.destStore64(data->rasterBuffer, x, y, dest, len); + op.destStore64(data->rasterBuffer, x, y, (QRgba64 *)dest, len); } }; @@ -4140,8 +4140,8 @@ static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, voi qWarning("Unsupported blend"); return blend_untransformed_generic(count, spans, userData); } - QRgba64 buffer[buffer_size]; - QRgba64 src_buffer[buffer_size]; + quint64 buffer[buffer_size]; + quint64 src_buffer[buffer_size]; const int image_width = data->texture.width; const int image_height = data->texture.height; @@ -4165,8 +4165,8 @@ static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, voi const int coverage = (spans->coverage * data->texture.const_alpha) >> 8; while (length) { int l = qMin(buffer_size, length); - const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l); - QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans->y, l); + const QRgba64 *src = op.srcFetch64((QRgba64 *)src_buffer, &op, data, sy, sx, l); + QRgba64 *dest = op.destFetch64((QRgba64 *)buffer, data->rasterBuffer, x, spans->y, l); op.func64(dest, src, l, coverage); op.destStore64(data->rasterBuffer, x, spans->y, dest, l); x += l; @@ -4381,8 +4381,8 @@ static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userD qDebug("unsupported rgb64 blend"); return blend_tiled_generic(count, spans, userData); } - QRgba64 buffer[buffer_size]; - QRgba64 src_buffer[buffer_size]; + quint64 buffer[buffer_size]; + quint64 src_buffer[buffer_size]; const int image_width = data->texture.width; const int image_height = data->texture.height; @@ -4409,8 +4409,8 @@ static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userD int l = qMin(image_width - sx, length); if (buffer_size < l) l = buffer_size; - const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l); - QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans->y, l); + const QRgba64 *src = op.srcFetch64((QRgba64 *)src_buffer, &op, data, sy, sx, l); + QRgba64 *dest = op.destFetch64((QRgba64 *)buffer, data->rasterBuffer, x, spans->y, l); op.func64(dest, src, l, coverage); op.destStore64(data->rasterBuffer, x, spans->y, dest, l); x += l; diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 933da560954..e4a1faf25b2 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -64,6 +64,8 @@ #include "private/qrasterdefs_p.h" #include +#include + QT_BEGIN_NAMESPACE #if defined(Q_CC_GNU) @@ -334,7 +336,11 @@ struct QSpanData QGradientData gradient; QTextureData texture; }; - QExplicitlySharedDataPointer cachedGradient; + class Pinnable { + protected: + ~Pinnable() {} + }; // QSharedPointer is not supported + QSharedPointer cachedGradient; void init(QRasterBuffer *rb, const QRasterPaintEngine *pe); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 647bd5cb2c0..43464d5d2c4 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -4182,7 +4182,7 @@ void QRasterBuffer::flushToARGBImage(QImage *target) const class QGradientCache { public: - struct CacheInfo : public QSharedData + struct CacheInfo : QSpanData::Pinnable { inline CacheInfo(QGradientStops s, int op, QGradient::InterpolationMode mode) : stops(qMove(s)), opacity(op), interpolationMode(mode) {} @@ -4193,9 +4193,9 @@ public: QGradient::InterpolationMode interpolationMode; }; - typedef QMultiHash > QGradientColorTableHash; + typedef QMultiHash> QGradientColorTableHash; - inline QExplicitlySharedDataPointer getBuffer(const QGradient &gradient, int opacity) { + inline QSharedPointer getBuffer(const QGradient &gradient, int opacity) { quint64 hash_val = 0; const QGradientStops stops = gradient.stops(); @@ -4209,7 +4209,7 @@ public: return addCacheElement(hash_val, gradient, opacity); else { do { - const QExplicitlySharedDataPointer &cache_info = it.value(); + const auto &cache_info = it.value(); if (cache_info->stops == stops && cache_info->opacity == opacity && cache_info->interpolationMode == gradient.interpolationMode()) return cache_info; ++it; @@ -4225,12 +4225,12 @@ protected: inline void generateGradientColorTable(const QGradient& g, QRgba64 *colorTable, int size, int opacity) const; - QExplicitlySharedDataPointer addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) { + QSharedPointer addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) { if (cache.size() == maxCacheSize()) { // may remove more than 1, but OK cache.erase(cache.begin() + (qrand() % maxCacheSize())); } - QExplicitlySharedDataPointer cache_entry(new CacheInfo (gradient.stops(), opacity, gradient.interpolationMode())); + auto cache_entry = QSharedPointer::create(gradient.stops(), opacity, gradient.interpolationMode()); generateGradientColorTable(gradient, cache_entry->buffer64, paletteSize(), opacity); for (int i = 0; i < GRADIENT_STOPTABLE_SIZE; ++i) cache_entry->buffer32[i] = cache_entry->buffer64[i].toArgb32(); @@ -4470,7 +4470,7 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode const QLinearGradient *g = static_cast(brush.gradient()); gradient.alphaColor = !brush.isOpaque() || alpha != 256; - QExplicitlySharedDataPointer cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha); + auto cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha); cachedGradient = cacheInfo; gradient.colorTable32 = cacheInfo->buffer32; gradient.colorTable64 = cacheInfo->buffer64; @@ -4492,7 +4492,7 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode const QRadialGradient *g = static_cast(brush.gradient()); gradient.alphaColor = !brush.isOpaque() || alpha != 256; - QExplicitlySharedDataPointer cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha); + auto cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha); cachedGradient = cacheInfo; gradient.colorTable32 = cacheInfo->buffer32; gradient.colorTable64 = cacheInfo->buffer64; @@ -4518,7 +4518,7 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode const QConicalGradient *g = static_cast(brush.gradient()); gradient.alphaColor = !brush.isOpaque() || alpha != 256; - QExplicitlySharedDataPointer cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha); + auto cacheInfo = qt_gradient_cache()->getBuffer(*g, alpha); cachedGradient = cacheInfo; gradient.colorTable32 = cacheInfo->buffer32; gradient.colorTable64 = cacheInfo->buffer64; diff --git a/src/gui/painting/qtriangulatingstroker.cpp b/src/gui/painting/qtriangulatingstroker.cpp index d9a32311655..6243f1e2a41 100644 --- a/src/gui/painting/qtriangulatingstroker.cpp +++ b/src/gui/painting/qtriangulatingstroker.cpp @@ -321,7 +321,7 @@ void QTriangulatingStroker::cubicTo(const qreal *pts) if (threshold < 4) threshold = 4; qreal threshold_minus_1 = threshold - 1; - float vx, vy; + float vx = 0, vy = 0; float cx = m_cx, cy = m_cy; float x, y; diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 3b24039ea6a..7f3ed3adaa4 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2077,6 +2077,8 @@ bool QFont::fromString(const QString &descrip) setFixedPitch(l[8].toInt()); if (count == 11) d->request.styleName = l[10].toString(); + else + d->request.styleName.clear(); } if (count >= 9 && !d->request.fixedPitch) // assume 'false' fixedPitch equals default diff --git a/src/gui/text/qtexthtmlparser_p.h b/src/gui/text/qtexthtmlparser_p.h index e93d46a59fa..77bfa685c09 100644 --- a/src/gui/text/qtexthtmlparser_p.h +++ b/src/gui/text/qtexthtmlparser_p.h @@ -243,7 +243,7 @@ struct QTextHtmlParserNode { void parseStyleAttribute(const QString &value, const QTextDocument *resourceProvider); -#ifndef QT_NO_CSSPARSER +#if QT_CONFIG(cssparser) void applyCssDeclarations(const QVector &declarations, const QTextDocument *resourceProvider); void setListStyle(const QVector &cssValues); @@ -317,7 +317,7 @@ protected: bool nodeIsChildOf(int i, QTextHTMLElements id) const; -#ifndef QT_NO_CSSPARSER +#if QT_CONFIG(cssparser) QVector declarationsForNode(int node) const; void resolveStyleSheetImports(const QCss::StyleSheet &sheet); void importStyleSheet(const QString &href); @@ -337,7 +337,9 @@ protected: const QTextDocument *resourceProvider; }; +#if QT_CONFIG(cssparser) Q_DECLARE_TYPEINFO(QTextHtmlParser::ExternalStyleSheet, Q_MOVABLE_TYPE); +#endif QT_END_NAMESPACE diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index d8ce28a7b02..094fd36637d 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -1083,8 +1083,8 @@ void QHttpNetworkConnectionChannel::_q_encrypted() "detected unknown Next Protocol Negotiation protocol"); break; } - Q_FALLTHROUGH(); } + Q_FALLTHROUGH(); case QSslConfiguration::NextProtocolNegotiationNone: protocolHandler.reset(new QHttpProtocolHandler(this)); connection->setConnectionType(QHttpNetworkConnection::ConnectionTypeHTTP); diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index 2da073fa5a2..a903ecda5fe 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -40,8 +40,6 @@ #include "qnetworkconfigmanager_p.h" #include "qbearerplugin_p.h" -#include - #include #include #include @@ -60,7 +58,9 @@ QT_BEGIN_NAMESPACE QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate() - : QObject(), pollTimer(0), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true) + : QObject(), pollTimer(0), mutex(QMutex::Recursive), + loader(QBearerEngineFactoryInterface_iid, QLatin1String("/bearer")), + forcedPolling(0), firstUpdate(true) { qRegisterMetaType(); qRegisterMetaType(); @@ -365,7 +365,6 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() bool envOK = false; const int skipGeneric = qEnvironmentVariableIntValue("QT_EXCLUDE_GENERIC_BEARER", &envOK); QBearerEngine *generic = 0; - static QFactoryLoader loader(QBearerEngineFactoryInterface_iid, QLatin1String("/bearer")); QFactoryLoader *l = &loader; const PluginKeyMap keyMap = l->keyMap(); const PluginKeyMapConstIterator cend = keyMap.constEnd(); diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h index a804e037a30..380e25c22f7 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.h +++ b/src/network/bearer/qnetworkconfigmanager_p.h @@ -55,6 +55,7 @@ #include "qnetworkconfigmanager.h" #include "qnetworkconfiguration_p.h" +#include #include #include @@ -118,6 +119,7 @@ private: private: mutable QMutex mutex; + QFactoryLoader loader; QList sessionEngines; QSet onlineConfigurations; diff --git a/src/network/configure.pri b/src/network/configure.pri index 57568902e41..f87b7f635fa 100644 --- a/src/network/configure.pri +++ b/src/network/configure.pri @@ -7,6 +7,7 @@ defineTest(qtConfLibrary_openssl) { export($${1}.libs) return(true) } + qtLog("$OPENSSL_LIBS is not set.") return(false) } diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index 1a960e4f7dd..5efd80619cc 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -282,21 +282,27 @@ bool QNetmaskAddress::setAddress(const QHostAddress &address) d->clear(); return false; // invalid IP-style netmask - // the rest always falls through case 254: ++netmask; + Q_FALLTHROUGH(); case 252: ++netmask; + Q_FALLTHROUGH(); case 248: ++netmask; + Q_FALLTHROUGH(); case 240: ++netmask; + Q_FALLTHROUGH(); case 224: ++netmask; + Q_FALLTHROUGH(); case 192: ++netmask; + Q_FALLTHROUGH(); case 128: ++netmask; + Q_FALLTHROUGH(); case 0: break; } @@ -1233,11 +1239,25 @@ QDebug operator<<(QDebug d, const QHostAddress &address) } #endif +/*! + \since 5.0 + \relates QHostAddress + Returns a hash of the host address \a key, using \a seed to seed the calculation. +*/ uint qHash(const QHostAddress &key, uint seed) Q_DECL_NOTHROW { return qHashBits(key.d->a6.c, 16, seed); } +/*! + \relates QHostAddress + \fn operator==(QHostAddress::SpecialAddress lhs, const QHostAddress &rhs) + + Returns \c true if special address \a lhs is the same as host address \a rhs; + otherwise returns \c false. + + \sa isEqual() +*/ #ifndef QT_NO_DATASTREAM /*! \relates QHostAddress diff --git a/src/network/kernel/qnetworkdatagram.cpp b/src/network/kernel/qnetworkdatagram.cpp index ba8a063edff..88ca7631875 100644 --- a/src/network/kernel/qnetworkdatagram.cpp +++ b/src/network/kernel/qnetworkdatagram.cpp @@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE /*! \class QNetworkDatagram - \brief The QNetworkDatagram class provides the data and matadata of a UDP datagram. + \brief The QNetworkDatagram class provides the data and metadata of a UDP datagram. \since 5.8 \ingroup network \inmodule QtNetwork diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index bed4355aa97..312c9346324 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -309,10 +309,8 @@ bool QLocalSocket::flush() { Q_D(QLocalSocket); bool written = false; - if (d->pipeWriter) { - while (d->pipeWriter->waitForWrite(0)) - written = true; - } + while (d->pipeWriter && d->pipeWriter->waitForWrite(0)) + written = true; return written; } diff --git a/src/network/ssl/qssldiffiehellmanparameters.cpp b/src/network/ssl/qssldiffiehellmanparameters.cpp index d0fcb3189a3..de7eab9a9e1 100644 --- a/src/network/ssl/qssldiffiehellmanparameters.cpp +++ b/src/network/ssl/qssldiffiehellmanparameters.cpp @@ -68,6 +68,12 @@ QT_BEGIN_NAMESPACE +// The 1024-bit MODP group from RFC 2459 (Second Oakley Group) +Q_AUTOTEST_EXPORT const char *qssl_dhparams_default_base64 = + "MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR" + "Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL" + "/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC"; + /*! Returns the default QSslDiffieHellmanParameters used by QSslSocket. @@ -76,15 +82,9 @@ QT_BEGIN_NAMESPACE */ QSslDiffieHellmanParameters QSslDiffieHellmanParameters::defaultParameters() { - // The 1024-bit MODP group from RFC 2459 (Second Oakley Group) - return fromEncoded( - QByteArray::fromBase64(QByteArrayLiteral( - "MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR" - "Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL" - "/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC" - )), - QSsl::Der - ); + QSslDiffieHellmanParameters def; + def.d->derData = QByteArray::fromBase64(QByteArray(qssl_dhparams_default_base64)); + return def; } /*! diff --git a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc index f0ef5ee2a7e..fab473b91b7 100644 --- a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc +++ b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc @@ -106,7 +106,7 @@ \fn void QXcbWindowFunctions::setWmWindowRole(QWindow *window, const QByteArray &role) \since 5.6.2 - Sets the WM_WINDOW_ROLE property from \role on the corresponding + Sets the WM_WINDOW_ROLE property from \a role on the corresponding X11 window. This is a convenience function that can be used directly instead diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp index a5779fc2910..ab1fc9d647b 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp @@ -1154,7 +1154,7 @@ void QWindowsFontDatabase::populateFamily(const QString &familyName) ReleaseDC(0, dummy); } -static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TEXTMETRIC *, +static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TEXTMETRIC *textmetric, DWORD, LPARAM) { // the "@family" fonts are just the same as "family". Ignore them. @@ -1163,6 +1163,13 @@ static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TE if (faceNameW[0] && faceNameW[0] != L'@' && wcsncmp(faceNameW, L"WST_", 4)) { const QString faceName = QString::fromWCharArray(faceNameW); QPlatformFontDatabase::registerFontFamily(faceName); + // Register current font's english name as alias + const bool ttf = (textmetric->tmPitchAndFamily & TMPF_TRUETYPE); + if (ttf && qt_localizedName(faceName)) { + const QString englishName = qt_getEnglishName(faceName); + if (!englishName.isEmpty()) + QPlatformFontDatabase::registerAliasToFontFamily(faceName, englishName); + } } return 1; // continue } @@ -1178,7 +1185,9 @@ void QWindowsFontDatabase::populateFontDatabase() EnumFontFamiliesEx(dummy, &lf, populateFontFamilies, 0, 0); ReleaseDC(0, dummy); // Work around EnumFontFamiliesEx() not listing the system font. - QPlatformFontDatabase::registerFontFamily(QWindowsFontDatabase::systemDefaultFont().family()); + QString systemDefaultFamily = QWindowsFontDatabase::systemDefaultFont().family(); + if (QPlatformFontDatabase::resolveFontFamilyAlias(systemDefaultFamily).isEmpty()) + QPlatformFontDatabase::registerFontFamily(systemDefaultFamily); } typedef QSharedPointer QWindowsFontEngineDataPtr; diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp index df84198862c..ebb82baf6f5 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp @@ -362,8 +362,15 @@ static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TE if (!key && ttf && qt_localizedName(faceName)) key = findFontKey(qt_getEnglishName(faceName)); } - if (key) + if (key) { QPlatformFontDatabase::registerFontFamily(faceName); + // Register current font's english name as alias + if (ttf && qt_localizedName(faceName)) { + const QString englishName = qt_getEnglishName(faceName); + if (!englishName.isEmpty()) + QPlatformFontDatabase::registerAliasToFontFamily(faceName, englishName); + } + } } return 1; // continue } @@ -378,7 +385,9 @@ void QWindowsFontDatabaseFT::populateFontDatabase() EnumFontFamiliesEx(dummy, &lf, populateFontFamilies, 0, 0); ReleaseDC(0, dummy); // Work around EnumFontFamiliesEx() not listing the system font - QPlatformFontDatabase::registerFontFamily(QWindowsFontDatabase::systemDefaultFont().family()); + QString systemDefaultFamily = QWindowsFontDatabase::systemDefaultFont().family(); + if (QPlatformFontDatabase::resolveFontFamilyAlias(systemDefaultFamily).isEmpty()) + QPlatformFontDatabase::registerFontFamily(systemDefaultFamily); } QFontEngine * QWindowsFontDatabaseFT::fontEngine(const QFontDef &fontDef, void *handle) diff --git a/src/platformsupport/input/input.pro b/src/platformsupport/input/input.pro index 2c2ace67806..f8ff4344cfd 100644 --- a/src/platformsupport/input/input.pro +++ b/src/platformsupport/input/input.pro @@ -11,7 +11,9 @@ qtConfig(evdev) { include($$PWD/evdevmouse/evdevmouse.pri) include($$PWD/evdevkeyboard/evdevkeyboard.pri) include($$PWD/evdevtouch/evdevtouch.pri) - include($$PWD/evdevtablet/evdevtablet.pri) + qtConfig(tabletevent) { + include($$PWD/evdevtablet/evdevtablet.pri) + } } qtConfig(tslib) { diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenubar.cpp b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenubar.cpp index 76d658f51a1..fb0705c8c74 100644 --- a/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenubar.cpp +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusmenubar.cpp @@ -59,6 +59,8 @@ QDBusMenuBar::QDBusMenuBar() m_menuAdaptor, &QDBusMenuAdaptor::ItemsPropertiesUpdated); connect(m_menu, &QDBusPlatformMenu::updated, m_menuAdaptor, &QDBusMenuAdaptor::LayoutUpdated); + connect(m_menu, &QDBusPlatformMenu::popupRequested, + m_menuAdaptor, &QDBusMenuAdaptor::ItemActivationRequested); } QDBusMenuBar::~QDBusMenuBar() diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu.cpp b/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu.cpp index 15440a03cd8..c1ebbbf91bb 100644 --- a/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu.cpp +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu.cpp @@ -39,6 +39,7 @@ #include "qdbusplatformmenu_p.h" +#include #include #include @@ -210,6 +211,8 @@ void QDBusPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem) this, &QDBusPlatformMenu::propertiesUpdated); disconnect(menu, &QDBusPlatformMenu::updated, this, &QDBusPlatformMenu::updated); + disconnect(menu, &QDBusPlatformMenu::popupRequested, + this, &QDBusPlatformMenu::popupRequested); } emitUpdated(); } @@ -222,6 +225,8 @@ void QDBusPlatformMenu::syncSubMenu(const QDBusPlatformMenu *menu) this, &QDBusPlatformMenu::propertiesUpdated, Qt::UniqueConnection); connect(menu, &QDBusPlatformMenu::updated, this, &QDBusPlatformMenu::updated, Qt::UniqueConnection); + connect(menu, &QDBusPlatformMenu::popupRequested, + this, &QDBusPlatformMenu::popupRequested, Qt::UniqueConnection); } void QDBusPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem) @@ -278,6 +283,15 @@ void QDBusPlatformMenu::setContainingMenuItem(QDBusPlatformMenuItem *item) m_containingMenuItem = item; } +void QDBusPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) +{ + Q_UNUSED(parentWindow); + Q_UNUSED(targetRect); + Q_UNUSED(item); + setVisible(true); + emit popupRequested(m_containingMenuItem->dbusID(), QDateTime::currentMSecsSinceEpoch()); +} + QPlatformMenuItem *QDBusPlatformMenu::menuItemAt(int position) const { return m_items.value(position); diff --git a/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h b/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h index 38c27e80517..2e6e04d28d4 100644 --- a/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h +++ b/src/platformsupport/themes/genericunix/dbusmenu/qdbusplatformmenu_p.h @@ -161,13 +161,7 @@ public: void setMenuType(MenuType type) Q_DECL_OVERRIDE { Q_UNUSED(type); } void setContainingMenuItem(QDBusPlatformMenuItem *item); - void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) Q_DECL_OVERRIDE - { - Q_UNUSED(parentWindow); - Q_UNUSED(targetRect); - Q_UNUSED(item); - setVisible(true); - } + void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) Q_DECL_OVERRIDE; void dismiss() Q_DECL_OVERRIDE { } // Closes this and all its related menu popups @@ -187,6 +181,7 @@ public: signals: void updated(uint revision, int dbusId); void propertiesUpdated(QDBusMenuItemList updatedProps, QDBusMenuItemKeysList removedProps); + void popupRequested(int id, uint timestamp); private: quintptr m_tag; diff --git a/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp b/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp index 5c4157c206c..b55ace357a5 100644 --- a/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp +++ b/src/platformsupport/themes/genericunix/dbustray/qdbustrayicon.cpp @@ -171,6 +171,12 @@ QTemporaryFile *QDBusTrayIcon::tempIcon(const QIcon &icon) uint pid = session.interface()->servicePid(KDEWatcherService).value(); QString processName = QLockFilePrivate::processNameByPid(pid); necessary = processName.endsWith(QLatin1String("indicator-application-service")); + if (!necessary && QGuiApplication::desktopSettingsAware()) { + // Accessing to process name might be not allowed if the application + // is confined, thus we can just rely on the current desktop in use + const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services(); + necessary = services->desktopEnvironment().split(':').contains("UNITY"); + } necessity_checked = true; } if (!necessary) diff --git a/src/plugins/bearer/generic/qgenericengine.cpp b/src/plugins/bearer/generic/qgenericengine.cpp index 02ea7abf889..059617b3676 100644 --- a/src/plugins/bearer/generic/qgenericengine.cpp +++ b/src/plugins/bearer/generic/qgenericengine.cpp @@ -37,6 +37,9 @@ ** ****************************************************************************/ +// see comment in ../platformdefs_win.h. +#define WIN32_LEAN_AND_MEAN 1 + #include "qgenericengine.h" #include "../qnetworksession_impl.h" diff --git a/src/plugins/bearer/platformdefs_win.h b/src/plugins/bearer/platformdefs_win.h index 8fb2f1bcc5c..5a8487d868a 100644 --- a/src/plugins/bearer/platformdefs_win.h +++ b/src/plugins/bearer/platformdefs_win.h @@ -40,6 +40,8 @@ #ifndef QPLATFORMDEFS_WIN_H #define QPLATFORMDEFS_WIN_H +// Since we need to include winsock2.h, we need to define WIN32_LEAN_AND_MEAN +// somewhere above so windows.h won't include winsock.h. #include #include #undef interface diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp index 5ce51670f7f..7756709e55c 100644 --- a/src/plugins/bearer/qnetworksession_impl.cpp +++ b/src/plugins/bearer/qnetworksession_impl.cpp @@ -37,6 +37,9 @@ ** ****************************************************************************/ +// see comment in ../platformdefs_win.h. +#define WIN32_LEAN_AND_MEAN 1 + #include "qnetworksession_impl.h" #include "qbearerengine_impl.h" diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 12e85046f84..4ab8a9d0603 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -354,10 +354,10 @@ static QRect inputItemRectangle() ? QHighDpiScaling::factor(window) : QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen()); if (pixelDensity != 1.0) { - rect.setX(rect.x() * pixelDensity); - rect.setY(rect.y() * pixelDensity); - rect.setWidth(rect.width() * pixelDensity); - rect.setHeight(rect.height() * pixelDensity); + rect.setRect(rect.x() * pixelDensity, + rect.y() * pixelDensity, + rect.width() * pixelDensity, + rect.height() * pixelDensity); } return rect; } diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 97bd402b732..e743dd56bf5 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -235,19 +235,19 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of if (!iface || !iface->isValid()) return nil; + if (QAccessibleInterface *parent = iface->parent()) { + QAccessible::Id parentId = QAccessible::uniqueId(parent); + return [QMacAccessibilityElement elementWithId: parentId]; + } + if (QWindow *window = iface->window()) { - QCocoaWindow *win = static_cast(window->handle()); - return qnsview_cast(win->view()); + QPlatformWindow *platformWindow = window->handle(); + if (platformWindow) { + QCocoaWindow *win = static_cast(platformWindow); + return qnsview_cast(win->view()); + } } - - QAccessibleInterface *parent = iface->parent(); - if (!parent) { - qWarning() << "INVALID PARENT FOR INTERFACE: " << iface; - return nil; - } - - QAccessible::Id parentId = QAccessible::uniqueId(parent); - return [QMacAccessibilityElement elementWithId: parentId]; + return nil; } @@ -537,7 +537,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (void)accessibilityPerformAction:(NSString *)action { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (iface) { + if (iface && iface->isValid()) { const QString qtAction = QCocoaAccessible::translateAction(action, iface); QAccessibleBridgeUtils::performEffectiveAction(iface, qtAction); } @@ -562,16 +562,16 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of int y = qt_mac_flipYCoordinate(point.y); QAccessibleInterface *childInterface = iface->childAt(point.x, y); // No child found, meaning we hit this element. - if (!childInterface) + if (!childInterface || !childInterface->isValid()) return NSAccessibilityUnignoredAncestor(self); // find the deepest child at the point QAccessibleInterface *childOfChildInterface = 0; do { childOfChildInterface = childInterface->childAt(point.x, y); - if (childOfChildInterface) + if (childOfChildInterface && childOfChildInterface->isValid()) childInterface = childOfChildInterface; - } while (childOfChildInterface); + } while (childOfChildInterface && childOfChildInterface->isValid()); QAccessible::Id childId = QAccessible::uniqueId(childInterface); // hit a child, forward to child accessible interface. @@ -590,7 +590,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of } QAccessibleInterface *childInterface = iface->focusChild(); - if (childInterface) { + if (childInterface && childInterface->isValid()) { QAccessible::Id childAxid = QAccessible::uniqueId(childInterface); QMacAccessibilityElement *accessibleElement = [QMacAccessibilityElement elementWithId:childAxid]; return NSAccessibilityUnignoredAncestor(accessibleElement); diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.mm b/src/plugins/platforms/cocoa/qcocoakeymapper.mm index e7952ae1f63..1ef7f110117 100644 --- a/src/plugins/platforms/cocoa/qcocoakeymapper.mm +++ b/src/plugins/platforms/cocoa/qcocoakeymapper.mm @@ -366,7 +366,9 @@ Qt::KeyboardModifiers QCocoaKeyMapper::queryKeyboardModifiers() bool QCocoaKeyMapper::updateKeyboard() { const UCKeyboardLayout *uchrData = 0; - QCFType source = TISCopyCurrentKeyboardInputSource(); + QCFType source = TISCopyInputMethodKeyboardLayoutOverride(); + if (!source) + source = TISCopyCurrentKeyboardInputSource(); if (keyboard_mode != NullMode && source == currentInputSource) { return false; } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 43817febd49..fe24f95db42 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -749,7 +749,7 @@ void QCocoaWindow::setVisible(bool visible) if (cocoaEventDispatcher) cocoaEventDispatcherPrivate = static_cast(QObjectPrivate::get(cocoaEventDispatcher)); - if (!(cocoaEventDispatcherPrivate && cocoaEventDispatcherPrivate->currentModalSession())) + if (cocoaEventDispatcherPrivate && cocoaEventDispatcherPrivate->cocoaModalSessionStack.isEmpty()) [m_nsWindow makeKeyAndOrderFront:nil]; else [m_nsWindow orderFront:nil]; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 689fd06d66a..7ce407f7d0f 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -754,9 +754,6 @@ static bool _q_dontOverrideCtrlLMB = false; if (masked) return false; - if (button == Qt::RightButton) - m_sendUpAsRightButton = true; - m_buttons |= button; [self handleMouseEvent:theEvent]; @@ -2094,7 +2091,8 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin } NSPoint windowPoint = [self.window convertRectFromScreen:NSMakeRect(screenPoint.x, screenPoint.y, 1, 1)].origin; - QPoint qtWindowPoint(windowPoint.x, windowPoint.y); + NSPoint nsViewPoint = [self convertPoint: windowPoint fromView: nil]; // NSView/QWindow coordinates + QPoint qtWindowPoint(nsViewPoint.x, nsViewPoint.y); QPoint qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y)); diff --git a/src/plugins/platforms/windows/qwin10helpers.cpp b/src/plugins/platforms/windows/qwin10helpers.cpp index 977bbfd11b1..12cccd124b4 100644 --- a/src/plugins/platforms/windows/qwin10helpers.cpp +++ b/src/plugins/platforms/windows/qwin10helpers.cpp @@ -57,7 +57,7 @@ #endif #ifdef HAS_UI_VIEW_SETTINGS_INTEROP -# include +# include #endif #ifndef HAS_UI_VIEW_SETTINGS_INTEROP diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 4248d5685e9..fefc848d019 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -1013,11 +1013,18 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::MouseWheelEvent: case QtWindows::MouseEvent: case QtWindows::LeaveEvent: + { + QWindow *window = platformWindow->window(); + while (window->flags() & Qt::WindowTransparentForInput) + window = window->parent(); + if (!window) + return false; #if !defined(QT_NO_SESSIONMANAGER) - return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); + return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result); #else - return d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); + return d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result); #endif + } case QtWindows::TouchEvent: #if !defined(QT_NO_SESSIONMANAGER) return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result); diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 6375f89531c..ab806fd3ea5 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -701,7 +701,8 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 quint32 fallbackKey = winceKeyBend(vk_key); if (!fallbackKey || fallbackKey == Qt::Key_unknown) { fallbackKey = 0; - if (vk_key != keyLayout[vk_key].qtKey[0] && vk_key < 0x5B && vk_key > 0x2F) + if (vk_key != keyLayout[vk_key].qtKey[0] && vk_key != keyLayout[vk_key].qtKey[1] + && vk_key < 0x5B && vk_key > 0x2F) fallbackKey = vk_key; } keyLayout[vk_key].qtKey[8] = fallbackKey; diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index 81349f2998f..81abf24131c 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -306,7 +306,8 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, // events, "click-through") can be considered as the window under mouse. QWindow *currentWindowUnderMouse = platformWindow->hasMouseCapture() ? QWindowsScreen::windowAt(globalPosition, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT) : window; - + while (currentWindowUnderMouse && currentWindowUnderMouse->flags() & Qt::WindowTransparentForInput) + currentWindowUnderMouse = currentWindowUnderMouse->parent(); // QTBUG-44332: When Qt is running at low integrity level and // a Qt Window is parented on a Window of a higher integrity process // using QWindow::fromWinId() (for example, Qt running in a browser plugin) @@ -425,22 +426,10 @@ static bool isValidWheelReceiver(QWindow *candidate) static void redirectWheelEvent(QWindow *window, const QPoint &globalPos, int delta, Qt::Orientation orientation, Qt::KeyboardModifiers mods) { - // Redirect wheel event to one of the following, in order of preference: - // 1) The window under mouse - // 2) The window receiving the event // If a window is blocked by modality, it can't get the event. - - QWindow *receiver = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE); - bool handleEvent = true; - if (!isValidWheelReceiver(receiver)) { - receiver = window; - if (!isValidWheelReceiver(receiver)) - handleEvent = false; - } - - if (handleEvent) { - QWindowSystemInterface::handleWheelEvent(receiver, - QWindowsGeometryHint::mapFromGlobal(receiver, globalPos), + if (isValidWheelReceiver(window)) { + QWindowSystemInterface::handleWheelEvent(window, + QWindowsGeometryHint::mapFromGlobal(window, globalPos), globalPos, delta, orientation, mods); } } diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index fa2fe6942a6..c38e96bdb7d 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -181,14 +181,30 @@ QWindowsScreen::QWindowsScreen(const QWindowsScreenData &data) : Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0); -QPixmap QWindowsScreen::grabWindow(WId window, int x, int y, int width, int height) const +QPixmap QWindowsScreen::grabWindow(WId window, int xIn, int yIn, int width, int height) const { - RECT r; - HWND hwnd = window ? reinterpret_cast(window) : GetDesktopWindow(); - GetClientRect(hwnd, &r); + QSize windowSize; + int x = xIn; + int y = yIn; + HWND hwnd = reinterpret_cast(window); + if (hwnd) { + RECT r; + GetClientRect(hwnd, &r); + windowSize = QSize(r.right - r.left, r.bottom - r.top); + } else { + // Grab current screen. The client rectangle of GetDesktopWindow() is the + // primary screen, but it is possible to grab other screens from it. + hwnd = GetDesktopWindow(); + const QRect screenGeometry = geometry(); + windowSize = screenGeometry.size(); + x += screenGeometry.x(); + y += screenGeometry.y(); + } - if (width < 0) width = r.right - r.left; - if (height < 0) height = r.bottom - r.top; + if (width < 0) + width = windowSize.width() - xIn; + if (height < 0) + height = windowSize.height() - yIn; // Create and setup bitmap HDC display_dc = GetDC(0); diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 5edf40b886a..96027f8e0a3 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -43,7 +43,7 @@ #include "qwindowsscreen.h" #include "qwindowsintegration.h" #include "qwindowsnativeinterface.h" -#include "qwindowsopenglcontext.h" +#include "qwindowsglcontext.h" #ifdef QT_NO_CURSOR # include "qwindowscursor.h" #endif @@ -1300,6 +1300,12 @@ void QWindowsWindow::updateTransientParent() const if (const QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(tp)) if (!tw->testFlag(WithinDestroy)) // Prevent destruction by parent window (QTBUG-35499, QTBUG-36666) newTransientParent = tw->handle(); + + // QTSOLBUG-71: When using the MFC/winmigrate solution, it is possible that a child + // window is found, which can cause issues with modality. Loop up to top level. + while (newTransientParent && (GetWindowLongPtr(newTransientParent, GWL_STYLE) & WS_CHILD) != 0) + newTransientParent = GetParent(newTransientParent); + if (newTransientParent != oldTransientParent) SetWindowLongPtr(m_data.hwnd, GWL_HWNDPARENT, LONG_PTR(newTransientParent)); } @@ -1609,6 +1615,16 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, return false; PAINTSTRUCT ps; +#if QT_CONFIG(dynamicgl) + // QTBUG-58178: GL software rendering needs InvalidateRect() to suppress + // artifacts while resizing. + if (testFlag(OpenGLSurface) + && QOpenGLStaticContext::opengl32.moduleIsNotOpengl32() + && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { + InvalidateRect(hwnd, 0, false); + } +#endif // dynamicgl + BeginPaint(hwnd, &ps); // Observed painting problems with Aero style disabled (QTBUG-7865). diff --git a/src/plugins/platforms/winrt/main.cpp b/src/plugins/platforms/winrt/main.cpp index 5d0d9e94ebc..222287b3ef7 100644 --- a/src/plugins/platforms/winrt/main.cpp +++ b/src/plugins/platforms/winrt/main.cpp @@ -49,15 +49,9 @@ class QWinRTIntegrationPlugin : public QPlatformIntegrationPlugin Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "winrt.json") public: - QStringList keys() const; QPlatformIntegration *create(const QString&, const QStringList&) override; }; -QStringList QWinRTIntegrationPlugin::keys() const -{ - return QStringList(QStringLiteral("WinRT")); -} - QPlatformIntegration *QWinRTIntegrationPlugin::create(const QString& system, const QStringList& paramList) { Q_UNUSED(paramList); diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 2834ff32245..915c29edcc6 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -417,7 +417,7 @@ void QXcbConnection::initializeScreens() qWarning("failed to get the current screen resources"); free(error); } else { - xcb_timestamp_t timestamp; + xcb_timestamp_t timestamp = 0; xcb_randr_output_t *outputs = Q_NULLPTR; int outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources_current.data()); if (outputCount) { diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 3754890796e..19c076e8882 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -517,6 +517,7 @@ public: #ifdef XCB_USE_XINPUT22 bool xi2MouseEvents() const; + bool isTouchScreen(int id) const; #endif protected: diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 0ace79a4f56..d91cbfe82d2 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -1025,6 +1025,14 @@ Qt::MouseButton QXcbConnection::xiToQtMouseButton(uint32_t b) return Qt::NoButton; } +bool QXcbConnection::isTouchScreen(int id) const +{ + auto device = m_touchDevices.value(id); + return device && device->qtTouchDevice + && device->qtTouchDevice->type() == QTouchDevice::TouchScreen; +} + +#if QT_CONFIG(tabletevent) static QTabletEvent::TabletDevice toolIdToTabletDevice(quint32 toolId) { // keep in sync with wacom_intuos_inout() in Linux kernel driver wacom_wac.c switch (toolId) { @@ -1058,7 +1066,6 @@ static QTabletEvent::TabletDevice toolIdToTabletDevice(quint32 toolId) { return QTabletEvent::Stylus; // Safe default assumption if nonzero } -#ifndef QT_NO_TABLETEVENT bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletData) { bool handled = true; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 0275cf56303..2d52f5dd468 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -315,6 +315,7 @@ static const char *wm_window_role_property_id = "_q_xcb_wm_window_role"; QXcbWindow::QXcbWindow(QWindow *window) : QPlatformWindow(window) , m_window(0) + , m_cmap(0) , m_syncCounter(0) , m_gravity(XCB_GRAVITY_STATIC) , m_mapped(false) @@ -443,7 +444,6 @@ void QXcbWindow::create() m_visualId = visual->visual_id; m_depth = platformScreen->depthOfVisual(m_visualId); m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap); - xcb_colormap_t colormap = 0; quint32 mask = XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL @@ -455,10 +455,10 @@ void QXcbWindow::create() static const bool haveOpenGL = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL); if ((window()->supportsOpenGL() && haveOpenGL) || m_format.hasAlpha()) { - colormap = xcb_generate_id(xcb_connection()); + m_cmap = xcb_generate_id(xcb_connection()); Q_XCB_CALL(xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, - colormap, + m_cmap, xcb_parent_id, m_visualId)); @@ -472,7 +472,7 @@ void QXcbWindow::create() type == Qt::Popup || type == Qt::ToolTip || (window()->flags() & Qt::BypassWindowManagerHint), type == Qt::Popup || type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip || type == Qt::Drawer, defaultEventMask, - colormap + m_cmap }; m_window = xcb_generate_id(xcb_connection()); @@ -638,6 +638,9 @@ void QXcbWindow::destroy() Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window)); m_window = 0; } + if (m_cmap) { + xcb_free_colormap(xcb_connection(), m_cmap); + } m_mapped = false; if (m_pendingSyncRequest) @@ -2420,22 +2423,27 @@ static inline int fixed1616ToInt(FP1616 val) return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF); } -void QXcbWindow::handleXIMouseButtonState(const xcb_ge_event_t *event) -{ - QXcbConnection *conn = connection(); - const xXIDeviceEvent *ev = reinterpret_cast(event); - if (ev->buttons_len > 0) { - unsigned char *buttonMask = (unsigned char *) &ev[1]; - for (int i = 1; i <= 15; ++i) - conn->setButton(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i)); - } -} - // With XI 2.2+ press/release/motion comes here instead of the above handlers. void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source) { QXcbConnection *conn = connection(); xXIDeviceEvent *ev = reinterpret_cast(event); + + if (ev->buttons_len > 0) { + unsigned char *buttonMask = (unsigned char *) &ev[1]; + // There is a bug in the evdev driver which leads to receiving mouse events without + // XIPointerEmulated being set: https://bugs.freedesktop.org/show_bug.cgi?id=98188 + // Filter them out by other attributes: when their source device is a touch screen + // and the LMB is pressed. + if (XIMaskIsSet(buttonMask, 1) && conn->isTouchScreen(ev->sourceid)) { + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) + qCDebug(lcQpaXInput, "XI2 mouse event from touch device %d was ignored", ev->sourceid); + return; + } + for (int i = 1; i <= 15; ++i) + conn->setButton(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i)); + } + const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective_mods); const int event_x = fixed1616ToInt(ev->event_x); const int event_y = fixed1616ToInt(ev->event_y); @@ -2455,23 +2463,18 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource switch (ev->evtype) { case XI_ButtonPress: - handleXIMouseButtonState(event); if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) qCDebug(lcQpaXInputEvents, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName); conn->setButton(button, true); handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source); break; case XI_ButtonRelease: - handleXIMouseButtonState(event); if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) qCDebug(lcQpaXInputEvents, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName); conn->setButton(button, false); handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source); break; case XI_Motion: - // Here we do NOT call handleXIMouseButtonState because we don't expect button state change to be bundled with motion. - // When a touchscreen is pressed, an XI_Motion event occurs in which XIMaskIsSet says the left button is pressed, - // but we don't want QGuiApplicationPrivate::processMouseEvent() to react by generating a mouse press event. if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) qCDebug(lcQpaXInputEvents, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName); handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, source); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 41befbf66f3..680629c040e 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -139,7 +139,6 @@ public: void handleFocusOutEvent(const xcb_focus_out_event_t *event) override; void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) override; #ifdef XCB_USE_XINPUT22 - void handleXIMouseButtonState(const xcb_ge_event_t *); void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized) override; void handleXIEnterLeave(xcb_ge_event_t *) override; #endif @@ -235,6 +234,7 @@ protected: quint8 mode, quint8 detail, xcb_timestamp_t timestamp); xcb_window_t m_window; + xcb_colormap_t m_cmap; uint m_depth; QImage::Format m_imageFormat; diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 941c25361ff..620d9cb8c91 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -1,7 +1,7 @@ TEMPLATE = subdirs QT_FOR_CONFIG += network -SUBDIRS *= sqldrivers +qtHaveModule(sql): SUBDIRS += sqldrivers qtHaveModule(network):qtConfig(bearermanagement): SUBDIRS += bearer qtHaveModule(gui) { SUBDIRS *= platforms platforminputcontexts platformthemes diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp index 0bea9ebfa12..7cfa5544186 100644 --- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp +++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp @@ -699,10 +699,8 @@ QVariant QMYSQLResult::data(int field) } if(ok) return v; - else - return QVariant(); + return QVariant(); } - return QVariant(val.toDouble()); case QVariant::Date: return qDateFromString(val); case QVariant::Time: @@ -719,12 +717,11 @@ QVariant QMYSQLResult::data(int field) } return QVariant(ba); } - default: case QVariant::String: + default: return QVariant(val); } - qWarning("QMYSQLResult::data: unknown data type"); - return QVariant(); + Q_UNREACHABLE(); } bool QMYSQLResult::isNull(int field) diff --git a/src/plugins/sqldrivers/oci/qsql_oci.cpp b/src/plugins/sqldrivers/oci/qsql_oci.cpp index 47d6db7ea46..32d3681a178 100644 --- a/src/plugins/sqldrivers/oci/qsql_oci.cpp +++ b/src/plugins/sqldrivers/oci/qsql_oci.cpp @@ -2405,16 +2405,16 @@ static QString make_where_clause(const QString &user, Expression e) static const char joinC[][4] = { "or" , "and" }; static Q_CONSTEXPR QLatin1Char bang[] = { QLatin1Char(' '), QLatin1Char('!') }; - const QLatin1String join(joinC[e], -1); // -1: force strlen call + const QLatin1String join(joinC[e]); QString result; result.reserve(sizeof sysUsers / sizeof *sysUsers * // max-sizeof(owner != and ) (9 + sizeof *sysUsers + 5)); for (const auto &sysUser : sysUsers) { - const QLatin1String l1(sysUser, -1); // -1: force strlen call + const QLatin1String l1(sysUser); if (l1 != user) - result += QLatin1String("owner ") + bang[e] + QLatin1String("= '") + l1 + QLatin1Char(' ') + join + QLatin1Char(' '); + result += QLatin1String("owner ") + bang[e] + QLatin1String("= '") + l1 + QLatin1String("' ") + join + QLatin1Char(' '); } result.chop(join.size() + 2); // remove final " " diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index bcc03636814..53bed87dfce 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -2200,4 +2200,8 @@ QPrinter::PrintRange QPrinter::printRange() const QT_END_NAMESPACE +#elif defined(Q_OS_WINRT) +QT_BEGIN_NAMESPACE +bool Q_PRINTSUPPORT_EXPORT qt_winrt_export_lib_creation_variable; +QT_END_NAMESPACE #endif // QT_NO_PRINTER diff --git a/src/sql/configure.pri b/src/sql/configure.pri index 62d56e21864..a8bc09e5240 100644 --- a/src/sql/configure.pri +++ b/src/sql/configure.pri @@ -26,6 +26,7 @@ defineTest(qtConfLibrary_psqlConfig) { export($${1}.includedir) return(true) } + qtLog("pg_config not found.") return(false) } @@ -74,6 +75,7 @@ defineTest(qtConfLibrary_mysqlConfig) { export($${1}.includedir) return(true) } + qtLog("mysql_config not found.") return(false) } diff --git a/src/src.pro b/src/src.pro index 9f3dbfa7121..f57b57b6eea 100644 --- a/src/src.pro +++ b/src/src.pro @@ -124,7 +124,6 @@ src_printsupport.depends = src_corelib src_gui src_widgets src_tools_uic src_plugins.subdir = $$PWD/plugins src_plugins.target = sub-plugins -src_plugins.depends = src_sql src_xml src_network src_android.subdir = $$PWD/android @@ -144,7 +143,16 @@ qtConfig(regularexpression):pcre2 { SUBDIRS += src_corelib src_tools_qlalr TOOLS = src_tools_moc src_tools_rcc src_tools_qlalr win32:SUBDIRS += src_winmain -SUBDIRS += src_network src_sql src_xml src_testlib +qtConfig(network) { + SUBDIRS += src_network + src_plugins.depends += src_network +} +qtConfig(sql) { + SUBDIRS += src_sql + src_plugins.depends += src_sql +} +qtConfig(xml): SUBDIRS += src_xml +qtConfig(testlib): SUBDIRS += src_testlib qtConfig(dbus) { force_dbus_bootstrap|qtConfig(private_tests): \ SUBDIRS += src_tools_bootstrap_dbus diff --git a/src/testlib/3rdparty/CALLGRIND_LICENSE.txt b/src/testlib/3rdparty/VALGRIND_LICENSE.txt similarity index 94% rename from src/testlib/3rdparty/CALLGRIND_LICENSE.txt rename to src/testlib/3rdparty/VALGRIND_LICENSE.txt index 0a6a7934226..714b75e6d19 100644 --- a/src/testlib/3rdparty/CALLGRIND_LICENSE.txt +++ b/src/testlib/3rdparty/VALGRIND_LICENSE.txt @@ -1,6 +1,4 @@ - This file is part of callgrind, a valgrind tool for cache simulation - and call tree tracing. - + Copyright (C) 2000-2007 Julian Seward Copyright (C) 2003-2007 Josef Weidendorfer. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/testlib/3rdparty/qt_attribution.json b/src/testlib/3rdparty/qt_attribution.json index d8b0ad1fc70..49d12580bd2 100644 --- a/src/testlib/3rdparty/qt_attribution.json +++ b/src/testlib/3rdparty/qt_attribution.json @@ -1,17 +1,18 @@ [ { - "Id": "callgrind", - "Name": "Callgrind", + "Id": "valgrind", + "Name": "Valgrind", "QDocModule": "qttestlib", "QtUsage": "Used on Linux ond MacOS in the Qt Test module.", "Files": "valgrind_p.h callgrind_p.h", - "Description": "Part of Valgrind: an instrumentation framework for building dynamic analysis tools.", + "Description": "An instrumentation framework for building dynamic analysis tools.", "Homepage": "http://valgrind.org/", "License": "BSD 4-clause \"Original\" or \"Old\" License", "LicenseId": "BSD-4-Clause", - "LicenseFile": "CALLGRIND_LICENSE.txt", - "Copyright": "Copyright (C) 2003-2007 Josef Weidendorfer. All rights reserved." + "LicenseFile": "VALGRIND_LICENSE.txt", + "Copyright": "Copyright (C) 2000-2007 Julian Seward +Copyright (C) 2003-2007 Josef Weidendorfer." }, { "Id": "cycle", diff --git a/src/testlib/qtestmouse.h b/src/testlib/qtestmouse.h index 11433613237..166622e9508 100644 --- a/src/testlib/qtestmouse.h +++ b/src/testlib/qtestmouse.h @@ -73,6 +73,11 @@ namespace QTest extern Q_TESTLIB_EXPORT Qt::MouseButton lastMouseButton; extern Q_TESTLIB_EXPORT int lastMouseTimestamp; + // This value is used to emulate timestamps to avoid creating double clicks by mistake. + // Use this constant instead of QStyleHints::mouseDoubleClickInterval property to avoid tests + // to depend on platform themes. + static const int mouseDoubleClickInterval = 500; + static void waitForEvents() { #ifdef Q_OS_MAC @@ -125,7 +130,7 @@ namespace QTest Q_FALLTHROUGH(); case MouseRelease: qt_handleMouseEvent(w, pos, global, Qt::NoButton, stateKey, ++lastMouseTimestamp); - lastMouseTimestamp += 500; // avoid double clicks being generated + lastMouseTimestamp += mouseDoubleClickInterval; // avoid double clicks being generated lastMouseButton = Qt::NoButton; break; case MouseMove: @@ -176,8 +181,10 @@ namespace QTest if (delay == -1 || delay < defaultMouseDelay()) delay = defaultMouseDelay(); - if (delay > 0) + if (delay > 0) { QTest::qWait(delay); + lastMouseTimestamp += delay; + } if (action == MouseClick) { mouseEvent(MousePress, widget, button, stateKey, pos); @@ -194,12 +201,16 @@ namespace QTest { case MousePress: me = QMouseEvent(QEvent::MouseButtonPress, pos, widget->mapToGlobal(pos), button, button, stateKey); + me.setTimestamp(++lastMouseTimestamp); break; case MouseRelease: me = QMouseEvent(QEvent::MouseButtonRelease, pos, widget->mapToGlobal(pos), button, Qt::MouseButton(), stateKey); + me.setTimestamp(++lastMouseTimestamp); + lastMouseTimestamp += mouseDoubleClickInterval; // avoid double clicks being generated break; case MouseDClick: me = QMouseEvent(QEvent::MouseButtonDblClick, pos, widget->mapToGlobal(pos), button, button, stateKey); + me.setTimestamp(++lastMouseTimestamp); break; case MouseMove: QCursor::setPos(widget->mapToGlobal(pos)); diff --git a/src/testlib/testlib.pro b/src/testlib/testlib.pro index 5b2205e875e..e84651ccd5d 100644 --- a/src/testlib/testlib.pro +++ b/src/testlib/testlib.pro @@ -111,4 +111,6 @@ mac { !qtHaveModule(widgets): HEADERSCLEAN_EXCLUDE += qtest_widgets.h +!qtHaveModule(network): HEADERSCLEAN_EXCLUDE += qtest_network.h + load(qt_module) diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 89bf2bd6a12..03f022da695 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -197,6 +197,7 @@ Type Moc::parseType() prev(); break; } + Q_FALLTHROUGH(); case CHAR: case SHORT: case INT: diff --git a/src/tools/moc/parser.h b/src/tools/moc/parser.h index ee8761108b9..bedcbbf7e26 100644 --- a/src/tools/moc/parser.h +++ b/src/tools/moc/parser.h @@ -68,8 +68,8 @@ public: inline QByteArray unquotedLexem() { return symbols.at(index-1).unquotedLexem();} inline const Symbol &symbol() { return symbols.at(index-1);} - void error(int rollback); - void error(const char *msg = 0); + Q_NORETURN void error(int rollback); + Q_NORETURN void error(const char *msg = 0); void warning(const char * = 0); void note(const char * = 0); diff --git a/src/widgets/configure.json b/src/widgets/configure.json index 1e72b61886d..8acbffef6ad 100644 --- a/src/widgets/configure.json +++ b/src/widgets/configure.json @@ -86,6 +86,7 @@ "label": "QFileSystemModel", "purpose": "Provides a data model for the local filesystem.", "section": "File I/O", + "condition": "features.itemmodel", "output": [ "publicFeature", "feature" ] }, "itemviews": { diff --git a/src/widgets/doc/snippets/code/src_gui_util_qcompleter.cpp b/src/widgets/doc/snippets/code/src_gui_util_qcompleter.cpp index 284a4ce4046..7d003e4886d 100644 --- a/src/widgets/doc/snippets/code/src_gui_util_qcompleter.cpp +++ b/src/widgets/doc/snippets/code/src_gui_util_qcompleter.cpp @@ -62,7 +62,7 @@ lineEdit->setCompleter(completer); //! [1] QCompleter *completer = new QCompleter(this); -completer->setModel(new QDirModel(completer)); +completer->setModel(new QFileSystemModel(completer)); lineEdit->setCompleter(completer); //! [1] diff --git a/src/widgets/doc/src/model-view-programming.qdoc b/src/widgets/doc/src/model-view-programming.qdoc index e727d7fe56f..84819e8c1ab 100644 --- a/src/widgets/doc/src/model-view-programming.qdoc +++ b/src/widgets/doc/src/model-view-programming.qdoc @@ -2070,9 +2070,22 @@ Normally, the begin and end functions are capable of informing other components about changes to the model's underlying structure. For more complex changes to the - model's structure, perhaps involving internal reorganization or sorting of data, - it is necessary to emit the \l{QAbstractItemModel::layoutChanged()}{layoutChanged()} - signal to cause any attached views to be updated. + model's structure, perhaps involving internal reorganization, sorting of data or + any other structural change, it is necessary to perform the following sequence: + + \li Emit the \l{QAbstractItemModel::layoutAboutToBeChanged()}{layoutAboutToBeChanged()} signal + \li Update internal data which represents the structure of the model. + \li Update persistent indexes using \l{QAbstractItemModel::changePersistentIndexList()}{changePersistentIndexList()} + \li Emit the \l{QAbstractItemModel::layoutChanged()}{layoutChanged()} signal. + + This sequence can be used for any structural update in lieu of the more + high-level and convenient protected methods. For example, if a model of + two million rows needs to have all odd numbered rows removed, that + is 1 million discountiguous ranges of 1 element each. It would be + possible to use beginRemoveRows and endRemoveRows 1 million times, but + that would obviously be inefficient. Instead, this can be signalled as a + single layout change which updates all necessary persistent indexes at + once. \section3 Lazy population of model data diff --git a/src/widgets/doc/src/modelview.qdoc b/src/widgets/doc/src/modelview.qdoc index 4a53ea5cbd7..1c0bb5195ac 100644 --- a/src/widgets/doc/src/modelview.qdoc +++ b/src/widgets/doc/src/modelview.qdoc @@ -83,7 +83,7 @@ Model/View is a technology used to separate data from views in widgets that handle data sets. Standard widgets are not designed for separating data - from views and this is why Qt 4 has two different types of widgets. Both + from views and this is why Qt has two different types of widgets. Both types of widgets look the same, but they interact with data differently. \table diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 837383f016d..1310a060eac 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -3857,6 +3857,20 @@ bool QHeaderViewPrivate::read(QDataStream &in) if (sectionItemsLengthTotal != lengthIn) return false; + const int currentCount = (orient == Qt::Horizontal ? model->columnCount(root) : model->rowCount(root)); + if (newSectionItems.count() < currentCount) { + // we have sections not in the saved state, give them default settings + for (int i = newSectionItems.count(); i < currentCount; ++i) { + visualIndicesIn.append(i); + logicalIndicesIn.append(i); + } + const int insertCount = currentCount - newSectionItems.count(); + const int insertLength = defaultSectionSizeIn * insertCount; + lengthIn += insertLength; + SectionItem section(defaultSectionSizeIn, globalResizeMode); + newSectionItems.insert(newSectionItems.count(), insertCount, section); // append + } + orientation = static_cast(orient); sortIndicatorOrder = static_cast(order); sortIndicatorSection = sortIndicatorSectionIn; diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 2f1f699bca4..45c547d3134 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -2370,7 +2370,7 @@ QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) c { if (flowPositions.isEmpty() || segmentPositions.isEmpty() - || index.row() >= flowPositions.count()) + || index.row() >= flowPositions.count() - 1) return QListViewItem(); const int segment = qBinarySearch(segmentStartRows, index.row(), diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 6258605a656..c6d59907a03 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3290,7 +3290,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(), wheel->modifiers(), phase, wheel->source(), wheel->inverted()); bool eventAccepted; - while (w) { + do { we.spont = spontaneous && w == receiver; we.ignore(); res = d->notify_helper(w, &we); @@ -3308,7 +3308,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) we.p += w->pos(); w = w->parentWidget(); - } + } while (w); wheel->setAccepted(eventAccepted); } else if (!spontaneous) { // wheel_widget may forward the wheel event to a delegate widget, @@ -4482,9 +4482,13 @@ void QApplicationPrivate::notifyThemeChanged() #ifndef QT_NO_DRAGANDDROP void QApplicationPrivate::notifyDragStarted(const QDrag *drag) { - // Prevent pickMouseReceiver() from using the widget where the drag was started after a drag operation. QGuiApplicationPrivate::notifyDragStarted(drag); - qt_button_down = 0; + // QTBUG-26145 + // Prevent pickMouseReceiver() from using the widget where the drag was started after a drag operation... + // QTBUG-56713 + // ...only if qt_button_down is not a QQuickWidget + if (qt_button_down && !qt_button_down->inherits("QQuickWidget")) + qt_button_down = nullptr; } #endif // QT_NO_DRAGANDDROP diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp index 6eec5ff7e87..be5788274e2 100644 --- a/src/widgets/kernel/qshortcut.cpp +++ b/src/widgets/kernel/qshortcut.cpp @@ -141,9 +141,11 @@ bool qWidgetShortcutContextMatcher(QObject *object, Qt::ShortcutContext context) static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidget *active_window) { bool visible = w->isVisible(); -#if defined(Q_OS_DARWIN) && !defined(QT_NO_MENUBAR) - if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast(w)) - visible = true; +#ifndef QT_NO_MENUBAR + if (QMenuBar *menuBar = qobject_cast(w)) { + if (menuBar->isNativeMenuBar()) + visible = true; + } #endif if (!visible || !w->isEnabled()) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 61956b3fa49..759821a0578 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -2526,10 +2526,6 @@ QWidget *QWidget::find(WId id) If a widget is non-native (alien) and winId() is invoked on it, that widget will be provided a native handle. - On \macos, the type returned depends on which framework Qt was linked - against. If Qt is using Carbon, the {WId} is actually an HIViewRef. If Qt - is using Cocoa, {WId} is a pointer to an NSView. - This value may change at run-time. An event with type QEvent::WinIdChange will be sent to the widget following a change in window system identifier. @@ -9988,8 +9984,8 @@ bool QWidget::nativeEvent(const QByteArray &eventType, void *message, long *resu } /*! - Ensures that the widget has been polished by QStyle (i.e., has a - proper font and palette). + Ensures that the widget and its children have been polished by + QStyle (i.e., have a proper font and palette). QWidget calls this function after it has been fully constructed but before it is shown the very first time. You can call this diff --git a/src/widgets/styles/qandroidstyle.cpp b/src/widgets/styles/qandroidstyle.cpp index b37dffbe800..110153d0f65 100644 --- a/src/widgets/styles/qandroidstyle.cpp +++ b/src/widgets/styles/qandroidstyle.cpp @@ -1606,15 +1606,14 @@ void QAndroidStyle::AndroidProgressBarControl::drawControl(const QStyleOption *o if (!m_progressDrawable) return; - if (const QStyleOptionProgressBar *progressBarOption = - qstyleoption_cast(option)) { + if (const QStyleOptionProgressBar *pb = qstyleoption_cast(option)) { if (m_progressDrawable->type() == QAndroidStyle::Layer) { - const double fraction = progressBarOption->progress / double(progressBarOption->maximum - progressBarOption->minimum); + const double fraction = double(qint64(pb->progress) - pb->minimum) / (qint64(pb->maximum) - pb->minimum); QAndroidStyle::AndroidDrawable *clipDrawable = static_cast(m_progressDrawable)->layer(m_progressId); if (clipDrawable->type() == QAndroidStyle::Clip) - static_cast(clipDrawable)->setFactor(fraction, progressBarOption->orientation); + static_cast(clipDrawable)->setFactor(fraction, pb->orientation); else - static_cast(m_progressDrawable)->setFactor(m_progressId, fraction, progressBarOption->orientation); + static_cast(m_progressDrawable)->setFactor(m_progressId, fraction, pb->orientation); } m_progressDrawable->draw(p, option); } diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 70af751fd38..54cc82bea98 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -1352,10 +1352,11 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio } int maxWidth = rect.width(); - int minWidth = 0; - qreal progress = qMax(bar->progress, bar->minimum); // workaround for bug in QProgressBar - int progressBarWidth = (progress - bar->minimum) * qreal(maxWidth) / qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum); - int width = indeterminate ? maxWidth : qMax(minWidth, progressBarWidth); + const auto progress = qMax(bar->progress, bar->minimum); // workaround for bug in QProgressBar + const auto totalSteps = qMax(Q_INT64_C(1), qint64(bar->maximum) - bar->minimum); + const auto progressSteps = qint64(progress) - bar->minimum; + const auto progressBarWidth = progressSteps * maxWidth / totalSteps; + int width = indeterminate ? maxWidth : progressBarWidth; bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical; if (inverted) @@ -1450,8 +1451,9 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio inverted = bar->invertedAppearance; if (vertical) rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height - const int progressIndicatorPos = (bar->progress - qreal(bar->minimum)) * rect.width() / - qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum); + const auto totalSteps = qMax(Q_INT64_C(1), qint64(bar->maximum) - bar->minimum); + const auto progressSteps = qint64(bar->progress) - bar->minimum; + const auto progressIndicatorPos = progressSteps * rect.width() / totalSteps; if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width()) leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height()); if (vertical) diff --git a/src/widgets/styles/qpixmapstyle.cpp b/src/widgets/styles/qpixmapstyle.cpp index e973a96a910..ce37065fb6e 100644 --- a/src/widgets/styles/qpixmapstyle.cpp +++ b/src/widgets/styles/qpixmapstyle.cpp @@ -819,11 +819,14 @@ void QPixmapStyle::drawProgressBarFill(const QStyleOption *option, drawCachedPixmap(vertical ? PB_VComplete : PB_HComplete, option->rect, painter); } else { - if (pbar->progress == 0) + if (pbar->progress == pbar->minimum) return; - const int maximum = pbar->maximum; - const qreal ratio = qreal(vertical?option->rect.height():option->rect.width())/maximum; - const int progress = pbar->progress*ratio; + const auto totalSteps = qint64(pbar->maximum) - pbar->minimum; + const auto progressSteps = qint64(pbar->progress) - pbar->minimum; + const auto availablePixels = vertical ? option->rect.height() : option->rect.width(); + const auto pixelsPerStep = double(availablePixels) / totalSteps; + + const auto progress = static_cast(progressSteps * pixelsPerStep); // width in pixels QRect optRect = option->rect; if (vertical) { diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index d63c96bf0ec..68ee8c22d33 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -3903,8 +3903,8 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if (inverted) reverse = !reverse; const bool indeterminate = pb->minimum == pb->maximum; - qreal fillRatio = indeterminate ? 0.50 : qreal(progress - minimum)/(maximum - minimum); - int fillWidth = int(rect.width() * fillRatio); + const auto fillRatio = indeterminate ? 0.50 : double(progress - minimum) / (maximum - minimum); + const auto fillWidth = static_cast(rect.width() * fillRatio); int chunkWidth = fillWidth; if (subRule.hasContentsSize()) { QSize sz = subRule.size(); diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index d6a4016e4cf..972deef1502 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -1872,8 +1872,7 @@ QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption case CT_MenuBarItem: if (!sz.isEmpty()) sz += QSize(windowsItemHMargin * 5 + 1, 5); - return sz; - break; + return sz; #endif case CT_ItemViewItem: sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget); diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index 64daad87aef..225c47052bc 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -473,7 +473,10 @@ bool QBalloonTip::isBalloonVisible() QBalloonTip::QBalloonTip(const QIcon &icon, const QString &title, const QString &message, QSystemTrayIcon *ti) - : QWidget(0, Qt::ToolTip), trayIcon(ti), timerId(-1) + : QWidget(0, Qt::ToolTip), + trayIcon(ti), + timerId(-1), + showArrow(true) { setAttribute(Qt::WA_DeleteOnClose); QObject::connect(ti, SIGNAL(destroyed()), this, SLOT(close())); diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp index cfca5787cb3..3d21320655a 100644 --- a/src/widgets/util/qundostack.cpp +++ b/src/widgets/util/qundostack.cpp @@ -724,10 +724,12 @@ void QUndoStack::setClean() This method resets the clean index to -1. This is typically called in the following cases, when a document has been: + \list \li created basing on some template and has not been saved, so no filename has been associated with the document yet. \li restored from a backup file. \li changed outside of the editor and the user did not reload it. + \endlist \sa isClean(), setClean(), cleanIndex() */ diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index 63f8172bf61..ad19e5d5f96 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -266,6 +266,16 @@ bool QDockAreaLayoutInfo::isEmpty() const return next(-1) == -1; } +bool QDockAreaLayoutInfo::onlyHasPlaceholders() const +{ + for (const QDockAreaLayoutItem &item : item_list) { + if (!item.placeHolderItem) + return false; + } + + return true; +} + QSize QDockAreaLayoutInfo::minimumSize() const { if (isEmpty()) diff --git a/src/widgets/widgets/qdockarealayout_p.h b/src/widgets/widgets/qdockarealayout_p.h index f22a3d2de2c..21787283f49 100644 --- a/src/widgets/widgets/qdockarealayout_p.h +++ b/src/widgets/widgets/qdockarealayout_p.h @@ -167,6 +167,7 @@ public: void clear(); bool isEmpty() const; + bool onlyHasPlaceholders() const; bool hasFixedSize() const; QList findSeparator(const QPoint &pos) const; int next(int idx) const; diff --git a/src/widgets/widgets/qkeysequenceedit.cpp b/src/widgets/widgets/qkeysequenceedit.cpp index 2fbc42330da..3252ce59414 100644 --- a/src/widgets/widgets/qkeysequenceedit.cpp +++ b/src/widgets/widgets/qkeysequenceedit.cpp @@ -257,7 +257,8 @@ void QKeySequenceEdit::keyPressEvent(QKeyEvent *e) if (nextKey == Qt::Key_Control || nextKey == Qt::Key_Shift || nextKey == Qt::Key_Meta - || nextKey == Qt::Key_Alt) { + || nextKey == Qt::Key_Alt + || nextKey == Qt::Key_unknown) { return; } diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index aef8b9cbd51..14d7f3d835c 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -1030,12 +1030,19 @@ bool QMainWindowLayoutState::restoreState(QDataStream &_stream, Qt::Horizontal, QTabBar::RoundedSouth, mainWindow); QRect geometry; stream >> geometry; - if (!floatingTab->layoutInfo()->restoreState(stream, dockWidgets, false)) + QDockAreaLayoutInfo *info = floatingTab->layoutInfo(); + if (!info->restoreState(stream, dockWidgets, false)) return false; geometry = QDockAreaLayout::constrainedRect(geometry, floatingTab); floatingTab->move(geometry.topLeft()); floatingTab->resize(geometry.size()); - floatingTab->show(); + + // Don't show an empty QDockWidgetGroupWindow if no dock widget is available yet. + // reparentWidgets() would be triggered by show(), so do it explicitly here. + if (info->onlyHasPlaceholders()) + info->reparentWidgets(floatingTab); + else + floatingTab->show(); } break; #endif // QT_NO_TABBAR diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 36a8a96b79e..2917083415b 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -1507,7 +1507,7 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) When inserting action items you usually specify a receiver and a slot. The receiver will be notifed whenever the item is \l{QAction::triggered()}{triggered()}. In addition, QMenu provides - two signals, activated() and highlighted(), which signal the + two signals, triggered() and hovered(), which signal the QAction that was triggered from the menu. You clear a menu with clear() and remove individual action items diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index ce43740524c..2a76f1e8a02 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -1267,10 +1267,12 @@ void QMenuBar::actionEvent(QActionEvent *e) } else if(e->type() == QEvent::ActionRemoved) { e->action()->disconnect(this); } - if (isVisible()) { + // updateGeometries() is also needed for native menu bars because + // it updates shortcutIndexMap + if (isVisible() || isNativeMenuBar()) d->updateGeometries(); + if (isVisible()) update(); - } } /*! @@ -1683,6 +1685,13 @@ void QMenuBarPrivate::_q_internalShortcutActivated(int id) { Q_Q(QMenuBar); QAction *act = actions.at(id); + if (act && act->menu()) { + if (QPlatformMenu *platformMenu = act->menu()->platformMenu()) { + platformMenu->showPopup(q->windowHandle(), actionRects.at(id), Q_NULLPTR); + return; + } + } + setCurrentAction(act, true, true); if (act && !act->menu()) { activateAction(act, QAction::Trigger); diff --git a/src/widgets/widgets/qprogressbar.cpp b/src/widgets/widgets/qprogressbar.cpp index 10f005e6d30..64f19047b61 100644 --- a/src/widgets/widgets/qprogressbar.cpp +++ b/src/widgets/widgets/qprogressbar.cpp @@ -144,16 +144,17 @@ bool QProgressBarPrivate::repaintRequired() const if (value == lastPaintedValue) return false; - int valueDifference = qAbs(value - lastPaintedValue); - + const auto valueDifference = qAbs(qint64(value) - lastPaintedValue); // Check if the text needs to be repainted if (value == minimum || value == maximum) return true; + + const auto totalSteps = qint64(maximum) - minimum; if (textVisible) { if ((format.contains(QLatin1String("%v")))) return true; if ((format.contains(QLatin1String("%p")) - && valueDifference >= qAbs((maximum - minimum) / 100))) + && valueDifference >= qAbs(totalSteps / 100))) return true; } @@ -166,7 +167,7 @@ bool QProgressBarPrivate::repaintRequired() const // (valueDifference / (maximum - minimum) > cw / groove.width()) // transformed to avoid integer division. int grooveBlock = (q->orientation() == Qt::Horizontal) ? groove.width() : groove.height(); - return (valueDifference * grooveBlock > cw * (maximum - minimum)); + return valueDifference * grooveBlock > cw * totalSteps; } /*! @@ -260,9 +261,10 @@ QProgressBar::~QProgressBar() void QProgressBar::reset() { Q_D(QProgressBar); - d->value = d->minimum - 1; if (d->minimum == INT_MIN) d->value = INT_MIN; + else + d->value = d->minimum - 1; repaint(); } @@ -358,7 +360,7 @@ void QProgressBar::setRange(int minimum, int maximum) d->minimum = minimum; d->maximum = qMax(minimum, maximum); - if (d->value < (d->minimum - 1) || d->value > d->maximum) + if (d->value < qint64(d->minimum) - 1 || d->value > d->maximum) reset(); else update(); @@ -479,11 +481,11 @@ QString QProgressBar::text() const // progress bar has one step and that we are on that step. Return // 100% here in order to avoid division by zero further down. if (totalSteps == 0) { - result.replace(QLatin1String("%p"), locale.toString(int(100))); + result.replace(QLatin1String("%p"), locale.toString(100)); return result; } - int progress = (qreal(d->value) - d->minimum) * 100.0 / totalSteps; + const auto progress = static_cast((qint64(d->value) - d->minimum) * 100.0 / totalSteps); result.replace(QLatin1String("%p"), locale.toString(progress)); return result; } diff --git a/tests/auto/corelib/animation/qpauseanimation/tst_qpauseanimation.cpp b/tests/auto/corelib/animation/qpauseanimation/tst_qpauseanimation.cpp index 25b62160754..290c2abc986 100644 --- a/tests/auto/corelib/animation/qpauseanimation/tst_qpauseanimation.cpp +++ b/tests/auto/corelib/animation/qpauseanimation/tst_qpauseanimation.cpp @@ -40,6 +40,16 @@ #ifdef BAD_TIMER_RESOLUTION static const char timerError[] = "On this platform, consistent timing is not working properly due to bad timer resolution"; + +# define WAIT_FOR_STOPPED(animation, duration) \ + QTest::qWait(duration); \ + if (animation.state() != QAbstractAnimation::Stopped) \ + QEXPECT_FAIL("", timerError, Abort); \ + QCOMPARE(animation.state(), QAbstractAnimation::Stopped) +#else +// Use QTRY_COMPARE with one additional timer tick +# define WAIT_FOR_STOPPED(animation, duration) \ + QTRY_COMPARE_WITH_TIMEOUT(animation.state(), QAbstractAnimation::Stopped, (duration)) #endif class TestablePauseAnimation : public QPauseAnimation @@ -108,11 +118,10 @@ void tst_QPauseAnimation::changeDirectionWhileRunning() TestablePauseAnimation animation; animation.setDuration(400); animation.start(); - QTest::qWait(100); - QCOMPARE(animation.state(), QAbstractAnimation::Running); + QTRY_COMPARE(animation.state(), QAbstractAnimation::Running); animation.setDirection(QAbstractAnimation::Backward); - QTest::qWait(animation.totalDuration() + 50); - QCOMPARE(animation.state(), QAbstractAnimation::Stopped); + const int expectedDuration = animation.totalDuration() + 100; + WAIT_FOR_STOPPED(animation, expectedDuration); } void tst_QPauseAnimation::noTimerUpdates_data() @@ -137,14 +146,9 @@ void tst_QPauseAnimation::noTimerUpdates() animation.setDuration(duration); animation.setLoopCount(loopCount); animation.start(); - QTest::qWait(animation.totalDuration() + 100); + const int expectedDuration = animation.totalDuration() + 150; + WAIT_FOR_STOPPED(animation, expectedDuration); -#ifdef BAD_TIMER_RESOLUTION - if (animation.state() != QAbstractAnimation::Stopped) - QEXPECT_FAIL("", timerError, Abort); -#endif - - QCOMPARE(animation.state(), QAbstractAnimation::Stopped); const int expectedLoopCount = 1 + loopCount; #ifdef BAD_TIMER_RESOLUTION @@ -166,13 +170,9 @@ void tst_QPauseAnimation::multiplePauseAnimations() animation.start(); animation2.start(); - QTest::qWait(animation.totalDuration() + 100); -#ifdef BAD_TIMER_RESOLUTION - if (animation.state() != QAbstractAnimation::Stopped) - QEXPECT_FAIL("", timerError, Abort); -#endif - QCOMPARE(animation.state(), QAbstractAnimation::Stopped); + const int expectedDuration = animation.totalDuration() + 150; + WAIT_FOR_STOPPED(animation, expectedDuration); #ifdef BAD_TIMER_RESOLUTION if (animation2.state() != QAbstractAnimation::Running) @@ -192,13 +192,7 @@ void tst_QPauseAnimation::multiplePauseAnimations() #endif QCOMPARE(animation2.m_updateCurrentTimeCount, 2); - QTest::qWait(550); - -#ifdef BAD_TIMER_RESOLUTION - if (animation2.state() != QAbstractAnimation::Stopped) - QEXPECT_FAIL("", timerError, Abort); -#endif - QCOMPARE(animation2.state(), QAbstractAnimation::Stopped); + WAIT_FOR_STOPPED(animation2, 600); #ifdef BAD_TIMER_RESOLUTION if (animation2.m_updateCurrentTimeCount != 3) @@ -229,13 +223,9 @@ void tst_QPauseAnimation::pauseAndPropertyAnimations() QCOMPARE(pause.state(), QAbstractAnimation::Running); QCOMPARE(pause.m_updateCurrentTimeCount, 2); - QTest::qWait(animation.totalDuration() + 100); + const int expectedDuration = animation.totalDuration() + 150; + WAIT_FOR_STOPPED(animation, expectedDuration); -#ifdef BAD_TIMER_RESOLUTION - if (animation.state() != QAbstractAnimation::Stopped) - QEXPECT_FAIL("", timerError, Abort); -#endif - QCOMPARE(animation.state(), QAbstractAnimation::Stopped); QCOMPARE(pause.state(), QAbstractAnimation::Stopped); QVERIFY(pause.m_updateCurrentTimeCount > 3); } @@ -405,13 +395,8 @@ void tst_QPauseAnimation::multipleSequentialGroups() // This is a pretty long animation so it tends to get rather out of sync // when using the consistent timer, so run for an extra half second for good // measure... - QTest::qWait(group.totalDuration() + 500); - -#ifdef BAD_TIMER_RESOLUTION - if (group.state() != QAbstractAnimation::Stopped) - QEXPECT_FAIL("", timerError, Abort); -#endif - QCOMPARE(group.state(), QAbstractAnimation::Stopped); + const int expectedDuration = group.totalDuration() + 550; + WAIT_FOR_STOPPED(group, expectedDuration); #ifdef BAD_TIMER_RESOLUTION if (subgroup1.state() != QAbstractAnimation::Stopped) @@ -449,8 +434,9 @@ void tst_QPauseAnimation::zeroDuration() TestablePauseAnimation animation; animation.setDuration(0); animation.start(); - QTest::qWait(animation.totalDuration() + 100); - QCOMPARE(animation.state(), QAbstractAnimation::Stopped); + const int expectedDuration = animation.totalDuration() + 150; + WAIT_FOR_STOPPED(animation, expectedDuration); + QCOMPARE(animation.m_updateCurrentTimeCount, 1); } diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp index 5666726a8c5..8f78aa937cb 100644 --- a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp +++ b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp @@ -237,39 +237,6 @@ void tst_Utf8::nonCharacters_data() QTest::addColumn("utf8"); QTest::addColumn("utf16"); - // Unicode has a couple of "non-characters" that one can use internally - // These characters may be used for interchange; - // see: http://www.unicode.org/versions/corrigendum9.html - // - // Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF, - // U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and - // U+FDEF (inclusive) - - // U+FDD0 through U+FDEF - for (int i = 0; i < 32; ++i) { - char utf8[] = { char(0357), char(0267), char(0220 + i), 0 }; - QString utf16 = QChar(0xfdd0 + i); - QTest::newRow(qPrintable(QString::number(0xfdd0 + i, 16))) << QByteArray(utf8) << utf16; - } - - // the last two in Planes 1 through 16 - for (uint plane = 1; plane <= 16; ++plane) { - for (uint lower = 0xfffe; lower < 0x10000; ++lower) { - uint ucs4 = (plane << 16) | lower; - char utf8[] = { char(0xf0 | uchar(ucs4 >> 18)), - char(0x80 | (uchar(ucs4 >> 12) & 0x3f)), - char(0x80 | (uchar(ucs4 >> 6) & 0x3f)), - char(0x80 | (uchar(ucs4) & 0x3f)), - 0 }; - ushort utf16[] = { QChar::highSurrogate(ucs4), QChar::lowSurrogate(ucs4), 0 }; - - QTest::newRow(qPrintable(QString::number(ucs4, 16))) << QByteArray(utf8) << QString::fromUtf16(utf16); - } - } - - QTest::newRow("fffe") << QByteArray("\xEF\xBF\xBE") << QString(QChar(0xfffe)); - QTest::newRow("ffff") << QByteArray("\xEF\xBF\xBF") << QString(QChar(0xffff)); - extern void loadNonCharactersRows(); loadNonCharactersRows(); } diff --git a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp index e946f3104a9..564b8547b19 100644 --- a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp @@ -68,6 +68,8 @@ private slots: void itemData(); + void persistIndexOnLayoutChange(); + protected: void verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex()); @@ -377,5 +379,79 @@ void tst_QIdentityProxyModel::itemData() QCOMPARE(proxy.itemData(topIndex).value(Qt::DisplayRole).toString(), QStringLiteral("Monday_appended")); } +void dump(QAbstractItemModel* model, QString const& indent = " - ", QModelIndex const& parent = {}) +{ + for (auto row = 0; row < model->rowCount(parent); ++row) + { + auto idx = model->index(row, 0, parent); + qDebug() << (indent + idx.data().toString()); + dump(model, indent + "- ", idx); + } +} + +void tst_QIdentityProxyModel::persistIndexOnLayoutChange() +{ + DynamicTreeModel model; + + QList ancestors; + for (auto i = 0; i < 3; ++i) + { + Q_UNUSED(i); + ModelInsertCommand insertCommand(&model); + insertCommand.setAncestorRowNumbers(ancestors); + insertCommand.setStartRow(0); + insertCommand.setEndRow(0); + insertCommand.doCommand(); + ancestors.push_back(0); + } + ModelInsertCommand insertCommand(&model); + insertCommand.setAncestorRowNumbers(ancestors); + insertCommand.setStartRow(0); + insertCommand.setEndRow(1); + insertCommand.doCommand(); + + // dump(&model); + // " - 1" + // " - - 2" + // " - - - 3" + // " - - - - 4" + // " - - - - 5" + + QIdentityProxyModel proxy; + proxy.setSourceModel(&model); + + QPersistentModelIndex persistentIndex; + + QPersistentModelIndex sourcePersistentIndex = model.match(model.index(0, 0), Qt::DisplayRole, "5", 1, Qt::MatchRecursive).first(); + + QCOMPARE(sourcePersistentIndex.data().toString(), QStringLiteral("5")); + + bool gotLayoutAboutToBeChanged = false; + bool gotLayoutChanged = false; + + QObject::connect(&proxy, &QAbstractItemModel::layoutAboutToBeChanged, &proxy, [&proxy, &persistentIndex, &gotLayoutAboutToBeChanged] + { + gotLayoutAboutToBeChanged = true; + persistentIndex = proxy.match(proxy.index(0, 0), Qt::DisplayRole, "5", 1, Qt::MatchRecursive).first(); + }); + + QObject::connect(&proxy, &QAbstractItemModel::layoutChanged, &proxy, [&proxy, &persistentIndex, &sourcePersistentIndex, &gotLayoutChanged] + { + gotLayoutChanged = true; + QCOMPARE(QModelIndex(persistentIndex), proxy.mapFromSource(sourcePersistentIndex)); + }); + + ModelChangeChildrenLayoutsCommand layoutChangeCommand(&model, 0); + + layoutChangeCommand.setAncestorRowNumbers(QList{0, 0, 0}); + layoutChangeCommand.setSecondAncestorRowNumbers(QList{0, 0}); + + layoutChangeCommand.doCommand(); + + QVERIFY(gotLayoutAboutToBeChanged); + QVERIFY(gotLayoutChanged); + QVERIFY(persistentIndex.isValid()); +} + QTEST_MAIN(tst_QIdentityProxyModel) #include "tst_qidentityproxymodel.moc" diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 38e3c6890d6..7b6c470dc4d 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -145,6 +145,9 @@ private slots: void canDropMimeData(); void filterHint(); + void sourceLayoutChangeLeavesValidPersistentIndexes(); + void rowMoveLeavesValidPersistentIndexes(); + protected: void buildHierarchy(const QStringList &data, QAbstractItemModel *model); void checkHierarchy(const QStringList &data, const QAbstractItemModel *model); @@ -4181,5 +4184,174 @@ void tst_QSortFilterProxyModel::filterHint() QAbstractItemModel::NoLayoutChangeHint); } +/** + + Creates a model where each item has one child, to a set depth, + and the last item has no children. For a model created with + setDepth(4): + + - 1 + - - 2 + - - - 3 + - - - - 4 +*/ +class StepTreeModel : public QAbstractItemModel +{ + Q_OBJECT +public: + StepTreeModel(QObject * parent = 0) + : QAbstractItemModel(parent), m_depth(0) {} + + int columnCount(const QModelIndex& = QModelIndex()) const override { return 1; } + + int rowCount(const QModelIndex& parent = QModelIndex()) const override + { + quintptr parentId = (parent.isValid()) ? parent.internalId() : 0; + return (parentId < m_depth) ? 1 : 0; + } + + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override + { + if (role != Qt::DisplayRole) + return QVariant(); + + return QString::number(index.internalId()); + } + + QModelIndex index(int, int, const QModelIndex& parent = QModelIndex()) const override + { + quintptr parentId = (parent.isValid()) ? parent.internalId() : 0; + if (parentId >= m_depth) + return QModelIndex(); + + return createIndex(0, 0, parentId + 1); + } + + QModelIndex parent(const QModelIndex& index) const override + { + if (index.internalId() == 0) + return QModelIndex(); + + return createIndex(0, 0, index.internalId() - 1); + } + + void setDepth(quintptr depth) + { + int parentIdWithLayoutChange = (m_depth < depth) ? m_depth : depth; + + QList parentsOfLayoutChange; + parentsOfLayoutChange.push_back(createIndex(0, 0, parentIdWithLayoutChange)); + + layoutAboutToBeChanged(parentsOfLayoutChange); + + auto existing = persistentIndexList(); + + QList updated; + + for (auto idx : existing) { + if (indexDepth(idx) <= depth) + updated.push_back(idx); + else + updated.push_back({}); + } + + m_depth = depth; + + changePersistentIndexList(existing, updated); + + layoutChanged(parentsOfLayoutChange); + } + +private: + static quintptr indexDepth(QModelIndex const& index) + { + return (index.isValid()) ? 1 + indexDepth(index.parent()) : 0; + } + +private: + quintptr m_depth; +}; + +void tst_QSortFilterProxyModel::sourceLayoutChangeLeavesValidPersistentIndexes() +{ + StepTreeModel model; + Q_SET_OBJECT_NAME(model); + model.setDepth(4); + + QSortFilterProxyModel proxy1; + proxy1.setSourceModel(&model); + Q_SET_OBJECT_NAME(proxy1); + + proxy1.setFilterRegExp("1|2"); + + // The current state of things: + // model proxy + // - 1 - 1 + // - - 2 - - 2 + // - - - 3 + // - - - - 4 + + // The setDepth call below removes '4' with a layoutChanged call. + // Because the proxy filters that out anyway, the proxy doesn't need + // to emit any signals or update persistent indexes. + + QPersistentModelIndex persistentIndex = proxy1.index(0, 0, proxy1.index(0, 0)); + + model.setDepth(3); + + // Calling parent() causes the internalPointer to be used. + // Before fixing QTBUG-47711, that could be a dangling pointer. + // The use of qDebug here makes sufficient use of the heap to + // cause corruption at runtime with normal use on linux (before + // the fix). valgrind confirms the fix. + qDebug() << persistentIndex.parent(); + QVERIFY(persistentIndex.parent().isValid()); +} + +void tst_QSortFilterProxyModel::rowMoveLeavesValidPersistentIndexes() +{ + DynamicTreeModel model; + Q_SET_OBJECT_NAME(model); + + QList ancestors; + for (auto i = 0; i < 5; ++i) + { + Q_UNUSED(i); + ModelInsertCommand insertCommand(&model); + insertCommand.setAncestorRowNumbers(ancestors); + insertCommand.setStartRow(0); + insertCommand.setEndRow(0); + insertCommand.doCommand(); + ancestors.push_back(0); + } + + QSortFilterProxyModel proxy1; + proxy1.setSourceModel(&model); + Q_SET_OBJECT_NAME(proxy1); + + proxy1.setFilterRegExp("1|2"); + + auto item5 = model.match(model.index(0, 0), Qt::DisplayRole, "5", 1, Qt::MatchRecursive).first(); + auto item3 = model.match(model.index(0, 0), Qt::DisplayRole, "3", 1, Qt::MatchRecursive).first(); + + Q_ASSERT(item5.isValid()); + Q_ASSERT(item3.isValid()); + + QPersistentModelIndex persistentIndex = proxy1.match(proxy1.index(0, 0), Qt::DisplayRole, "2", 1, Qt::MatchRecursive).first(); + + ModelMoveCommand moveCommand(&model, 0); + moveCommand.setAncestorRowNumbers(QList{0, 0, 0, 0}); + moveCommand.setStartRow(0); + moveCommand.setEndRow(0); + moveCommand.setDestRow(0); + moveCommand.setDestAncestors(QList{0, 0, 0}); + moveCommand.doCommand(); + + // Calling parent() causes the internalPointer to be used. + // Before fixing QTBUG-47711 (moveRows case), that could be + // a dangling pointer. + QVERIFY(persistentIndex.parent().isValid()); +} + QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" diff --git a/tests/auto/corelib/kernel/qobject/test/test.pro b/tests/auto/corelib/kernel/qobject/test/test.pro index f3bc045455d..4e77cb48c54 100644 --- a/tests/auto/corelib/kernel/qobject/test/test.pro +++ b/tests/auto/corelib/kernel/qobject/test/test.pro @@ -3,5 +3,8 @@ TARGET = ../tst_qobject QT = core-private network testlib SOURCES = ../tst_qobject.cpp +# Force C++17 if available (needed due to P0012R1) +contains(QT_CONFIG, c++1z): CONFIG += c++1z + !winrt: TEST_HELPER_INSTALLS = ../signalbug/signalbug DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 5eea8581078..f44c40c27fa 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -120,6 +120,7 @@ private slots: void connectCxx0x(); void connectToStaticCxx0x(); void connectCxx0xTypeMatching(); + void connectCxx17Noexcept(); void connectConvert(); void connectWithReference(); void connectManyArguments(); @@ -4755,10 +4756,13 @@ class LotsOfSignalsAndSlots: public QObject public slots: void slot_v() {} + void slot_v_noexcept() Q_DECL_NOTHROW {} void slot_vi(int) {} + void slot_vi_noexcept() Q_DECL_NOTHROW {} void slot_vii(int, int) {} void slot_viii(int, int, int) {} int slot_i() { return 0; } + int slot_i_noexcept() Q_DECL_NOTHROW { return 0; } int slot_ii(int) { return 0; } int slot_iii(int, int) { return 0; } int slot_iiii(int, int, int) { return 0; } @@ -4772,13 +4776,18 @@ class LotsOfSignalsAndSlots: public QObject void slot_vPFvvE(fptr) {} void const_slot_v() const {}; + void const_slot_v_noexcept() const Q_DECL_NOTHROW {} void const_slot_vi(int) const {}; + void const_slot_vi_noexcept(int) const Q_DECL_NOTHROW {} static void static_slot_v() {} + static void static_slot_v_noexcept() Q_DECL_NOTHROW {} static void static_slot_vi(int) {} + static void static_slot_vi_noexcept(int) Q_DECL_NOTHROW {} static void static_slot_vii(int, int) {} static void static_slot_viii(int, int, int) {} static int static_slot_i() { return 0; } + static int static_slot_i_noexcept() Q_DECL_NOTHROW { return 0; } static int static_slot_ii(int) { return 0; } static int static_slot_iii(int, int) { return 0; } static int static_slot_iiii(int, int, int) { return 0; } @@ -4941,6 +4950,32 @@ void tst_QObject::connectCxx0xTypeMatching() } +void receiverFunction_noexcept() Q_DECL_NOTHROW {} +struct Functor_noexcept { void operator()() Q_DECL_NOTHROW {} }; +void tst_QObject::connectCxx17Noexcept() +{ + // this is about connecting signals to slots with the Q_DECL_NOTHROW qualifier + // as semantics changed due to http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0012r1.html + typedef LotsOfSignalsAndSlots Foo; + Foo obj; + + QObject::connect(&obj, &Foo::signal_v, &obj, &Foo::slot_v_noexcept); + QObject::connect(&obj, &Foo::signal_v, &obj, &Foo::slot_i_noexcept); + QObject::connect(&obj, &Foo::signal_v, &obj, &Foo::slot_vi_noexcept); + + QObject::connect(&obj, &Foo::signal_vii, &Foo::static_slot_v_noexcept); + QObject::connect(&obj, &Foo::signal_vii, &Foo::static_slot_i_noexcept); + QObject::connect(&obj, &Foo::signal_vii, &Foo::static_slot_vi_noexcept); + + QVERIFY(QObject::connect(&obj, &Foo::signal_vi, &obj, &Foo::const_slot_vi_noexcept)); + QVERIFY(QObject::connect(&obj, &Foo::signal_vi, &obj, &Foo::const_slot_v_noexcept)); + + QObject::connect(&obj, &Foo::signal_v, receiverFunction_noexcept); + + Functor_noexcept fn; + QObject::connect(&obj, &Foo::signal_v, fn); +} + class StringVariant : public QObject { Q_OBJECT signals: diff --git a/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro b/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro index 69062a97413..3a4697750e8 100644 --- a/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro +++ b/tests/auto/corelib/kernel/qsharedmemory/qsharedmemory.pro @@ -1,5 +1,6 @@ TEMPLATE = subdirs -!winrt: SUBDIRS = sharedmemoryhelper - -SUBDIRS += test +qtConfig(sharedmemory) { + !winrt: SUBDIRS = sharedmemoryhelper + SUBDIRS += test +} diff --git a/tests/auto/corelib/kernel/qtimer/qtimer.pro b/tests/auto/corelib/kernel/qtimer/qtimer.pro index 8afdbb148ed..b27d862bc5f 100644 --- a/tests/auto/corelib/kernel/qtimer/qtimer.pro +++ b/tests/auto/corelib/kernel/qtimer/qtimer.pro @@ -2,3 +2,6 @@ CONFIG += testcase TARGET = tst_qtimer QT = core testlib SOURCES = tst_qtimer.cpp + +# Force C++17 if available +contains(QT_CONFIG, c++1z): CONFIG += c++1z diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp index fe97695d199..29ff552f6a3 100644 --- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp +++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp @@ -766,6 +766,11 @@ class StaticEventLoop { public: static void quitEventLoop() + { + quitEventLoop_noexcept(); + } + + static void quitEventLoop_noexcept() Q_DECL_NOTHROW { QVERIFY(!_e.isNull()); _e->quit(); @@ -787,6 +792,9 @@ void tst_QTimer::singleShotToFunctors() QTimer::singleShot(0, &StaticEventLoop::quitEventLoop); QCOMPARE(_e->exec(), 0); + QTimer::singleShot(0, &StaticEventLoop::quitEventLoop_noexcept); + QCOMPARE(_e->exec(), 0); + QThread t1; QObject c1; c1.moveToThread(&t1); diff --git a/tests/auto/corelib/thread/qfuture/qfuture.pro b/tests/auto/corelib/thread/qfuture/qfuture.pro index ed9e1896680..b1667760d6e 100644 --- a/tests/auto/corelib/thread/qfuture/qfuture.pro +++ b/tests/auto/corelib/thread/qfuture/qfuture.pro @@ -1,5 +1,5 @@ CONFIG += testcase TARGET = tst_qfuture -QT = core core-private testlib concurrent +QT = core core-private testlib SOURCES = tst_qfuture.cpp DEFINES += QT_STRICT_ITERATORS diff --git a/tests/auto/corelib/thread/qfuturesynchronizer/qfuturesynchronizer.pro b/tests/auto/corelib/thread/qfuturesynchronizer/qfuturesynchronizer.pro index 5eebd12deb8..0d20117ed00 100644 --- a/tests/auto/corelib/thread/qfuturesynchronizer/qfuturesynchronizer.pro +++ b/tests/auto/corelib/thread/qfuturesynchronizer/qfuturesynchronizer.pro @@ -1,4 +1,4 @@ CONFIG += testcase TARGET = tst_qfuturesynchronizer -QT = core testlib concurrent +QT = core testlib SOURCES = tst_qfuturesynchronizer.cpp diff --git a/tests/auto/corelib/thread/qresultstore/qresultstore.pro b/tests/auto/corelib/thread/qresultstore/qresultstore.pro index 2f6c18f64c6..bbebe0976bc 100644 --- a/tests/auto/corelib/thread/qresultstore/qresultstore.pro +++ b/tests/auto/corelib/thread/qresultstore/qresultstore.pro @@ -1,5 +1,5 @@ CONFIG += testcase TARGET = tst_qresultstore -QT = core-private testlib concurrent +QT = core-private testlib SOURCES = tst_qresultstore.cpp DEFINES += QT_STRICT_ITERATORS diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index 7681f4755cc..f56cff4d29a 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -186,12 +186,50 @@ void tst_QLocale::ctor() QVERIFY(l.country() == default_country); } +#define TEST_CTOR(req_lang, req_script, req_country, exp_lang, exp_script, exp_country) \ + { \ + QLocale l(QLocale::req_lang, QLocale::req_script, QLocale::req_country); \ + QCOMPARE((int)l.language(), (int)exp_lang); \ + QCOMPARE((int)l.script(), (int)exp_script); \ + QCOMPARE((int)l.country(), (int)exp_country); \ + } + + // Exact matches + TEST_CTOR(Chinese, SimplifiedHanScript, China, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); + TEST_CTOR(Chinese, TraditionalHanScript, Taiwan, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan); + TEST_CTOR(Chinese, TraditionalHanScript, HongKong, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::HongKong); + + // Best match for AnyCountry + TEST_CTOR(Chinese, SimplifiedHanScript, AnyCountry, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); + TEST_CTOR(Chinese, TraditionalHanScript, AnyCountry, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan); + + // Best match for AnyScript (and change country to supported one, if necessary) + TEST_CTOR(Chinese, AnyScript, China, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); + TEST_CTOR(Chinese, AnyScript, Taiwan, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan); + TEST_CTOR(Chinese, AnyScript, HongKong, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::HongKong); + TEST_CTOR(Chinese, AnyScript, UnitedStates, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); + + // Fully-specified not found; find best alternate country + TEST_CTOR(Chinese, SimplifiedHanScript, Taiwan, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); + TEST_CTOR(Chinese, SimplifiedHanScript, UnitedStates, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); + TEST_CTOR(Chinese, TraditionalHanScript, China, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan); + TEST_CTOR(Chinese, TraditionalHanScript, UnitedStates, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan); + + // Fully-specified not found; find best alternate script + TEST_CTOR(Chinese, LatinScript, China, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); + TEST_CTOR(Chinese, LatinScript, Taiwan, QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan); + + // Fully-specified not found; find best alternate country and script + TEST_CTOR(Chinese, LatinScript, UnitedStates, QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); + +#undef TEST_CTOR #define TEST_CTOR(req_lang, req_country, exp_lang, exp_country) \ { \ QLocale l(QLocale::req_lang, QLocale::req_country); \ QCOMPARE((int)l.language(), (int)exp_lang); \ QCOMPARE((int)l.country(), (int)exp_country); \ } + { QLocale l(QLocale::C, QLocale::AnyCountry); QCOMPARE(l.language(), QLocale::C); @@ -295,7 +333,6 @@ void tst_QLocale::ctor() TEST_CTOR(Uzbek, AnyCountry, QLocale::Uzbek, QLocale::Uzbekistan) #undef TEST_CTOR - #define TEST_CTOR(req_lc, exp_lang, exp_country) \ { \ QLocale l(req_lc); \ diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp index a6d89446569..2603206ab09 100644 --- a/tests/auto/gui/text/qfont/tst_qfont.cpp +++ b/tests/auto/gui/text/qfont/tst_qfont.cpp @@ -63,6 +63,7 @@ private slots: void defaultFamily_data(); void defaultFamily(); void toAndFromString(); + void fromStringWithoutStyleName(); void sharing(); }; @@ -358,6 +359,8 @@ void tst_QFont::serialize_data() // Versions <= Qt 2.1 had broken point size serialization, // so we set an integer point size. basicFont.setPointSize(9); + // Versions <= Qt 5.4 didn't serialize styleName, so clear it + basicFont.setStyleName(QString()); QFont font = basicFont; QTest::newRow("defaultConstructed") << font << QDataStream::Qt_1_0; @@ -559,6 +562,19 @@ void tst_QFont::toAndFromString() } } +void tst_QFont::fromStringWithoutStyleName() +{ + QFont font1; + font1.fromString("Noto Sans,12,-1,5,50,0,0,0,0,0,Regular"); + + QFont font2 = font1; + const QString str = "Times,16,-1,5,50,0,0,0,0,0"; + font2.fromString(str); + + QCOMPARE(font2.toString(), str); +} + + void tst_QFont::sharing() { // QFontCache references the engineData diff --git a/tests/auto/network/bearer/qnetworkconfiguration/tst_qnetworkconfiguration.cpp b/tests/auto/network/bearer/qnetworkconfiguration/tst_qnetworkconfiguration.cpp index 6ca881d38a9..9c49e0c173e 100644 --- a/tests/auto/network/bearer/qnetworkconfiguration/tst_qnetworkconfiguration.cpp +++ b/tests/auto/network/bearer/qnetworkconfiguration/tst_qnetworkconfiguration.cpp @@ -115,7 +115,7 @@ void tst_QNetworkConfiguration::comparison() QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete QList configs = manager.allConfigurations(QNetworkConfiguration::Discovered); QVERIFY(configs.count()); @@ -162,7 +162,7 @@ void tst_QNetworkConfiguration::isRoamingAvailable() //force update to get maximum list QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete foreach(QNetworkConfiguration c, configs) { diff --git a/tests/auto/network/bearer/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp b/tests/auto/network/bearer/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp index 838612f638d..b251a654207 100644 --- a/tests/auto/network/bearer/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp +++ b/tests/auto/network/bearer/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp @@ -68,7 +68,7 @@ void tst_QNetworkConfigurationManager::allConfigurations() QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete QList configs = manager.allConfigurations(); @@ -145,7 +145,7 @@ void tst_QNetworkConfigurationManager::defaultConfiguration() QNetworkConfigurationManager manager; QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete QList configs = manager.allConfigurations(); QNetworkConfiguration defaultConfig = manager.defaultConfiguration(); @@ -175,7 +175,7 @@ void tst_QNetworkConfigurationManager::configurationFromIdentifier() //force an update to get maximum number of configs QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete QList configs = manager.allConfigurations(); @@ -203,7 +203,7 @@ protected: preScanConfigs = manager.allConfigurations(); QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete configs = manager.allConfigurations(); } public: @@ -229,7 +229,7 @@ void tst_QNetworkConfigurationManager::usedInThread() QList preScanConfigs = manager.allConfigurations(); QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); //initiate scans - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); //wait for scan to complete + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); //wait for scan to complete QList configs = manager.allConfigurations(); QCOMPARE(thread.configs, configs); //Don't compare pre scan configs, because these may be cached and therefore give different results diff --git a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp index 4ae511cf542..138a0859cd6 100644 --- a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp +++ b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp @@ -106,7 +106,7 @@ void tst_QNetworkSession::initTestCase() QSignalSpy spy(&manager, SIGNAL(updateCompleted())); manager.updateConfigurations(); - QTRY_VERIFY_WITH_TIMEOUT(spy.count() == 1, TestTimeOut); + QTRY_VERIFY_WITH_TIMEOUT(spy.count() >= 1, TestTimeOut); lackeyDir = QFINDTESTDATA("lackey"); QVERIFY2(!lackeyDir.isEmpty(), qPrintable( @@ -1007,7 +1007,7 @@ QNetworkConfiguration suitableConfiguration(QString bearerType, QNetworkConfigur QSignalSpy updateSpy(&mgr, SIGNAL(updateCompleted())); mgr.updateConfigurations(); - QTRY_NOOP(updateSpy.count() == 1); + QTRY_NOOP(updateSpy.count() >= 1); if (updateSpy.count() != 1) { qDebug("tst_QNetworkSession::suitableConfiguration() failure: unable to update configurations"); return QNetworkConfiguration(); @@ -1052,7 +1052,7 @@ void updateConfigurations() QNetworkConfigurationManager mgr; QSignalSpy updateSpy(&mgr, SIGNAL(updateCompleted())); mgr.updateConfigurations(); - QTRY_NOOP(updateSpy.count() == 1); + QTRY_NOOP(updateSpy.count() >= 1); } // A convenience-function: updates and prints all available confiurations and their states diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp index 364e435d3d6..a715c38f325 100644 --- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp @@ -271,6 +271,7 @@ void tst_QHostAddress::specialAddresses() //check special address equal to itself (QTBUG-22898), note two overloads of operator== QVERIFY(QHostAddress(address) == QHostAddress(address)); QVERIFY(QHostAddress(address) == address); + QVERIFY(address == QHostAddress(address)); QVERIFY(!(QHostAddress(address) != QHostAddress(address))); QVERIFY(!(QHostAddress(address) != address)); diff --git a/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp b/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp index c945d77cdaf..18da122000a 100644 --- a/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp +++ b/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp @@ -54,7 +54,6 @@ class tst_QSocks5SocketEngine : public QObject, public QAbstractSocketEngineRece private slots: void initTestCase(); - void init(); void construction(); void errorTest_data(); void errorTest(); @@ -74,13 +73,6 @@ private slots: void incomplete(); protected slots: - void tcpSocketNonBlocking_hostFound(); - void tcpSocketNonBlocking_connected(); - void tcpSocketNonBlocking_closed(); - void tcpSocketNonBlocking_readyRead(); - void tcpSocketNonBlocking_bytesWritten(qint64); - void exitLoopSlot(); - void downloadBigFileSlot(); void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); private: @@ -89,11 +81,6 @@ private: void closeNotification() { } void exceptionNotification() { } void connectionNotification() { } - QTcpSocket *tcpSocketNonBlocking_socket; - QStringList tcpSocketNonBlocking_data; - qint64 tcpSocketNonBlocking_totalWritten; - QTcpSocket *tmpSocket; - qint64 bytesAvailable; }; class MiniSocks5ResponseHandler : public QObject @@ -153,12 +140,6 @@ void tst_QSocks5SocketEngine::initTestCase() QVERIFY(QtNetworkSettings::verifyTestNetworkSettings()); } -void tst_QSocks5SocketEngine::init() -{ - tmpSocket = 0; - bytesAvailable = 0; -} - //--------------------------------------------------------------------------- void tst_QSocks5SocketEngine::construction() { @@ -631,13 +612,27 @@ void tst_QSocks5SocketEngine::tcpSocketNonBlockingTest() { QSocks5SocketEngineHandler socks5; + qint64 tcpSocketNonBlocking_totalWritten = 0; + QStringList tcpSocketNonBlocking_data; QTcpSocket socket; - connect(&socket, SIGNAL(hostFound()), SLOT(tcpSocketNonBlocking_hostFound())); - connect(&socket, SIGNAL(connected()), SLOT(tcpSocketNonBlocking_connected())); - connect(&socket, SIGNAL(disconnected()), SLOT(tcpSocketNonBlocking_closed())); - connect(&socket, SIGNAL(bytesWritten(qint64)), SLOT(tcpSocketNonBlocking_bytesWritten(qint64))); - connect(&socket, SIGNAL(readyRead()), SLOT(tcpSocketNonBlocking_readyRead())); - tcpSocketNonBlocking_socket = &socket; + connect(&socket, &QAbstractSocket::hostFound, + &QTestEventLoop::instance(), &QTestEventLoop::exitLoop); + connect(&socket, &QAbstractSocket::connected, + &QTestEventLoop::instance(), &QTestEventLoop::exitLoop); + connect(&socket, &QIODevice::bytesWritten, + [&tcpSocketNonBlocking_totalWritten] (qint64 written) + { + tcpSocketNonBlocking_totalWritten += written; + QTestEventLoop::instance().exitLoop(); + }); + + connect(&socket, &QIODevice::readyRead, + [&tcpSocketNonBlocking_data, &socket] () + { + while (socket.canReadLine()) + tcpSocketNonBlocking_data.append(socket.readLine()); + QTestEventLoop::instance().exitLoop(); + }); // Connect socket.connectToHost(QtNetworkSettings::serverName(), 143); @@ -725,62 +720,50 @@ void tst_QSocks5SocketEngine::tcpSocketNonBlockingTest() QCOMPARE(socket.state(), QTcpSocket::UnconnectedState); } -void tst_QSocks5SocketEngine::tcpSocketNonBlocking_hostFound() -{ - QTestEventLoop::instance().exitLoop(); -} - -void tst_QSocks5SocketEngine::tcpSocketNonBlocking_connected() -{ - QTestEventLoop::instance().exitLoop(); -} - -void tst_QSocks5SocketEngine::tcpSocketNonBlocking_readyRead() -{ - while (tcpSocketNonBlocking_socket->canReadLine()) - tcpSocketNonBlocking_data.append(tcpSocketNonBlocking_socket->readLine()); - - QTestEventLoop::instance().exitLoop(); -} - -void tst_QSocks5SocketEngine::tcpSocketNonBlocking_bytesWritten(qint64 written) -{ - tcpSocketNonBlocking_totalWritten += written; - QTestEventLoop::instance().exitLoop(); -} - -void tst_QSocks5SocketEngine::tcpSocketNonBlocking_closed() -{ -} - //---------------------------------------------------------------------------------- void tst_QSocks5SocketEngine::downloadBigFile() { QSocks5SocketEngineHandler socks5; - if (tmpSocket) - delete tmpSocket; - tmpSocket = new QTcpSocket; + QTcpSocket socket; + qint64 bytesAvailable = 0; + connect(&socket, &QAbstractSocket::connected, + &QTestEventLoop::instance(), &QTestEventLoop::exitLoop); + connect(&socket, &QIODevice::readyRead, + [&socket, &bytesAvailable] () + { + const QByteArray tmp = socket.readAll(); + int correction = tmp.indexOf(char(0), 0); //skip header + if (correction == -1) + correction = 0; + bytesAvailable += (tmp.size() - correction); + if (bytesAvailable >= 10000000) + QTestEventLoop::instance().exitLoop(); + }); - connect(tmpSocket, SIGNAL(connected()), SLOT(exitLoopSlot())); - connect(tmpSocket, SIGNAL(readyRead()), SLOT(downloadBigFileSlot())); + connect(&socket, QOverload::of(&QAbstractSocket::error), + [&socket] (QAbstractSocket::SocketError errorCode) + { + qWarning().noquote().nospace() << QTest::currentTestFunction() + << ": error " << errorCode << ": " << socket.errorString(); + }); - tmpSocket->connectToHost(QtNetworkSettings::serverName(), 80); + socket.connectToHost(QtNetworkSettings::serverName(), 80); QTestEventLoop::instance().enterLoop(30); if (QTestEventLoop::instance().timeout()) QFAIL("Network operation timed out"); QByteArray hostName = QtNetworkSettings::serverName().toLatin1(); - QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState); - QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0); - QVERIFY(tmpSocket->write("HOST: ") > 0); - QVERIFY(tmpSocket->write(hostName.data()) > 0); - QVERIFY(tmpSocket->write("\r\n") > 0); - QVERIFY(tmpSocket->write("\r\n") > 0); + QCOMPARE(socket.state(), QAbstractSocket::ConnectedState); + QVERIFY(socket.write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0); + QVERIFY(socket.write("HOST: ") > 0); + QVERIFY(socket.write(hostName.data()) > 0); + QVERIFY(socket.write("\r\n") > 0); + QVERIFY(socket.write("\r\n") > 0); + - bytesAvailable = 0; QTime stopWatch; stopWatch.start(); @@ -791,31 +774,12 @@ void tst_QSocks5SocketEngine::downloadBigFile() QCOMPARE(bytesAvailable, qint64(10000000)); - QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState); + QCOMPARE(socket.state(), QAbstractSocket::ConnectedState); /*qDebug("\t\t%.1fMB/%.1fs: %.1fMB/s", bytesAvailable / (1024.0 * 1024.0), stopWatch.elapsed() / 1024.0, (bytesAvailable / (stopWatch.elapsed() / 1000.0)) / (1024 * 1024));*/ - - delete tmpSocket; - tmpSocket = 0; -} - -void tst_QSocks5SocketEngine::exitLoopSlot() -{ - QTestEventLoop::instance().exitLoop(); -} - - -void tst_QSocks5SocketEngine::downloadBigFileSlot() -{ - QByteArray tmp=tmpSocket->readAll(); - int correction=tmp.indexOf((char)0,0); //skip header - if (correction==-1) correction=0; - bytesAvailable += (tmp.size()-correction); - if (bytesAvailable >= 10000000) - QTestEventLoop::instance().exitLoop(); } void tst_QSocks5SocketEngine::passwordAuth() diff --git a/tests/auto/network/ssl/qssldiffiehellmanparameters/tst_qssldiffiehellmanparameters.cpp b/tests/auto/network/ssl/qssldiffiehellmanparameters/tst_qssldiffiehellmanparameters.cpp index f3b9003fbb5..ddf503eed67 100644 --- a/tests/auto/network/ssl/qssldiffiehellmanparameters/tst_qssldiffiehellmanparameters.cpp +++ b/tests/auto/network/ssl/qssldiffiehellmanparameters/tst_qssldiffiehellmanparameters.cpp @@ -42,6 +42,13 @@ #include #include +// Default DH parameters, exported by qssldiffiehellmanparameters.cpp. +QT_BEGIN_NAMESPACE +extern Q_AUTOTEST_EXPORT const char *qssl_dhparams_default_base64; +QT_END_NAMESPACE + +QT_USE_NAMESPACE + class tst_QSslDiffieHellmanParameters : public QObject { Q_OBJECT @@ -54,6 +61,7 @@ private Q_SLOTS: void constructionPEM(); void unsafe512Bits(); void unsafeNonPrime(); + void defaultIsValid(); #endif }; @@ -157,6 +165,33 @@ void tst_QSslDiffieHellmanParameters::unsafeNonPrime() #endif } +void tst_QSslDiffieHellmanParameters::defaultIsValid() +{ + // The QSslDiffieHellmanParameters::defaultParameters() method takes a shortcut, + // by not verifying the passed-in parameters. Instead, it simply assigns the default + // DH parameters to the derData field of QSslDiffieHellmanParametersPrivate. + // + // This test ensures that our default parameters pass the internal verification tests + // by constructing, using fromEncoded(), a QSslDiffieHellmanParameters instance that + // we expect to be equivalent to the one returned by defaultParameters(). By using + // fromEncoded() we go through the internal verification mechanisms. Finally, to ensure + // the two instances are equivalent, we compare them. + + const auto dh = QSslDiffieHellmanParameters::fromEncoded( + QByteArray::fromBase64(QByteArray(qssl_dhparams_default_base64)), + QSsl::Der + ); + + const auto defaultdh = QSslDiffieHellmanParameters::defaultParameters(); + +#ifndef QT_NO_OPENSSL + QCOMPARE(dh.isEmpty(), false); + QCOMPARE(dh.isValid(), true); + QCOMPARE(dh.error(), QSslDiffieHellmanParameters::NoError); + QCOMPARE(dh, defaultdh); +#endif +} + #endif // QT_NO_SSL QTEST_MAIN(tst_QSslDiffieHellmanParameters) diff --git a/tests/auto/other/lancelot/lancelot.pro b/tests/auto/other/lancelot/lancelot.pro index 798482f02ce..73c12e67a2a 100644 --- a/tests/auto/other/lancelot/lancelot.pro +++ b/tests/auto/other/lancelot/lancelot.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_lancelot -QT += xml testlib +QT += testlib SOURCES += tst_lancelot.cpp \ paintcommands.cpp diff --git a/tests/auto/printsupport/kernel/qprintdevice/qprintdevice.pro b/tests/auto/printsupport/kernel/qprintdevice/qprintdevice.pro index 56c1b60d941..a859f15fbb7 100644 --- a/tests/auto/printsupport/kernel/qprintdevice/qprintdevice.pro +++ b/tests/auto/printsupport/kernel/qprintdevice/qprintdevice.pro @@ -2,6 +2,6 @@ CONFIG += testcase TARGET = tst_qprintdevice SOURCES += tst_qprintdevice.cpp -QT += printsupport-private network testlib +QT += printsupport-private testlib DEFINES += QT_USE_USING_NAMESPACE diff --git a/tests/auto/printsupport/kernel/qprinterinfo/qprinterinfo.pro b/tests/auto/printsupport/kernel/qprinterinfo/qprinterinfo.pro index f397f48bb8d..36261780fd4 100644 --- a/tests/auto/printsupport/kernel/qprinterinfo/qprinterinfo.pro +++ b/tests/auto/printsupport/kernel/qprinterinfo/qprinterinfo.pro @@ -2,6 +2,6 @@ CONFIG += testcase TARGET = tst_qprinterinfo SOURCES += tst_qprinterinfo.cpp -QT += printsupport network testlib +QT += printsupport testlib DEFINES += QT_USE_USING_NAMESPACE diff --git a/tests/auto/testlib/selftests/test/test.pro b/tests/auto/testlib/selftests/test/test.pro index a2a1dd3f0b3..a7487736b39 100644 --- a/tests/auto/testlib/selftests/test/test.pro +++ b/tests/auto/testlib/selftests/test/test.pro @@ -1,6 +1,6 @@ CONFIG += testcase SOURCES += ../tst_selftests.cpp -QT = core xml testlib-private +QT = core testlib-private TARGET = ../tst_selftests diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index 32a324b8886..1078dcc2e9c 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -169,6 +169,9 @@ private slots: void moveSectionAndReset(); void moveSectionAndRemove(); void saveRestore(); + void restoreQt4State(); + void restoreToMoreColumns(); + void restoreBeforeSetModel(); void defaultSectionSizeTest(); void defaultSectionSizeTestStyles(); @@ -1523,11 +1526,11 @@ public: { return hasIndex(row, column, parent) ? createIndex(row, column) : QModelIndex(); } - int rowCount(const QModelIndex & /* parent */) const + int rowCount(const QModelIndex & /*parent*/ = QModelIndex()) const { return 8; } - int columnCount(const QModelIndex &/*parent= QModelIndex()*/) const + int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { return m_col_count; } @@ -1588,41 +1591,56 @@ void tst_QHeaderView::moveSectionAndRemove() QCOMPARE(v.count(), 0); } -void tst_QHeaderView::saveRestore() +static QByteArray savedState() { - SimpleModel m; + QStandardItemModel m(4, 4); QHeaderView h1(Qt::Horizontal); h1.setModel(&m); h1.swapSections(0, 2); h1.resizeSection(1, 10); h1.setSortIndicatorShown(true); - h1.setSortIndicator(1,Qt::DescendingOrder); - QByteArray s1 = h1.saveState(); + h1.setSortIndicator(2, Qt::DescendingOrder); + h1.setSectionHidden(3, true); + return h1.saveState(); +} + +void tst_QHeaderView::saveRestore() +{ + QStandardItemModel m(4, 4); + const QByteArray s1 = savedState(); QHeaderView h2(Qt::Vertical); QSignalSpy spy(&h2, SIGNAL(sortIndicatorChanged(int,Qt::SortOrder))); h2.setModel(&m); - h2.restoreState(s1); + QVERIFY(h2.restoreState(s1)); QCOMPARE(spy.count(), 1); - QCOMPARE(spy.at(0).at(0).toInt(), 1); + QCOMPARE(spy.at(0).at(0).toInt(), 2); QCOMPARE(h2.logicalIndex(0), 2); QCOMPARE(h2.logicalIndex(2), 0); QCOMPARE(h2.sectionSize(1), 10); - QCOMPARE(h2.sortIndicatorSection(), 1); + QCOMPARE(h2.sortIndicatorSection(), 2); QCOMPARE(h2.sortIndicatorOrder(), Qt::DescendingOrder); QCOMPARE(h2.isSortIndicatorShown(), true); + QVERIFY(!h2.isSectionHidden(2)); + QVERIFY(h2.isSectionHidden(3)); + QCOMPARE(h2.hiddenSectionCount(), 1); QByteArray s2 = h2.saveState(); - QCOMPARE(s1, s2); - QVERIFY(!h2.restoreState(QByteArrayLiteral("Garbage"))); + QVERIFY(!h2.restoreState(QByteArrayLiteral("Garbage"))); +} + +void tst_QHeaderView::restoreQt4State() +{ // QTBUG-40462 // Setting from Qt4, where information about multiple sections were grouped together in one // sectionItem object + QStandardItemModel m(4, 10); + QHeaderView h2(Qt::Vertical); QByteArray settings_qt4 = QByteArray::fromHex("000000ff00000000000000010000000100000000010000000000000000000000000000" "0000000003e80000000a0101000100000000000000000000000064ffffffff00000081" @@ -1652,6 +1670,50 @@ void tst_QHeaderView::saveRestore() QCOMPARE(h2.saveState(), old_state); } +void tst_QHeaderView::restoreToMoreColumns() +{ + // Restore state onto a model with more columns + const QByteArray s1 = savedState(); + QHeaderView h4(Qt::Horizontal); + QStandardItemModel fiveColumnsModel(1, 5); + h4.setModel(&fiveColumnsModel); + QCOMPARE(fiveColumnsModel.columnCount(), 5); + QCOMPARE(h4.count(), 5); + QVERIFY(h4.restoreState(s1)); + QCOMPARE(fiveColumnsModel.columnCount(), 5); + QCOMPARE(h4.count(), 5); + QCOMPARE(h4.sectionSize(1), 10); + for (int i = 0; i < h4.count(); ++i) + QVERIFY(h4.sectionSize(i) > 0 || h4.isSectionHidden(i)); + QVERIFY(!h4.isSectionHidden(2)); + QVERIFY(h4.isSectionHidden(3)); + QCOMPARE(h4.hiddenSectionCount(), 1); + QCOMPARE(h4.sortIndicatorSection(), 2); + QCOMPARE(h4.sortIndicatorOrder(), Qt::DescendingOrder); +} + +void tst_QHeaderView::restoreBeforeSetModel() +{ + QHeaderView h2(Qt::Horizontal); + const QByteArray s1 = savedState(); + // First restore + QVERIFY(h2.restoreState(s1)); + // Then setModel + QStandardItemModel model(4, 4); + h2.setModel(&model); + + // Check the result + QCOMPARE(h2.logicalIndex(0), 2); + QCOMPARE(h2.logicalIndex(2), 0); + QCOMPARE(h2.sectionSize(1), 10); + QCOMPARE(h2.sortIndicatorSection(), 2); + QCOMPARE(h2.sortIndicatorOrder(), Qt::DescendingOrder); + QCOMPARE(h2.isSortIndicatorShown(), true); + QVERIFY(!h2.isSectionHidden(2)); + QVERIFY(h2.isSectionHidden(3)); + QCOMPARE(h2.hiddenSectionCount(), 1); +} + void tst_QHeaderView::defaultSectionSizeTest() { // Setup diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index e5e9b87df4b..8c7c5f10504 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -151,6 +151,7 @@ private slots: void taskQTBUG_7232_AllowUserToControlSingleStep(); void taskQTBUG_51086_skippingIndexesInSelectedIndexes(); void expandingListItems(); + void taskQTBUG_47694_indexOutOfBoundBatchLayout(); }; // Testing get/set functions @@ -2510,5 +2511,18 @@ void tst_QListView::expandingListItems() QVERIFY(w.visualRect(item1->index()).width() < w.visualRect(item2->index()).width()); } +void tst_QListView::taskQTBUG_47694_indexOutOfBoundBatchLayout() +{ + QListView view; + view.setLayoutMode(QListView::Batched); + int batchSize = view.batchSize(); + + QStandardItemModel model(batchSize + 1, 1); + + view.setModel(&model); + + view.scrollTo(model.index(batchSize - 1, 0)); +} + QTEST_MAIN(tst_QListView) #include "tst_qlistview.moc" diff --git a/tests/auto/widgets/kernel/qstackedlayout/tst_qstackedlayout.cpp b/tests/auto/widgets/kernel/qstackedlayout/tst_qstackedlayout.cpp index 835b6ca7990..5be4846b3ee 100644 --- a/tests/auto/widgets/kernel/qstackedlayout/tst_qstackedlayout.cpp +++ b/tests/auto/widgets/kernel/qstackedlayout/tst_qstackedlayout.cpp @@ -377,7 +377,7 @@ void tst_QStackedLayout::replaceWidget() QCOMPARE(stackLayout->indexOf(replaceFrom), 1); QCOMPARE(stackLayout->indexOf(replaceTo), -1); - stackLayout->replaceWidget(replaceFrom, replaceTo); + delete stackLayout->replaceWidget(replaceFrom, replaceTo); QCOMPARE(stackLayout->indexOf(replaceFrom), -1); QCOMPARE(stackLayout->indexOf(replaceTo), 1); diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index 434876eb3c4..f8dc5d91a26 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -93,6 +93,7 @@ private slots: #if !defined(Q_OS_DARWIN) void accel(); void activatedCount(); + void activatedCount_data(); void check_accelKeys(); void check_cursorKeys1(); @@ -145,8 +146,8 @@ protected slots: void slotForTaskQTBUG53205(); private: - TestMenu initSimpleMenuBar(QMenuBar *mb); - TestMenu initWindowWithSimpleMenuBar(QMainWindow &w); + TestMenu initSimpleMenuBar(QMenuBar *mb, bool forceNonNative = true); + TestMenu initWindowWithSimpleMenuBar(QMainWindow &w, bool forceNonNative = true); QAction *createCharacterAction(QMenu *menu, char lowerAscii); QMenu *addNumberedMenu(QMenuBar *mb, int n); TestMenu initComplexMenuBar(QMenuBar *mb); @@ -214,10 +215,10 @@ void tst_QMenuBar::cleanup() // Create a simple menu bar and connect its actions to onSimpleActivated(). -TestMenu tst_QMenuBar::initSimpleMenuBar(QMenuBar *mb) -{ +TestMenu tst_QMenuBar::initSimpleMenuBar(QMenuBar *mb, bool forceNonNative) { TestMenu result; - mb->setNativeMenuBar(false); + if (forceNonNative) + mb->setNativeMenuBar(false); connect(mb, SIGNAL(triggered(QAction*)), this, SLOT(onSimpleActivated(QAction*))); QMenu *menu = mb->addMenu(QStringLiteral("&accel")); QAction *action = menu->addAction(QStringLiteral("menu1") ); @@ -245,11 +246,11 @@ TestMenu tst_QMenuBar::initSimpleMenuBar(QMenuBar *mb) return result; } -inline TestMenu tst_QMenuBar::initWindowWithSimpleMenuBar(QMainWindow &w) +inline TestMenu tst_QMenuBar::initWindowWithSimpleMenuBar(QMainWindow &w, bool forceNonNative) { w.resize(200, 200); centerOnScreen(&w); - return initSimpleMenuBar(w.menuBar()); + return initSimpleMenuBar(w.menuBar(), forceNonNative); } // add a menu with number n, set number as data. @@ -347,7 +348,8 @@ void tst_QMenuBar::activatedCount() { // create a popup menu with menu items set the accelerators later... QMainWindow w; - initWindowWithSimpleMenuBar(w); + QFETCH( bool, forceNonNative ); + initWindowWithSimpleMenuBar(w, forceNonNative); w.show(); QApplication::setActiveWindow(&w); QVERIFY(QTest::qWaitForWindowActive(&w)); @@ -356,6 +358,13 @@ void tst_QMenuBar::activatedCount() //wait(5000); QCOMPARE( m_simpleActivatedCount, 2 ); //1 from the popupmenu and 1 from the menubar } + +void tst_QMenuBar::activatedCount_data() +{ + QTest::addColumn("forceNonNative"); + QTest::newRow( "forcing non-native menubar" ) << true; + QTest::newRow( "not forcing non-native menubar" ) << false; +} #endif void tst_QMenuBar::clear() diff --git a/tests/benchmarks/corelib/tools/qdatetime/main.cpp b/tests/benchmarks/corelib/tools/qdatetime/main.cpp index 8f43a412b7d..2c1e3d97aef 100644 --- a/tests/benchmarks/corelib/tools/qdatetime/main.cpp +++ b/tests/benchmarks/corelib/tools/qdatetime/main.cpp @@ -547,8 +547,9 @@ void tst_QDateTime::currentMSecsSinceEpoch() void tst_QDateTime::fromString() { - QString format = "yyy-MM-dd hh:mm:ss.zzz t"; - QString input = "2010-01-01 13:12:11.999 UTC"; + QString format = "yyyy-MM-dd hh:mm:ss.zzz"; + QString input = "2010-01-01 13:12:11.999"; + QVERIFY(QDateTime::fromString(input, format).isValid()); QBENCHMARK { for (int i = 0; i < 1000; ++i) QDateTime::fromString(input, format); diff --git a/tools/configure/Makefile.mingw b/tools/configure/Makefile.mingw deleted file mode 100644 index e589ea35263..00000000000 --- a/tools/configure/Makefile.mingw +++ /dev/null @@ -1,129 +0,0 @@ -CORESRC = $(QTSRC)src/corelib -TOOLSRC = $(QTSRC)tools -CONFSRC = $(TOOLSRC)/configure - -RAW_PCH = configure_pch.h -PCH = $(RAW_PCH).gch/c++ -DEFINES = -DUNICODE -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -DQT_USE_QSTRINGBUILDER -DQT_VERSION_STR=\"$(QTVERSION)\" -DQT_VERSION_MAJOR=$(QT_VERSION_MAJOR) -DQT_VERSION_MINOR=$(QT_VERSION_MINOR) -DQT_VERSION_PATCH=$(QT_VERSION_PATCH) -INCPATH = -I"../../include" -I"../../include/QtCore" -I"../../include/QtCore/$(QTVERSION)" -I"../../include/QtCore/$(QTVERSION)/QtCore" -I"$(TOOLSRC)/shared" -I"$(QTSRC)mkspecs/win32-g++" -CXXFLAGS_BARE = -std=c++11 -fno-rtti -fno-exceptions -mthreads -Wall -Wextra $(DEFINES) $(INCPATH) -CXXFLAGS = -include $(RAW_PCH) $(CXXFLAGS_BARE) -LINK = g++ -LFLAGS = -Wl,-subsystem,console -mthreads -LIBS = -lole32 -ladvapi32 -luuid - -TARGET = ../../configureapp.exe - -OBJECTS = \ - main.o \ - configureapp.o \ - environment.o \ - qarraydata.o \ - qbytearray.o \ - qbytearraymatcher.o \ - qhash.o \ - qlist.o \ - qlocale.o \ - qlocale_win.o \ - qlocale_tools.o \ - qvector.o \ - qutfcodec.o \ - qtextcodec.o \ - qglobal.o \ - qnumeric.o \ - qbuffer.o \ - qdatastream.o \ - qdir.o \ - qdiriterator.o \ - qfiledevice.o \ - qfile.o \ - qfileinfo.o \ - qabstractfileengine.o \ - qfilesystementry.o \ - qfilesystemengine.o \ - qfilesystemengine_win.o \ - qfilesystemiterator_win.o \ - qfsfileengine.o \ - qfsfileengine_win.o \ - qfsfileengine_iterator.o \ - qiodevice.o \ - qoperatingsystemversion.o \ - qoperatingsystemversion_win.o \ - qringbuffer.o \ - qdebug.o \ - qtextstream.o \ - qlogging.o \ - qtemporaryfile.o \ - qstandardpaths.o \ - qstandardpaths_win.o \ - qsystemlibrary.o \ - qbitarray.o \ - qdatetime.o \ - qmap.o \ - qregexp.o \ - qstring.o \ - qstring_compat.o \ - qstringbuilder.o \ - qstringlist.o \ - qvsnprintf.o \ - qvariant.o \ - qsystemerror.o \ - qmetatype.o \ - qmalloc.o \ - qxmlstream.o \ - qxmlutils.o \ - quuid.o \ - registry.o - -$(TARGET): $(OBJECTS) - $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS) - -$(OBJECTS): $(PCH) - -# SHELL is the full path of sh.exe, unless -# 1) it is found in the current directory -# 2) it is not found at all -# 3) it is overridden on the command line with an existing file -# ... otherwise it is always sh.exe. Specifically, SHELL from the -# environment has no effect. -# -# This check will fail if SHELL is explicitly set to a not -# sh-compatible shell. This is not a problem, because configure.bat -# will not do that. -ifeq ($(SHELL), sh.exe) - ifeq ($(wildcard "$(CURDIR)/sh.exe"), ) - SH = 0 - else - SH = 1 - endif -else - SH = 1 -endif - -ifeq ($(SH), 1) - CHK_DIR_EXISTS = test -d - CHK_DIR_EXISTS_GLUE = || - MKDIR = mkdir -p -else - CHK_DIR_EXISTS = if not exist - CHK_DIR_EXISTS_GLUE = - MKDIR = md -endif - -$(PCH): $(CONFSRC)/configure_pch.h - @$(CHK_DIR_EXISTS) $(RAW_PCH).gch $(CHK_DIR_EXISTS_GLUE) $(MKDIR) $(RAW_PCH).gch - $(CXX) -x c++-header -c $(CXXFLAGS_BARE) -o $@ $< - -VPATH = $(CONFSRC):$(TOOLSRC)/shared/windows:$(CORESRC)/global:$(CORESRC)/kernel:$(CORESRC)/tools:$(CORESRC)/codecs:$(CORESRC)/io:$(CORESRC)/xml:$(CORESRC)/plugin - -main.o: $(CONFSRC)/configureapp.h -configureapp.o: $(CONFSRC)/configureapp.h $(CONFSRC)/environment.h -environment.o: $(CONFSRC)/environment.h - -# Make sure qstring_compat.obj isn't compiled with PCH enabled -qstring_compat.o: $(CORESRC)/tools/qstring_compat.cpp - $(CXX) -c $(CXXFLAGS_BARE) -o $@ $< - -clean: - -rm -f *.o - -rm -rf *.gch diff --git a/tools/configure/Makefile.win32 b/tools/configure/Makefile.win32 deleted file mode 100644 index cc56610578a..00000000000 --- a/tools/configure/Makefile.win32 +++ /dev/null @@ -1,183 +0,0 @@ -CORESRC = $(QTSRC)src\corelib -TOOLSRC = $(QTSRC)tools -CONFSRC = $(TOOLSRC)\configure - -DEFINES = -DUNICODE -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -DQT_USE_QSTRINGBUILDER -DQT_VERSION_STR=\"$(QTVERSION)\" -DQT_VERSION_MAJOR=$(QT_VERSION_MAJOR) -DQT_VERSION_MINOR=$(QT_VERSION_MINOR) -DQT_VERSION_PATCH=$(QT_VERSION_PATCH) -INCPATH = -I"..\..\include" -I"..\..\include\QtCore" -I"..\..\include\QtCore\$(QTVERSION)" -I"..\..\include\QtCore\$(QTVERSION)\QtCore" -I"$(TOOLSRC)\shared" -I"$(QTSRC)mkspecs\win32-msvc2012" -CXXFLAGS_BARE = -nologo -Zc:wchar_t -W3 -GR -EHsc -w34100 -w34189 -wd4577 $(CFLAGS_CRT) $(EXTRA_CXXFLAGS) $(DEFINES) $(INCPATH) -!IF ("$(CXX)" != "clang-cl") -PCH = configure_pch.pch -PCH_OBJECT = configure_pch.obj -CXXFLAGS = -FIconfigure_pch.h -Yuconfigure_pch.h -Fp$(PCH) -MP $(CXXFLAGS_BARE) -!ELSE -PCH = -CXXFLAGS = -Wmicrosoft $(CXXFLAGS_BARE) -!ENDIF -LINK = link -LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT /INCREMENTAL:NO /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:"configure.intermediate.manifest" -LIBS = ole32.lib advapi32.lib shell32.lib - -TARGET = ..\..\configureapp.exe - -OBJECTS = \ - main.obj \ - configureapp.obj \ - environment.obj \ - qarraydata.obj \ - qbytearray.obj \ - qbytearraymatcher.obj \ - qhash.obj \ - qlist.obj \ - qlocale.obj \ - qlocale_win.obj \ - qlocale_tools.obj \ - qvector.obj \ - qutfcodec.obj \ - qtextcodec.obj \ - qglobal.obj \ - qnumeric.obj \ - qoperatingsystemversion.obj \ - qoperatingsystemversion_win.obj \ - qbuffer.obj \ - qdatastream.obj \ - qdir.obj \ - qdiriterator.obj \ - qfiledevice.obj \ - qfile.obj \ - qfileinfo.obj \ - qabstractfileengine.obj \ - qfilesystementry.obj \ - qfilesystemengine.obj \ - qfilesystemengine_win.obj \ - qfilesystemiterator_win.obj \ - qfsfileengine.obj \ - qfsfileengine_win.obj \ - qfsfileengine_iterator.obj \ - qiodevice.obj \ - qringbuffer.obj \ - qdebug.obj \ - qtextstream.obj \ - qlogging.obj \ - qtemporaryfile.obj \ - qstandardpaths.obj \ - qstandardpaths_win.obj \ - qsystemlibrary.obj \ - qbitarray.obj \ - qdatetime.obj \ - qmap.obj \ - qregexp.obj \ - qstring.obj \ - qstring_compat.obj \ - qstringbuilder.obj \ - qstringlist.obj \ - qvsnprintf.obj \ - qvariant.obj \ - qsystemerror.obj \ - qmetatype.obj \ - qmalloc.obj \ - qxmlstream.obj \ - qxmlutils.obj \ - quuid.obj \ - registry.obj \ - $(PCH_OBJECT) - -$(TARGET): $(OBJECTS) - $(LINK) $(LFLAGS) /OUT:$(TARGET) @<< - $(OBJECTS) $(LIBS) -<< - mt.exe -nologo -manifest "configure.intermediate.manifest" -outputresource:$(TARGET);1 - -clean: - -del *.obj - -del *.pch - -del configure.intermediate.manifest - -$(PCH): $(CONFSRC)\configure_pch.h - $(CXX) -c -Yc $(CXXFLAGS_BARE) -Fp$@ -Foconfigure_pch.obj -TP $** - -$(OBJECTS): $(PCH) - -main.obj: $(CONFSRC)\main.cpp $(CONFSRC)\configureapp.h $(PCH) -configureapp.obj: $(CONFSRC)\configureapp.cpp $(CONFSRC)\configureapp.h $(CONFSRC)\environment.h $(PCH) -environment.obj: $(CONFSRC)\environment.cpp $(CONFSRC)\environment.h $(PCH) -registry.obj: $(TOOLSRC)\shared\windows\registry.cpp $(PCH) -qarraydata.obj: $(CORESRC)\tools\qarraydata.cpp $(PCH) -qbytearray.obj: $(CORESRC)\tools\qbytearray.cpp $(PCH) -qbytearraymatcher.obj: $(CORESRC)\tools\qbytearraymatcher.cpp $(PCH) -qhash.obj: $(CORESRC)\tools\qhash.cpp $(PCH) -qlist.obj: $(CORESRC)\tools\qlist.cpp $(PCH) -qlocale.obj: $(CORESRC)\tools\qlocale.cpp $(PCH) -qlocale_win.obj: $(CORESRC)\tools\qlocale_win.cpp $(PCH) -qlocale_tools.obj: $(CORESRC)\tools\qlocale_tools.cpp $(PCH) -qvector.obj: $(CORESRC)\tools\qvector.cpp $(PCH) -qutfcodec.obj: $(CORESRC)\codecs\qutfcodec.cpp $(PCH) -qtextcodec.obj: $(CORESRC)\codecs\qtextcodec.cpp $(PCH) -qglobal.obj: $(CORESRC)\global\qglobal.cpp $(PCH) -qnumeric.obj: $(CORESRC)\global\qnumeric.cpp $(PCH) -qoperatingsystemversion.obj: $(CORESRC)\global\qoperatingsystemversion.cpp $(PCH) -qoperatingsystemversion_win.obj: $(CORESRC)\global\qoperatingsystemversion_win.cpp $(PCH) -qbuffer.obj: $(CORESRC)\io\qbuffer.cpp $(PCH) -qdatastream.obj: $(CORESRC)\io\qdatastream.cpp $(PCH) -qdir.obj: $(CORESRC)\io\qdir.cpp $(PCH) -qdiriterator.obj: $(CORESRC)\io\qdiriterator.cpp $(PCH) -qfiledevice.obj: $(CORESRC)\io\qfiledevice.cpp $(PCH) -qfile.obj: $(CORESRC)\io\qfile.cpp $(PCH) -qfileinfo.obj: $(CORESRC)\io\qfileinfo.cpp $(PCH) -qabstractfileengine.obj: $(CORESRC)\io\qabstractfileengine.cpp $(PCH) -qfilesystementry.obj: $(CORESRC)\io\qfilesystementry.cpp $(PCH) -qfilesystemengine.obj: $(CORESRC)\io\qfilesystemengine.cpp $(PCH) -qfilesystemengine_win.obj: $(CORESRC)\io\qfilesystemengine_win.cpp $(PCH) -qfilesystemiterator_win.obj: $(CORESRC)\io\qfilesystemiterator_win.cpp $(PCH) -qfsfileengine.obj: $(CORESRC)\io\qfsfileengine.cpp $(PCH) -qfsfileengine_win.obj: $(CORESRC)\io\qfsfileengine_win.cpp $(PCH) -qfsfileengine_iterator.obj: $(CORESRC)\io\qfsfileengine_iterator.cpp $(PCH) -qiodevice.obj: $(CORESRC)\io\qiodevice.cpp $(PCH) -qringbuffer.obj: $(CORESRC)\tools\qringbuffer.cpp $(PCH) -qdebug.obj: $(CORESRC)\io\qdebug.cpp $(PCH) -qtextstream.obj: $(CORESRC)\io\qtextstream.cpp $(PCH) -qtemporaryfile.obj: $(CORESRC)\io\qtemporaryfile.cpp $(PCH) -qstandardpaths.obj: $(CORESRC)\io\qstandardpaths.cpp $(PCH) -qstandardpaths_win.obj: $(CORESRC)\io\qstandardpaths_win.cpp $(PCH) -qsystemlibrary.obj: $(CORESRC)\plugin\qsystemlibrary.cpp $(PCH) -qbitarray.obj: $(CORESRC)\tools\qbitarray.cpp $(PCH) -qdatetime.obj: $(CORESRC)\tools\qdatetime.cpp $(PCH) -qmap.obj: $(CORESRC)\tools\qmap.cpp $(PCH) -qregexp.obj: $(CORESRC)\tools\qregexp.cpp $(PCH) -qstring.obj: $(CORESRC)\tools\qstring.cpp $(PCH) -qstringbuilder.obj: $(CORESRC)\tools\qstringbuilder.cpp $(PCH) -qstringlist.obj: $(CORESRC)\tools\qstringlist.cpp $(PCH) -qvsnprintf.obj: $(CORESRC)\tools\qvsnprintf.cpp $(PCH) -qvariant.obj: $(CORESRC)\kernel\qvariant.cpp $(PCH) -qsystemerror.obj: $(CORESRC)\kernel\qsystemerror.cpp $(PCH) -qline.obj: $(CORESRC)\tools\qline.cpp $(PCH) -qsize.obj: $(CORESRC)\tools\qsize.cpp $(PCH) -qpoint.obj: $(CORESRC)\tools\qpoint.cpp $(PCH) -qrect.obj: $(CORESRC)\tools\qrect.cpp $(PCH) -qmetatype.obj: $(CORESRC)\kernel\qmetatype.cpp $(PCH) -qmalloc.obj: $(CORESRC)\global\qmalloc.cpp $(PCH) -qxmlstream.obj: $(CORESRC)\xml\qxmlstream.cpp $(PCH) -qxmlutils.obj: $(CORESRC)\xml\qxmlutils.cpp $(PCH) -quuid.obj: $(CORESRC)\plugin\quuid.cpp $(PCH) - -{$(CONFSRC)}.cpp{}.obj:: - $(CXX) -c $(CXXFLAGS) $< -{$(TOOLSRC)\shared\windows}.cpp{}.obj:: - $(CXX) -c $(CXXFLAGS) $< -{$(CORESRC)\tools}.cpp{}.obj:: - $(CXX) -c $(CXXFLAGS) $< -{$(CORESRC)\codecs}.cpp{}.obj:: - $(CXX) -c $(CXXFLAGS) $< -{$(CORESRC)\global}.cpp{}.obj:: - $(CXX) -c $(CXXFLAGS) $< -{$(CORESRC)\io}.cpp{}.obj:: - $(CXX) -c $(CXXFLAGS) $< -{$(CORESRC)\kernel}.cpp{}.obj:: - $(CXX) -c $(CXXFLAGS) $< -{$(CORESRC)\plugin}.cpp{}.obj:: - $(CXX) -c $(CXXFLAGS) $< -{$(CORESRC)\xml}.cpp{}.obj:: - $(CXX) -c $(CXXFLAGS) $< - -# Make sure qstring_compat.obj isn't compiled with PCH enabled -qstring_compat.obj: $(CORESRC)\tools\qstring_compat.cpp - $(CXX) -c $(CXXFLAGS_BARE) $(CORESRC)\tools\qstring_compat.cpp diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro deleted file mode 100644 index 93e6a197a22..00000000000 --- a/tools/configure/configure.pro +++ /dev/null @@ -1,138 +0,0 @@ -TARGET = configureapp -DESTDIR = $$PWD/../.. # build directly in source dir - -CONFIG += console flat stl rtti_off -CONFIG -= moc qt -DEFINES = UNICODE _CRT_SECURE_NO_DEPRECATE QT_USE_QSTRINGBUILDER -DEFINES += QT_BOOTSTRAPPED QT_BUILD_CONFIGURE - -win32 : LIBS += -lole32 -ladvapi32 -mingw : LIBS += -luuid - -win32-msvc* { - QMAKE_CFLAGS_RELEASE -= -MD - QMAKE_CFLAGS_RELEASE -= -O2 - QMAKE_CFLAGS_RELEASE += -MT -O1 -Os - QMAKE_CFLAGS_DEBUG -= -MDd - QMAKE_CFLAGS_DEBUG += -MTd - QMAKE_CXXFLAGS_RELEASE -= -MD - QMAKE_CXXFLAGS_RELEASE -= -O2 - QMAKE_CXXFLAGS_RELEASE += -MT -O1 -Os - QMAKE_CXXFLAGS_DEBUG -= -MDd - QMAKE_CXXFLAGS_DEBUG += -MTd -} - -PRECOMPILED_HEADER = configure_pch.h - -INCLUDEPATH += \ - $$QT_BUILD_TREE/include \ - $$QT_BUILD_TREE/include/QtCore \ - $$QT_BUILD_TREE/include/QtCore/$$QT.core.VERSION \ - $$QT_BUILD_TREE/include/QtCore/$$QT.core.VERSION/QtCore \ - $$QT_SOURCE_TREE/tools/shared - -HEADERS = configureapp.h environment.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qarraydata.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qbytearray.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qarraydatapointer.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qarraydataops.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qbytearraymatcher.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qchar.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qhash.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qlist.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qlocale.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qvector.h \ - $$QT_SOURCE_TREE/src/corelib/codecs/qutfcodec_p.h \ - $$QT_SOURCE_TREE/src/corelib/codecs/qtextcodec.h \ - $$QT_SOURCE_TREE/src/corelib/global/qglobal.h \ - $$QT_SOURCE_TREE/src/corelib/global/qnumeric.h \ - $$QT_SOURCE_TREE/src/corelib/global/qlogging.h \ - $$QT_SOURCE_TREE/src/corelib/io/qbuffer.h \ - $$QT_SOURCE_TREE/src/corelib/io/qdatastream.h \ - $$QT_SOURCE_TREE/src/corelib/io/qdir.h \ - $$QT_SOURCE_TREE/src/corelib/io/qdiriterator.h \ - $$QT_SOURCE_TREE/src/corelib/io/qfiledevice.h \ - $$QT_SOURCE_TREE/src/corelib/io/qfile.h \ - $$QT_SOURCE_TREE/src/corelib/io/qfileinfo.h \ - $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry_p.h \ - $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine_p.h \ - $$QT_SOURCE_TREE/src/corelib/io/qfilesystemmetadata_p.h \ - $$QT_SOURCE_TREE/src/corelib/io/qfilesystemiterator_p.h \ - $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.h \ - $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator_p.h \ - $$QT_SOURCE_TREE/src/corelib/io/qiodevice.h \ - $$QT_SOURCE_TREE/src/corelib/io/qtextstream.h \ - $$QT_SOURCE_TREE/src/corelib/io/qtemporaryfile.h \ - $$QT_SOURCE_TREE/src/corelib/io/qstandardpaths.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qbitarray.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qdatetime.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qmap.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qregexp.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qringbuffer_p.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qstring.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qstringbuilder.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qstringlist.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qstringmatcher.h \ - $$QT_SOURCE_TREE/src/corelib/tools/qunicodetables_p.h \ - $$QT_SOURCE_TREE/src/corelib/kernel/qsystemerror_p.h \ - $$QT_SOURCE_TREE/src/corelib/xml/qxmlstream.h \ - $$QT_SOURCE_TREE/src/corelib/xml/qxmlutils_p.h \ - $$QT_SOURCE_TREE/tools/shared/windows/registry_p.h - - -SOURCES = main.cpp configureapp.cpp environment.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qbytearray.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qarraydata.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qbytearraymatcher.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qhash.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qlist.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qlocale.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qlocale_win.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qlocale_tools.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qvector.cpp \ - $$QT_SOURCE_TREE/src/corelib/codecs/qutfcodec.cpp \ - $$QT_SOURCE_TREE/src/corelib/codecs/qtextcodec.cpp \ - $$QT_SOURCE_TREE/src/corelib/global/qglobal.cpp \ - $$QT_SOURCE_TREE/src/corelib/global/qnumeric.cpp \ - $$QT_SOURCE_TREE/src/corelib/global/qlogging.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qbuffer.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qdatastream.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qdir.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qdiriterator.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qfiledevice.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qfile.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qfileinfo.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qabstractfileengine.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qfilesystementry.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qfilesystemengine_win.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qfilesystemiterator_win.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_win.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qfsfileengine_iterator.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qiodevice.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qdebug.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qtextstream.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qtemporaryfile.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qstandardpaths.cpp \ - $$QT_SOURCE_TREE/src/corelib/io/qstandardpaths_win.cpp \ - $$QT_SOURCE_TREE/src/corelib/plugin/qsystemlibrary.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qbitarray.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qdatetime.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qmap.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qregexp.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qringbuffer.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qstring.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qstringbuilder.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qstring_compat.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qstringlist.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qvsnprintf.cpp \ - $$QT_SOURCE_TREE/src/corelib/kernel/qvariant.cpp \ - $$QT_SOURCE_TREE/src/corelib/kernel/qsystemerror.cpp \ - $$QT_SOURCE_TREE/src/corelib/kernel/qmetatype.cpp \ - $$QT_SOURCE_TREE/src/corelib/global/qmalloc.cpp \ - $$QT_SOURCE_TREE/src/corelib/xml/qxmlstream.cpp \ - $$QT_SOURCE_TREE/src/corelib/xml/qxmlutils.cpp \ - $$QT_SOURCE_TREE/src/corelib/plugin/quuid.cpp \ - $$QT_SOURCE_TREE/src/corelib/tools/qcryptographichash.cpp \ - $$QT_SOURCE_TREE/tools/shared/windows/registry.cpp diff --git a/tools/configure/configure_pch.h b/tools/configure/configure_pch.h deleted file mode 100644 index 8e36f7e54ea..00000000000 --- a/tools/configure/configure_pch.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ - -// for rand_s, _CRT_RAND_S must be #defined before #including stdlib.h. -// put it at the beginning so some indirect inclusion doesn't break it -#ifndef _CRT_RAND_S -#define _CRT_RAND_S -#endif -#include -#include -#include -#include // All moc genereated code has this include -#include -#include -#include -#include diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp deleted file mode 100644 index 2ffec0707fe..00000000000 --- a/tools/configure/configureapp.cpp +++ /dev/null @@ -1,375 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** 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$ -** -****************************************************************************/ - -#include "configureapp.h" -#include "environment.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -std::ostream &operator<<(std::ostream &s, const QString &val) { - s << val.toLocal8Bit().data(); - return s; -} - - -using namespace std; - -Configure::Configure(int& argc, char** argv) -{ - int i; - - for (i = 1; i < argc; i++) - configCmdLine += argv[ i ]; - - if (configCmdLine.size() >= 2 && configCmdLine.at(0) == "-srcdir") { - sourcePath = QDir::cleanPath(configCmdLine.at(1)); - sourceDir = QDir(sourcePath); - configCmdLine.erase(configCmdLine.begin(), configCmdLine.begin() + 2); - } else { - // Get the path to the executable - wchar_t module_name[MAX_PATH]; - GetModuleFileName(0, module_name, sizeof(module_name) / sizeof(wchar_t)); - QFileInfo sourcePathInfo = QString::fromWCharArray(module_name); - sourcePath = sourcePathInfo.absolutePath(); - sourceDir = sourcePathInfo.dir(); - } - buildPath = QDir::currentPath(); - if (sourceDir != buildDir) { //shadow builds! - QDir(buildPath).mkpath("bin"); - - buildDir.mkpath("mkspecs"); - } - - if (dictionary[ "QMAKESPEC" ].size() == 0) { - dictionary[ "QMAKESPEC" ] = Environment::detectQMakeSpec(); - dictionary[ "QMAKESPEC_FROM" ] = "detected"; - } - - dictionary[ "SYNCQT" ] = "auto"; - - QString tmp = dictionary[ "QMAKESPEC" ]; - if (tmp.contains("\\")) { - tmp = tmp.mid(tmp.lastIndexOf("\\") + 1); - } else { - tmp = tmp.mid(tmp.lastIndexOf("/") + 1); - } - dictionary[ "QMAKESPEC" ] = tmp; -} - -Configure::~Configure() -{ -} - -void Configure::parseCmdLine() -{ - sourcePathMangled = sourcePath; - buildPathMangled = buildPath; - if (configCmdLine.size() && configCmdLine.at(0) == "-top-level") { - dictionary[ "TOPLEVEL" ] = "yes"; - configCmdLine.removeAt(0); - sourcePathMangled = QFileInfo(sourcePath).path(); - buildPathMangled = QFileInfo(buildPath).path(); - } - qmakeCmdLine = configCmdLine; - - int argCount = configCmdLine.size(); - int i = 0; - - // Look first for -redo - for (int k = 0 ; k < argCount; ++k) { - if (configCmdLine.at(k) == "-redo") { - configCmdLine.removeAt(k); - if (!reloadCmdLine(k)) { - dictionary["DONE"] = "error"; - return; - } - argCount = configCmdLine.size(); - break; - } - } - - for (; i -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class Configure -{ -public: - Configure( int& argc, char** argv ); - ~Configure(); - - void parseCmdLine(); - - void buildQmake(); - - void prepareConfigureInput(); - void configure(); - - void generateHeaders(); - - bool isDone(); - bool isOk(); - -private: - int verbose; - - // Our variable dictionaries - QMap dictionary; - QStringList configCmdLine, qmakeCmdLine; - - QString outputLine; - - QTextStream outStream; - QString sourcePath, buildPath; - QString sourcePathMangled, buildPathMangled; - QDir sourceDir, buildDir; - - bool reloadCmdLine(int idx); -}; - -QT_END_NAMESPACE diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp deleted file mode 100644 index 260af276fa9..00000000000 --- a/tools/configure/environment.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** 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$ -** -****************************************************************************/ - -#include "environment.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -//#define CONFIGURE_DEBUG_EXECUTE -//#define CONFIGURE_DEBUG_CP_DIR - -using namespace std; - -#ifdef Q_OS_WIN32 -#include -#endif - -#include // from tools/shared - -QT_BEGIN_NAMESPACE - -struct CompilerInfo{ - Compiler compiler; - const char *compilerStr; - const char *regKey; - const char *executable; -} compiler_info[] = { - // The compilers here are sorted in a reversed-preferred order - {CC_MINGW, "MinGW (Minimalist GNU for Windows)", 0, "g++.exe"}, - {CC_INTEL, "Intel(R) C++ Compiler for 32-bit applications", 0, "icl.exe"}, // xilink.exe, xilink5.exe, xilink6.exe, xilib.exe - {CC_MSVC2012, "Microsoft (R) Visual Studio 2012 C/C++ Compiler (11.0)", "Software\\Microsoft\\VisualStudio\\SxS\\VC7\\11.0", "cl.exe"}, // link.exe, lib.exe - {CC_MSVC2013, "Microsoft (R) Visual Studio 2013 C/C++ Compiler (12.0)", "Software\\Microsoft\\VisualStudio\\SxS\\VC7\\12.0", "cl.exe"}, // link.exe, lib.exe - // Microsoft skipped version 13 - {CC_MSVC2015, "Microsoft (R) Visual Studio 2015 C/C++ Compiler (14.0)", "Software\\Microsoft\\VisualStudio\\SxS\\VS7\\14.0", "cl.exe"}, // link.exe, lib.exe - {CC_MSVC2017, "Microsoft (R) Visual Studio 2017 C/C++ Compiler (15.0)", "Software\\Microsoft\\VisualStudio\\SxS\\VS7\\15.0", "cl.exe"}, // link.exe, lib.exe - {CC_UNKNOWN, "Unknown", 0, 0}, -}; - - -// Initialize static variables -Compiler Environment::detectedCompiler = CC_UNKNOWN; - -/*! - Returns the pointer to the CompilerInfo for a \a compiler. -*/ -CompilerInfo *Environment::compilerInfo(Compiler compiler) -{ - int i = 0; - while(compiler_info[i].compiler != compiler && compiler_info[i].compiler != CC_UNKNOWN) - ++i; - return &(compiler_info[i]); -} - -/*! - Returns the qmakespec for the compiler detected on the system. -*/ -QString Environment::detectQMakeSpec() -{ - QString spec; - switch (detectCompiler()) { - case CC_MSVC2017: - spec = "win32-msvc2017"; - break; - case CC_MSVC2015: - spec = "win32-msvc2015"; - break; - case CC_MSVC2013: - spec = "win32-msvc2013"; - break; - case CC_MSVC2012: - spec = "win32-msvc2012"; - break; - case CC_INTEL: - spec = "win32-icc"; - break; - case CC_MINGW: - spec = "win32-g++"; - break; - default: - break; - } - - return spec; -} - -/*! - Returns the enum of the compiler which was detected on the system. - The compilers are detected in the order as entered into the - compiler_info list. - - If more than one compiler is found, CC_UNKNOWN is returned. -*/ -Compiler Environment::detectCompiler() -{ -#ifndef Q_OS_WIN32 - return CC_UNKNOWN; // Always generate CC_UNKNOWN on other platforms -#else - if(detectedCompiler != CC_UNKNOWN) - return detectedCompiler; - - int installed = 0; - - // Check for compilers in registry first, to see which version is in PATH - QString paths = qgetenv("PATH"); - QStringList pathlist = paths.toLower().split(";"); - for(int i = 0; compiler_info[i].compiler; ++i) { - QString productPath = qt_readRegistryKey(HKEY_LOCAL_MACHINE, compiler_info[i].regKey, - KEY_WOW64_32KEY).toLower(); - if (productPath.length()) { - QStringList::iterator it; - for(it = pathlist.begin(); it != pathlist.end(); ++it) { - if((*it).contains(productPath)) { - if (detectedCompiler != compiler_info[i].compiler) { - ++installed; - detectedCompiler = compiler_info[i].compiler; - } - /* else { - - We detected the same compiler again, which happens when - configure is build with the 64-bit compiler. Skip the - duplicate so that we don't think it's installed twice. - - } - */ - break; - } - } - } - } - - // Now just go looking for the executables, and accept any executable as the lowest version - if (!installed) { - for(int i = 0; compiler_info[i].compiler; ++i) { - QString executable = QString(compiler_info[i].executable).toLower(); - if (executable.length() && !QStandardPaths::findExecutable(executable).isEmpty()) { - if (detectedCompiler != compiler_info[i].compiler) { - ++installed; - detectedCompiler = compiler_info[i].compiler; - } - /* else { - - We detected the same compiler again, which happens when - configure is build with the 64-bit compiler. Skip the - duplicate so that we don't think it's installed twice. - - } - */ - break; - } - } - } - - if (installed > 1) { - cout << "Found more than one known compiler! Using \"" << compilerInfo(detectedCompiler)->compilerStr << "\"" << endl; - detectedCompiler = CC_UNKNOWN; - } - return detectedCompiler; -#endif -}; - -/*! - Creates a commandling from \a program and it \a arguments, - escaping characters that needs it. -*/ -static QString qt_create_commandline(const QString &program, const QStringList &arguments) -{ - QString programName = program; - if (!programName.startsWith("\"") && !programName.endsWith("\"") && programName.contains(" ")) - programName = "\"" + programName + "\""; - programName.replace("/", "\\"); - - QString args; - // add the prgram as the first arrg ... it works better - args = programName + " "; - for (int i=0; i0 && tmp.at(i-1) == '\\') { - --i; - endQuote += "\\"; - } - args += QString(" \"") + tmp.left(i) + endQuote; - } else { - args += ' ' + tmp; - } - } - return args; -} - -/*! - Creates a QByteArray of the \a environment. -*/ -static QByteArray qt_create_environment(const QStringList &environment) -{ - QByteArray envlist; - if (environment.isEmpty()) - return envlist; - - int pos = 0; - // add PATH if necessary (for DLL loading) - QByteArray path = qgetenv("PATH"); - if (environment.filter(QRegExp("^PATH=",Qt::CaseInsensitive)).isEmpty() && !path.isNull()) { - QString tmp = QString(QLatin1String("PATH=%1")).arg(QString::fromLocal8Bit(path)); - uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1); - envlist.resize(envlist.size() + tmpSize); - memcpy(envlist.data() + pos, tmp.utf16(), tmpSize); - pos += tmpSize; - } - // add the user environment - foreach (const QString &tmp, environment) { - uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1); - envlist.resize(envlist.size() + tmpSize); - memcpy(envlist.data() + pos, tmp.utf16(), tmpSize); - pos += tmpSize; - } - // add the 2 terminating 0 (actually 4, just to be on the safe side) - envlist.resize(envlist.size() + 4); - envlist[pos++] = 0; - envlist[pos++] = 0; - envlist[pos++] = 0; - envlist[pos++] = 0; - - return envlist; -} - -/*! - Executes the command described in \a arguments, in the - environment inherited from the parent process, with the - \a additionalEnv settings applied. - \a removeEnv removes the specified environment variables from - the environment of the executed process. - - Returns the exit value of the process, or -1 if the command could - not be executed. - - This function uses _(w)spawnvpe to spawn a process by searching - through the PATH environment variable. -*/ -int Environment::execute(QStringList arguments, const QStringList &additionalEnv, const QStringList &removeEnv) -{ -#ifdef CONFIGURE_DEBUG_EXECUTE - qDebug() << "About to Execute: " << arguments; - qDebug() << " " << QDir::currentPath(); - qDebug() << " " << additionalEnv; - qDebug() << " " << removeEnv; -#endif - // Create the full environment from the current environment and - // the additionalEnv strings, then remove all variables defined - // in removeEnv - QMap fullEnvMap; - LPWSTR envStrings = GetEnvironmentStrings(); - if (envStrings) { - int strLen = 0; - for (LPWSTR envString = envStrings; *(envString); envString += strLen + 1) { - strLen = int(wcslen(envString)); - QString str = QString((const QChar*)envString, strLen); - if (!str.startsWith("=")) { // These are added by the system - int sepIndex = str.indexOf('='); - fullEnvMap.insert(str.left(sepIndex).toUpper(), str.mid(sepIndex +1)); - } - } - } - FreeEnvironmentStrings(envStrings); - - // Add additionalEnv variables - for (int i = 0; i < additionalEnv.count(); ++i) { - const QString &str = additionalEnv.at(i); - int sepIndex = str.indexOf('='); - fullEnvMap.insert(str.left(sepIndex).toUpper(), str.mid(sepIndex +1)); - } - - // Remove removeEnv variables - for (int j = 0; j < removeEnv.count(); ++j) - fullEnvMap.remove(removeEnv.at(j).toUpper()); - - // Add all variables to a QStringList - QStringList fullEnv; - QMapIterator it(fullEnvMap); - while (it.hasNext()) { - it.next(); - fullEnv += QString(it.key() + "=" + it.value()); - } - - // ---------------------------- - QString program = arguments.takeAt(0); - QString args = qt_create_commandline(program, arguments); - QByteArray envlist = qt_create_environment(fullEnv); - - DWORD exitCode = DWORD(-1); - PROCESS_INFORMATION procInfo; - memset(&procInfo, 0, sizeof(procInfo)); - - STARTUPINFO startInfo; - memset(&startInfo, 0, sizeof(startInfo)); - startInfo.cb = sizeof(startInfo); - - bool couldExecute = CreateProcess(0, (wchar_t*)args.utf16(), - 0, 0, true, CREATE_UNICODE_ENVIRONMENT, - envlist.isEmpty() ? 0 : envlist.data(), - 0, &startInfo, &procInfo); - - if (couldExecute) { - WaitForSingleObject(procInfo.hProcess, INFINITE); - GetExitCodeProcess(procInfo.hProcess, &exitCode); - CloseHandle(procInfo.hThread); - CloseHandle(procInfo.hProcess); - } - - - if (exitCode == DWORD(-1)) { - switch(GetLastError()) { - case E2BIG: - cerr << "execute: Argument list exceeds 1024 bytes" << endl; - foreach (const QString &arg, arguments) - cerr << " (" << arg.toLocal8Bit().constData() << ")" << endl; - break; - case ENOENT: - cerr << "execute: File or path is not found (" << program.toLocal8Bit().constData() << ")" << endl; - break; - case ENOEXEC: - cerr << "execute: Specified file is not executable or has invalid executable-file format (" << program.toLocal8Bit().constData() << ")" << endl; - break; - case ENOMEM: - cerr << "execute: Not enough memory is available to execute new process." << endl; - break; - default: - cerr << "execute: Unknown error" << endl; - foreach (const QString &arg, arguments) - cerr << " (" << arg.toLocal8Bit().constData() << ")" << endl; - break; - } - } - return exitCode; -} - -QT_END_NAMESPACE diff --git a/tools/configure/environment.h b/tools/configure/environment.h deleted file mode 100644 index 8415fa10a6c..00000000000 --- a/tools/configure/environment.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ - -#include - -QT_BEGIN_NAMESPACE - - -enum Compiler { - CC_UNKNOWN = 0, - CC_MINGW = 0x02, - CC_INTEL = 0x03, - CC_MSVC2005 = 0x80, - CC_MSVC2008 = 0x90, - CC_MSVC2010 = 0xA0, - CC_MSVC2012 = 0xB0, - CC_MSVC2013 = 0xC0, - CC_MSVC2015 = 0xD0, - CC_MSVC2017 = 0xE0 -}; - -struct CompilerInfo; -class Environment -{ -public: - static Compiler detectCompiler(); - static QString detectQMakeSpec(); - - static int execute(QStringList arguments, const QStringList &additionalEnv, const QStringList &removeEnv); - -private: - static Compiler detectedCompiler; - - static CompilerInfo *compilerInfo(Compiler compiler); -}; - - -QT_END_NAMESPACE diff --git a/tools/configure/main.cpp b/tools/configure/main.cpp deleted file mode 100644 index c6b555d14de..00000000000 --- a/tools/configure/main.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ - -/* -** Configure tool -** -*/ - -#include "configureapp.h" - -QT_BEGIN_NAMESPACE - -int runConfigure( int argc, char** argv ) -{ - Configure app( argc, argv ); - if (!app.isOk()) - return 3; - - app.parseCmdLine(); - if (!app.isOk()) - return 3; - - // Bootstrapped includes. Needed by qmake. - app.generateHeaders(); - if (!app.isOk()) - return 3; - - // Bootstrap qmake. Needed by config tests. - app.buildQmake(); - if (!app.isOk()) - return 3; - - // run qmake based configure - app.configure(); - if (!app.isOk()) - return 3; - - return 0; -} - -QT_END_NAMESPACE - -int main( int argc, char** argv ) -{ - QT_USE_NAMESPACE - return runConfigure(argc, argv); -}