bool MingwMakefileGenerator::findLibraries() { QStringList &l = project->values("QMAKE_LIBS"); QList<QMakeLocalFileName> dirs; { QStringList &libpaths = project->values("QMAKE_LIBDIR"); for(QStringList::Iterator libpathit = libpaths.begin(); libpathit != libpaths.end(); ++libpathit) dirs.append(QMakeLocalFileName((*libpathit))); } QStringList::Iterator it = l.begin(); while (it != l.end()) { if ((*it).startsWith("-l")) { QString steam = (*it).mid(2); QString suffix; if (!project->isEmpty("QMAKE_" + steam.toUpper() + "_SUFFIX")) suffix = project->first("QMAKE_" + steam.toUpper() + "_SUFFIX"); QString extension; for (QList<QMakeLocalFileName>::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { int ver = findHighestVersion((*dir_it).local(), steam, "dll.a|a"); if (ver != -1) { extension += QString::number(ver); break; } } extension += suffix; (*it) += extension; } else if((*it).startsWith("-L")) { dirs.append(QMakeLocalFileName((*it).mid(2))); } ++it; } return true; }
void QMakeSourceFileInfo::saveCache(const QString &cf) { #ifdef QMAKE_USE_CACHE if(cf.isEmpty()) return; QFile file(QMakeLocalFileName(cf).local()); if(file.open(QIODevice::WriteOnly)) { QTextStream stream(&file); stream << qmake_version() << endl << endl; //version { //cache verification QMap<QString, QStringList> verify = getCacheVerification(); stream << verify.count() << endl; for(QMap<QString, QStringList>::iterator it = verify.begin(); it != verify.end(); ++it) { stream << it.key() << endl << it.value().join(";") << endl; } stream << endl; } if(files->nodes) { for(int file = 0; file < files->num_nodes; ++file) { for(SourceFiles::SourceFileNode *node = files->nodes[file]; node; node = node->next) { stream << node->file->file.local() << endl; //source stream << node->file->type << endl; //type //depends stream << ";"; if(node->file->deps) { for(int depend = 0; depend < node->file->deps->used_nodes; ++depend) { if(depend) stream << ";"; stream << node->file->deps->children[depend]->file.local(); } } stream << endl; stream << node->file->mocable << endl; //mocable stream << endl; //just for human readability } } } stream.flush(); file.close(); } #else Q_UNUSED(cf); #endif }
bool MingwMakefileGenerator::findLibraries() { QList<QMakeLocalFileName> dirs; static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; for (int i = 0; lflags[i]; i++) { ProStringList &l = project->values(lflags[i]); ProStringList::Iterator it = l.begin(); while (it != l.end()) { if ((*it).startsWith("-l")) { QString steam = (*it).mid(2).toQString(); ProString out; QString suffix = project->first(ProKey("QMAKE_" + steam.toUpper() + "_SUFFIX")).toQString(); for (QList<QMakeLocalFileName>::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { QString extension; int ver = findHighestVersion((*dir_it).local(), steam, "dll.a|a"); if (ver > 0) extension += QString::number(ver); extension += suffix; if(QMakeMetaInfo::libExists((*dir_it).local() + Option::dir_sep + steam) || exists((*dir_it).local() + Option::dir_sep + steam + extension + ".a") || exists((*dir_it).local() + Option::dir_sep + steam + extension + ".dll.a")) { out = *it + extension; break; } } if (!out.isEmpty()) // We assume if it never finds it that its correct (*it) = out; } else if((*it).startsWith("-L")) { dirs.append(QMakeLocalFileName((*it).mid(2).toQString())); } ++it; } } return true; }
QStringList QMakeSourceFileInfo::dependencies(const QString &file) { QStringList ret; if(!files) return ret; if(SourceFile *node = files->lookupFile(QMakeLocalFileName(file))) { if(node->deps) { /* I stick them into a SourceDependChildren here because it is faster to just iterate over the list to stick them in the list, and reset the flag, then it is to loop over the tree (about 50% faster I saw) --Sam */ SourceDependChildren place; for(int i = 0; i < node->deps->used_nodes; i++) dependTreeWalker(node->deps->children[i], &place); if(place.children) { for(int i = 0; i < place.used_nodes; i++) { place.children[i]->traversed = false; //reset flag ret.append(place.children[i]->file.real()); } } } } return ret; }
bool Win32MakefileGenerator::findLibraries(const QString &where) { QStringList &l = project->values(where); QList<QMakeLocalFileName> dirs; { QStringList &libpaths = project->values("QMAKE_LIBDIR"); for(QStringList::Iterator libpathit = libpaths.begin(); libpathit != libpaths.end(); ++libpathit) dirs.append(QMakeLocalFileName((*libpathit))); } for(QStringList::Iterator it = l.begin(); it != l.end();) { QChar quote; bool modified_opt = false, remove = false; QString opt = (*it).trimmed(); if((opt[0] == '\'' || opt[0] == '"') && opt[(int)opt.length()-1] == opt[0]) { quote = opt[0]; opt = opt.mid(1, opt.length()-2); } if(opt.startsWith("/LIBPATH:")) { dirs.append(QMakeLocalFileName(opt.mid(9))); } else if(opt.startsWith("-L") || opt.startsWith("/L")) { QString libpath = opt.mid(2); QMakeLocalFileName l(libpath); if(!dirs.contains(l)) { dirs.append(l); modified_opt = true; if (!quote.isNull()) { libpath = quote + libpath + quote; quote = QChar(); } (*it) = "/LIBPATH:" + libpath; } else { remove = true; } } else if(opt.startsWith("-l") || opt.startsWith("/l")) { QString lib = opt.right(opt.length() - 2), out; if(!lib.isEmpty()) { QString suffix; if(!project->isEmpty("QMAKE_" + lib.toUpper() + "_SUFFIX")) suffix = project->first("QMAKE_" + lib.toUpper() + "_SUFFIX"); for(QList<QMakeLocalFileName>::Iterator it = dirs.begin(); it != dirs.end(); ++it) { QString extension; int ver = findHighestVersion((*it).local(), lib); if(ver > 0) extension += QString::number(ver); extension += suffix; extension += ".lib"; if(QMakeMetaInfo::libExists((*it).local() + Option::dir_sep + lib) || exists((*it).local() + Option::dir_sep + lib + extension)) { out = (*it).real() + Option::dir_sep + lib + extension; if (out.contains(QLatin1Char(' '))) { out.prepend(QLatin1Char('\"')); out.append(QLatin1Char('\"')); } break; } } } if(out.isEmpty()) out = lib + ".lib"; modified_opt = true; (*it) = out; } else if(!exists(Option::fixPathToLocalOS(opt))) { QList<QMakeLocalFileName> lib_dirs; QString file = opt; int slsh = file.lastIndexOf(Option::dir_sep); if(slsh != -1) { lib_dirs.append(QMakeLocalFileName(file.left(slsh+1))); file = file.right(file.length() - slsh - 1); } else { lib_dirs = dirs; } if(file.endsWith(".lib")) { file = file.left(file.length() - 4); if(!file.at(file.length()-1).isNumber()) { QString suffix; if(!project->isEmpty("QMAKE_" + file.section(Option::dir_sep, -1).toUpper() + "_SUFFIX")) suffix = project->first("QMAKE_" + file.section(Option::dir_sep, -1).toUpper() + "_SUFFIX"); for(QList<QMakeLocalFileName>::Iterator dep_it = lib_dirs.begin(); dep_it != lib_dirs.end(); ++dep_it) { QString lib_tmpl(file + "%1" + suffix + ".lib"); int ver = findHighestVersion((*dep_it).local(), file); if(ver != -1) { if(ver) lib_tmpl = lib_tmpl.arg(ver); else lib_tmpl = lib_tmpl.arg(""); if(slsh != -1) { QString dir = (*dep_it).real(); if(!dir.endsWith(Option::dir_sep)) dir += Option::dir_sep; lib_tmpl.prepend(dir); } modified_opt = true; (*it) = lib_tmpl; break; } } } } } if(remove) { it = l.erase(it); } else { if(!quote.isNull() && modified_opt) (*it) = quote + (*it) + quote; ++it; } } return true; }
void UnixMakefileGenerator::processPrlFiles() { QList<QMakeLocalFileName> libdirs, frameworkdirs; frameworkdirs.append(QMakeLocalFileName("/System/Library/Frameworks")); const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_FRAMEWORKPATH_FLAGS", "QMAKE_LFLAGS", "QMAKE_LIBS", QString() }; for(int i = 0; !lflags[i].isNull(); i++) { QStringList &l = project->values(lflags[i]); for(int lit = 0; lit < l.size(); ++lit) { QString opt = l.at(lit).trimmed(); if(opt.startsWith("-")) { if(opt.startsWith("-L")) { QMakeLocalFileName l(opt.right(opt.length()-2)); if(!libdirs.contains(l)) libdirs.append(l); } else if(opt.startsWith("-l")) { QString lib = opt.right(opt.length() - 2); for(int dep_i = 0; dep_i < libdirs.size(); ++dep_i) { const QMakeLocalFileName &lfn = libdirs[dep_i]; if(!project->isActiveConfig("compile_libtool")) { //give them the .libs.. QString la = lfn.local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + lib + Option::libtool_ext; if(exists(la) && QFile::exists(lfn.local() + Option::dir_sep + ".libs")) { QString dot_libs = lfn.real() + Option::dir_sep + ".libs"; l.append("-L" + dot_libs); libdirs.append(QMakeLocalFileName(dot_libs)); } } QString prl = lfn.local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + lib; if(!project->isEmpty("QMAKE_" + lib.toUpper() + "_SUFFIX")) prl += project->first("QMAKE_" + lib.toUpper() + "_SUFFIX"); if(processPrlFile(prl)) { if(prl.startsWith(lfn.local())) prl.replace(0, lfn.local().length(), lfn.real()); opt = linkLib(prl, lib); break; } } } else if(Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-F")) { QMakeLocalFileName f(opt.right(opt.length()-2)); if(!frameworkdirs.contains(f)) frameworkdirs.append(f); } else if(Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-framework")) { if(opt.length() > 11) opt = opt.mid(11); else opt = l.at(++lit); opt = opt.trimmed(); const QList<QMakeLocalFileName> dirs = frameworkdirs + libdirs; for(int dep_i = 0; dep_i < dirs.size(); ++dep_i) { QString prl = dirs[dep_i].local() + "/" + opt + ".framework/" + opt + Option::prl_ext; if(processPrlFile(prl)) break; } } } else if(!opt.isNull()) { QString lib = opt; processPrlFile(lib); #if 0 if(ret) opt = linkLib(lib, ""); #endif if(!opt.isEmpty()) l.replaceInStrings(lib, opt); } QStringList &prl_libs = project->values("QMAKE_CURRENT_PRL_LIBS"); if(!prl_libs.isEmpty()) { for(int prl = 0; prl < prl_libs.size(); ++prl) l.insert(lit+prl+1, prl_libs.at(prl)); prl_libs.clear(); } } //merge them into a logical order if(!project->isActiveConfig("no_smart_library_merge") && !project->isActiveConfig("no_lflags_merge")) { QHash<QString, QStringList> lflags; for(int lit = 0; lit < l.size(); ++lit) { QString arch("default"); QString opt = l.at(lit).trimmed(); if(opt.startsWith("-")) { if (Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-Xarch")) { if (opt.length() > 7) { arch = opt.mid(7); opt = l.at(++lit); } } if(opt.startsWith("-L") || (Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-F"))) { if(!lflags[arch].contains(opt)) lflags[arch].append(opt); } else if(opt.startsWith("-l") || opt == "-pthread") { // Make sure we keep the dependency-order of libraries if (lflags[arch].contains(opt)) lflags[arch].removeAll(opt); lflags[arch].append(opt); } else if(Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-framework")) { if(opt.length() > 11) opt = opt.mid(11); else { opt = l.at(++lit); if (Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-Xarch")) opt = l.at(++lit); // The user has done the right thing and prefixed each part } bool found = false; for(int x = 0; x < lflags[arch].size(); ++x) { QString xf = lflags[arch].at(x); if(xf.startsWith("-framework")) { QString framework; if(xf.length() > 11) framework = xf.mid(11); else framework = lflags[arch].at(++x); if(framework == opt) { found = true; break; } } } if(!found) { lflags[arch].append("-framework"); lflags[arch].append(opt); } } else { lflags[arch].append(opt); } } else if(!opt.isNull()) { if(!lflags[arch].contains(opt)) lflags[arch].append(opt); } } l = lflags.take("default"); // Process architecture specific options (Xarch) QHash<QString, QStringList>::const_iterator archIterator = lflags.constBegin(); while (archIterator != lflags.constEnd()) { const QStringList archOptions = archIterator.value(); for (int i = 0; i < archOptions.size(); ++i) { l.append(QLatin1String("-Xarch_") + archIterator.key()); l.append(archOptions.at(i)); } ++archIterator; } } } }
bool UnixMakefileGenerator::findLibraries() { QList<QMakeLocalFileName> libdirs, frameworkdirs; frameworkdirs.append(QMakeLocalFileName("/System/Library/Frameworks")); frameworkdirs.append(QMakeLocalFileName("/Library/Frameworks")); const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_FRAMEWORKPATH_FLAGS", "QMAKE_LFLAGS", "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", QString() }; for(int i = 0; !lflags[i].isNull(); i++) { QStringList &l = project->values(lflags[i]); for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { bool do_suffix = true; QString stub, dir, extn, opt = (*it).trimmed(); if(opt.startsWith("-")) { if(opt.startsWith("-L")) { QMakeLocalFileName f(opt.right(opt.length()-2)); if(!libdirs.contains(f)) libdirs.append(f); } else if(opt.startsWith("-l")) { if (!project->isEmpty("QMAKE_RVCT_LINKSTYLE")) { (*it) = opt.mid(2); } else if (project->isActiveConfig("rvct_linker")) { (*it) = "lib" + opt.mid(2) + ".so"; } else { stub = opt.mid(2); } } else if(Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-F")) { frameworkdirs.append(QMakeLocalFileName(opt.right(opt.length()-2))); } else if(Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-framework")) { if(opt.length() > 11) { opt = opt.mid(11); } else { ++it; opt = (*it); } do_suffix = false; extn = ""; dir = "/System/Library/Frameworks/" + opt + ".framework/"; stub = opt; } } else { extn = dir = ""; stub = opt; int slsh = opt.lastIndexOf(Option::dir_sep); if(slsh != -1) { dir = opt.left(slsh); stub = opt.mid(slsh+1); } QRegExp stub_reg("^.*lib(" + stub + "[^./=]*)\\.(.*)$"); if(stub_reg.exactMatch(stub)) { stub = stub_reg.cap(1); extn = stub_reg.cap(2); } } if(!stub.isEmpty()) { if(do_suffix && !project->isEmpty("QMAKE_" + stub.toUpper() + "_SUFFIX")) stub += project->first("QMAKE_" + stub.toUpper() + "_SUFFIX"); bool found = false; QStringList extens; if(!extn.isNull()) extens << extn; else if (!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) // In Symbian you link to the stub .lib file, but run with the .dll file. extens << "lib"; else extens << project->values("QMAKE_EXTENSION_SHLIB").first() << "a"; for(QStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) { if(dir.isNull()) { for(QList<QMakeLocalFileName>::Iterator dep_it = libdirs.begin(); dep_it != libdirs.end(); ++dep_it) { QString pathToLib = ((*dep_it).local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + "." + (*extit)); if(exists(pathToLib)) { if (!project->isEmpty("QMAKE_RVCT_LINKSTYLE")) (*it) = pathToLib; else (*it) = "-l" + stub; found = true; break; } } } else { if(exists(project->values("QMAKE_PREFIX_SHLIB").first() + stub + "." + (*extit))) { (*it) = project->values("QMAKE_PREFIX_SHLIB").first() + stub + "." + (*extit); found = true; break; } } } if(!found && project->isActiveConfig("compile_libtool")) { for(int dep_i = 0; dep_i < libdirs.size(); ++dep_i) { if(exists(libdirs[dep_i].local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + Option::libtool_ext)) { (*it) = libdirs[dep_i].real() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + Option::libtool_ext; found = true; break; } } } } } } return false; }
void ProjectGenerator::init() { if(init_flag) return; int file_count = 0; init_flag = true; verifyCompilers(); project->read(QMakeProject::ReadFeatures); project->variables()["CONFIG"].clear(); QMap<QString, QStringList> &v = project->variables(); QString templ = Option::user_template.isEmpty() ? QString("app") : Option::user_template; if(!Option::user_template_prefix.isEmpty()) templ.prepend(Option::user_template_prefix); v["TEMPLATE_ASSIGN"] += templ; //figure out target if(Option::output.fileName() == "-") v["TARGET_ASSIGN"] = QStringList("unknown"); else v["TARGET_ASSIGN"] = QStringList(QFileInfo(Option::output).baseName()); //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 < (int)files.count(); i++) { if(files[i] != "." && files[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); for(int i = 0; i < (int)entries.count(); i++) { if(entries[i] != "." && entries[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); QStringList &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(profiles[i] != "." && profiles[i] != ".." && !subdirs.contains(nd, Qt::CaseInsensitive) && !out_file.endsWith(nd)) subdirs.append(nd); } } if(Option::recursive) { QStringList dirs = QDir(newdir).entryList(QDir::Dirs); for(int i = 0; i < (int)dirs.count(); i++) { QString nd = fileFixify(newdir + QDir::separator() + dirs[i]); if(dirs[i] != "." && dirs[i] != ".." && !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); QStringList &subdirs = v["SUBDIRS"]; for(int i = 0; i < (int)files.count(); i++) { QString newdir(dir + files[i]); QFileInfo fi(fileInfo(newdir)); if(fi.fileName() != "." && fi.fileName() != "..") { 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"] = QStringList("subdirs"); return; } //setup deplist QList<QMakeLocalFileName> deplist; { const QStringList &d = v["DEPENDPATH"]; for(int i = 0; i < d.size(); ++i) deplist.append(QMakeLocalFileName(d[i])); } setDependencyPaths(deplist); QStringList &h = v["HEADERS"]; bool no_qt_files = true; QString srcs[] = { "SOURCES", "YACCSOURCES", "LEXSOURCES", "FORMS", QString() }; for(int i = 0; !srcs[i].isNull(); i++) { const QStringList &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[i]); 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)) { QStringList &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 QStringList &quc = project->variables()["QMAKE_EXTRA_COMPILERS"]; for(QStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { QString tmp_out = project->variables()[(*it) + ".output"].first(); if(tmp_out.isEmpty()) continue; QStringList var_out = project->variables()[(*it) + ".variable_out"]; bool defaults = var_out.isEmpty(); for(int i = 0; i < var_out.size(); ++i) { QString v = var_out.at(i); if(v.startsWith("GENERATED_")) { defaults = true; break; } } if(defaults) { var_out << "SOURCES"; var_out << "HEADERS"; var_out << "FORMS"; } const QStringList &tmp = project->variables()[(*it) + ".input"]; for(QStringList::ConstIterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { QStringList &inputs = project->variables()[(*it2)]; for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { QString path = replaceExtraCompilerVariables(tmp_out, (*input), QString()); path = fixPathToQmake(path).section('/', -1); for(int i = 0; i < var_out.size(); ++i) { QString v = var_out.at(i); QStringList &list = project->variables()[v]; for(int src = 0; src < list.size(); ) { if(list[src] == path || list[src].endsWith("/" + path)) list.removeAt(src); else ++src; } } } } } }
void QMakeSourceFileInfo::loadCache(const QString &cf) { if(cf.isEmpty()) return; #ifdef QMAKE_USE_CACHE QMakeLocalFileName cache_file(cf); int fd = open(QMakeLocalFileName(cf).local().toLatin1(), O_RDONLY); if(fd == -1) return; QFileInfo cache_fi = findFileInfo(cache_file); if(!cache_fi.exists() || cache_fi.isDir()) return; QFile file; if(!file.open(QIODevice::ReadOnly, fd)) return; QTextStream stream(&file); if(stream.readLine() == qmake_version()) { //version check stream.skipWhiteSpace(); bool verified = true; { //cache verification QMap<QString, QStringList> verify; int len = stream.readLine().toInt(); for(int i = 0; i < len; ++i) { QString var = stream.readLine(); QString val = stream.readLine(); verify.insert(var, val.split(';', QString::SkipEmptyParts)); } verified = verifyCache(verify); } if(verified) { stream.skipWhiteSpace(); if(!files) files = new SourceFiles; while(!stream.atEnd()) { QString source = stream.readLine(); QString type = stream.readLine(); QString depends = stream.readLine(); QString mocable = stream.readLine(); stream.skipWhiteSpace(); QMakeLocalFileName fn(source); QFileInfo fi = findFileInfo(fn); SourceFile *file = files->lookupFile(fn); if(!file) { file = new SourceFile; file->file = fn; files->addFile(file); file->type = (SourceFileType)type.toInt(); file->exists = fi.exists(); } if(fi.exists() && fi.lastModified() < cache_fi.lastModified()) { if(!file->dep_checked) { //get depends if(!file->deps) file->deps = new SourceDependChildren; file->dep_checked = true; QStringList depend_list = depends.split(";", QString::SkipEmptyParts); for(int depend = 0; depend < depend_list.size(); ++depend) { QMakeLocalFileName dep_fn(depend_list.at(depend)); QFileInfo dep_fi(findFileInfo(dep_fn)); SourceFile *dep = files->lookupFile(dep_fn); if(!dep) { dep = new SourceFile; dep->file = dep_fn; dep->exists = dep_fi.exists(); dep->type = QMakeSourceFileInfo::TYPE_UNKNOWN; files->addFile(dep); } dep->included_count++; file->deps->addChild(dep); } } if(!file->moc_checked) { //get mocs file->moc_checked = true; file->mocable = mocable.toInt(); } } } } } #endif }
bool QMakeSourceFileInfo::findDeps(SourceFile *file) { if(file->dep_checked || file->type == TYPE_UNKNOWN) return true; files_changed = true; file->dep_checked = true; struct stat fst; char *buffer = 0; int buffer_len = 0; { int fd; #if defined(_MSC_VER) && _MSC_VER >= 1400 if (_sopen_s(&fd, fixPathForFile(file->file, true).local().toLatin1().constData(), _O_RDONLY, _SH_DENYNO, _S_IREAD) != 0) fd = -1; #else fd = open(fixPathForFile(file->file, true).local().toLatin1().constData(), O_RDONLY); #endif if(fd == -1 || fstat(fd, &fst) || S_ISDIR(fst.st_mode)) return false; buffer = getBuffer(fst.st_size); for(int have_read = 0; (have_read = QT_READ(fd, buffer + buffer_len, fst.st_size - buffer_len)); buffer_len += have_read); QT_CLOSE(fd); } if(!buffer) return false; if(!file->deps) file->deps = new SourceDependChildren; int line_count = 1; for(int x = 0; x < buffer_len; ++x) { bool try_local = true; char *inc = 0; if(file->type == QMakeSourceFileInfo::TYPE_UI) { // skip whitespaces while(x < buffer_len && (*(buffer+x) == ' ' || *(buffer+x) == '\t')) ++x; if(*(buffer + x) == '<') { ++x; if(buffer_len >= x + 12 && !strncmp(buffer + x, "includehint", 11) && (*(buffer + x + 11) == ' ' || *(buffer + x + 11) == '>')) { for(x += 11; *(buffer + x) != '>'; ++x); int inc_len = 0; for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len); *(buffer + x + inc_len) = '\0'; inc = buffer + x; } else if(buffer_len >= x + 13 && !strncmp(buffer + x, "customwidget", 12) && (*(buffer + x + 12) == ' ' || *(buffer + x + 12) == '>')) { for(x += 13; *(buffer + x) != '>'; ++x); //skip up to > while(x < buffer_len) { for(x++; *(buffer + x) != '<'; ++x); //skip up to < x++; if(buffer_len >= x + 7 && !strncmp(buffer+x, "header", 6) && (*(buffer + x + 6) == ' ' || *(buffer + x + 6) == '>')) { for(x += 7; *(buffer + x) != '>'; ++x); //skip up to > int inc_len = 0; for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len); *(buffer + x + inc_len) = '\0'; inc = buffer + x; break; } else if(buffer_len >= x + 14 && !strncmp(buffer+x, "/customwidget", 13) && (*(buffer + x + 13) == ' ' || *(buffer + x + 13) == '>')) { x += 14; break; } } } else if(buffer_len >= x + 8 && !strncmp(buffer + x, "include", 7) && (*(buffer + x + 7) == ' ' || *(buffer + x + 7) == '>')) { for(x += 8; *(buffer + x) != '>'; ++x) { if(buffer_len >= x + 9 && *(buffer + x) == 'i' && !strncmp(buffer + x, "impldecl", 8)) { for(x += 8; *(buffer + x) != '='; ++x); if(*(buffer + x) != '=') continue; for(++x; *(buffer+x) == '\t' || *(buffer+x) == ' '; ++x); char quote = 0; if(*(buffer+x) == '\'' || *(buffer+x) == '"') { quote = *(buffer + x); ++x; } int val_len; for(val_len = 0; true; ++val_len) { if(quote) { if(*(buffer+x+val_len) == quote) break; } else if(*(buffer + x + val_len) == '>' || *(buffer + x + val_len) == ' ') { break; } } //? char saved = *(buffer + x + val_len); *(buffer + x + val_len) = '\0'; if(!strcmp(buffer+x, "in implementation")) { //### do this } } } int inc_len = 0; for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len); *(buffer + x + inc_len) = '\0'; inc = buffer + x; } } //read past new line now.. for(; x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x); ++line_count; } else if(file->type == QMakeSourceFileInfo::TYPE_QRC) { } else if(file->type == QMakeSourceFileInfo::TYPE_C) { for(int beginning=1; x < buffer_len; ++x) { // whitespace comments and line-endings for(; x < buffer_len; ++x) { if(*(buffer+x) == ' ' || *(buffer+x) == '\t') { // keep going } else if(*(buffer+x) == '/') { ++x; if(buffer_len >= x) { if(*(buffer+x) == '/') { //c++ style comment for(; x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x); beginning = 1; } else if(*(buffer+x) == '*') { //c style comment for(++x; x < buffer_len; ++x) { if(*(buffer+x) == '*') { if(x < buffer_len-1 && *(buffer + (x+1)) == '/') { ++x; break; } } else if(qmake_endOfLine(*(buffer+x))) { ++line_count; } } } } } else if(qmake_endOfLine(*(buffer+x))) { ++line_count; beginning = 1; } else { break; } } if(x >= buffer_len) break; // preprocessor directive if(beginning && *(buffer+x) == '#') break; // quoted strings if(*(buffer+x) == '\'' || *(buffer+x) == '"') { const char term = *(buffer+(x++)); for(; x < buffer_len; ++x) { if(*(buffer+x) == term) { ++x; break; } else if(*(buffer+x) == '\\') { ++x; } else if(qmake_endOfLine(*(buffer+x))) { ++line_count; } } } beginning = 0; } if(x >= buffer_len) break; //got a preprocessor symbol ++x; while(x < buffer_len) { if(*(buffer+x) != ' ' && *(buffer+x) != '\t') break; ++x; } int keyword_len = 0; const char *keyword = buffer+x; while(x+keyword_len < buffer_len) { if(((*(buffer+x+keyword_len) < 'a' || *(buffer+x+keyword_len) > 'z')) && *(buffer+x+keyword_len) != '_') { for(x+=keyword_len; //skip spaces after keyword x < buffer_len && (*(buffer+x) == ' ' || *(buffer+x) == '\t'); x++); break; } else if(qmake_endOfLine(*(buffer+x+keyword_len))) { x += keyword_len-1; keyword_len = 0; break; } keyword_len++; } if(keyword_len == 7 && !strncmp(keyword, "include", keyword_len)) { char term = *(buffer + x); if(term == '<') { try_local = false; term = '>'; } else if(term != '"') { //wtf? continue; } x++; int inc_len; for(inc_len = 0; *(buffer + x + inc_len) != term && !qmake_endOfLine(*(buffer + x + inc_len)); ++inc_len); *(buffer + x + inc_len) = '\0'; inc = buffer + x; x += inc_len; } else if(keyword_len == 13 && !strncmp(keyword, "qmake_warning", keyword_len)) { char term = 0; if(*(buffer + x) == '"') term = '"'; if(*(buffer + x) == '\'') term = '\''; if(term) x++; int msg_len; for(msg_len = 0; (term && *(buffer + x + msg_len) != term) && !qmake_endOfLine(*(buffer + x + msg_len)); ++msg_len); *(buffer + x + msg_len) = '\0'; debug_msg(0, "%s:%d %s -- %s", file->file.local().toLatin1().constData(), line_count, keyword, buffer+x); x += msg_len; } else if(*(buffer+x) == '\'' || *(buffer+x) == '"') { const char term = *(buffer+(x++)); while(x < buffer_len) { if(*(buffer+x) == term) break; if(*(buffer+x) == '\\') { x+=2; } else { if(qmake_endOfLine(*(buffer+x))) ++line_count; ++x; } } } else { --x; } } if(inc) { if(!includes) includes = new SourceFiles; SourceFile *dep = includes->lookupFile(inc); if(!dep) { bool exists = false; QMakeLocalFileName lfn(inc); if(QDir::isRelativePath(lfn.real())) { if(try_local) { QString dir = findFileInfo(file->file).path(); if(QDir::isRelativePath(dir)) dir.prepend(qmake_getpwd() + "/"); if(!dir.endsWith("/")) dir += "/"; QMakeLocalFileName f(dir + lfn.local()); if(findFileInfo(f).exists()) { lfn = fixPathForFile(f); exists = true; } } if(!exists) { //path lookup for(QList<QMakeLocalFileName>::Iterator it = depdirs.begin(); it != depdirs.end(); ++it) { QMakeLocalFileName f((*it).real() + Option::dir_sep + lfn.real()); QFileInfo fi(findFileInfo(f)); if(fi.exists() && !fi.isDir()) { lfn = fixPathForFile(f); exists = true; break; } } } if(!exists) { //heuristic lookup lfn = findFileForDep(QMakeLocalFileName(inc), file->file); if((exists = !lfn.isNull())) lfn = fixPathForFile(lfn); } } else { exists = QFile::exists(lfn.real()); } if(!lfn.isNull()) { dep = files->lookupFile(lfn); if(!dep) { dep = new SourceFile; dep->file = lfn; dep->type = QMakeSourceFileInfo::TYPE_C; files->addFile(dep); includes->addFile(dep, inc, false); } dep->exists = exists; } } if(dep && dep->file != file->file) { dep->included_count++; if(dep->exists) { debug_msg(5, "%s:%d Found dependency to %s", file->file.real().toLatin1().constData(), line_count, dep->file.local().toLatin1().constData()); file->deps->addChild(dep); } } } } if(dependencyMode() == Recursive) { //done last because buffer is shared for(int i = 0; i < file->deps->used_nodes; i++) { if(!file->deps->children[i]->deps) findDeps(file->deps->children[i]); } } return true; }
QMakeLocalFileName QMakeSourceFileInfo::findFileForDep(const QMakeLocalFileName &/*dep*/, const QMakeLocalFileName &/*file*/) { return QMakeLocalFileName(); }
bool QMakeSourceFileInfo::containsSourceFile(const QString &f, SourceFileType type) { if(SourceFile *file = files->lookupFile(QMakeLocalFileName(f))) return (file->type == type || file->type == TYPE_UNKNOWN || type == TYPE_UNKNOWN); return false; }
bool QMakeSourceFileInfo::mocable(const QString &file) { if(SourceFile *node = files->lookupFile(QMakeLocalFileName(file))) return node->mocable; return false; }
void UnixMakefileGenerator::processPrlFiles() { const QString libArg = project->first("QMAKE_L_FLAG").toQString(); QList<QMakeLocalFileName> libdirs, frameworkdirs; int libidx = 0, fwidx = 0; foreach (const ProString &dlib, project->values("QMAKE_DEFAULT_LIBDIRS")) libdirs.append(QMakeLocalFileName(dlib.toQString())); frameworkdirs.append(QMakeLocalFileName("/System/Library/Frameworks")); frameworkdirs.append(QMakeLocalFileName("/Library/Frameworks")); 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.startsWith("-")) { if (opt.startsWith(libArg)) { QMakeLocalFileName l(opt.mid(libArg.length())); if(!libdirs.contains(l)) libdirs.insert(libidx++, l); } else if(opt.startsWith("-l")) { QString lib = opt.right(opt.length() - 2); QString prl_ext = project->first(ProKey("QMAKE_" + lib.toUpper() + "_SUFFIX")).toQString(); for(int dep_i = 0; dep_i < libdirs.size(); ++dep_i) { const QMakeLocalFileName &lfn = libdirs[dep_i]; if(!project->isActiveConfig("compile_libtool")) { //give them the .libs.. QString la = lfn.local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + lib + Option::libtool_ext; if(exists(la) && QFile::exists(lfn.local() + Option::dir_sep + ".libs")) { QString dot_libs = lfn.real() + Option::dir_sep + ".libs"; l.append("-L" + dot_libs); libdirs.insert(libidx++, QMakeLocalFileName(dot_libs)); } } QString prl = lfn.local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + lib + prl_ext; if(processPrlFile(prl)) { if(prl.startsWith(lfn.local())) prl.replace(0, lfn.local().length(), lfn.real()); opt = linkLib(prl, lib); break; } } } else if (target_mode == TARG_MAC_MODE && opt.startsWith("-F")) { QMakeLocalFileName f(opt.right(opt.length()-2)); if(!frameworkdirs.contains(f)) frameworkdirs.insert(fwidx++, f); } else if (target_mode == TARG_MAC_MODE && opt.startsWith("-framework")) { if(opt.length() > 11) opt = opt.mid(11); else opt = l.at(++lit).toQString(); opt = opt.trimmed(); foreach (const QMakeLocalFileName &dir, frameworkdirs) { QString prl = dir.local() + "/" + opt + ".framework/" + opt + Option::prl_ext; if(processPrlFile(prl)) break; } } } else if(!opt.isNull()) { QString lib = opt; processPrlFile(lib); #if 0 if(ret) opt = linkLib(lib, ""); #endif if(!opt.isEmpty()) for (int k = 0; k < l.size(); ++k) l[k] = l.at(k).toQString().replace(lib, opt); } ProStringList &prl_libs = project->values("QMAKE_CURRENT_PRL_LIBS"); if(!prl_libs.isEmpty()) { for(int prl = 0; prl < prl_libs.size(); ++prl) l.insert(lit+prl+1, escapeFilePath(prl_libs.at(prl).toQString())); prl_libs.clear(); } }
bool UnixMakefileGenerator::findLibraries() { ProString libArg = project->first("QMAKE_L_FLAG"); if (libArg == "-L") libArg.clear(); QList<QMakeLocalFileName> libdirs; int libidx = 0; foreach (const ProString &dlib, project->values("QMAKE_DEFAULT_LIBDIRS")) libdirs.append(QMakeLocalFileName(dlib.toQString())); 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 (ProStringList::Iterator it = l.begin(); it != l.end(); ) { QString stub, dir, extn, opt = (*it).trimmed().toQString(); if(opt.startsWith("-")) { if(opt.startsWith("-L")) { QString lib = opt.mid(2); QMakeLocalFileName f(lib); int idx = libdirs.indexOf(f); if (idx >= 0 && idx < libidx) { it = l.erase(it); continue; } libdirs.insert(libidx++, f); if (!libArg.isEmpty()) *it = libArg + lib; } else if(opt.startsWith("-l")) { if (project->isActiveConfig("rvct_linker") || project->isActiveConfig("armcc_linker")) { (*it) = "lib" + opt.mid(2) + ".so"; } else if (project->isActiveConfig("ti_linker")) { (*it) = opt.mid(2); } else { stub = opt.mid(2); } } else if (target_mode == TARG_MAC_MODE && opt.startsWith("-framework")) { if (opt.length() == 10) ++it; // Skip } } else { extn = dir = ""; stub = opt; int slsh = opt.lastIndexOf(Option::dir_sep); if(slsh != -1) { dir = opt.left(slsh); stub = opt.mid(slsh+1); } QRegExp stub_reg("^.*lib(" + stub + "[^./=]*)\\.(.*)$"); if(stub_reg.exactMatch(stub)) { stub = stub_reg.cap(1); extn = stub_reg.cap(2); } } if(!stub.isEmpty()) { stub += project->first(ProKey("QMAKE_" + stub.toUpper() + "_SUFFIX")).toQString(); bool found = false; ProStringList extens; if(!extn.isNull()) extens << extn; else extens << project->values("QMAKE_EXTENSION_SHLIB").first() << "a"; for (ProStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) { if(dir.isNull()) { for(QList<QMakeLocalFileName>::Iterator dep_it = libdirs.begin(); dep_it != libdirs.end(); ++dep_it) { QString pathToLib = ((*dep_it).local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + "." + (*extit)); if(exists(pathToLib)) { (*it) = "-l" + stub; found = true; break; } } } else { QString lib = dir + project->values("QMAKE_PREFIX_SHLIB").first() + stub + "." + (*extit); if (exists(lib)) { (*it) = lib; found = true; break; } } } if(!found && project->isActiveConfig("compile_libtool")) { for(int dep_i = 0; dep_i < libdirs.size(); ++dep_i) { if(exists(libdirs[dep_i].local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + Option::libtool_ext)) { (*it) = libdirs[dep_i].real() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + Option::libtool_ext; found = true; break; } } } } ++it; } } return false; }