summaryrefslogtreecommitdiffstats
path: root/qmake/generators
diff options
context:
space:
mode:
authorLeander Beernaert <leander.beernaert@qt.io>2020-01-22 13:47:08 +0100
committerLeander Beernaert <leander.beernaert@qt.io>2020-01-24 13:17:33 +0100
commit502d3d6744913899da87acfda5ebdab42c40329e (patch)
tree16658a328503bfd5a62b4fd5d69ffb66e9854b18 /qmake/generators
parentd1be8b9ceb2c7b20bbe53a07154c79699540ea3d (diff)
parent06bb315beb6c2c398223cfe52cbc7f66e14a8557 (diff)
Merge remote-tracking branch 'origin/dev' into merge-dev
Diffstat (limited to 'qmake/generators')
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp29
-rw-r--r--qmake/generators/makefile.cpp31
-rw-r--r--qmake/generators/makefile.h4
-rw-r--r--qmake/generators/unix/unixmake.cpp21
-rw-r--r--qmake/generators/unix/unixmake.h2
-rw-r--r--qmake/generators/unix/unixmake2.cpp100
-rw-r--r--qmake/generators/win32/mingw_make.cpp24
-rw-r--r--qmake/generators/win32/msvc_objectmodel.cpp36
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp15
-rw-r--r--qmake/generators/win32/msvc_vcproj.h2
10 files changed, 145 insertions, 119 deletions
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index 24e69444c9..c2f6df7787 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -1629,17 +1629,24 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
}
}
- // The symroot is marked by xcodebuild as excluded from Time Machine
- // backups, as it's a temporary build dir, so we don't want it to be
- // the same as the possibe in-source dir, as that would leave out
- // sources from being backed up.
- t << "\t\t\t\t" << writeSettings("SYMROOT",
- Option::output_dir + Option::dir_sep + ".xcode") << ";\n";
-
- // The configuration build dir however is not treated as excluded,
- // so we can safely point it to the root output dir.
- t << "\t\t\t\t" << writeSettings("CONFIGURATION_BUILD_DIR",
- Option::output_dir + Option::dir_sep + "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)") << ";\n";
+ if (Option::output_dir != qmake_getpwd()) {
+ // The SYMROOT is marked by Xcode as excluded from Time Machine
+ // backups, as it's a temporary build dir, but that's fine when
+ // we are shadow building.
+ t << "\t\t\t\t" << writeSettings("SYMROOT", "$(PROJECT_DIR)") << ";\n";
+ } else {
+ // For in-source builds we don't want to exclude the sources
+ // from being backed up, so we point SYMROOT to a temporary
+ // build directory.
+ t << "\t\t\t\t" << writeSettings("SYMROOT", ".xcode") << ";\n";
+
+ // Then we set the configuration build dir instead, so that the
+ // final build artifacts end up in the place Qt Creator expects.
+ // The disadvantage of using this over SYMROOT is that Xcode will
+ // fail to archive projects that override this variable.
+ t << "\t\t\t\t" << writeSettings("CONFIGURATION_BUILD_DIR",
+ "$(PROJECT_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)") << ";\n";
+ }
if (!project->isEmpty("DESTDIR")) {
ProString dir = project->first("DESTDIR");
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index c5868adf27..7e471f126c 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -1520,7 +1520,7 @@ MakefileGenerator::createObjectList(const ProStringList &sources)
if (!noIO()) {
// Ensure that the final output directory of each object exists
QString outRelativePath = fileFixify(dir, FileFixifyBackwards);
- if (!mkdir(outRelativePath))
+ if (!outRelativePath.isEmpty() && !mkdir(outRelativePath))
warn_msg(WarnLogic, "Cannot create directory '%s'", outRelativePath.toLatin1().constData());
}
} else {
@@ -1857,10 +1857,13 @@ void MakefileGenerator::callExtraCompilerDependCommand(const ProString &extraCom
const QString &tmp_out,
bool dep_lines,
QStringList *deps,
- bool existingDepsOnly)
+ bool existingDepsOnly,
+ bool checkCommandAvailability)
{
char buff[256];
QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, inpf, tmp_out, LocalShell);
+ if (checkCommandAvailability && !canExecute(dep_cmd))
+ return;
dep_cmd = dep_cd_cmd + fixEnvVariables(dep_cmd);
if (FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), QT_POPEN_READ)) {
QByteArray depData;
@@ -3455,4 +3458,28 @@ ProKey MakefileGenerator::fullTargetVariable() const
return "TARGET";
}
+void MakefileGenerator::createResponseFile(const QString &fileName, const ProStringList &objList)
+{
+ QString filePath = Option::output_dir + QDir::separator() + fileName;
+ QFile file(filePath);
+ if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ QTextStream t(&file);
+ for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) {
+ QString path = (*it).toQString();
+ // In response files, whitespace and special characters are
+ // escaped with a backslash; backslashes themselves can either
+ // be escaped into double backslashes, or, as this is a list of
+ // path names, converted to forward slashes.
+ path.replace(QLatin1Char('\\'), QLatin1String("/"))
+ .replace(QLatin1Char(' '), QLatin1String("\\ "))
+ .replace(QLatin1Char('\t'), QLatin1String("\\\t"))
+ .replace(QLatin1Char('"'), QLatin1String("\\\""))
+ .replace(QLatin1Char('\''), QLatin1String("\\'"));
+ t << path << Qt::endl;
+ }
+ t.flush();
+ file.close();
+ }
+}
+
QT_END_NAMESPACE
diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h
index 18c27a4385..ab970c966f 100644
--- a/qmake/generators/makefile.h
+++ b/qmake/generators/makefile.h
@@ -87,7 +87,8 @@ protected:
void callExtraCompilerDependCommand(const ProString &extraCompiler, const QString &dep_cd_cmd,
const QString &tmp_dep_cmd, const QString &inpf,
const QString &tmp_out, bool dep_lines, QStringList *deps,
- bool existingDepsOnly);
+ bool existingDepsOnly,
+ bool checkCommandAvailability = false);
void writeExtraCompilerTargets(QTextStream &t);
void writeExtraCompilerVariables(QTextStream &t);
bool writeDummyMakefile(QTextStream &t);
@@ -257,6 +258,7 @@ protected:
const QStringRef &fixedBase, int slashOff);
bool processPrlFileCore(QString &origFile, const QStringRef &origName,
const QString &fixedFile);
+ void createResponseFile(const QString &fileName, const ProStringList &objList);
public:
QMakeProject *projectFile() const;
diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp
index e56e8c41b6..f7bd6dc663 100644
--- a/qmake/generators/unix/unixmake.cpp
+++ b/qmake/generators/unix/unixmake.cpp
@@ -208,15 +208,15 @@ UnixMakefileGenerator::init()
escapeFilePath(pchBaseName + language + headerSuffix));
const ProStringList pchArchs = project->values("QMAKE_PCH_ARCHS");
for (const ProString &arch : pchArchs) {
- QString suffix = headerSuffix;
- suffix.replace(QLatin1String("${QMAKE_PCH_ARCH}"), arch.toQString());
+ QString file = pchBaseName + language + headerSuffix;
+ file.replace(QLatin1String("${QMAKE_PCH_ARCH}"), arch.toQString());
if (project->isActiveConfig("clang_pch_style")
- && (suffix.endsWith(QLatin1String(".pch"))
- || suffix.endsWith(QLatin1String(".gch")))) {
- suffix.chop(4); // must omit header suffix for -include to recognize the PCH
+ && (file.endsWith(QLatin1String(".pch"))
+ || file.endsWith(QLatin1String(".gch")))) {
+ file.chop(4); // must omit header suffix for -include to recognize the PCH
}
pchFlags.replace(QLatin1String("${QMAKE_PCH_OUTPUT_") + arch + QLatin1Char('}'),
- escapeFilePath(pchBaseName + language + suffix));
+ escapeFilePath(file));
}
}
}
@@ -363,10 +363,11 @@ QStringList
if (pchArchs.isEmpty())
pchArchs << ProString(); // normal single-arch PCH
for (const ProString &arch : qAsConst(pchArchs)) {
- QString suffix = header_suffix;
- if (!arch.isEmpty())
- suffix.replace(QLatin1String("${QMAKE_PCH_ARCH}"), arch.toQString());
- QString precompiledHeader = header_prefix + language + suffix;
+ QString precompiledHeader = header_prefix + language + header_suffix;
+ if (!arch.isEmpty()) {
+ precompiledHeader.replace(QLatin1String("${QMAKE_PCH_ARCH}"),
+ arch.toQString());
+ }
if (!ret.contains(precompiledHeader))
ret += precompiledHeader;
}
diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h
index 79b161f6da..28302b4f15 100644
--- a/qmake/generators/unix/unixmake.h
+++ b/qmake/generators/unix/unixmake.h
@@ -58,7 +58,7 @@ protected:
void writeSubTargets(QTextStream &t, QList<SubTarget*> subtargets, int flags) override;
void writeMakeParts(QTextStream &);
bool writeMakefile(QTextStream &) override;
-
+ std::pair<bool, QString> writeObjectsPart(QTextStream &, bool do_incremental);
private:
void init2();
ProStringList libdirToFlags(const ProKey &key);
diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp
index a87fbe0fc3..4a6a42c7d2 100644
--- a/qmake/generators/unix/unixmake2.cpp
+++ b/qmake/generators/unix/unixmake2.cpp
@@ -246,38 +246,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << "####### Files\n\n";
// This is used by the dist target.
t << "SOURCES = " << fileVarList("SOURCES") << ' ' << fileVarList("GENERATED_SOURCES") << Qt::endl;
- if(do_incremental) {
- const ProStringList &objs = project->values("OBJECTS");
- const ProStringList &incrs = project->values("QMAKE_INCREMENTAL");
- ProStringList incrs_out;
- t << "OBJECTS = ";
- for (ProStringList::ConstIterator objit = objs.begin(); objit != objs.end(); ++objit) {
- bool increment = false;
- for (ProStringList::ConstIterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) {
- if ((*objit).toQString().indexOf(QRegExp((*incrit).toQString(), Qt::CaseSensitive,
- QRegExp::Wildcard)) != -1) {
- increment = true;
- incrs_out.append((*objit));
- break;
- }
- }
- if(!increment)
- t << "\\\n\t\t" << (*objit);
- }
- if(incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done!
- t << escapeFilePaths(incrs_out).join(QString(" \\\n\t\t")) << Qt::endl;
- } else if(!incrs_out.count()) {
- t << Qt::endl;
- } else {
- src_incremental = true;
- t << Qt::endl;
- t << "INCREMENTAL_OBJECTS = "
- << escapeFilePaths(incrs_out).join(QString(" \\\n\t\t")) << Qt::endl;
- }
- } else {
- // Used all over the place in both deps and commands.
- t << "OBJECTS = " << valList(escapeDependencyPaths(project->values("OBJECTS"))) << Qt::endl;
- }
+ auto objectParts = writeObjectsPart(t, do_incremental);
+ src_incremental = objectParts.first;
if(do_incremental && !src_incremental)
do_incremental = false;
t << "DIST = " << valList(fileFixify(project->values("DISTFILES").toQStringList())) << " "
@@ -513,7 +483,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << mkdir_p_asstring(destdir) << "\n\t";
if (!project->isEmpty("QMAKE_PRE_LINK"))
t << var("QMAKE_PRE_LINK") << "\n\t";
- t << "$(LINK) $(LFLAGS) " << var("QMAKE_LINK_O_FLAG") << "$(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)";
+ t << "$(LINK) $(LFLAGS) " << var("QMAKE_LINK_O_FLAG") << "$(TARGET) "
+ << objectParts.second << " $(OBJCOMP) $(LIBS)";
if (!project->isEmpty("QMAKE_POST_LINK"))
t << "\n\t" << var("QMAKE_POST_LINK");
}
@@ -1046,10 +1017,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
if (pchArchs.isEmpty())
pchArchs << ProString(); // normal single-arch PCH
for (const ProString &arch : qAsConst(pchArchs)) {
- auto suffix = header_suffix.toQString();
+ QString file = precomph_out_dir + header_prefix + language + header_suffix;
if (!arch.isEmpty())
- suffix.replace(QStringLiteral("${QMAKE_PCH_ARCH}"), arch.toQString());
- precomp_files += precomph_out_dir + header_prefix + language + suffix;
+ file.replace(QStringLiteral("${QMAKE_PCH_ARCH}"), arch.toQString());
+ precomp_files += file;
}
}
}
@@ -1169,7 +1140,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\n\techo \"// Automatically generated, do not modify\" > " << sourceFile_f
<< "\n\trm -f " << escapeFilePath(pchArchOutput);
} else {
- t << "\n\t" << mkdir_p_asstring(pchOutputDir);
+ QString outDir = pchOutputDir;
+ if (!arch.isEmpty())
+ outDir.replace(QStringLiteral("${QMAKE_PCH_ARCH}"), arch.toQString());
+ t << "\n\t" << mkdir_p_asstring(outDir);
}
auto pchArchFlags = pchFlags;
@@ -1545,4 +1519,56 @@ UnixMakefileGenerator::writeLibtoolFile()
"libdir='" << Option::fixPathToTargetOS(install_dir.toQString(), false) << "'\n";
}
+std::pair<bool, QString> UnixMakefileGenerator::writeObjectsPart(QTextStream &t, bool do_incremental)
+{
+ bool src_incremental = false;
+ QString objectsLinkLine;
+ const ProStringList &objs = project->values("OBJECTS");
+ if (do_incremental) {
+ const ProStringList &incrs = project->values("QMAKE_INCREMENTAL");
+ ProStringList incrs_out;
+ t << "OBJECTS = ";
+ for (ProStringList::ConstIterator objit = objs.begin(); objit != objs.end(); ++objit) {
+ bool increment = false;
+ for (ProStringList::ConstIterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) {
+ if ((*objit).toQString().indexOf(QRegExp((*incrit).toQString(), Qt::CaseSensitive,
+ QRegExp::Wildcard)) != -1) {
+ increment = true;
+ incrs_out.append((*objit));
+ break;
+ }
+ }
+ if (!increment)
+ t << "\\\n\t\t" << (*objit);
+ }
+ if (incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done!
+ t << escapeFilePaths(incrs_out).join(QString(" \\\n\t\t")) << Qt::endl;
+ } else if (!incrs_out.count()) {
+ t << Qt::endl;
+ } else {
+ src_incremental = true;
+ t << Qt::endl;
+ t << "INCREMENTAL_OBJECTS = "
+ << escapeFilePaths(incrs_out).join(QString(" \\\n\t\t")) << Qt::endl;
+ }
+ } else {
+ const ProString &objMax = project->first("QMAKE_LINK_OBJECT_MAX");
+ // Used all over the place in both deps and commands.
+ if (objMax.isEmpty() || project->values("OBJECTS").count() < objMax.toInt()) {
+ objectsLinkLine = "$(OBJECTS)";
+ } else {
+ QString ld_response_file = fileVar("OBJECTS_DIR");
+ ld_response_file += var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
+ if (!var("BUILD_NAME").isEmpty())
+ ld_response_file += "." + var("BUILD_NAME");
+ if (!var("MAKEFILE").isEmpty())
+ ld_response_file += "." + var("MAKEFILE");
+ createResponseFile(ld_response_file, objs);
+ objectsLinkLine = "@" + escapeFilePath(ld_response_file);
+ }
+ t << "OBJECTS = " << valList(escapeDependencyPaths(objs)) << Qt::endl;
+ }
+ return std::make_pair(src_incremental, objectsLinkLine);
+}
+
QT_END_NAMESPACE
diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp
index 878291fae9..096b041056 100644
--- a/qmake/generators/win32/mingw_make.cpp
+++ b/qmake/generators/win32/mingw_make.cpp
@@ -115,30 +115,6 @@ QString MingwMakefileGenerator::installRoot() const
return QStringLiteral("$(INSTALL_ROOT:@msyshack@%=%)");
}
-static void createResponseFile(const QString &fileName, const ProStringList &objList)
-{
- QString filePath = Option::output_dir + QDir::separator() + fileName;
- QFile file(filePath);
- if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- QTextStream t(&file);
- for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) {
- QString path = (*it).toQString();
- // In response files, whitespace and special characters are
- // escaped with a backslash; backslashes themselves can either
- // be escaped into double backslashes, or, as this is a list of
- // path names, converted to forward slashes.
- path.replace(QLatin1Char('\\'), QLatin1String("/"))
- .replace(QLatin1Char(' '), QLatin1String("\\ "))
- .replace(QLatin1Char('\t'), QLatin1String("\\\t"))
- .replace(QLatin1Char('"'), QLatin1String("\\\""))
- .replace(QLatin1Char('\''), QLatin1String("\\'"));
- t << path << Qt::endl;
- }
- t.flush();
- file.close();
- }
-}
-
void MingwMakefileGenerator::writeMingwParts(QTextStream &t)
{
writeStandardParts(t);
diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp
index 5396eba72e..2b39a4baaa 100644
--- a/qmake/generators/win32/msvc_objectmodel.cpp
+++ b/qmake/generators/win32/msvc_objectmodel.cpp
@@ -2351,33 +2351,15 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
if (!tmp_dep.isEmpty())
deps = tmp_dep;
if (!tmp_dep_cmd.isEmpty()) {
- // Execute dependency command, and add every line as a dep
- char buff[256];
- QString dep_cmd = Project->replaceExtraCompilerVariables(
- tmp_dep_cmd, inFile, out, MakefileGenerator::LocalShell);
- if(Project->canExecute(dep_cmd)) {
- dep_cmd.prepend(QLatin1String("cd ")
- + IoUtils::shellQuote(Option::fixPathToLocalOS(Option::output_dir, false))
- + QLatin1String(" && "));
- if (FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), QT_POPEN_READ)) {
- QString indeps;
- while(!feof(proc)) {
- int read_in = (int)fread(buff, 1, 255, proc);
- if(!read_in)
- break;
- indeps += QByteArray(buff, read_in);
- }
- QT_PCLOSE(proc);
- if(!indeps.isEmpty()) {
- QStringList extradeps = indeps.split(QLatin1Char('\n'));
- for (int i = 0; i < extradeps.count(); ++i) {
- QString dd = extradeps.at(i).simplified();
- if (!dd.isEmpty())
- deps += Project->fileFixify(dd, MakefileGenerator::FileFixifyFromOutdir);
- }
- }
- }
- }
+ const QString dep_cd_cmd = QLatin1String("cd ")
+ + IoUtils::shellQuote(Option::fixPathToLocalOS(Option::output_dir, false))
+ + QLatin1String(" && ");
+ Project->callExtraCompilerDependCommand(extraCompilerName, dep_cd_cmd, tmp_dep_cmd,
+ inFile, out,
+ true, // dep_lines
+ &deps,
+ configs.contains("dep_existing_only"),
+ true /* checkCommandAvailability */);
}
for (int i = 0; i < deps.count(); ++i)
deps[i] = Option::fixPathToTargetOS(
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index e45beca459..867b14faea 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -1247,10 +1247,10 @@ void VcprojGenerator::initDeploymentTool()
+ "|" + targetPath
+ "|0;";
if (!qpaPluginDeployed) {
- QChar debugInfixChar;
+ QString debugInfix;
bool foundGuid = dllName.contains(QLatin1String("Guid"));
if (foundGuid)
- debugInfixChar = QLatin1Char('d');
+ debugInfix = QLatin1Char('d');
if (foundGuid || dllName.contains(QLatin1String("Gui"))) {
QFileInfo info2;
@@ -1258,13 +1258,14 @@ void VcprojGenerator::initDeploymentTool()
QString absoluteDllFilePath = dllPath.toQString();
if (!absoluteDllFilePath.endsWith(QLatin1Char('/')))
absoluteDllFilePath += QLatin1Char('/');
- absoluteDllFilePath += QLatin1String("../plugins/platforms/qwindows") + debugInfixChar + QLatin1String(".dll");
+ absoluteDllFilePath += QLatin1String("../plugins/platforms/qwindows")
+ + debugInfix + QLatin1String(".dll");
info2 = QFileInfo(absoluteDllFilePath);
if (info2.exists())
break;
}
if (info2.exists()) {
- conf.deployment.AdditionalFiles += QLatin1String("qwindows") + debugInfixChar + QLatin1String(".dll")
+ conf.deployment.AdditionalFiles += QLatin1String("qwindows") + debugInfix + QLatin1String(".dll")
+ QLatin1Char('|') + QDir::toNativeSeparators(info2.absolutePath())
+ QLatin1Char('|') + targetPath + QLatin1String("\\platforms")
+ QLatin1String("|0;");
@@ -1581,12 +1582,14 @@ void VcprojGenerator::initExtraCompilerOutputs()
if (!outputVar.isEmpty() && otherFilters.contains(outputVar))
continue;
- QString tmp_out = project->first(outputs.first().toKey()).toQString();
+ QString tmp_out;
+ if (!outputs.isEmpty())
+ tmp_out = project->first(outputs.first().toKey()).toQString();
if (project->values(ProKey(*it + ".CONFIG")).indexOf("combine") != -1) {
// Combined output, only one file result
extraCompile.addFile(Option::fixPathToTargetOS(
replaceExtraCompilerVariables(tmp_out, QString(), QString(), NoShell), false));
- } else {
+ } else if (!inputVars.isEmpty()) {
// One output file per input
const ProStringList &tmp_in = project->values(inputVars.first().toKey());
for (int i = 0; i < tmp_in.count(); ++i) {
diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h
index 8f38252274..c565b709d2 100644
--- a/qmake/generators/win32/msvc_vcproj.h
+++ b/qmake/generators/win32/msvc_vcproj.h
@@ -69,6 +69,8 @@ public:
bool pchIsCFile = false;
VCProjectWriter *projectWriter;
+ using Win32MakefileGenerator::callExtraCompilerDependCommand;
+
protected:
virtual VCProjectWriter *createProjectWriter();
bool doDepends() const override { return false; } // Never necessary