diff options
Diffstat (limited to 'qmake/project.cpp')
-rw-r--r-- | qmake/project.cpp | 81 |
1 files changed, 57 insertions, 24 deletions
diff --git a/qmake/project.cpp b/qmake/project.cpp index 4d4dfe955e..f3a3856d82 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -531,7 +531,7 @@ static void qmake_error_msg(const QString &msg) 1) features/(unix|win32|macx)/ 2) features/ */ -QStringList qmake_feature_paths(QMakeProperty *prop=0) +QStringList qmake_feature_paths(QMakeProperty *prop, bool host_build) { const QString mkspecs_concat = QLatin1String("/mkspecs"); const QString base_concat = QLatin1String("/features"); @@ -578,12 +578,13 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0) feature_roots << ((*it) + mkspecs_concat + (*concat_it)); } } - if(!Option::mkfile::qmakespec.isEmpty()) { + QString *specp = host_build ? &Option::mkfile::qmakespec : &Option::mkfile::xqmakespec; + if (!specp->isEmpty()) { // The spec is already platform-dependent, so no subdirs here. - feature_roots << Option::mkfile::qmakespec + base_concat; + feature_roots << *specp + base_concat; // Also check directly under the root directory of the mkspecs collection - QFileInfo specfi(Option::mkfile::qmakespec); + QFileInfo specfi(*specp); QDir specrootdir(specfi.absolutePath()); while (!specrootdir.isRoot()) { const QString specrootpath = specrootdir.path(); @@ -629,16 +630,7 @@ QMakeProject::~QMakeProject() { if(own_prop) delete prop; - for(QHash<QString, FunctionBlock*>::iterator it = replaceFunctions.begin(); it != replaceFunctions.end(); ++it) { - if(!it.value()->deref()) - delete it.value(); - } - replaceFunctions.clear(); - for(QHash<QString, FunctionBlock*>::iterator it = testFunctions.begin(); it != testFunctions.end(); ++it) { - if(!it.value()->deref()) - delete it.value(); - } - testFunctions.clear(); + cleanup(); } @@ -653,14 +645,29 @@ QMakeProject::init(QMakeProperty *p) own_prop = false; } recursive = false; + host_build = false; reset(); } +void +QMakeProject::cleanup() +{ + for (QHash<QString, FunctionBlock*>::iterator it = replaceFunctions.begin(); it != replaceFunctions.end(); ++it) + if (!it.value()->deref()) + delete it.value(); + replaceFunctions.clear(); + for (QHash<QString, FunctionBlock*>::iterator it = testFunctions.begin(); it != testFunctions.end(); ++it) + if (!it.value()->deref()) + delete it.value(); + testFunctions.clear(); +} + // Duplicate project. It is *not* allowed to call the complex read() functions on the copy. QMakeProject::QMakeProject(QMakeProject *p, const QHash<QString, QStringList> *_vars) { init(p->properties()); vars = _vars ? *_vars : p->variables(); + host_build = p->host_build; for(QHash<QString, FunctionBlock*>::iterator it = p->replaceFunctions.begin(); it != p->replaceFunctions.end(); ++it) { it.value()->ref(); replaceFunctions.insert(it.key(), it.value()); @@ -680,6 +687,7 @@ QMakeProject::reset() iterator = 0; function = 0; backslashWarned = false; + need_restart = false; } bool @@ -1226,6 +1234,8 @@ QMakeProject::read(QTextStream &file, QHash<QString, QStringList> &place) } s = ""; numLines = 0; + if (need_restart) + break; } } } @@ -1271,7 +1281,7 @@ QMakeProject::read(const QString &file, QHash<QString, QStringList> &place) if(!using_stdin) qfile.close(); } - if(scope_blocks.count() != 1) { + if (!need_restart && scope_blocks.count() != 1) { qmake_error_msg("Unterminated conditional block at end of file"); ret = false; } @@ -1290,6 +1300,7 @@ QMakeProject::read(const QString &project, uchar cmd) bool QMakeProject::read(uchar cmd) { + again: if ((cmd & ReadSetup) && base_vars.isEmpty()) { // hack to get the Option stuff in there base_vars["QMAKE_EXT_CPP"] = Option::cpp_ext; @@ -1320,8 +1331,13 @@ QMakeProject::read(uchar cmd) Option::mkfile::cachefile.clear(); goto no_cache; } - if (Option::mkfile::qmakespec.isEmpty() && !cache["QMAKESPEC"].isEmpty()) + if (Option::mkfile::xqmakespec.isEmpty() && !cache["XQMAKESPEC"].isEmpty()) + Option::mkfile::xqmakespec = cache["XQMAKESPEC"].first(); + if (Option::mkfile::qmakespec.isEmpty() && !cache["QMAKESPEC"].isEmpty()) { Option::mkfile::qmakespec = cache["QMAKESPEC"].first(); + if (Option::mkfile::xqmakespec.isEmpty()) + Option::mkfile::xqmakespec = Option::mkfile::qmakespec; + } if (Option::output_dir.startsWith(project_build_root)) Option::mkfile::cachefile_depth = @@ -1355,9 +1371,10 @@ QMakeProject::read(uchar cmd) } { // parse mkspec - QString qmakespec = Option::mkfile::qmakespec; + QString *specp = host_build ? &Option::mkfile::qmakespec : &Option::mkfile::xqmakespec; + QString qmakespec = *specp; if (qmakespec.isEmpty()) - qmakespec = "default"; + qmakespec = host_build ? "default-host" : "default"; if (QDir::isRelativePath(qmakespec)) { QStringList mkspec_roots = qmake_mkspec_paths(); debug_msg(2, "Looking for mkspec %s in (%s)", qmakespec.toLatin1().constData(), @@ -1367,7 +1384,7 @@ QMakeProject::read(uchar cmd) QString mkspec = (*it) + QLatin1Char('/') + qmakespec; if (QFile::exists(mkspec)) { found_mkspec = true; - Option::mkfile::qmakespec = qmakespec = mkspec; + *specp = qmakespec = mkspec; break; } } @@ -1441,6 +1458,11 @@ QMakeProject::read(uchar cmd) pfile += Option::pro_ext; if(!read(pfile, vars)) return false; + if (need_restart) { + base_vars.clear(); + cleanup(); + goto again; + } } if (cmd & ReadSetup) { @@ -1537,7 +1559,7 @@ QMakeProject::resolveSpec(QString *spec, const QString &qmakespec) { if (spec->isEmpty()) { *spec = QFileInfo(qmakespec).fileName(); - if (*spec == "default") { + if (*spec == "default" || *spec == "default-host") { #ifdef Q_OS_UNIX char buffer[1024]; int l = readlink(qmakespec.toLatin1().constData(), buffer, 1023); @@ -1586,9 +1608,14 @@ QMakeProject::isActiveConfig(const QString &x, bool regex, QHash<QString, QStrin return Option::target_mode == Option::TARG_WIN_MODE; } + if (x == "host_build") + return host_build ? "true" : "false"; + //mkspecs - static QString spec; - resolveSpec(&spec, Option::mkfile::qmakespec); + static QString hspec, xspec; + resolveSpec(&hspec, Option::mkfile::qmakespec); + resolveSpec(&xspec, Option::mkfile::xqmakespec); + const QString &spec = host_build ? hspec : xspec; QRegExp re(x, Qt::CaseSensitive, QRegExp::Wildcard); if((regex && re.exactMatch(spec)) || (!regex && spec == x)) return true; @@ -1646,9 +1673,10 @@ QMakeProject::doProjectInclude(QString file, uchar flags, QHash<QString, QString file += Option::prf_ext; validateModes(); // init dir_sep if(file.indexOf(QLatin1Char('/')) == -1 || !QFile::exists(file)) { - static QStringList *feature_roots = 0; + static QStringList *all_feature_roots[2] = { 0, 0 }; + QStringList *&feature_roots = all_feature_roots[host_build]; if(!feature_roots) { - feature_roots = new QStringList(qmake_feature_paths(prop)); + feature_roots = new QStringList(qmake_feature_paths(prop, host_build)); qmakeAddCacheClear(qmakeDeleteCacheClear<QStringList>, (void**)&feature_roots); } debug_msg(2, "Looking for feature '%s' in (%s)", file.toLatin1().constData(), @@ -2742,6 +2770,11 @@ QMakeProject::doProjectTest(QString func, QList<QStringList> args_list, QHash<QS } if (args.first() == "recursive") { recursive = true; + } else if (args.first() == "host_build") { + if (!host_build && isActiveConfig("cross_compile")) { + host_build = true; + need_restart = true; + } } else { fprintf(stderr, "%s:%d: unrecognized option() argument '%s'.\n", parser.file.toLatin1().constData(), parser.line_no, |