📄 makefile.cpp
字号:
file = fileFixify(file, qmake_getpwd(), Option::output_dir); if (file.at(0) == '\"' && file.at(file.length() - 1) == '\"') file = file.mid(1, file.length() - 2); if(exists(file)) { ++val_it; continue; } bool found = false; if(QDir::isRelativePath(val)) { if(vpath.isEmpty()) { if(!vpath_var.isEmpty()) vpath = v[vpath_var]; vpath += v["VPATH"] + v["QMAKE_ABSOLUTE_SOURCE_PATH"] + v["DEPENDPATH"]; if(Option::output_dir != qmake_getpwd()) vpath += Option::output_dir; } for(QStringList::Iterator vpath_it = vpath.begin(); vpath_it != vpath.end(); ++vpath_it) { QString real_dir = Option::fixPathToLocalOS((*vpath_it)); if(exists(real_dir + QDir::separator() + val)) { QString dir = (*vpath_it); if(dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; val = dir + val; if(!(flags & VPATH_NoFixify)) val = fileFixify(val); found = true; debug_msg(1, "Found file through vpath %s -> %s", file.toLatin1().constData(), val.toLatin1().constData()); break; } } } if(!found) { QString dir, regex = val, real_dir; if(regex.lastIndexOf(Option::dir_sep) != -1) { dir = regex.left(regex.lastIndexOf(Option::dir_sep) + 1); real_dir = dir; if(!(flags & VPATH_NoFixify)) real_dir = fileFixify(real_dir, qmake_getpwd(), Option::output_dir); regex = regex.right(regex.length() - dir.length()); } if(real_dir.isEmpty() || exists(real_dir)) { QStringList files = QDir(real_dir).entryList(QStringList(regex)); if(files.isEmpty()) { debug_msg(1, "%s:%d Failure to find %s in vpath (%s)", __FILE__, __LINE__, val.toLatin1().constData(), vpath.join("::").toLatin1().constData()); if(flags & VPATH_RemoveMissingFiles) remove_file = true; else if(flags & VPATH_WarnMissingFiles) warn_msg(WarnLogic, "Failure to find: %s", val.toLatin1().constData()); } else { l.removeAt(val_it); QString a; for(int i = (int)files.count()-1; i >= 0; i--) { if(files[i] == "." || files[i] == "..") continue; a = dir + files[i]; if(!(flags & VPATH_NoFixify)) a = fileFixify(a); l.insert(val_it, a); } } } else { debug_msg(1, "%s:%d Cannot match %s%c%s, as %s does not exist.", __FILE__, __LINE__, real_dir.toLatin1().constData(), QDir::separator().toLatin1(), regex.toLatin1().constData(), real_dir.toLatin1().constData()); if(flags & VPATH_RemoveMissingFiles) remove_file = true; else if(flags & VPATH_WarnMissingFiles) warn_msg(WarnLogic, "Failure to find: %s", val.toLatin1().constData()); } } } if(remove_file) l.removeAt(val_it); else ++val_it; } return l;}voidMakefileGenerator::initCompiler(const MakefileGenerator::Compiler &comp){ QMap<QString, QStringList> &v = project->variables(); QStringList &l = v[comp.variable_in]; // find all the relevant file inputs if(!init_compiler_already.contains(comp.variable_in)) { init_compiler_already.insert(comp.variable_in, true); if(!noIO()) l = findFilesInVPATH(l, (comp.flags & Compiler::CompilerRemoveNoExist) ? VPATH_RemoveMissingFiles : VPATH_WarnMissingFiles, "VPATH_" + comp.variable_in); }}voidMakefileGenerator::init(){ initOutPaths(); if(init_already) return; verifyCompilers(); init_already = true; QMap<QString, QStringList> &v = project->variables(); QStringList &quc = v["QMAKE_EXTRA_COMPILERS"]; //make sure the COMPILERS are in the correct input/output chain order for(int comp_out = 0, jump_count = 0; comp_out < quc.size(); ++comp_out) { continue_compiler_chain: if(jump_count > quc.size()) //just to avoid an infinite loop here break; if(project->variables().contains(quc.at(comp_out) + ".variable_out")) { const QStringList &outputs = project->variables().value(quc.at(comp_out) + ".variable_out"); for(int out = 0; out < outputs.size(); ++out) { for(int comp_in = 0; comp_in < quc.size(); ++comp_in) { if(comp_in == comp_out) continue; if(project->variables().contains(quc.at(comp_in) + ".input")) { const QStringList &inputs = project->variables().value(quc.at(comp_in) + ".input"); for(int in = 0; in < inputs.size(); ++in) { if(inputs.at(in) == outputs.at(out) && comp_out > comp_in) { ++jump_count; //move comp_out to comp_in and continue the compiler chain quc.move(comp_out, comp_in); comp_out = comp_in; goto continue_compiler_chain; } } } } } } } if(!project->isEmpty("QMAKE_SUBSTITUTES")) { const QStringList &subs = v["QMAKE_SUBSTITUTES"]; for(int i = 0; i < subs.size(); ++i) { if(!subs.at(i).endsWith(".in")) { warn_msg(WarnLogic, "Substitute '%s' does not end with '.in'", subs.at(i).toLatin1().constData()); continue; } QFile in(fileFixify(subs.at(i))), out(fileInfo(subs.at(i)).fileName()); if(out.fileName().endsWith(".in")) out.setFileName(out.fileName().left(out.fileName().length()-3)); if(in.open(QFile::ReadOnly)) { QString contents; QStack<int> state; enum { IN_CONDITION, MET_CONDITION, PENDING_CONDITION }; for(int count = 1; !in.atEnd(); ++count) { QString line = QString::fromUtf8(in.readLine()); if(line.startsWith("!!IF ")) { if(state.isEmpty() || state.top() == IN_CONDITION) { QString test = line.mid(5, line.length()-(5+1)); if(project->test(test)) state.push(IN_CONDITION); else state.push(PENDING_CONDITION); } else { state.push(MET_CONDITION); } } else if(line.startsWith("!!ELIF ")) { if(state.isEmpty()) { warn_msg(WarnLogic, "(%s:%d): Unexpected else condition", in.fileName().toLatin1().constData(), count); } else if(state.top() == PENDING_CONDITION) { QString test = line.mid(7, line.length()-(7+1)); if(project->test(test)) { state.pop(); state.push(IN_CONDITION); } } else if(state.top() == IN_CONDITION) { state.pop(); state.push(MET_CONDITION); } } else if(line.startsWith("!!ELSE")) { if(state.isEmpty()) { warn_msg(WarnLogic, "(%s:%d): Unexpected else condition", in.fileName().toLatin1().constData(), count); } else if(state.top() == PENDING_CONDITION) { state.pop(); state.push(IN_CONDITION); } else if(state.top() == IN_CONDITION) { state.pop(); state.push(MET_CONDITION); } } else if(line.startsWith("!!ENDIF")) { if(state.isEmpty()) warn_msg(WarnLogic, "(%s:%d): Unexpected endif", in.fileName().toLatin1().constData(), count); else state.pop(); } else if(state.isEmpty() || state.top() == IN_CONDITION) { contents += project->expand(line).join(QString(Option::field_sep)); } } if(out.exists() && out.open(QFile::ReadOnly)) { QString old = QString::fromUtf8(out.readAll()); if(contents == old) { v["QMAKE_INTERNAL_INCLUDED_FILES"].append(subs.at(i)); continue; } out.close(); if(!out.remove()) { warn_msg(WarnLogic, "Cannot clear substitute '%s'", out.fileName().toLatin1().constData()); continue; } } if(out.open(QFile::WriteOnly)) { v["QMAKE_INTERNAL_INCLUDED_FILES"].append(subs.at(i)); out.write(contents.toUtf8()); } else { warn_msg(WarnLogic, "Cannot open substitute for output '%s'", out.fileName().toLatin1().constData()); } } else { warn_msg(WarnLogic, "Cannot open substitute for input '%s'", in.fileName().toLatin1().constData()); } } } int x; //build up a list of compilers QList<Compiler> compilers; { const char *builtins[] = { "OBJECTS", "SOURCES", "PRECOMPILED_HEADER", 0 }; for(x = 0; builtins[x]; ++x) { Compiler compiler; compiler.variable_in = builtins[x]; compiler.flags = Compiler::CompilerBuiltin; compiler.type = QMakeSourceFileInfo::TYPE_C; if(!strcmp(builtins[x], "OBJECTS")) compiler.flags |= Compiler::CompilerNoCheckDeps; compilers.append(compiler); } for(QStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { const QStringList &inputs = v[(*it) + ".input"]; for(x = 0; x < inputs.size(); ++x) { Compiler compiler; compiler.variable_in = inputs.at(x); compiler.flags = Compiler::CompilerNoFlags; if(v[(*it) + ".CONFIG"].indexOf("ignore_no_exist") != -1) compiler.flags |= Compiler::CompilerRemoveNoExist; if(v[(*it) + ".CONFIG"].indexOf("no_dependencies") != -1) compiler.flags |= Compiler::CompilerNoCheckDeps; QString dep_type; if(!project->isEmpty((*it) + ".dependency_type")) dep_type = project->first((*it) + ".dependency_type"); if (dep_type.isEmpty()) compiler.type = QMakeSourceFileInfo::TYPE_UNKNOWN; else if(dep_type == "TYPE_UI") compiler.type = QMakeSourceFileInfo::TYPE_UI; else compiler.type = QMakeSourceFileInfo::TYPE_C; compilers.append(compiler); } } } { //do the path fixifying QStringList paths; for(x = 0; x < compilers.count(); ++x) { if(!paths.contains(compilers.at(x).variable_in)) paths << compilers.at(x).variable_in; } paths << "INCLUDEPATH" << "QMAKE_INTERNAL_INCLUDED_FILES" << "PRECOMPILED_HEADER"; for(int y = 0; y < paths.count(); y++) { QStringList &l = v[paths[y]]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { if((*it).isEmpty()) continue; if(exists((*it))) (*it) = fileFixify((*it)); } } } if(noIO() || !doDepends()) QMakeSourceFileInfo::setDependencyMode(QMakeSourceFileInfo::NonRecursive); for(x = 0; x < compilers.count(); ++x) initCompiler(compilers.at(x)); //merge actual compiler outputs into their variable_out. This is done last so that //files are already properly fixified. for(QStringList::Iterator it = quc.begin(); it != quc.end(); ++it) { QString tmp_out = project->values((*it) + ".output").first(); if(tmp_out.isEmpty()) continue; if(project->values((*it) + ".CONFIG").indexOf("combine") != -1) { QStringList &compilerInputs = project->values((*it) + ".input"); // Don't generate compiler output if it doesn't have input. if (compilerInputs.isEmpty() || project->values(compilerInputs.first()).isEmpty()) continue; if(tmp_out.indexOf("$") == -1) { if(!verifyExtraCompiler((*it), QString())) //verify continue; QString out = fileFixify(tmp_out, Option::output_dir, Option::output_dir); bool pre_dep = (project->values((*it) + ".CONFIG").indexOf("target_predeps") != -1); if(project->variables().contains((*it) + ".variable_out")) { const QStringList &var_out = project->variables().value((*it) + ".variable_out"); for(int i = 0; i < var_out.size(); ++i) { QString v = var_out.at(i); if(v == QLatin1String("SOURCES")) v = "GENERATED_SOURCES"; else if(v == QLatin1String("OBJECTS")) pre_dep = false; QStringList &list = project->values(v); if(!list.contains(out)) list.append(out); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -