diff options
Diffstat (limited to 'qmake/project.cpp')
-rw-r--r-- | qmake/project.cpp | 142 |
1 files changed, 43 insertions, 99 deletions
diff --git a/qmake/project.cpp b/qmake/project.cpp index 1179812b1b..7655f05f2e 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -530,9 +530,10 @@ static void qmake_error_msg(const QString &msg) */ QStringList qmake_feature_paths(QMakeProperty *prop=0) { + const QString mkspecs_concat = QLatin1String("/mkspecs"); + const QString base_concat = QLatin1String("/features"); QStringList concat; { - const QString base_concat = QLatin1String("/features"); switch(Option::target_mode) { case Option::TARG_MACX_MODE: //also a unix concat << base_concat + QLatin1String("/mac"); @@ -549,7 +550,7 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0) } concat << base_concat; } - const QString mkspecs_concat = QLatin1String("/mkspecs"); + QStringList feature_roots; QByteArray mkspec_path = qgetenv("QMAKEFEATURES"); if(!mkspec_path.isNull()) @@ -574,44 +575,28 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0) feature_roots << ((*it) + mkspecs_concat + (*concat_it)); } } - if(!Option::mkfile::qmakespec.isEmpty()) - feature_roots << Option::mkfile::qmakespec + QLatin1String("/features"); if(!Option::mkfile::qmakespec.isEmpty()) { + // The spec is already platform-dependent, so no subdirs here. + feature_roots << Option::mkfile::qmakespec + base_concat; + QFileInfo specfi(Option::mkfile::qmakespec); - QDir specdir(specfi.absoluteFilePath()); - while(!specdir.isRoot()) { - if(!specdir.cdUp() || specdir.isRoot()) - break; - if(QFile::exists(specdir.path() + QLatin1String("/features"))) { + if (!specfi.isRoot()) { + QDir specdir(specfi.absolutePath()); + if (specdir.exists(QLatin1String("features"))) { for(QStringList::Iterator concat_it = concat.begin(); concat_it != concat.end(); ++concat_it) feature_roots << (specdir.path() + (*concat_it)); - break; } } } for(QStringList::Iterator concat_it = concat.begin(); concat_it != concat.end(); ++concat_it) - feature_roots << (QLibraryInfo::location(QLibraryInfo::DataPath) + + feature_roots << (QLibraryInfo::location(QLibraryInfo::HostDataPath) + mkspecs_concat + (*concat_it)); + feature_roots.removeDuplicates(); return feature_roots; } -QStringList qmake_mkspec_paths() -{ - QStringList ret; - const QString concat = QLatin1String("/mkspecs"); - QByteArray qmakepath = qgetenv("QMAKEPATH"); - if (!qmakepath.isEmpty()) { - const QStringList lst = splitPathList(QString::fromLocal8Bit(qmakepath)); - for(QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it) - ret << ((*it) + concat); - } - ret << QLibraryInfo::location(QLibraryInfo::DataPath) + concat; - - return ret; -} - QMakeProject::~QMakeProject() { if(own_prop) @@ -630,10 +615,8 @@ QMakeProject::~QMakeProject() void -QMakeProject::init(QMakeProperty *p, const QHash<QString, QStringList> *vars) +QMakeProject::init(QMakeProperty *p) { - if(vars) - base_vars = *vars; if(!p) { prop = new QMakeProperty; own_prop = true; @@ -645,9 +628,11 @@ QMakeProject::init(QMakeProperty *p, const QHash<QString, QStringList> *vars) reset(); } -QMakeProject::QMakeProject(QMakeProject *p, const QHash<QString, QStringList> *vars) +// 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 : &p->variables()); + init(p->properties()); + vars = _vars ? *_vars : p->variables(); for(QHash<QString, FunctionBlock*>::iterator it = p->replaceFunctions.begin(); it != p->replaceFunctions.end(); ++it) { it.value()->ref(); replaceFunctions.insert(it.key(), it.value()); @@ -1174,6 +1159,8 @@ QMakeProject::parse(const QString &t, QHash<QString, QStringList> &place, int nu } if(var == "REQUIRES") // special case to get communicated to backends! doProjectCheckReqs(vallist, place); + else if (var == "_QMAKE_CACHE_") + Option::mkfile::cachefile = varlist.isEmpty() ? QString() : varlist.at(0); } return true; } @@ -1271,7 +1258,7 @@ QMakeProject::read(const QString &project, uchar cmd) bool QMakeProject::read(uchar cmd) { - if(cfile.isEmpty()) { + if ((cmd & ReadSetup) && base_vars.isEmpty()) { // hack to get the Option stuff in there base_vars["QMAKE_EXT_CPP"] = Option::cpp_ext; base_vars["QMAKE_EXT_C"] = Option::c_ext; @@ -1280,56 +1267,13 @@ QMakeProject::read(uchar cmd) if(!Option::user_template_prefix.isEmpty()) base_vars["TEMPLATE_PREFIX"] = QStringList(Option::user_template_prefix); - if ((cmd & ReadSetup) && Option::mkfile::do_cache) { // parse the cache + if (Option::mkfile::do_cache) { // parse the cache if (Option::output_dir.startsWith(Option::mkfile::project_build_root)) Option::mkfile::cachefile_depth = Option::output_dir.mid(Option::mkfile::project_build_root.length()).count('/'); } - if (cmd & ReadSetup) { // parse mkspec - QString qmakespec = fixEnvVariables(Option::mkfile::qmakespec); - QStringList mkspec_roots = qmake_mkspec_paths(); - debug_msg(2, "Looking for mkspec %s in (%s)", qmakespec.toLatin1().constData(), - mkspec_roots.join("::").toLatin1().constData()); - if(qmakespec.isEmpty()) { - for(QStringList::ConstIterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { - QString mkspec = (*it) + QLatin1String("/default"); - QFileInfo default_info(mkspec); - if(default_info.exists() && default_info.isDir()) { - qmakespec = mkspec; - break; - } - } - if(qmakespec.isEmpty()) { - fprintf(stderr, "QMAKESPEC has not been set, so configuration cannot be deduced.\n"); - return false; - } - Option::mkfile::qmakespec = qmakespec; - } - - if(QDir::isRelativePath(qmakespec)) { - if (QFile::exists(Option::output_dir+"/"+qmakespec+"/qmake.conf")) { - qmakespec = Option::mkfile::qmakespec = QFileInfo(Option::output_dir+"/"+qmakespec).absoluteFilePath(); - } else if (QFile::exists(qmakespec+"/qmake.conf")) { - Option::mkfile::qmakespec = QFileInfo(Option::mkfile::qmakespec).absoluteFilePath(); - } else { - bool found_mkspec = false; - for(QStringList::ConstIterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { - QString mkspec = (*it) + QLatin1Char('/') + qmakespec; - if(QFile::exists(mkspec)) { - found_mkspec = true; - Option::mkfile::qmakespec = qmakespec = mkspec; - break; - } - } - if(!found_mkspec) { - fprintf(stderr, "Could not find mkspecs for your QMAKESPEC(%s) after trying:\n\t%s\n", - qmakespec.toLatin1().constData(), mkspec_roots.join("\n\t").toLatin1().constData()); - return false; - } - } - } - - // parse qmake configuration + { // parse mkspec + QString qmakespec = Option::mkfile::qmakespec; while(qmakespec.endsWith(QLatin1Char('/'))) qmakespec.truncate(qmakespec.length()-1); QString spec = qmakespec + QLatin1String("/qmake.conf"); @@ -1349,6 +1293,10 @@ QMakeProject::read(uchar cmd) vars = base_vars; // start with the base + for (QHash<QString, QStringList>::ConstIterator it = extra_vars.constBegin(); + it != extra_vars.constEnd(); ++it) + vars.insert(it.key(), it.value()); + if(cmd & ReadFeatures) { debug_msg(1, "Processing default_pre: %s", vars["CONFIG"].join("::").toLatin1().constData()); doProjectInclude("default_pre", IncludeFlagFeature, vars); @@ -1360,7 +1308,6 @@ QMakeProject::read(uchar cmd) //before commandline if (cmd & ReadSetup) { - cfile = pfile; parser.file = "(internal)"; parser.from_file = false; parser.line_no = 1; //really arg count now.. duh @@ -1375,12 +1322,12 @@ QMakeProject::read(uchar cmd) } } - //commandline configs - if ((cmd & ReadSetup) && !Option::user_configs.isEmpty()) { - parser.file = "(configs)"; + // After user configs, to override them + if (!extra_configs.isEmpty()) { + parser.file = "(extra configs)"; parser.from_file = false; parser.line_no = 1; //really arg count now.. duh - parse("CONFIG += " + Option::user_configs.join(" "), vars); + parse("CONFIG += " + extra_configs.join(" "), vars); } if(cmd & ReadProFile) { // parse project file @@ -1406,12 +1353,14 @@ QMakeProject::read(uchar cmd) } } - //after configs (set in BUILDS) - if ((cmd & ReadSetup) && !Option::after_user_configs.isEmpty()) { - parser.file = "(configs)"; + // Again, to ensure the project does not mess with us. + // Specifically, do not allow a project to override debug/release within a + // debug_and_release build pass - it's too late for that at this point anyway. + if (!extra_configs.isEmpty()) { + parser.file = "(extra configs)"; parser.from_file = false; parser.line_no = 1; //really arg count now.. duh - parse("CONFIG += " + Option::after_user_configs.join(" "), vars); + parse("CONFIG += " + extra_configs.join(" "), vars); } if(cmd & ReadFeatures) { @@ -1437,7 +1386,6 @@ QMakeProject::read(uchar cmd) break; } } - Option::postProcessProject(this); // let Option post-process return true; } @@ -1487,7 +1435,7 @@ QMakeProject::resolveSpec(QString *spec, const QString &qmakespec) if (*spec == "default") { #ifdef Q_OS_UNIX char buffer[1024]; - int l = readlink(qmakespec.toLatin1(), buffer, 1023); + int l = readlink(qmakespec.toLatin1().constData(), buffer, 1023); if (l != -1) { buffer[l] = '\0'; *spec = QString::fromLatin1(buffer); @@ -1685,12 +1633,8 @@ QMakeProject::doProjectInclude(QString file, uchar flags, QHash<QString, QString if(flags & (IncludeFlagNewProject|IncludeFlagNewParser)) { // The "project's variables" are used in other places (eg. export()) so it's not // possible to use "place" everywhere. Instead just set variables and grab them later - QMakeProject proj(this, &place); + QMakeProject proj(prop); if(flags & IncludeFlagNewParser) { -#if 1 - if(proj.doProjectInclude("default_pre", IncludeFlagFeature, proj.variables()) == IncludeNoExist) - proj.doProjectInclude("default", IncludeFlagFeature, proj.variables()); -#endif parsed = proj.read(file, proj.variables()); // parse just that file (fromfile, infile) } else { parsed = proj.read(file); // parse all aux files (load/include into) @@ -2040,7 +1984,7 @@ QMakeProject::doProjectExpand(QString func, QList<QStringList> args_list, if(args.count() > 1) singleLine = (args[1].toLower() == "true"); QString output; - FILE *proc = QT_POPEN(args[0].toLatin1(), "r"); + FILE *proc = QT_POPEN(args[0].toLatin1().constData(), "r"); while(proc && !feof(proc)) { int read_in = int(fread(buff, 1, 255, proc)); if(!read_in) @@ -3113,19 +3057,19 @@ QStringList &QMakeProject::values(const QString &_var, QHash<QString, QStringLis place[var] = QStringList(Option::fixPathToTargetOS( !Option::qmake_abslocation.isEmpty() ? Option::qmake_abslocation - : QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmake", + : QLibraryInfo::location(QLibraryInfo::HostBinariesPath) + "/qmake", false)); } #if defined(Q_OS_WIN32) && defined(Q_CC_MSVC) else if(var.startsWith(QLatin1String("QMAKE_TARGET."))) { QString ret, type = var.mid(13); if(type == "arch") { - QString paths = qgetenv("PATH"); - QString vcBin64 = qgetenv("VCINSTALLDIR"); + QString paths = QString::fromLocal8Bit(qgetenv("PATH")); + QString vcBin64 = QString::fromLocal8Bit(qgetenv("VCINSTALLDIR")); if (!vcBin64.endsWith('\\')) vcBin64.append('\\'); vcBin64.append("bin\\amd64"); - QString vcBinX86_64 = qgetenv("VCINSTALLDIR"); + QString vcBinX86_64 = QString::fromLocal8Bit(qgetenv("VCINSTALLDIR")); if (!vcBinX86_64.endsWith('\\')) vcBinX86_64.append('\\'); vcBinX86_64.append("bin\\x86_amd64"); |