Fix circular dependencies in generated vcxproj files

For QMAKE_EXTRA_COMPILERS with inputs that are "buildable" (e.g. C++
sources) the custom build step is added to the output file. From Visual
Studio's point of view this looks like a circular dependency (e.g.
foo.moc generates foo.moc). Usually this just prints a warning that can
be ignored. But this circular dependency also breaks dependencies
between custom build steps. This became noticeable when the generation of
moc_predefs.h was added. Generating moc_predefs.h must be done before
any moc custom build step is executed.

This patch fixes the issue by using fake files (output file plus suffix
".cbt" for "custom build tool") that act as dummy inputs for the custom
build tools.

Task-number: QTBUG-16904
Task-number: QTBUG-57196
Change-Id: I4711e44a0551046d215db151fa0312af8a9177a2
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
This commit is contained in:
Joerg Bornemann 2016-11-28 18:16:35 +01:00 committed by Jani Heikkinen
parent 448790eaed
commit dcd2f82951
3 changed files with 11 additions and 1 deletions

View File

@ -2264,6 +2264,10 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
bool hasBuiltIn = false;
if (!objectMappedFile.isEmpty()) {
hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile);
// Remove the fake file suffix we've added initially to generate correct command lines.
inFile.chop(Project->customBuildToolFilterFileSuffix.length());
// qDebug("*** Extra compiler file has object mapped file '%s' => '%s'", qPrintable(inFile), qPrintable(objectMappedFile.join(' ')));
}

View File

@ -198,7 +198,8 @@ const char _slnExtSections[] = "\n\tGlobalSection(ExtensibilityGlobals) = pos
VcprojGenerator::VcprojGenerator()
: Win32MakefileGenerator(),
is64Bit(false),
projectWriter(0)
projectWriter(0),
customBuildToolFilterFileSuffix(QStringLiteral(".cbt"))
{
}
@ -886,8 +887,12 @@ void VcprojGenerator::init()
if (!hasBuiltinCompiler(file)) {
extraCompilerSources[file] += quc.toQString();
} else {
// Use a fake file name 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;
extraCompilerSources[out] += quc.toQString();
extraCompilerOutputs[out] = file;
}

View File

@ -64,6 +64,7 @@ public:
QHash<QString, QStringList> extraCompilerSources;
QHash<QString, QString> extraCompilerOutputs;
const QString customBuildToolFilterFileSuffix;
bool usePCH;
VCProjectWriter *projectWriter;