diff options
Diffstat (limited to 'qmake/generators/win32/msvc_nmake.cpp')
-rw-r--r-- | qmake/generators/win32/msvc_nmake.cpp | 244 |
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; } } |