qmake: rewrite msvc/nmake cross-build environment setup
rather than reproducing vcvarsall.bat's functionality as hard-wired code in the nmake generator, just invoke the actual script from toolchain.prf. this is much easier, more future proof, and - critically - makes the detected variables available to configure's new library & header search facilities. [ChangeLog][Important Behavior Changes][qmake][WinRT] Cross-builds will now ignore pre-set values of %INCLUDE% and %LIB% when building target executables. If necessary, use configure's -I and -L switches when building Qt, and pass QMAKE_INCDIR and QMAKE_LIBDIR on qmake's command line when building own projects. Change-Id: I36f53e8880d6523f3f6f7a44d40d87d04bd06854 Reviewed-by: Thomas Miller <thomaslmiller91@gmail.com> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
This commit is contained in:
parent
ef14c3dc1a
commit
45e4dfb449
44
mkspecs/features/data/dumpvcvars.bat
Normal file
44
mkspecs/features/data/dumpvcvars.bat
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
::
|
||||||
|
:: Copyright (C) 2018 The Qt Company Ltd.
|
||||||
|
:: Contact: https://www.qt.io/licensing/
|
||||||
|
::
|
||||||
|
:: This file is part of the tools applications of the Qt Toolkit.
|
||||||
|
::
|
||||||
|
:: $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||||
|
:: Commercial License Usage
|
||||||
|
:: Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
:: accordance with the commercial license agreement provided with the
|
||||||
|
:: Software or, alternatively, in accordance with the terms contained in
|
||||||
|
:: a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
:: and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
:: information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
::
|
||||||
|
:: GNU General Public License Usage
|
||||||
|
:: Alternatively, this file may be used under the terms of the GNU
|
||||||
|
:: General Public License version 3 as published by the Free Software
|
||||||
|
:: Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
:: included in the packaging of this file. Please review the following
|
||||||
|
:: information to ensure the GNU General Public License requirements will
|
||||||
|
:: be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
::
|
||||||
|
:: $QT_END_LICENSE$
|
||||||
|
::
|
||||||
|
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
|
@echo off
|
||||||
|
|
||||||
|
REM We clear INCLUDE and LIB, because we want to obtain pristine values.
|
||||||
|
REM PATH cannot be cleared, because then the script does not even run,
|
||||||
|
REM and it would be counterproductive anyway (see toolchain.prf).
|
||||||
|
set INCLUDE=
|
||||||
|
set LIB=
|
||||||
|
|
||||||
|
call %* || exit 1
|
||||||
|
REM VS2015 does not set errorlevel in case of failure.
|
||||||
|
if "%INCLUDE%" == "" exit 1
|
||||||
|
|
||||||
|
echo =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
|
||||||
|
echo %INCLUDE%
|
||||||
|
echo %LIB%
|
||||||
|
echo %PATH%
|
@ -1,3 +1,13 @@
|
|||||||
|
defineTest(qtToolchainError) {
|
||||||
|
msg = \
|
||||||
|
$$1 \
|
||||||
|
"===================" \
|
||||||
|
$$2 \
|
||||||
|
"===================" \
|
||||||
|
$$3
|
||||||
|
error($$join(msg, $$escape_expand(\\n)))
|
||||||
|
}
|
||||||
|
|
||||||
defineTest(qtCompilerError) {
|
defineTest(qtCompilerError) {
|
||||||
!cross_compile: \
|
!cross_compile: \
|
||||||
what =
|
what =
|
||||||
@ -5,13 +15,8 @@ defineTest(qtCompilerError) {
|
|||||||
what = " host"
|
what = " host"
|
||||||
else: \
|
else: \
|
||||||
what = " target"
|
what = " target"
|
||||||
msg = \
|
qtToolchainError("Cannot run$$what compiler '$$1'. Output:", $$2, \
|
||||||
"Cannot run$$what compiler '$$1'. Output:" \
|
"Maybe you forgot to setup the environment?")
|
||||||
"===================" \
|
|
||||||
$$2 \
|
|
||||||
"===================" \
|
|
||||||
"Maybe you forgot to setup the environment?"
|
|
||||||
error($$join(msg, $$escape_expand(\\n)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cross_compile:host_build: \
|
cross_compile:host_build: \
|
||||||
@ -125,6 +130,36 @@ defineReplace(qtMakeExpand) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defineReplace(qtSplitPathList) {
|
||||||
|
paths = $$split(1, $$QMAKE_DIRLIST_SEP)
|
||||||
|
ret =
|
||||||
|
for (p, paths): \
|
||||||
|
ret += $$clean_path($$p)
|
||||||
|
return($$ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
defineReplace(qtNmakePathList) {
|
||||||
|
paths =
|
||||||
|
for (p, 1): \
|
||||||
|
paths += $$shell_path($$p)
|
||||||
|
paths ~= s,$${LITERAL_HASH},^$${LITERAL_HASH},g
|
||||||
|
paths ~= s,\\$,\$\$,g
|
||||||
|
return($$join(paths, $$QMAKE_DIRLIST_SEP))
|
||||||
|
}
|
||||||
|
|
||||||
|
msvc {
|
||||||
|
arch = $$lower($$VCPROJ_ARCH)
|
||||||
|
equals(arch, x64): \ # may be "win32" or undefined
|
||||||
|
arch = amd64
|
||||||
|
else: !equals(arch, arm):!equals(arch, arm64): \ # may be "win32" or undefined
|
||||||
|
arch = x86
|
||||||
|
# Consider only WinRT and ARM64 desktop builds to be cross-builds -
|
||||||
|
# the host is assumed to be Intel and capable of running the target
|
||||||
|
# executables (so building for x64 on x86 will break).
|
||||||
|
winrt|equals(arch, arm64): \
|
||||||
|
CONFIG += msvc_cross
|
||||||
|
}
|
||||||
|
|
||||||
isEmpty($${target_prefix}.INCDIRS) {
|
isEmpty($${target_prefix}.INCDIRS) {
|
||||||
#
|
#
|
||||||
# Get default include and library paths from compiler
|
# Get default include and library paths from compiler
|
||||||
@ -264,9 +299,89 @@ isEmpty($${target_prefix}.INCDIRS) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else: msvc_cross {
|
||||||
|
# Use a batch file, because %VAR% in the system() call expands to
|
||||||
|
# the pre-script-call value, and !VAR! cannot be enabled outside
|
||||||
|
# a batch file without invoking another shell instance.
|
||||||
|
cmd = $$system_quote($$system_path($$PWD/data/dumpvcvars.bat))
|
||||||
|
|
||||||
|
hostArch = $$QMAKE_HOST.arch
|
||||||
|
equals(hostArch, x86_64): \
|
||||||
|
hostArch = amd64
|
||||||
|
!equals(arch, $$hostArch): \
|
||||||
|
arch = $${hostArch}_$$arch
|
||||||
|
|
||||||
|
isEmpty(MSVC_VER): \
|
||||||
|
error("Mkspec does not specify MSVC_VER. Cannot continue.")
|
||||||
|
versionAtLeast(MSVC_VER, 15.0) {
|
||||||
|
dir = $$(VSINSTALLDIR)
|
||||||
|
isEmpty(dir): \
|
||||||
|
dir = $$read_registry(HKLM, \
|
||||||
|
"Software\\Microsoft\\VisualStudio\\SxS\\VS7\\$$MSVC_VER", 32)
|
||||||
|
isEmpty(dir): \
|
||||||
|
error("Failed to find the Visual Studio installation directory.")
|
||||||
|
cmd += $$system_quote($$dir\\VC\\Auxiliary\\Build\\vcvarsall.bat) $$arch
|
||||||
|
} else {
|
||||||
|
dir = $$(VCINSTALLDIR)
|
||||||
|
isEmpty(dir): \
|
||||||
|
dir = $$read_registry(HKLM, \
|
||||||
|
"Software\\Microsoft\\VisualStudio\\$$MSVC_VER\\Setup\\VC\\ProductDir", 32)
|
||||||
|
isEmpty(dir): \
|
||||||
|
error("Failed to find the Visual C installation directory.")
|
||||||
|
cmd += $$system_quote($$dir\\vcvarsall.bat) $$arch
|
||||||
|
}
|
||||||
|
winrt: cmd += store
|
||||||
|
|
||||||
|
isEmpty(WINSDK_VER): \
|
||||||
|
error("Mkspec does not specify WINSDK_VER. Cannot continue.")
|
||||||
|
# We prefer the environment variable, because that may work around
|
||||||
|
# a broken registry entry after uninstalling a newer SDK.
|
||||||
|
# However, we do that only if the major+minor SDK version matches
|
||||||
|
# the one requested by the mkspec, as we might be building for a
|
||||||
|
# newer target than the host.
|
||||||
|
winsdk_ver = $$(WindowsSDKVersion)
|
||||||
|
!isEmpty(winsdk_ver) {
|
||||||
|
winsdk_ver ~= s,\\\\$,, # Work around SDK breakage.
|
||||||
|
!equals(WINSDK_VER, $$replace(winsdk_ver, ^(\\d+\\.\\d+).*$, \\1)): \
|
||||||
|
winsdk_ver =
|
||||||
|
}
|
||||||
|
!isEmpty(winsdk_ver) {
|
||||||
|
cmd += $$winsdk_ver
|
||||||
|
} else {
|
||||||
|
winsdk_ver = $$read_registry(HKLM, \
|
||||||
|
"Software\\Microsoft\\Microsoft SDKs\\Windows\\v$$WINSDK_VER\\ProductVersion", 32)
|
||||||
|
isEmpty(winsdk_ver): \
|
||||||
|
error("Windows SDK $$WINSDK_VER requested by mkspec is not installed. Cannot continue.")
|
||||||
|
cmd += $${winsdk_ver}.0
|
||||||
|
}
|
||||||
|
|
||||||
|
output = $$system("$$cmd 2>&1", lines, ec)
|
||||||
|
!equals(ec, 0): \
|
||||||
|
qtToolchainError("SDK setup script failed. Output:", $$output, \
|
||||||
|
"Command was: $$cmd")
|
||||||
|
lines = $$output
|
||||||
|
for(ever) {
|
||||||
|
isEmpty(lines): \
|
||||||
|
break()
|
||||||
|
line = $$take_first(lines)
|
||||||
|
equals(line, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+="): \
|
||||||
|
break()
|
||||||
|
}
|
||||||
|
!count(lines, 3): \
|
||||||
|
qtToolchainError("SDK setup script returned unexpected output:", $$output, \
|
||||||
|
"Command was: $$cmd")
|
||||||
|
|
||||||
|
# These contain only paths for the target.
|
||||||
|
QMAKE_DEFAULT_INCDIRS = $$qtSplitPathList($$member(lines, 0))
|
||||||
|
QMAKE_DEFAULT_LIBDIRS = $$qtSplitPathList($$member(lines, 1))
|
||||||
|
# PATH is inherently for the host, and paths that are not shadowed
|
||||||
|
# by vcvarsall.bat are assumed to contain only tools that work for
|
||||||
|
# both host and target builds.
|
||||||
|
QMAKE_DEFAULT_PATH = $$qtSplitPathList($$member(lines, 2))
|
||||||
|
# We de-duplicate, because the script just prepends to the paths for
|
||||||
|
# the host, some of which are identical to the ones for the target.
|
||||||
|
QMAKE_DEFAULT_PATH = $$unique(QMAKE_DEFAULT_PATH)
|
||||||
} else: msvc {
|
} else: msvc {
|
||||||
# This doesn't differentiate between host and target,
|
|
||||||
# but neither do the compilers.
|
|
||||||
LIB = $$getenv("LIB")
|
LIB = $$getenv("LIB")
|
||||||
QMAKE_DEFAULT_LIBDIRS = $$split(LIB, $$QMAKE_DIRLIST_SEP)
|
QMAKE_DEFAULT_LIBDIRS = $$split(LIB, $$QMAKE_DIRLIST_SEP)
|
||||||
INCLUDE = $$getenv("INCLUDE")
|
INCLUDE = $$getenv("INCLUDE")
|
||||||
@ -283,9 +398,22 @@ isEmpty($${target_prefix}.INCDIRS) {
|
|||||||
cache($${target_prefix}.INCDIRS, set stash, QMAKE_DEFAULT_INCDIRS)
|
cache($${target_prefix}.INCDIRS, set stash, QMAKE_DEFAULT_INCDIRS)
|
||||||
!isEmpty(QMAKE_DEFAULT_LIBDIRS): \
|
!isEmpty(QMAKE_DEFAULT_LIBDIRS): \
|
||||||
cache($${target_prefix}.LIBDIRS, set stash, QMAKE_DEFAULT_LIBDIRS)
|
cache($${target_prefix}.LIBDIRS, set stash, QMAKE_DEFAULT_LIBDIRS)
|
||||||
|
!isEmpty(QMAKE_DEFAULT_PATH): \
|
||||||
|
cache($${target_prefix}.PATH, set stash, QMAKE_DEFAULT_PATH)
|
||||||
} else {
|
} else {
|
||||||
QMAKE_DEFAULT_INCDIRS = $$eval($${target_prefix}.INCDIRS)
|
QMAKE_DEFAULT_INCDIRS = $$eval($${target_prefix}.INCDIRS)
|
||||||
QMAKE_DEFAULT_LIBDIRS = $$eval($${target_prefix}.LIBDIRS)
|
QMAKE_DEFAULT_LIBDIRS = $$eval($${target_prefix}.LIBDIRS)
|
||||||
|
QMAKE_DEFAULT_PATH = $$eval($${target_prefix}.PATH)
|
||||||
|
}
|
||||||
|
|
||||||
|
msvc_cross {
|
||||||
|
qmake_inc_exp.name = INCLUDE
|
||||||
|
qmake_inc_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_INCDIRS)
|
||||||
|
qmake_lib_exp.name = LIB
|
||||||
|
qmake_lib_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_LIBDIRS)
|
||||||
|
qmake_path_exp.name = PATH
|
||||||
|
qmake_path_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_PATH)
|
||||||
|
QMAKE_EXPORTED_VARIABLES += qmake_inc_exp qmake_lib_exp qmake_path_exp
|
||||||
}
|
}
|
||||||
|
|
||||||
unset(target_prefix)
|
unset(target_prefix)
|
||||||
|
@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One
|
|||||||
|
|
||||||
VCPROJ_ARCH = ARM
|
VCPROJ_ARCH = ARM
|
||||||
WINSDK_VER = 10.0
|
WINSDK_VER = 10.0
|
||||||
WINTARGET_VER = winv10.0
|
|
||||||
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
|
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
|
||||||
WINRT_MANIFEST.architecture = arm
|
WINRT_MANIFEST.architecture = arm
|
||||||
|
@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One
|
|||||||
|
|
||||||
VCPROJ_ARCH = ARM
|
VCPROJ_ARCH = ARM
|
||||||
WINSDK_VER = 10.0
|
WINSDK_VER = 10.0
|
||||||
WINTARGET_VER = winv10.0
|
|
||||||
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
|
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
|
||||||
WINRT_MANIFEST.architecture = arm
|
WINRT_MANIFEST.architecture = arm
|
||||||
|
@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One
|
|||||||
|
|
||||||
VCPROJ_ARCH = x64
|
VCPROJ_ARCH = x64
|
||||||
WINSDK_VER = 10.0
|
WINSDK_VER = 10.0
|
||||||
WINTARGET_VER = winv10.0
|
|
||||||
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
|
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
|
||||||
WINRT_MANIFEST.architecture = x64
|
WINRT_MANIFEST.architecture = x64
|
||||||
|
@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One
|
|||||||
|
|
||||||
VCPROJ_ARCH = x64
|
VCPROJ_ARCH = x64
|
||||||
WINSDK_VER = 10.0
|
WINSDK_VER = 10.0
|
||||||
WINTARGET_VER = winv10.0
|
|
||||||
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
|
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
|
||||||
WINRT_MANIFEST.architecture = x64
|
WINRT_MANIFEST.architecture = x64
|
||||||
|
@ -14,6 +14,5 @@ QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib
|
|||||||
QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib
|
QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib
|
||||||
VCPROJ_ARCH = Win32
|
VCPROJ_ARCH = Win32
|
||||||
WINSDK_VER = 10.0
|
WINSDK_VER = 10.0
|
||||||
WINTARGET_VER = winv10.0
|
|
||||||
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
|
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
|
||||||
WINRT_MANIFEST.architecture = x86
|
WINRT_MANIFEST.architecture = x86
|
||||||
|
@ -14,6 +14,5 @@ QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib
|
|||||||
QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib
|
QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib
|
||||||
VCPROJ_ARCH = Win32
|
VCPROJ_ARCH = Win32
|
||||||
WINSDK_VER = 10.0
|
WINSDK_VER = 10.0
|
||||||
WINTARGET_VER = winv10.0
|
|
||||||
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
|
WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
|
||||||
WINRT_MANIFEST.architecture = x86
|
WINRT_MANIFEST.architecture = x86
|
||||||
|
@ -34,23 +34,10 @@
|
|||||||
#include <qdiriterator.h>
|
#include <qdiriterator.h>
|
||||||
#include <qset.h>
|
#include <qset.h>
|
||||||
|
|
||||||
#include <registry_p.h>
|
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
static QString nmakePathList(const QStringList &list)
|
|
||||||
{
|
|
||||||
QStringList pathList;
|
|
||||||
pathList.reserve(list.size());
|
|
||||||
for (const QString &path : list)
|
|
||||||
pathList.append(QDir::cleanPath(path));
|
|
||||||
|
|
||||||
return QDir::toNativeSeparators(pathList.join(QLatin1Char(';')))
|
|
||||||
.replace('#', QLatin1String("^#")).replace('$', QLatin1String("$$"));
|
|
||||||
}
|
|
||||||
|
|
||||||
NmakeMakefileGenerator::NmakeMakefileGenerator() : usePCH(false), usePCHC(false)
|
NmakeMakefileGenerator::NmakeMakefileGenerator() : usePCH(false), usePCHC(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -70,194 +57,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t)
|
|||||||
if(Option::mkfile::do_stub_makefile)
|
if(Option::mkfile::do_stub_makefile)
|
||||||
return MakefileGenerator::writeStubMakefile(t);
|
return MakefileGenerator::writeStubMakefile(t);
|
||||||
#endif
|
#endif
|
||||||
if (!project->isHostBuild()) {
|
|
||||||
const QString msvcVer = project->first("MSVC_VER").toQString();
|
|
||||||
if (msvcVer.isEmpty()) {
|
|
||||||
fprintf(stderr, "Mkspec does not specify MSVC_VER. Cannot continue.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool winrtBuild = false;
|
|
||||||
bool crossPlatformDesktopBuild = false;
|
|
||||||
QString arch = project->first("VCPROJ_ARCH").toQString().toLower();
|
|
||||||
if (project->isActiveConfig(QStringLiteral("winrt"))) {
|
|
||||||
winrtBuild = true;
|
|
||||||
|
|
||||||
// Only add explicit support for arm64 cross-platform desktop builds.
|
|
||||||
} else if ((arch == QLatin1String("arm64")) && (msvcVer == QStringLiteral("15.0"))) {
|
|
||||||
crossPlatformDesktopBuild = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (winrtBuild || crossPlatformDesktopBuild) {
|
|
||||||
QString compiler;
|
|
||||||
QString compilerArch;
|
|
||||||
const ProStringList hostArch = project->values("QMAKE_TARGET.arch");
|
|
||||||
if (msvcVer == QStringLiteral("15.0")) {
|
|
||||||
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 if (arch == QLatin1String("arm64")) {
|
|
||||||
compiler += QStringLiteral("arm64");
|
|
||||||
compilerArch = QStringLiteral("arm64");
|
|
||||||
} else {
|
|
||||||
arch = QStringLiteral("x86");
|
|
||||||
compiler += QStringLiteral("x86");
|
|
||||||
}
|
|
||||||
} 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");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const QString targetVer = project->first("WINTARGET_VER").toQString();
|
|
||||||
if (targetVer.isEmpty() && winrtBuild) {
|
|
||||||
fprintf(stderr, "Mkspec does not specify WINTARGET_VER. Cannot continue.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
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");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString windowsPath = "Software\\Microsoft\\Microsoft SDKs\\Windows\\v";
|
|
||||||
|
|
||||||
regKey = windowsPath + winsdkVer + QStringLiteral("\\InstallationFolder");
|
|
||||||
const QString kitDir = qt_readRegistryKey(HKEY_LOCAL_MACHINE, regKey, KEY_WOW64_32KEY);
|
|
||||||
if (kitDir.isEmpty()) {
|
|
||||||
fprintf(stderr, "Failed to find the Windows Kit installation directory.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
const QString vcInstallDir = "/fake/vc_install_dir";
|
|
||||||
const QString kitDir = "/fake/sdk_install_dir";
|
|
||||||
#endif // Q_OS_WIN
|
|
||||||
QStringList incDirs;
|
|
||||||
QStringList libDirs;
|
|
||||||
QStringList binDirs;
|
|
||||||
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");
|
|
||||||
|
|
||||||
if (winrtBuild) {
|
|
||||||
libDirs << toolsInstallDir + QStringLiteral("lib/") + arch + QStringLiteral("/store");
|
|
||||||
} else {
|
|
||||||
// Desktop projects may require the atl headers and libs.
|
|
||||||
incDirs << toolsInstallDir + QStringLiteral("atlmfc/include");
|
|
||||||
libDirs << toolsInstallDir + QStringLiteral("atlmfc/lib/") + compilerArch;
|
|
||||||
libDirs << toolsInstallDir + QStringLiteral("lib/") + arch;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
binDirs << vcInstallDir + QStringLiteral("../Common7/Tools/bin");
|
|
||||||
binDirs << vcInstallDir + QStringLiteral("../Common7/Tools");
|
|
||||||
binDirs << vcInstallDir + QStringLiteral("../Common7/ide");
|
|
||||||
binDirs << kitDir + QStringLiteral("Windows Performance Toolkit/");
|
|
||||||
|
|
||||||
incDirs << vcInstallDir + QStringLiteral("include");
|
|
||||||
incDirs << vcInstallDir + QStringLiteral("atlmfc/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");
|
|
||||||
|
|
||||||
libDirs << vcInstallDir + QStringLiteral("lib/store/") + compilerArch;
|
|
||||||
libDirs << vcInstallDir + QStringLiteral("atlmfc/lib") + compilerArch;
|
|
||||||
|
|
||||||
libDirs << crtLib + QStringLiteral("/ucrt/") + arch;
|
|
||||||
libDirs << crtLib + QStringLiteral("/um/") + arch;
|
|
||||||
} else {
|
|
||||||
incDirs << vcInstallDir + QStringLiteral("/include");
|
|
||||||
libDirs << vcInstallDir + QStringLiteral("/lib/store/") + compilerArch
|
|
||||||
<< vcInstallDir + QStringLiteral("/lib/") + compilerArch;
|
|
||||||
binDirs << vcInstallDir + QStringLiteral("/bin/") + compiler
|
|
||||||
<< vcInstallDir + QStringLiteral("/../Common7/IDE");
|
|
||||||
libDirs << kitDir + QStringLiteral("/Lib/") + targetVer + ("/um/") + arch;
|
|
||||||
incDirs << kitDir + QStringLiteral("/include/um")
|
|
||||||
<< kitDir + QStringLiteral("/include/shared")
|
|
||||||
<< kitDir + QStringLiteral("/include/winrt");
|
|
||||||
}
|
|
||||||
|
|
||||||
binDirs << vcInstallDir + QStringLiteral("/bin");
|
|
||||||
|
|
||||||
// Inherit PATH
|
|
||||||
binDirs << QString::fromLocal8Bit(qgetenv("PATH")).split(QLatin1Char(';'));
|
|
||||||
|
|
||||||
t << "\nINCLUDE = " << nmakePathList(incDirs);
|
|
||||||
t << "\nLIB = " << nmakePathList(libDirs);
|
|
||||||
t << "\nPATH = " << nmakePathList(binDirs) << '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writeNmakeParts(t);
|
writeNmakeParts(t);
|
||||||
return MakefileGenerator::writeMakefile(t);
|
return MakefileGenerator::writeMakefile(t);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user