summaryrefslogtreecommitdiffstats
path: root/qmake/generators/win32
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@theqtcompany.com>2014-12-22 14:54:08 +0100
committerJoerg Bornemann <joerg.bornemann@theqtcompany.com>2015-01-28 12:33:18 +0000
commit5582851c33a768cfe63a418da0bf0df69260f227 (patch)
treed477e777afb11922f97ad2aa7032620022448a09 /qmake/generators/win32
parentce9c4915d53c9dabfa3b5a28e62ecd2bb49337d4 (diff)
turn off nmake inference rule generation on detected conflicts
When there are source files with the same file name in different directories of the project, then nmake's inference rules might pick up the wrong source file. Note that this even happens when only one of those files is in SOURCES. The existence of conflicting file names is enough to cause hard-to-find build failures. The usual work-around for this situation is CONFIG+=no_batch. This is now done automatically when a conflict situation is detected and a warning message is printed. Task-number: QTBUG-13496 Change-Id: Icd81027407d3d489dbc50231e5ed8bcb91f8d2bc Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Diffstat (limited to 'qmake/generators/win32')
-rw-r--r--qmake/generators/win32/msvc_nmake.cpp53
-rw-r--r--qmake/generators/win32/msvc_nmake.h1
2 files changed, 48 insertions, 6 deletions
diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp
index 37e247c5cb..e6170e4825 100644
--- a/qmake/generators/win32/msvc_nmake.cpp
+++ b/qmake/generators/win32/msvc_nmake.cpp
@@ -37,6 +37,7 @@
#include <qregexp.h>
#include <qdir.h>
+#include <qdiriterator.h>
#include <qset.h>
#include <windows/registry_p.h>
@@ -425,6 +426,17 @@ void NmakeMakefileGenerator::init()
}
}
+QStringList NmakeMakefileGenerator::sourceFilesForImplicitRulesFilter()
+{
+ QStringList filter;
+ const QChar wildcard = QLatin1Char('*');
+ foreach (const QString &ext, Option::c_ext)
+ filter << wildcard + ext;
+ foreach (const QString &ext, Option::cpp_ext)
+ filter << wildcard + ext;
+ return filter;
+}
+
void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t)
{
t << ".SUFFIXES:";
@@ -434,12 +446,9 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t)
t << " " << (*cppit);
t << endl << endl;
- if(!project->isActiveConfig("no_batch")) {
- // Batchmode doesn't use the non implicit rules QMAKE_RUN_CXX & QMAKE_RUN_CC
- project->variables().remove("QMAKE_RUN_CXX");
- project->variables().remove("QMAKE_RUN_CC");
-
- QSet<QString> source_directories;
+ bool useInferenceRules = !project->isActiveConfig("no_batch");
+ QSet<QString> source_directories;
+ if (useInferenceRules) {
source_directories.insert(".");
static const char * const directories[] = { "UI_SOURCES_DIR", "UI_DIR", 0 };
for (int y = 0; directories[y]; y++) {
@@ -462,6 +471,38 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t)
}
}
+ // nmake's inference rules might pick up the wrong files when encountering source files with
+ // the same name in different directories. In this situation, turn inference rules off.
+ QHash<QString, QString> fileNames;
+ bool duplicatesFound = false;
+ const QStringList sourceFilesFilter = sourceFilesForImplicitRulesFilter();
+ QStringList fixifiedSourceDirs = fileFixify(source_directories.toList(), FileFixifyAbsolute);
+ fixifiedSourceDirs.removeDuplicates();
+ foreach (const QString &sourceDir, fixifiedSourceDirs) {
+ QDirIterator dit(sourceDir, sourceFilesFilter, QDir::Files | QDir::NoDotAndDotDot);
+ while (dit.hasNext()) {
+ dit.next();
+ QString &duplicate = fileNames[dit.fileName()];
+ if (duplicate.isNull()) {
+ duplicate = dit.filePath();
+ } else {
+ warn_msg(WarnLogic, "%s conflicts with %s", qPrintable(duplicate),
+ qPrintable(dit.filePath()));
+ duplicatesFound = true;
+ }
+ }
+ }
+ if (duplicatesFound) {
+ useInferenceRules = false;
+ warn_msg(WarnLogic, "Automatically turning off nmake's inference rules. (CONFIG += no_batch)");
+ }
+ }
+
+ if (useInferenceRules) {
+ // Batchmode doesn't use the non implicit rules QMAKE_RUN_CXX & QMAKE_RUN_CC
+ project->variables().remove("QMAKE_RUN_CXX");
+ project->variables().remove("QMAKE_RUN_CC");
+
foreach (const QString &sourceDir, source_directories) {
if (sourceDir.isEmpty())
continue;
diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h
index 753223b98e..c514fa4452 100644
--- a/qmake/generators/win32/msvc_nmake.h
+++ b/qmake/generators/win32/msvc_nmake.h
@@ -48,6 +48,7 @@ class NmakeMakefileGenerator : public Win32MakefileGenerator
void writeLinkCommand(QTextStream &t, const QString &extraFlags = QString(), const QString &extraInlineFileContent = QString());
int msvcVersion() const;
void init();
+ static QStringList sourceFilesForImplicitRulesFilter();
protected:
virtual void writeSubMakeCall(QTextStream &t, const QString &callPrefix,