203 lines
11 KiB
Java
203 lines
11 KiB
Java
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() + " не помечен как активный.");
|
||
}
|
||
}
|
||
}
|
||
}
|