summaryrefslogtreecommitdiffstats
path: root/qmake/generators/win32/msvc_nmake.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qmake/generators/win32/msvc_nmake.cpp')
-rw-r--r--qmake/generators/win32/msvc_nmake.cpp244
1 files changed, 33 insertions, 211 deletions
diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp
index f2cd7c633b..63d89a5388 100644
--- a/qmake/generators/win32/msvc_nmake.cpp
+++ b/qmake/generators/win32/msvc_nmake.cpp
@@ -34,23 +34,10 @@
#include <qdiriterator.h>
#include <qset.h>
-#include <registry_p.h>
-
#include <time.h>
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)
{
@@ -70,180 +57,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t)
if(Option::mkfile::do_stub_makefile)
return MakefileGenerator::writeStubMakefile(t);
#endif
- if (!project->isHostBuild()) {
- if (project->isActiveConfig(QStringLiteral("winrt"))) {
- QString arch = project->first("VCPROJ_ARCH").toQString().toLower();
- QString compiler;
- QString compilerArch;
- 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 {
- 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()) {
- 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");
-
- 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);
- 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");
-
- incDirs << kitDir + QStringLiteral("Extension SDKs/WindowsMobile/")
- + crtVersion + QStringLiteral("/Include/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);
return MakefileGenerator::writeMakefile(t);
}
@@ -263,6 +76,11 @@ void NmakeMakefileGenerator::writeSubMakeCall(QTextStream &t, const QString &cal
Win32MakefileGenerator::writeSubMakeCall(t, callPrefix, makeArguments);
}
+ProStringList NmakeMakefileGenerator::extraSubTargetDependencies()
+{
+ return { "$(MAKEFILE)" };
+}
+
QString NmakeMakefileGenerator::defaultInstall(const QString &t)
{
QString ret = Win32MakefileGenerator::defaultInstall(t);
@@ -277,7 +95,9 @@ QString NmakeMakefileGenerator::defaultInstall(const QString &t)
if (project->isActiveConfig("debug_info")) {
if (t == "dlltarget" || project->values(ProKey(t + ".CONFIG")).indexOf("no_dll") == -1) {
- QString pdb_target = project->first("TARGET") + project->first("TARGET_VERSION_EXT") + ".pdb";
+ const QFileInfo targetFileInfo = project->first("DESTDIR") + project->first("TARGET")
+ + project->first("TARGET_EXT");
+ const QString pdb_target = targetFileInfo.completeBaseName() + ".pdb";
QString src_targ = (project->isEmpty("DESTDIR") ? QString("$(DESTDIR)") : project->first("DESTDIR")) + pdb_target;
QString dst_targ = filePrefixRoot(root, fileFixify(targetdir + pdb_target, FileFixifyAbsolute));
if(!ret.isEmpty())
@@ -345,21 +165,17 @@ QString NmakeMakefileGenerator::var(const ProKey &value) const
|| value == "QMAKE_RUN_CXX_IMP"
|| value == "QMAKE_RUN_CXX");
if ((isRunCpp && usePCH) || (isRunC && usePCHC)) {
- QFileInfo precompHInfo(fileInfo(precompH));
- QString precompH_f = escapeFilePath(precompHInfo.fileName());
+ QString precompH_f = escapeFilePath(fileFixify(precompH, FileFixifyBackwards));
QString precompRule = QString("-c -FI%1 -Yu%2 -Fp%3")
.arg(precompH_f, precompH_f, escapeFilePath(isRunC ? precompPchC : precompPch));
+ // ### For clang_cl 8 we force inline methods to be compiled here instead
+ // linking them from a pch.o file. We do this by pretending we are also doing
+ // the pch.o generation step.
+ if (project->isActiveConfig("clang_cl"))
+ precompRule += QString(" -Xclang -building-pch-with-obj");
QString p = MakefileGenerator::var(value);
p.replace(QLatin1String("-c"), precompRule);
- // Cannot use -Gm with -FI & -Yu, as this gives an
- // internal compiler error, on the newer compilers
- // ### work-around for a VS 2003 bug. Move to some prf file or remove completely.
- p.remove("-Gm");
return p;
- } else if (value == "QMAKE_CXXFLAGS") {
- // Remove internal compiler error option
- // ### work-around for a VS 2003 bug. Move to some prf file or remove completely.
- return MakefileGenerator::var(value).remove("-Gm");
}
}
@@ -418,7 +234,10 @@ void NmakeMakefileGenerator::init()
precompObj = var("PRECOMPILED_DIR") + project->first("TARGET") + "_pch" + Option::obj_ext;
precompPch = var("PRECOMPILED_DIR") + project->first("TARGET") + "_pch.pch";
// Add linking of precompObj (required for whole precompiled classes)
- project->values("OBJECTS") += precompObj;
+ // ### For clang_cl we currently let inline methods be generated in the normal objects,
+ // since the PCH object is buggy (as of clang 8.0.0)
+ if (!project->isActiveConfig("clang_cl"))
+ project->values("OBJECTS") += precompObj;
// Add pch file to cleanup
project->values("QMAKE_CLEAN") += precompPch;
// Return to variable pool
@@ -428,21 +247,23 @@ void NmakeMakefileGenerator::init()
if (usePCHC) {
precompObjC = var("PRECOMPILED_DIR") + project->first("TARGET") + "_pch_c" + Option::obj_ext;
precompPchC = var("PRECOMPILED_DIR") + project->first("TARGET") + "_pch_c.pch";
- project->values("OBJECTS") += precompObjC;
+ if (!project->isActiveConfig("clang_cl"))
+ project->values("OBJECTS") += precompObjC;
project->values("QMAKE_CLEAN") += precompPchC;
project->values("PRECOMPILED_OBJECT_C") = ProStringList(precompObjC);
project->values("PRECOMPILED_PCH_C") = ProStringList(precompPchC);
}
- ProString tgt = project->first("DESTDIR")
- + project->first("TARGET") + project->first("TARGET_VERSION_EXT");
- if(project->isActiveConfig("shared")) {
- project->values("QMAKE_CLEAN").append(tgt + ".exp");
- project->values("QMAKE_DISTCLEAN").append(tgt + ".lib");
+ const QFileInfo targetFileInfo = project->first("DESTDIR") + project->first("TARGET")
+ + project->first("TARGET_EXT");
+ const ProString targetBase = targetFileInfo.path() + '/' + targetFileInfo.completeBaseName();
+ if (project->first("TEMPLATE") == "lib" && project->isActiveConfig("shared")) {
+ project->values("QMAKE_CLEAN").append(targetBase + ".exp");
+ project->values("QMAKE_DISTCLEAN").append(targetBase + ".lib");
}
if (project->isActiveConfig("debug_info")) {
QString pdbfile;
- QString distPdbFile = tgt + ".pdb";
+ QString distPdbFile = targetBase + ".pdb";
if (project->isActiveConfig("staticlib")) {
// For static libraries, the compiler's pdb file and the dist pdb file are the same.
pdbfile = distPdbFile;
@@ -458,8 +279,8 @@ void NmakeMakefileGenerator::init()
project->values("QMAKE_DISTCLEAN").append(distPdbFile);
}
if (project->isActiveConfig("debug")) {
- project->values("QMAKE_CLEAN").append(tgt + ".ilk");
- project->values("QMAKE_CLEAN").append(tgt + ".idb");
+ project->values("QMAKE_CLEAN").append(targetBase + ".ilk");
+ project->values("QMAKE_CLEAN").append(targetBase + ".idb");
} else {
ProStringList &defines = project->values("DEFINES");
if (!defines.contains("NDEBUG"))
@@ -531,12 +352,13 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t)
QDirIterator dit(sourceDir, sourceFilesFilter, QDir::Files | QDir::NoDotAndDotDot);
while (dit.hasNext()) {
dit.next();
- QString &duplicate = fileNames[dit.fileName()];
+ const QFileInfo fi = dit.fileInfo();
+ QString &duplicate = fileNames[fi.completeBaseName()];
if (duplicate.isNull()) {
- duplicate = dit.filePath();
+ duplicate = fi.filePath();
} else {
warn_msg(WarnLogic, "%s conflicts with %s", qPrintable(duplicate),
- qPrintable(dit.filePath()));
+ qPrintable(fi.filePath()));
duplicatesFound = true;
}
}