Files
VisualSapfor/src/_VisualDVM/GlobalData/Makefile/Makefile.java
2024-10-09 22:21:57 +03:00

203 lines
11 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package _VisualDVM.GlobalData.Makefile;
import Common.Utils.CommonUtils;
import _VisualDVM.Current;
import Common.Utils.TextLog;
import _VisualDVM.Utils;
import _VisualDVM.GlobalData.Compiler.Compiler;
import _VisualDVM.GlobalData.Compiler.CompilerType;
import _VisualDVM.GlobalData.Machine.Machine;
import _VisualDVM.GlobalData.Module.Module;
import _VisualDVM.GlobalData.Module.ModuleAnchestor;
import _VisualDVM.ProjectData.Files.DBProjectFile;
import _VisualDVM.ProjectData.LanguageName;
import _VisualDVM.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<LanguageName, Module> 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<LanguageName, Module> getModules() {
return CommonUtils.db.getByFKAndGroupBy(this, Module.class, "language", LanguageName.class);
}
public String Generate(db_project_info project, boolean useFilesOrder, LinkedHashMap<LanguageName, Module> modules) throws Exception {
Compiler linker = getCompiler();
if (linker == null) return "";
LinkedHashMap<LanguageName, Vector<DBProjectFile>> programs = project.getPrograms();
Vector<String> titles = new Vector<>();
Vector<String> objects = new Vector<>();
Vector<String> 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<String> module_objects = new Vector<>();
String module_body = "";
int i = 1;
//-------------------------------------------------------------------------
Vector<DBProjectFile> 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<LanguageName, Module> modules) {
Compiler linker = getCompiler();
if (linker == null) return "";
LinkedHashMap<LanguageName, Vector<DBProjectFile>> programs = project.getPrograms();
Vector<String> titles = new Vector<>();
Vector<String> objects = new Vector<>();
Vector<String> 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<String> module_objects = new Vector<>();
String module_body = "";
int i = 1;
//-------------------------------------------------------------------------
Vector<DBProjectFile> 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<LanguageName, Module> 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<LanguageName, Module> 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() + " не помечен как активный.");
}
}
}
}