summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@nokia.com>2012-05-18 22:13:51 +0200
committerOswald Buddenhagen <oswald.buddenhagen@nokia.com>2012-06-19 16:46:08 +0200
commit575a51663007095c8c4d14295ed6028cc18513f8 (patch)
tree2df9fb4d9853a6700f8b291db11c67faf7bf5f60
parente6d97f3f77b94268edbe2a651476188cdcc8dc5d (diff)
revamp automatic makefile generation for sub-projects
instead of making the "real" targets depend on the makefiles, add conditional makefile generation to the targets themselves. this causes makefile generation to follow the recursion order determined by the project, which is important when dealing with prl and module pri files. a side effect of this is that qmake and make calls are interleaved now, which is entirely different from a 'qmake -r' run. on the downside, calling make with multiple targets which operate on the same subprojects without prior makefile generation will make a mess, as the qmake calls will be racing. this should be no problem, as qmake does not generate recursive targets where this would be useful - at least by default. it is not sufficient to just order the creation of the makefiles non-recursively (e.g., by using gnu-specific order-only-prerequisites), as an interrupted and subsequently resumed build would happily skip the nested makefiles. workable alternative approaches would be walking the entire tree in a pre-pass to ensure makefile presence (which is incredibly slow) or creating additional stamp files only after recursing and having the makefiles depend on them (which is ugly). Task-number: QTBUG-23376 Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com> Change-Id: I88d3e7610215677d362026de316513d3bea04b06
-rw-r--r--mkspecs/common/shell-unix.conf1
-rw-r--r--mkspecs/common/shell-win32.conf1
-rw-r--r--qmake/generators/makefile.cpp78
-rw-r--r--qmake/generators/makefile.h5
4 files changed, 52 insertions, 33 deletions
diff --git a/mkspecs/common/shell-unix.conf b/mkspecs/common/shell-unix.conf
index 967a658cff..17c3612fdc 100644
--- a/mkspecs/common/shell-unix.conf
+++ b/mkspecs/common/shell-unix.conf
@@ -8,6 +8,7 @@ QMAKE_MOVE = mv -f
QMAKE_DEL_FILE = rm -f
QMAKE_DEL_DIR = rmdir
QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_CHK_FILE_EXISTS = test -f
QMAKE_CHK_EXISTS_GLUE = "|| "
QMAKE_MKDIR = mkdir -p
QMAKE_STREAM_EDITOR = sed
diff --git a/mkspecs/common/shell-win32.conf b/mkspecs/common/shell-win32.conf
index 16f86e5e27..3b2ace7c90 100644
--- a/mkspecs/common/shell-win32.conf
+++ b/mkspecs/common/shell-win32.conf
@@ -6,5 +6,6 @@ QMAKE_MOVE = move
QMAKE_DEL_FILE = del
QMAKE_DEL_DIR = rmdir
QMAKE_CHK_DIR_EXISTS = if not exist
+QMAKE_CHK_FILE_EXISTS = if not exist
QMAKE_CHK_EXISTS_GLUE =
QMAKE_MKDIR = mkdir
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index a14e7233f6..83354b9114 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -428,6 +428,9 @@ MakefileGenerator::init()
QHash<QString, QStringList> &v = project->variables();
chkdir = v["QMAKE_CHK_DIR_EXISTS"].join(" ");
+ chkfile = v["QMAKE_CHK_FILE_EXISTS"].join(" ");
+ if (chkfile.isEmpty()) // Backwards compat with Qt4 specs
+ chkfile = isWindowsShell() ? "if not exist" : "test -f";
chkglue = v["QMAKE_CHK_EXISTS_GLUE"].join(" ");
if (chkglue.isEmpty()) // Backwards compat with Qt4 specs
chkglue = isWindowsShell() ? "" : "|| ";
@@ -2369,6 +2372,22 @@ void MakefileGenerator::writeSubMakeCall(QTextStream &t, const QString &callPref
}
void
+MakefileGenerator::writeSubTargetCall(QTextStream &t,
+ const QString &in_directory, const QString &in, const QString &out_directory, const QString &out,
+ const QString &out_directory_cdin, const QString &makefilein, const QString &out_directory_cdout)
+{
+ QString pfx;
+ if (!in.isEmpty()) {
+ if (!in_directory.isEmpty())
+ t << "\n\t" << mkdir_p_asstring(out_directory);
+ pfx = "( " + chkfile + " " + out + " " + chkglue
+ + "$(QMAKE) " + in + buildArgs(in_directory) + " -o " + out
+ + " ) && ";
+ }
+ writeSubMakeCall(t, out_directory_cdin + pfx, makefilein, out_directory_cdout);
+}
+
+void
MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubTarget*> targets, int flags)
{
// blasted includes
@@ -2426,10 +2445,6 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT
if(!abs_source_path.isEmpty() && out_directory.startsWith(abs_source_path))
out_directory = Option::output_dir + out_directory.mid(abs_source_path.length());
- QString mkfile = subtarget->makefile;
- if(!in_directory.isEmpty())
- mkfile.prepend(out_directory);
-
#define MAKE_CD_IN_AND_OUT(directory) \
if(!directory.isEmpty()) { \
if(project->isActiveConfig("cd_change_global")) { \
@@ -2457,20 +2472,13 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT
QString makefilein = " -f " + subtarget->makefile;
//qmake it
+ QString out;
+ QString in;
if(!subtarget->profile.isEmpty()) {
- QString out = subtarget->makefile;
- QString in = escapeFilePath(fileFixify(in_directory + subtarget->profile, FileFixifyAbsolute));
+ out = subtarget->makefile;
+ in = escapeFilePath(fileFixify(in_directory + subtarget->profile, FileFixifyAbsolute));
if(out.startsWith(in_directory))
out = out.mid(in_directory.length());
- t << mkfile << ": " << "\n\t";
- if(!in_directory.isEmpty()) {
- t << mkdir_p_asstring(out_directory)
- << out_directory_cdin
- << "$(QMAKE) " << in << buildArgs(in_directory) << " -o " << out
- << out_directory_cdout << endl;
- } else {
- t << "$(QMAKE) " << in << buildArgs(in_directory) << " -o " << out << endl;
- }
t << subtarget->target << "-qmake_all: ";
if (flags & SubTargetOrdered) {
if (target)
@@ -2497,12 +2505,13 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT
}
{ //actually compile
- t << subtarget->target << ": " << mkfile;
+ t << subtarget->target << ":";
if(!subtarget->depends.isEmpty())
t << " " << valList(subtarget->depends);
if(project->isEmpty("QMAKE_NOFORCE"))
t << " FORCE";
- writeSubMakeCall(t, out_directory_cdin, makefilein, out_directory_cdout);
+ writeSubTargetCall(t, in_directory, in, out_directory, out,
+ out_directory_cdin, makefilein, out_directory_cdout);
}
for(int suffix = 0; suffix < targetSuffixes.size(); ++suffix) {
@@ -2515,20 +2524,22 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT
s = QString();
if(flags & SubTargetOrdered) {
- t << subtarget->target << "-" << targetSuffixes.at(suffix) << "-ordered: " << mkfile;
+ t << subtarget->target << "-" << targetSuffixes.at(suffix) << "-ordered:";
if(target)
t << " " << targets.at(target-1)->target << "-" << targetSuffixes.at(suffix) << "-ordered ";
if(project->isEmpty("QMAKE_NOFORCE"))
t << " FORCE";
- writeSubMakeCall(t, out_directory_cdin, makefilein + " " + s, out_directory_cdout);
+ writeSubTargetCall(t, in_directory, in, out_directory, out,
+ out_directory_cdin, makefilein + " " + s, out_directory_cdout);
}
- t << subtarget->target << "-" << targetSuffixes.at(suffix) << ": " << mkfile;
+ t << subtarget->target << "-" << targetSuffixes.at(suffix) << ":";
if(!subtarget->depends.isEmpty())
t << " " << valGlue(subtarget->depends, QString(), "-" + targetSuffixes.at(suffix) + " ",
"-"+targetSuffixes.at(suffix));
if(project->isEmpty("QMAKE_NOFORCE"))
t << " FORCE";
- writeSubMakeCall(t, out_directory_cdin, makefilein + " " + s, out_directory_cdout);
+ writeSubTargetCall(t, in_directory, in, out_directory, out,
+ out_directory_cdin, makefilein + " " + s, out_directory_cdout);
}
}
t << endl;
@@ -2627,28 +2638,31 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT
if(!recurse.contains(subtarget->name))
continue;
- QString mkfile = subtarget->makefile;
- if(!in_directory.isEmpty()) {
- if(!out_directory.endsWith(Option::dir_sep))
- mkfile.prepend(out_directory + Option::dir_sep);
- else
- mkfile.prepend(out_directory);
- }
+
QString out_directory_cdin, out_directory_cdout;
MAKE_CD_IN_AND_OUT(out_directory);
QString makefilein = " -f " + subtarget->makefile;
+ QString out;
+ QString in;
+ if (!subtarget->profile.isEmpty()) {
+ out = subtarget->makefile;
+ in = escapeFilePath(fileFixify(in_directory + subtarget->profile, FileFixifyAbsolute));
+ if (out.startsWith(in_directory))
+ out = out.mid(in_directory.length());
+ }
+
//write the rule/depends
if(flags & SubTargetOrdered) {
const QString dep = subtarget->target + "-" + (*qut_it) + "_ordered";
- t << dep << ": " << mkfile;
+ t << dep << ":";
if(target)
t << " " << targets.at(target-1)->target << "-" << (*qut_it) << "_ordered ";
deps += " " + dep;
} else {
const QString dep = subtarget->target + "-" + (*qut_it);
- t << dep << ": " << mkfile;
+ t << dep << ":";
if(!subtarget->depends.isEmpty())
t << " " << valGlue(subtarget->depends, QString(), "-" + (*qut_it) + " ", "-" + (*qut_it));
deps += " " + dep;
@@ -2659,8 +2673,8 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT
sub_targ = project->first((*qut_it) + ".recurse_target");
//write the commands
- writeSubMakeCall(t, out_directory_cdin, makefilein + " " + sub_targ,
- out_directory_cdout);
+ writeSubTargetCall(t, in_directory, in, out_directory, out,
+ out_directory_cdin, makefilein + " " + sub_targ, out_directory_cdout);
}
}
if(project->isEmpty("QMAKE_NOFORCE") &&
diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h
index 3a41fb4a9a..33602dcf80 100644
--- a/qmake/generators/makefile.h
+++ b/qmake/generators/makefile.h
@@ -81,7 +81,7 @@ class MakefileGenerator : protected QMakeSourceFileInfo
QString spec;
bool init_opath_already, init_already, no_io;
QHash<QString, bool> init_compiler_already;
- QString chkdir, chkglue;
+ QString chkdir, chkfile, chkglue;
QString build_args(const QString &outdir=QString());
void checkMultipleDefinition(const QString &, const QString &);
@@ -128,6 +128,9 @@ protected:
SubTargetsNoFlags=0x00
};
QList<MakefileGenerator::SubTarget*> findSubDirsSubTargets() const;
+ void writeSubTargetCall(QTextStream &t,
+ const QString &in_directory, const QString &in, const QString &out_directory, const QString &out,
+ const QString &out_directory_cdin, const QString &makefilein, const QString &out_directory_cdout);
virtual void writeSubMakeCall(QTextStream &t, const QString &outDirectory_cdin,
const QString &makeFileIn, const QString &outDirectory_cdout);
void writeSubTargets(QTextStream &t, QList<SubTarget*> subtargets, int flags);