diff options
Diffstat (limited to 'qmake/generators/makefile.cpp')
-rw-r--r-- | qmake/generators/makefile.cpp | 141 |
1 files changed, 90 insertions, 51 deletions
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index e41e391cad..b634ec622b 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -81,8 +81,8 @@ bool MakefileGenerator::canExecute(const QStringList &cmdline, int *a) const QString MakefileGenerator::mkdir_p_asstring(const QString &dir, bool escape) const { - QString edir = escape ? escapeFilePath(Option::fixPathToTargetOS(dir, false, false)) : dir; - return "@" + makedir.arg(edir); + return "@" + makedir.arg( + escape ? escapeFilePath(Option::fixPathToTargetOS(dir, false, false)) : dir); } bool MakefileGenerator::mkdir(const QString &in_path) const @@ -424,6 +424,9 @@ MakefileGenerator::init() } incs.append(project->specDir()); + const auto platform = v["QMAKE_PLATFORM"]; + resolveDependenciesInFrameworks = platform.contains("darwin"); + const char * const cacheKeys[] = { "_QMAKE_STASH_", "_QMAKE_SUPER_CACHE_", nullptr }; for (int i = 0; cacheKeys[i]; ++i) { if (v[cacheKeys[i]].isEmpty()) @@ -529,7 +532,7 @@ MakefileGenerator::init() QStack<int> state; enum { IN_CONDITION, MET_CONDITION, PENDING_CONDITION }; for (int count = 1; !in.atEnd(); ++count) { - QString line = QString::fromUtf8(in.readLine()); + QString line = QString::fromLatin1(in.readLine()); if (line.startsWith("!!IF ")) { if (state.isEmpty() || state.top() == IN_CONDITION) { QString test = line.mid(5, line.length()-(5+1)); @@ -575,7 +578,7 @@ MakefileGenerator::init() contents += project->expand(line, in.fileName(), count); } } - contentBytes = contents.toUtf8(); + contentBytes = contents.toLatin1(); } QFile out(outn); QFileInfo outfi(out); @@ -624,7 +627,7 @@ MakefileGenerator::init() compiler.flags |= Compiler::CompilerNoCheckDeps; compilers.append(compiler); } - for (ProStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { + for (ProStringList::ConstIterator it = quc.cbegin(); it != quc.cend(); ++it) { const ProStringList &inputs = v[ProKey(*it + ".input")]; for(x = 0; x < inputs.size(); ++x) { Compiler compiler; @@ -909,7 +912,7 @@ MakefileGenerator::processPrlFileCore(QString &origFile, const QStringRef &origN const QString meta_file = QMakeMetaInfo::checkLib(fixedFile); if (meta_file.isEmpty()) return false; - QMakeMetaInfo libinfo(project); + QMakeMetaInfo libinfo; debug_msg(1, "Processing PRL file: %s", meta_file.toLatin1().constData()); if (!libinfo.readLib(meta_file)) { fprintf(stderr, "Error processing meta file %s\n", meta_file.toLatin1().constData()); @@ -1101,8 +1104,6 @@ QString MakefileGenerator::prlFileName(bool fixify) { QString ret = project->first("PRL_TARGET") + Option::prl_ext; - if(!project->isEmpty("QMAKE_BUNDLE")) - ret.prepend(project->first("QMAKE_BUNDLE") + Option::dir_sep); if(fixify) { if(!project->isEmpty("DESTDIR")) ret.prepend(project->first("DESTDIR").toQString()); @@ -1291,6 +1292,7 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) } } bool is_target = (wild == fileFixify(var("TARGET"), FileFixifyAbsolute)); + const bool noStrip = installConfigValues.contains("nostrip"); if(is_target || exists(wild)) { //real file or target QFileInfo fi(fileInfo(wild)); QString dst_file = filePrefixRoot(root, dst_dir); @@ -1304,7 +1306,7 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) cmd = QLatin1String("-$(QINSTALL)"); cmd += " " + escapeFilePath(wild) + " " + escapeFilePath(dst_file); inst << cmd; - if (!project->isActiveConfig("debug_info") && !project->isActiveConfig("nostrip") && + if (!noStrip && !project->isActiveConfig("debug_info") && !project->isActiveConfig("nostrip") && !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) inst << QString("-") + var("QMAKE_STRIP") + " " + escapeFilePath(filePrefixRoot(root, fileFixify(dst_dir + filestr, FileFixifyAbsolute, false))); @@ -1339,7 +1341,7 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) QString cmd = QLatin1String("-$(QINSTALL) ") + escapeFilePath(dirstr + file) + " " + escapeFilePath(dst_file); inst << cmd; - if (!project->isActiveConfig("debug_info") && !project->isActiveConfig("nostrip") && + if (!noStrip && !project->isActiveConfig("debug_info") && !project->isActiveConfig("nostrip") && !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) inst << QString("-") + var("QMAKE_STRIP") + " " + escapeFilePath(filePrefixRoot(root, fileFixify(dst_dir + file, FileFixifyAbsolute, false))); @@ -1840,6 +1842,33 @@ static QStringList splitDeps(const QString &indeps, bool lineMode) return deps; } +QString MakefileGenerator::resolveDependency(const QDir &outDir, const QString &file) +{ + const QList<QMakeLocalFileName> &depdirs = QMakeSourceFileInfo::dependencyPaths(); + for (const auto &depdir : depdirs) { + const QString &local = depdir.local(); + QString lf = outDir.absoluteFilePath(local + '/' + file); + if (exists(lf)) + return lf; + + if (resolveDependenciesInFrameworks) { + // Given a file like "QtWidgets/QWidget", try to resolve it + // as framework header "QtWidgets.framework/Headers/QWidget". + int cut = file.indexOf('/'); + if (cut < 0 || cut + 1 >= file.size()) + continue; + QStringRef framework = file.leftRef(cut); + QStringRef include = file.midRef(cut + 1); + if (local.endsWith('/' + framework + ".framework/Headers")) { + lf = outDir.absoluteFilePath(local + '/' + include); + if (exists(lf)) + return lf; + } + } + } + return {}; +} + void MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) { @@ -1877,12 +1906,14 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) if (config.indexOf("combine") != -1) { // compilers with a combined input only have one output QString input = project->first(ProKey(*it + ".output")).toQString(); - t << ' ' << escapeDependencyPath(Option::fixPathToTargetOS( - replaceExtraCompilerVariables(tmp_out, input, QString(), NoShell))); + t << ' ' << escapeDependencyPath(fileFixify( + replaceExtraCompilerVariables(tmp_out, input, QString(), NoShell), + FileFixifyFromOutdir)); } else { - for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { - t << ' ' << escapeDependencyPath(Option::fixPathToTargetOS( - replaceExtraCompilerVariables(tmp_out, (*input).toQString(), QString(), NoShell))); + for (ProStringList::ConstIterator input = tmp_inputs.cbegin(); input != tmp_inputs.cend(); ++input) { + t << ' ' << escapeDependencyPath(fileFixify( + replaceExtraCompilerVariables(tmp_out, (*input).toQString(), QString(), NoShell), + FileFixifyFromOutdir)); } } t << endl; @@ -1914,12 +1945,13 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) const QString del_statement("-$(DEL_FILE)"); if(!wrote_clean) { QStringList dels; - for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { + for (ProStringList::ConstIterator input = tmp_inputs.cbegin(); input != tmp_inputs.cend(); ++input) { QString tinp = (*input).toQString(); QString out = replaceExtraCompilerVariables(tmp_out, tinp, QString(), NoShell); for (const QString &rc : qAsConst(raw_clean)) { - dels << ' ' + escapeFilePath(Option::fixPathToTargetOS( - replaceExtraCompilerVariables(rc, tinp, out, NoShell), false)); + dels << ' ' + escapeFilePath(fileFixify( + replaceExtraCompilerVariables(rc, tinp, out, NoShell), + FileFixifyFromOutdir)); } } if(project->isActiveConfig("no_delete_multiple_files")) { @@ -1942,7 +1974,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) if(!cleans.isEmpty()) t << valGlue(cleans, "\n\t" + del_statement, "\n\t" + del_statement, ""); if(!wrote_clean_cmds) { - for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { + for (ProStringList::ConstIterator input = tmp_inputs.cbegin(); input != tmp_inputs.cend(); ++input) { QString tinp = (*input).toQString(); t << "\n\t" << replaceExtraCompilerVariables(tmp_clean_cmds, tinp, replaceExtraCompilerVariables(tmp_out, tinp, QString(), NoShell), TargetShell); @@ -1961,7 +1993,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) QStringList deps, inputs; if(!tmp_dep.isEmpty()) deps += fileFixify(tmp_dep, FileFixifyFromOutdir); - for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { + for (ProStringList::ConstIterator input = tmp_inputs.cbegin(); input != tmp_inputs.cend(); ++input) { QString inpf = (*input).toQString(); deps += findDependencies(inpf); inputs += Option::fixPathToTargetOS(inpf, false); @@ -1989,16 +2021,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) } else if (exists(absFile)) { file = absFile; } else { - QString localFile; - QList<QMakeLocalFileName> depdirs = QMakeSourceFileInfo::dependencyPaths(); - for (QList<QMakeLocalFileName>::Iterator dit = depdirs.begin(); - dit != depdirs.end(); ++dit) { - QString lf = outDir.absoluteFilePath((*dit).local() + '/' + file); - if (exists(lf)) { - localFile = lf; - break; - } - } + QString localFile = resolveDependency(outDir, file); if (localFile.isEmpty()) { if (exists(file)) warn_msg(WarnDeprecated, ".depend_command for extra compiler %s" @@ -2035,7 +2058,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) QString out = replaceExtraCompilerVariables(tmp_out, QString(), QString(), NoShell); QString cmd = replaceExtraCompilerVariables(tmp_cmd, inputs, QStringList() << out, TargetShell); - t << escapeDependencyPath(Option::fixPathToTargetOS(out)) << ":"; + t << escapeDependencyPath(fileFixify(out, FileFixifyFromOutdir)) << ":"; // compiler.CONFIG+=explicit_dependencies means that ONLY compiler.depends gets to cause Makefile dependencies if (config.indexOf("explicit_dependencies") != -1) { t << " " << valList(escapeDependencyPaths(fileFixify(tmp_dep, FileFixifyFromOutdir))); @@ -2045,16 +2068,18 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) t << "\n\t" << cmd << endl << endl; continue; } - for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { + for (ProStringList::ConstIterator input = tmp_inputs.cbegin(); input != tmp_inputs.cend(); ++input) { QString inpf = (*input).toQString(); - QString in = Option::fixPathToTargetOS(inpf, false); - QStringList deps = findDependencies(inpf); - deps << in; - QString out = Option::fixPathToTargetOS(replaceExtraCompilerVariables(tmp_out, inpf, QString(), NoShell)); + QStringList deps; + deps << fileFixify(inpf, FileFixifyFromOutdir); + deps += findDependencies(inpf); + QString out = fileFixify(replaceExtraCompilerVariables(tmp_out, inpf, QString(), NoShell), + FileFixifyFromOutdir); if(!tmp_dep.isEmpty()) { QStringList pre_deps = fileFixify(tmp_dep, FileFixifyFromOutdir); for(int i = 0; i < pre_deps.size(); ++i) - deps << replaceExtraCompilerVariables(pre_deps.at(i), inpf, out, NoShell); + deps << fileFixify(replaceExtraCompilerVariables(pre_deps.at(i), inpf, out, NoShell), + FileFixifyFromOutdir); } QString cmd = replaceExtraCompilerVariables(tmp_cmd, inpf, out, TargetShell); // NOTE: The var -> QMAKE_COMP_var replace feature is unsupported, do not use! @@ -2084,16 +2109,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) } else if (exists(absFile)) { file = absFile; } else { - QString localFile; - QList<QMakeLocalFileName> depdirs = QMakeSourceFileInfo::dependencyPaths(); - for (QList<QMakeLocalFileName>::Iterator dit = depdirs.begin(); - dit != depdirs.end(); ++dit) { - QString lf = outDir.absoluteFilePath((*dit).local() + '/' + file); - if (exists(lf)) { - localFile = lf; - break; - } - } + QString localFile = resolveDependency(outDir, file); if (localFile.isEmpty()) { if (exists(file)) warn_msg(WarnDeprecated, ".depend_command for extra compiler %s" @@ -2114,7 +2130,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) //use the depend system to find includes of these included files QStringList inc_deps; for(int i = 0; i < deps.size(); ++i) { - const QString dep = deps.at(i); + const QString dep = fileFixify(deps.at(i), FileFixifyFromOutdir | FileFixifyAbsolute); if(QFile::exists(dep)) { SourceFileType type = TYPE_UNKNOWN; if(type == TYPE_UNKNOWN) { @@ -2151,11 +2167,10 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) } } } - deps += inc_deps; + deps += fileFixify(inc_deps, FileFixifyFromOutdir); } for(int i = 0; i < deps.size(); ) { QString &dep = deps[i]; - dep = Option::fixPathToTargetOS(dep, false); if(out == dep) deps.removeAt(i); else @@ -2209,6 +2224,25 @@ MakefileGenerator::writeExtraVariables(QTextStream &t) } } +// This is a more powerful alternative to the above function. +// It's meant to be internal, as one can make quite a mess with it. +void +MakefileGenerator::writeExportedVariables(QTextStream &t) +{ + const auto &vars = project->values("QMAKE_EXPORTED_VARIABLES"); + if (vars.isEmpty()) + return; + for (const auto &exp : vars) { + const ProString &name = project->first(ProKey(exp + ".name")); + const ProString &value = project->first(ProKey(exp + ".value")); + if (!value.isEmpty()) + t << name << " = " << value << endl; + else + t << name << " =\n"; + } + t << endl; +} + bool MakefileGenerator::writeDummyMakefile(QTextStream &t) { @@ -2327,6 +2361,7 @@ MakefileGenerator::writeHeader(QTextStream &t) if (ofile.lastIndexOf(Option::dir_sep) != -1) ofile.remove(0, ofile.lastIndexOf(Option::dir_sep) +1); t << "MAKEFILE = " << escapeFilePath(ofile) << endl << endl; + t << "EQ = =\n\n"; } QList<MakefileGenerator::SubTarget*> @@ -2550,6 +2585,9 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT { //actually compile t << subtarget->target << ":"; + auto extraDeps = extraSubTargetDependencies(); + if (!extraDeps.isEmpty()) + t << " " << valList(extraDeps); if(!subtarget->depends.isEmpty()) t << " " << valList(subtarget->depends); t << " FORCE"; @@ -2871,6 +2909,7 @@ MakefileGenerator::escapeDependencyPath(const QString &path) const static const QRegExp criticalChars(QStringLiteral("([\t #])")); #endif ret.replace(criticalChars, QStringLiteral("\\\\1")); + ret.replace(QLatin1Char('='), QStringLiteral("$(EQ)")); debug_msg(2, "escapeDependencyPath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); } return ret; @@ -3352,7 +3391,7 @@ MakefileGenerator::writePkgConfigFile() libs << "QMAKE_LIBS_PRIVATE"; libs << "QMAKE_LFLAGS_THREAD"; //not sure about this one, but what about things like -pthread? t << "Libs.private:"; - for (ProStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it) + for (ProStringList::ConstIterator it = libs.cbegin(); it != libs.cend(); ++it) t << ' ' << fixLibFlags((*it).toKey()).join(' '); t << endl; } |