package GlobalData.Makefile; import Common.Utils.CommonUtils; import Common_old.Current; import Common.Utils.TextLog; import Common_old.Utils.Utils; import GlobalData.Compiler.Compiler; import GlobalData.Compiler.CompilerType; import GlobalData.Machine.Machine; import GlobalData.Module.Module; import GlobalData.Module.ModuleAnchestor; import ProjectData.Files.DBProjectFile; import ProjectData.LanguageName; import ProjectData.Project.db_project_info; import java.util.LinkedHashMap; import java.util.Vector; import java.util.stream.Collectors; //мейкфайл. цепочка модулей. он сам отвечает за линковку. //И по одному модулю на каждый язык. public class Makefile extends ModuleAnchestor { public Makefile() { } @Override public boolean isVisible() { return Current.HasMachine() && (machine_id == Current.getMachine().id); } public LinkedHashMap getActiveModules() { return CommonUtils.db.getByFKAndGroupBy(this, Module.class, "language", LanguageName.class).values().stream().filter(Module::isSelected).collect(Collectors.toMap(module -> module.language, module -> module, (a, b) -> b, LinkedHashMap::new)); } public LinkedHashMap getModules() { return CommonUtils.db.getByFKAndGroupBy(this, Module.class, "language", LanguageName.class); } public String Generate(db_project_info project, boolean useFilesOrder, LinkedHashMap modules) throws Exception { Compiler linker = getCompiler(); if (linker == null) return ""; LinkedHashMap> programs = project.getPrograms(); Vector titles = new Vector<>(); Vector objects = new Vector<>(); Vector bodies = new Vector<>(); String binary = CommonUtils.DQuotes("0"); // Utils.DQuotes(project.name); for (Module module : modules.values()) { //определить а активен ли модуль. //выбран ли он. есть ли у него компилятор. есть ли для него программы. Compiler module_compiler; if (module.isSelected() && ((module_compiler = module.getCompiler()) != null) && (!programs.get(module.language).isEmpty())) { //--------------------------------------------------------- String LANG_ = module.language.toString().toUpperCase() + "_"; Vector module_objects = new Vector<>(); String module_body = ""; int i = 1; //------------------------------------------------------------------------- Vector programsToAssembly = new Vector<>(); if (module.language.equals(LanguageName.fortran) && useFilesOrder) { //для фортрана берем порядок с парсера. for (String progName : project.files_order) programsToAssembly.add(project.db.files.get(progName)); } else programsToAssembly = programs.get(module.language); //-------------------------------------------------------------------------- for (DBProjectFile program : programsToAssembly) { //-- program.last_assembly_name = module.language.toString() + "_" + i + ".o"; String object = CommonUtils.DQuotes(program.last_assembly_name); module_objects.add(object); module_body += object + ":\n" + "\t" + String.join(" ", Utils.MFVar(LANG_ + "COMMAND"), Utils.MFVar(LANG_ + "FLAGS"), module_compiler.getStyleOptions(program), "-c", program.getQSourceName(), "-o", object + "\n\n" ); ++i; } titles.add(String.join("\n", LANG_ + "COMMAND=" + CommonUtils.DQuotes(module_compiler.call_command) + " " + module.command, LANG_ + "FLAGS=" + module.flags, LANG_ + "OBJECTS=" + String.join(" ", module_objects), "" )); objects.add(Utils.MFVar(LANG_ + "OBJECTS")); bodies.add(module_body); } } return String.join("\n", "LINK_COMMAND=" + CommonUtils.DQuotes(linker.call_command) + " " + command, "LINK_FLAGS=" + flags + "\n", String.join("\n", titles), "all: " + binary, binary + " : " + String.join(" ", objects), "\t" + Utils.MFVar("LINK_COMMAND") + " " + Utils.MFVar("LINK_FLAGS") + " " + String.join(" ", objects) + " -o " + binary, String.join(" ", bodies)); } public String Generate(db_project_info project_info) throws Exception { return Generate(project_info, true, getActiveModules()); } public String GenerateForPrecompilation(db_project_info project, LinkedHashMap modules) { Compiler linker = getCompiler(); if (linker == null) return ""; LinkedHashMap> programs = project.getPrograms(); Vector titles = new Vector<>(); Vector objects = new Vector<>(); Vector bodies = new Vector<>(); for (Module module : modules.values()) { //определить а активен ли модуль. //выбран ли он. есть ли у него компилятор. есть ли для него программы. Compiler module_compiler; if (module.isSelected() && ((module_compiler = module.getCompiler()) != null) && (!programs.get(module.language).isEmpty())) { //--------------------------------------------------------- String LANG_ = module.language.toString().toUpperCase() + "_"; Vector module_objects = new Vector<>(); String module_body = ""; int i = 1; //------------------------------------------------------------------------- Vector programsToAssembly = programs.get(module.language); //-------------------------------------------------------------------------- for (DBProjectFile program : programsToAssembly) { //-- program.last_assembly_name = module.language.toString() + "_" + i + ".o"; String object = CommonUtils.DQuotes(program.last_assembly_name); module_objects.add(object); module_body += object + ":\n" + "\t" + String.join(" ", Utils.MFVar(LANG_ + "COMMAND"), Utils.MFVar(LANG_ + "FLAGS"), module_compiler.getStyleOptions(program), "-c", program.getQSourceName() + "\n\n" // "-o", // object ); ++i; } titles.add(String.join("\n", LANG_ + "COMMAND=" + CommonUtils.DQuotes(module_compiler.call_command) + " " + module.command, LANG_ + "FLAGS=" + module.flags, LANG_ + "OBJECTS=" + String.join(" ", module_objects), "" )); objects.add(Utils.MFVar(LANG_ + "OBJECTS")); bodies.add(module_body); } } return String.join("\n", String.join("\n", titles), "all: " + String.join(" ", objects), String.join(" ", bodies)); } //--------------------------------------- //todo возможно улучшить //https://habr.com/ru/post/211751/ public Machine getMachine() { return CommonUtils.db.getById(Machine.class, machine_id); } public boolean DependsToCompiler(Compiler compiler) { if (compiler_id == compiler.id) return true; else { LinkedHashMap modules = getModules(); for (Module module : modules.values()) if (module.compiler_id == compiler.id) return true; } return false; } public void Validate(TextLog Log) { Compiler linker; if ((linker = getCompiler()) == null) Log.Writeln("Линковщик не выбран"); else { if (linker.type.equals(CompilerType.dvm)) { if (!Current.getProject().languageName.getDVMLink().equals(command)) Log.Writeln("команда линковки " + CommonUtils.Quotes(command) + " не соответствует языку текущего проекта " + Current.getProject().languageName.getDescription() + "\n" + "Используйте команду " + Current.getProject().languageName.getDVMLink()); } } LinkedHashMap modules = getModules(); for (Module module : modules.values()) { boolean isMain = module.language.equals(Current.getProject().languageName); if (module.isSelected()) { if (module.getCompiler() == null) Log.Writeln("Не назначен компилятор для языка " + module.language.getDescription()); if (isMain && Current.getProject().getPrograms().get(module.language).isEmpty()) Log.Writeln("В текущем проекте не найдено ни одной программы на языке " + module.language.getDescription()); } else { if (isMain) Log.Writeln("Языковой модуль, соответствующий языку текущего проекта " + Current.getProject().languageName.getDescription() + " не помечен как активный."); } } } }