From 1f83f0cf2ad077733fe783879ae16e293a2ceaee Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 10 May 2012 12:59:14 +0200 Subject: add support for a super cache qmake will now look for .qmake.super, just like it looks for .qmake.cache, and the cache() function has a mode to write this super cache. this allows the creation of aggregator projects like, say, qt5. a notable difference to the normal cache is that this file is *not* added as a dependency of the Makefile. this means that modifications done by later sub-projects will not cause a re-processing of earlier projects, and consequently that one should be cautious regarding what information to store there. another notable difference is that this file is read *before* the spec, so the spec can use the variables from the cache without resorting to $$fromfile() & co. Change-Id: I4807b6d34014261fa9eebd6f0ae128b802d86691 Reviewed-by: Joerg Bornemann --- qmake/project.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 13 deletions(-) (limited to 'qmake/project.cpp') diff --git a/qmake/project.cpp b/qmake/project.cpp index a60c168ef4..58c2b8cb86 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -1333,12 +1333,28 @@ QMakeProject::read(uchar cmd) if(!Option::user_template_prefix.isEmpty()) base_vars["TEMPLATE_PREFIX"] = QStringList(Option::user_template_prefix); + QString superdir; QString project_root; QString project_build_root; QStringList qmakepath; QStringList qmakefeatures; if (Option::mkfile::do_cache) { // parse the cache QHash cache; + QString rdir = Option::output_dir; + forever { + QFileInfo qfi(rdir, QLatin1String(".qmake.super")); + if (qfi.exists()) { + superfile = qfi.filePath(); + if (!read(superfile, cache)) + return false; + superdir = rdir; + break; + } + QFileInfo qdfi(rdir); + if (qdfi.isRoot()) + break; + rdir = qdfi.path(); + } if (Option::mkfile::cachefile.isEmpty()) { //find it as it has not been specified QString sdir = qmake_getpwd(); QString dir = Option::output_dir; @@ -1360,6 +1376,8 @@ QMakeProject::read(uchar cmd) project_build_root = dir; break; } + if (dir == superdir) + goto no_cache; QFileInfo qsdfi(sdir); QFileInfo qdfi(dir); if (qsdfi.isRoot() || qdfi.isRoot()) @@ -1405,7 +1423,8 @@ QMakeProject::read(uchar cmd) project_root.clear(); break; } - } while (!srcdir.isRoot() && srcdir.cdUp() && !dstdir.isRoot() && dstdir.cdUp()); + } while (!srcdir.isRoot() && srcdir.cdUp() + && dstdir != superdir && !dstdir.isRoot() && dstdir.cdUp()); } if (qmakepath != cached_qmakepath || qmakefeatures != cached_qmakefeatures @@ -1442,6 +1461,13 @@ QMakeProject::read(uchar cmd) } } + // We do this before reading the spec, so it can use module and feature paths from + // here without resorting to tricks. This is the only planned use case anyway. + if (!superfile.isEmpty()) { + debug_msg(1, "Project super cache file: reading %s", superfile.toLatin1().constData()); + read(superfile, base_vars); + } + // parse qmake configuration while(qmakespec.endsWith(QLatin1Char('/'))) qmakespec.truncate(qmakespec.length()-1); @@ -3184,17 +3210,20 @@ QMakeProject::doProjectTest(QString func, QList args_list, QHash 3) { - fprintf(stderr, "%s:%d: cache(var, [set|add|sub] [transient], [srcvar]) requires one to three arguments.\n", + fprintf(stderr, "%s:%d: cache(var, [set|add|sub] [transient] [super], [srcvar]) requires one to three arguments.\n", parser.file.toLatin1().constData(), parser.line_no); return false; } bool persist = true; + bool super = false; enum { CacheSet, CacheAdd, CacheSub } mode = CacheSet; QString srcvar; if (args.count() >= 2) { foreach (const QString &opt, split_value_list(args.at(1))) { if (opt == QLatin1String("transient")) { persist = false; + } else if (opt == QLatin1String("super")) { + super = true; } else if (opt == QLatin1String("set")) { mode = CacheSet; } else if (opt == QLatin1String("add")) { @@ -3277,16 +3306,26 @@ QMakeProject::doProjectTest(QString func, QList args_list, QHash args_list, QHash