summaryrefslogtreecommitdiffstats
path: root/qmake/project.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qmake/project.cpp')
-rw-r--r--qmake/project.cpp142
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");