Files
VisualSapfor/src/GlobalData/Makefile/Makefile.java

203 lines
11 KiB
Java
Raw Normal View History

2023-09-17 22:13:42 +03:00
package GlobalData.Makefile;
2024-10-07 14:22:52 +03:00
import Common.Utils.CommonUtils;
2024-10-09 22:01:19 +03:00
import _VisualDVM.Current;
2023-09-17 22:13:42 +03:00
import Common.Utils.TextLog;
2024-10-09 22:01:19 +03:00
import _VisualDVM.Utils;
2023-09-17 22:13:42 +03:00
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<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));
2023-09-17 22:13:42 +03:00
}
public LinkedHashMap<LanguageName, Module> getModules() {
return CommonUtils.db.getByFKAndGroupBy(this, Module.class, "language", LanguageName.class);
2023-09-17 22:13:42 +03:00
}
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<>();
2024-10-07 14:22:52 +03:00
String binary = CommonUtils.DQuotes("0"); // Utils.DQuotes(project.name);
2023-09-17 22:13:42 +03:00
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";
2024-10-07 14:22:52 +03:00
String object = CommonUtils.DQuotes(program.last_assembly_name);
2023-09-17 22:13:42 +03:00
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",
2024-10-07 14:22:52 +03:00
LANG_ + "COMMAND=" + CommonUtils.DQuotes(module_compiler.call_command) + " " + module.command,
2023-09-17 22:13:42 +03:00
LANG_ + "FLAGS=" + module.flags,
LANG_ + "OBJECTS=" + String.join(" ", module_objects),
""
));
objects.add(Utils.MFVar(LANG_ + "OBJECTS"));
bodies.add(module_body);
}
}
return String.join("\n",
2024-10-07 14:22:52 +03:00
"LINK_COMMAND=" + CommonUtils.DQuotes(linker.call_command) + " " + command,
2023-09-17 22:13:42 +03:00
"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";
2024-10-07 14:22:52 +03:00
String object = CommonUtils.DQuotes(program.last_assembly_name);
2023-09-17 22:13:42 +03:00
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",
2024-10-07 14:22:52 +03:00
LANG_ + "COMMAND=" + CommonUtils.DQuotes(module_compiler.call_command) + " " + module.command,
2023-09-17 22:13:42 +03:00
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);
2023-09-17 22:13:42 +03:00
}
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("команда линковки " +
2024-10-07 14:22:52 +03:00
CommonUtils.Quotes(command) +
2023-09-17 22:13:42 +03:00
" не соответствует языку текущего проекта "
+ 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() + " не помечен как активный.");
}
}
}
}