void Win32MakefileGenerator::processPrlFiles() { const QString libArg = project->first("QMAKE_L_FLAG").toQString(); QList<QMakeLocalFileName> libdirs; static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; for (int i = 0; lflags[i]; i++) { ProStringList &l = project->values(lflags[i]); for (int lit = 0; lit < l.size(); ++lit) { QString opt = l.at(lit).trimmed().toQString(); if((opt[0] == '\'' || opt[0] == '"') && opt[(int)opt.length()-1] == opt[0]) opt = opt.mid(1, opt.length()-2); if (opt.startsWith(libArg)) { QMakeLocalFileName l(opt.mid(libArg.length())); if (!libdirs.contains(l)) libdirs.append(l); } else if (!opt.startsWith("/")) { if (!processPrlFile(opt) && (QDir::isRelativePath(opt) || opt.startsWith("-l"))) { QString tmp; if (opt.startsWith("-l")) tmp = opt.mid(2); else tmp = opt; for(QList<QMakeLocalFileName>::Iterator it = libdirs.begin(); it != libdirs.end(); ++it) { QString prl = (*it).local() + Option::dir_sep + tmp; if (processPrlFile(prl)) break; } } } ProStringList &prl_libs = project->values("QMAKE_CURRENT_PRL_LIBS"); for (int prl = 0; prl < prl_libs.size(); ++prl) { ProString arg = prl_libs.at(prl); if (arg.startsWith(libArg)) arg = arg.left(libArg.length()) + escapeFilePath(arg.mid(libArg.length()).toQString()); else if (!arg.startsWith('/')) arg = escapeFilePath(arg.toQString()); l.insert(lit + prl + 1, arg); } prl_libs.clear(); } // Merge them into a logical order if (!project->isActiveConfig("no_smart_library_merge") && !project->isActiveConfig("no_lflags_merge")) { ProStringList lflags; for (int lit = 0; lit < l.size(); ++lit) { ProString opt = l.at(lit).trimmed(); if (opt.startsWith(libArg)) { if (!lflags.contains(opt)) lflags.append(opt); } else { // Make sure we keep the dependency-order of libraries lflags.removeAll(opt); lflags.append(opt); } } l = lflags; } } }
bool QMakeMetaInfo::readLibtoolFile(const QString &f) { /* I can just run the .la through the .pro parser since they are compatible.. */ QMakeProject proj; QString nf = Option::normalizePath(f); if (!proj.read(nf, QMakeEvaluator::LoadProOnly)) return false; QString dirf = nf.section(QLatin1Char('/'), 0, -2); if(dirf == nf) dirf = ""; else if(!dirf.isEmpty() && !dirf.endsWith(Option::output_dir)) dirf += QLatin1Char('/'); const ProValueMap &v = proj.variables(); for (ProValueMap::ConstIterator it = v.begin(); it != v.end(); ++it) { ProStringList lst = it.value(); if(lst.count() == 1 && (lst.first().startsWith("'") || lst.first().startsWith("\"")) && lst.first().endsWith(QString(lst.first().at(0)))) lst = ProStringList(lst.first().mid(1, lst.first().length() - 2)); if(!vars.contains("QMAKE_PRL_TARGET") && (it.key() == "dlname" || it.key() == "library_names" || it.key() == "old_library")) { ProString dir = v["libdir"].first(); if ((dir.startsWith('\'') || dir.startsWith('"')) && dir.endsWith(dir.at(0))) dir = dir.mid(1, dir.length() - 2); dir = dir.trimmed(); if(!dir.isEmpty() && !dir.endsWith(QLatin1Char('/'))) dir += QLatin1Char('/'); if(lst.count() == 1) lst = ProStringList(lst.first().toQString().split(" ")); for (ProStringList::Iterator lst_it = lst.begin(); lst_it != lst.end(); ++lst_it) { bool found = false; QString dirs[] = { "", dir.toQString(), dirf, dirf + ".libs/", "(term)" }; for(int i = 0; !found && dirs[i] != "(term)"; i++) { if(QFile::exists(dirs[i] + (*lst_it))) { QString targ = dirs[i] + (*lst_it); if(QDir::isRelativePath(targ)) targ.prepend(qmake_getpwd() + QLatin1Char('/')); vars["QMAKE_PRL_TARGET"] << targ; found = true; } } if(found) break; } } else if(it.key() == "dependency_libs") { if(lst.count() == 1) { ProString dep = lst.first(); if ((dep.startsWith('\'') || dep.startsWith('"')) && dep.endsWith(dep.at(0))) dep = dep.mid(1, dep.length() - 2); lst = ProStringList(dep.trimmed().toQString().split(" ")); } for (ProStringList::Iterator lit = lst.begin(); lit != lst.end(); ++lit) { if((*lit).startsWith("-R")) { if(!conf->isEmpty("QMAKE_LFLAGS_RPATH")) (*lit) = conf->first("QMAKE_LFLAGS_RPATH") + (*lit).mid(2); } } vars["QMAKE_PRL_LIBS"] += lst; } } return true; }
void ProjectGenerator::init() { if(init_flag) return; int file_count = 0; init_flag = true; verifyCompilers(); project->loadSpec(); project->evaluateFeatureFile("default_pre.prf"); project->evaluateFeatureFile("default_post.prf"); project->evaluateConfigFeatures(); project->values("CONFIG").clear(); Option::postProcessProject(project); ProValueMap &v = project->variables(); QString templ = Option::globals->user_template.isEmpty() ? QString("app") : Option::globals->user_template; if (!Option::globals->user_template_prefix.isEmpty()) templ.prepend(Option::globals->user_template_prefix); v["TEMPLATE_ASSIGN"] += templ; //the scary stuff if(project->first("TEMPLATE_ASSIGN") != "subdirs") { QString builtin_regex = project_builtin_regx(); QStringList dirs = Option::projfile::project_dirs; if(Option::projfile::do_pwd) { if(!v["INCLUDEPATH"].contains(".")) v["INCLUDEPATH"] += "."; dirs.prepend(qmake_getpwd()); } for(int i = 0; i < dirs.count(); ++i) { QString dir, regex, pd = dirs.at(i); bool add_depend = false; if(exists(pd)) { QFileInfo fi(fileInfo(pd)); if(fi.isDir()) { dir = pd; add_depend = true; if(dir.right(1) != Option::dir_sep) dir += Option::dir_sep; if (Option::recursive) { QStringList files = QDir(dir).entryList(QDir::Files); for (int i = 0; i < files.count(); i++) dirs.append(dir + files[i] + QDir::separator() + builtin_regex); } regex = builtin_regex; } else { QString file = pd; int s = file.lastIndexOf(Option::dir_sep); if(s != -1) dir = file.left(s+1); if(addFile(file)) { add_depend = true; file_count++; } } } else { //regexp regex = pd; } if(!regex.isEmpty()) { int s = regex.lastIndexOf(Option::dir_sep); if(s != -1) { dir = regex.left(s+1); regex = regex.right(regex.length() - (s+1)); } if (Option::recursive) { QStringList entries = QDir(dir).entryList(QDir::Dirs | QDir::NoDotAndDotDot); for (int i = 0; i < entries.count(); i++) dirs.append(dir + entries[i] + QDir::separator() + regex); } QStringList files = QDir(dir).entryList(QDir::nameFiltersFromString(regex)); for(int i = 0; i < (int)files.count(); i++) { QString file = dir + files[i]; if (addFile(file)) { add_depend = true; file_count++; } } } if(add_depend && !dir.isEmpty() && !v["DEPENDPATH"].contains(dir, Qt::CaseInsensitive)) { QFileInfo fi(fileInfo(dir)); if(fi.absoluteFilePath() != qmake_getpwd()) v["DEPENDPATH"] += fileFixify(dir); } } } if(!file_count) { //shall we try a subdir? QStringList knownDirs = Option::projfile::project_dirs; if(Option::projfile::do_pwd) knownDirs.prepend("."); const QString out_file = fileFixify(Option::output.fileName()); for(int i = 0; i < knownDirs.count(); ++i) { QString pd = knownDirs.at(i); if(exists(pd)) { QString newdir = pd; QFileInfo fi(fileInfo(newdir)); if(fi.isDir()) { newdir = fileFixify(newdir); ProStringList &subdirs = v["SUBDIRS"]; if(exists(fi.filePath() + QDir::separator() + fi.fileName() + Option::pro_ext) && !subdirs.contains(newdir, Qt::CaseInsensitive)) { subdirs.append(newdir); } else { QStringList profiles = QDir(newdir).entryList(QStringList("*" + Option::pro_ext), QDir::Files); for(int i = 0; i < (int)profiles.count(); i++) { QString nd = newdir; if(nd == ".") nd = ""; else if(!nd.isEmpty() && !nd.endsWith(QString(QChar(QDir::separator())))) nd += QDir::separator(); nd += profiles[i]; fileFixify(nd); if (!subdirs.contains(nd, Qt::CaseInsensitive) && !out_file.endsWith(nd)) subdirs.append(nd); } } if (Option::recursive) { QStringList dirs = QDir(newdir).entryList(QDir::Dirs | QDir::NoDotAndDotDot); for(int i = 0; i < (int)dirs.count(); i++) { QString nd = fileFixify(newdir + QDir::separator() + dirs[i]); if (!knownDirs.contains(nd, Qt::CaseInsensitive)) knownDirs.append(nd); } } } } else { //regexp QString regx = pd, dir; int s = regx.lastIndexOf(Option::dir_sep); if(s != -1) { dir = regx.left(s+1); regx = regx.right(regx.length() - (s+1)); } QStringList files = QDir(dir).entryList(QDir::nameFiltersFromString(regx), QDir::Dirs | QDir::NoDotAndDotDot); ProStringList &subdirs = v["SUBDIRS"]; for(int i = 0; i < (int)files.count(); i++) { QString newdir(dir + files[i]); QFileInfo fi(fileInfo(newdir)); { newdir = fileFixify(newdir); if(exists(fi.filePath() + QDir::separator() + fi.fileName() + Option::pro_ext) && !subdirs.contains(newdir)) { subdirs.append(newdir); } else { QStringList profiles = QDir(newdir).entryList(QStringList("*" + Option::pro_ext), QDir::Files); for(int i = 0; i < (int)profiles.count(); i++) { QString nd = newdir + QDir::separator() + files[i]; fileFixify(nd); if(files[i] != "." && files[i] != ".." && !subdirs.contains(nd, Qt::CaseInsensitive)) { if(newdir + files[i] != Option::output_dir + Option::output.fileName()) subdirs.append(nd); } } } if (Option::recursive && !knownDirs.contains(newdir, Qt::CaseInsensitive)) knownDirs.append(newdir); } } } } v["TEMPLATE_ASSIGN"] = ProStringList("subdirs"); return; } //setup deplist QList<QMakeLocalFileName> deplist; { const ProStringList &d = v["DEPENDPATH"]; for(int i = 0; i < d.size(); ++i) deplist.append(QMakeLocalFileName(d[i].toQString())); } setDependencyPaths(deplist); ProStringList &h = v["HEADERS"]; bool no_qt_files = true; static const char *srcs[] = { "SOURCES", "YACCSOURCES", "LEXSOURCES", "FORMS", 0 }; for (int i = 0; srcs[i]; i++) { const ProStringList &l = v[srcs[i]]; QMakeSourceFileInfo::SourceFileType type = QMakeSourceFileInfo::TYPE_C; QMakeSourceFileInfo::addSourceFiles(l, QMakeSourceFileInfo::SEEK_DEPS, type); for(int i = 0; i < l.size(); ++i) { QStringList tmp = QMakeSourceFileInfo::dependencies(l.at(i).toQString()); if(!tmp.isEmpty()) { for(int dep_it = 0; dep_it < tmp.size(); ++dep_it) { QString dep = tmp[dep_it]; dep = fixPathToQmake(dep); QString file_dir = dep.section(Option::dir_sep, 0, -2), file_no_path = dep.section(Option::dir_sep, -1); if(!file_dir.isEmpty()) { for(int inc_it = 0; inc_it < deplist.size(); ++inc_it) { QMakeLocalFileName inc = deplist[inc_it]; if(inc.local() == file_dir && !v["INCLUDEPATH"].contains(inc.real(), Qt::CaseInsensitive)) v["INCLUDEPATH"] += inc.real(); } } if(no_qt_files && file_no_path.indexOf(QRegExp("^q[a-z_0-9].h$")) != -1) no_qt_files = false; QString h_ext; for(int hit = 0; hit < Option::h_ext.size(); ++hit) { if(dep.endsWith(Option::h_ext.at(hit))) { h_ext = Option::h_ext.at(hit); break; } } if(!h_ext.isEmpty()) { for(int cppit = 0; cppit < Option::cpp_ext.size(); ++cppit) { QString src(dep.left(dep.length() - h_ext.length()) + Option::cpp_ext.at(cppit)); if(exists(src)) { ProStringList &srcl = v["SOURCES"]; if(!srcl.contains(src, Qt::CaseInsensitive)) srcl.append(src); } } } else if(dep.endsWith(Option::lex_ext) && file_no_path.startsWith(Option::lex_mod)) { addConfig("lex_included"); } if(!h.contains(dep, Qt::CaseInsensitive)) h += dep; } } } } //strip out files that are actually output from internal compilers (ie temporary files) const ProStringList &quc = project->values("QMAKE_EXTRA_COMPILERS"); for (ProStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { QString tmp_out = project->first(ProKey(*it + ".output")).toQString(); if(tmp_out.isEmpty()) continue; ProStringList var_out = project->values(ProKey(*it + ".variable_out")); bool defaults = var_out.isEmpty(); for(int i = 0; i < var_out.size(); ++i) { ProString v = var_out.at(i); if(v.startsWith("GENERATED_")) { defaults = true; break; } } if(defaults) { var_out << "SOURCES"; var_out << "HEADERS"; var_out << "FORMS"; } const ProStringList &tmp = project->values(ProKey(*it + ".input")); for (ProStringList::ConstIterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { ProStringList &inputs = project->values((*it2).toKey()); for (ProStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { QString path = replaceExtraCompilerVariables(tmp_out, (*input).toQString(), QString()); path = fixPathToQmake(path).section('/', -1); for(int i = 0; i < var_out.size(); ++i) { ProString v = var_out.at(i); ProStringList &list = project->values(v.toKey()); for(int src = 0; src < list.size(); ) { if(list[src] == path || list[src].endsWith("/" + path)) list.removeAt(src); else ++src; } } } } } }