Move compile script generation to ftl

parent a66fab83
...@@ -15,7 +15,7 @@ public class TemplateHelper { ...@@ -15,7 +15,7 @@ public class TemplateHelper {
} }
String tmpStr = ""; String tmpStr = "";
String resourceFileName = "/de/monticore/lang/monticar/generator/middleware/" + fileName; String resourceFileName = "/de/monticore/lang/monticar/generator/middleware/templates/" + fileName;
try { try {
tmpStr = IOUtils.toString(TemplateHelper.class.getResourceAsStream(resourceFileName)); tmpStr = IOUtils.toString(TemplateHelper.class.getResourceAsStream(resourceFileName));
...@@ -48,21 +48,4 @@ public class TemplateHelper { ...@@ -48,21 +48,4 @@ public class TemplateHelper {
return getTemplate("coordinatorCmakeListsTemplate.ftl"); return getTemplate("coordinatorCmakeListsTemplate.ftl");
} }
public static String getCompilationBashTemplate(){
return getTemplate("compile.sh.template");
}
public static String getCompilationMingwTemplate(){
return getTemplate("compileMingw.bat.template");
}
public static String getCompilationMsbuildTemplate(){
return getTemplate("compileMsbuild.bat.template");
}
public static String getSubstTemplate(){
return getTemplate("subst.bat.template");
}
} }
package de.monticore.lang.monticar.generator.middleware.templates;
import de.monticore.lang.monticar.generator.middleware.templates.compile.BashCompilationGenerator;
import de.monticore.lang.monticar.generator.middleware.templates.compile.MingwCompilationGenerator;
import de.monticore.lang.monticar.generator.middleware.templates.compile.MsbuildCompilationGenerator;
import de.monticore.lang.monticar.generator.middleware.templates.compile.WindowsCompilationGenerator;
import de.se_rwth.commons.logging.Log;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
public class MiddlewareTemplates {
private static final Template COMPILE_BATCH;
private static final Template COMPILE_BASH;
private static final Template COMPILE_SUBST;
static {
Configuration conf = new Configuration(Configuration.VERSION_2_3_23);
conf.setDefaultEncoding("UTF-8");
conf.setTemplateExceptionHandler(TemplateExceptionHandler.DEBUG_HANDLER);
conf.setLogTemplateExceptions(false);
conf.setClassForTemplateLoading(MiddlewareTemplates.class, "");
try {
COMPILE_BATCH = conf.getTemplate("compile.bat.ftl");
COMPILE_BASH = conf.getTemplate("compile.sh.ftl");
COMPILE_SUBST = conf.getTemplate("subst.bat.ftl");
} catch (IOException e) {
String msg = "could not load templates";
Log.error(msg, e);
throw new RuntimeException(msg, e);
}
}
public static String generateCompileMsbuild(MsbuildCompilationGenerator model) {
HashMap<String, Object> data = new HashMap<>();
data.put("model", model);
return generate(COMPILE_BATCH, data);
}
public static String generateCompileMingw(MingwCompilationGenerator model) {
HashMap<String, Object> data = new HashMap<>();
data.put("model", model);
return generate(COMPILE_BATCH, data);
}
public static String generateCompileBash(BashCompilationGenerator model) {
HashMap<String, Object> data = new HashMap<>();
data.put("model", model);
return generate(COMPILE_BASH, data);
}
public static String generateCompileSubst(WindowsCompilationGenerator model) {
HashMap<String, Object> data = new HashMap<>();
data.put("model", model);
return generate(COMPILE_SUBST, data);
}
private static String generate(Template template, Object dataForTemplate) {
Log.errorIfNull(template);
Log.errorIfNull(dataForTemplate);
StringWriter sw = new StringWriter();
try {
template.process(dataForTemplate, sw);
} catch (TemplateException | IOException e) {
Log.error("template generation failed, template: " + template.getName(), e);
}
return sw.toString();
}
}
package de.monticore.lang.monticar.generator.middleware.compile; package de.monticore.lang.monticar.generator.middleware.templates.compile;
import de.monticore.lang.monticar.generator.middleware.helpers.TemplateHelper; import de.monticore.lang.monticar.generator.middleware.templates.MiddlewareTemplates;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
public class BashCompilationGenerator extends CompilationGenerator { public class BashCompilationGenerator extends CompilationGenerator {
private String PATH_TEMPLATE = "if [ -n \"$<new_exe>_HOME\" ]\n" +
"then\n"+
"\texport PATH=\"$<new_exe>_HOME:$PATH\"\n" +
"fi";
private String CHECK_EXE_TEMPLATE = "if [[ `command -v <exe>` ]]\n" +
"then\n" +
"\techo \"Found <exe>\"\n" +
"else\n" +
"\techo \"Can not find <exe> in PATH! Aborting.\"\n" +
"<additional_error>" +
"\texit 1\n" +
"fi";
private String SOURCE_ENV_VARS_TEMPLATE = "source <env_file>";
@Override
public String getContent() {
return MiddlewareTemplates.generateCompileBash(this);
}
@Override @Override
public boolean supportsRos() { public boolean supportsRos() {
...@@ -36,44 +25,24 @@ public class BashCompilationGenerator extends CompilationGenerator { ...@@ -36,44 +25,24 @@ public class BashCompilationGenerator extends CompilationGenerator {
} }
@Override @Override
protected String getPathTemplate() { public List<String> getAdditionalPathDirs() {
return PATH_TEMPLATE;
}
@Override
protected String getCheckExeTemplate() {
return CHECK_EXE_TEMPLATE;
}
@Override
protected String getSourceEnvVarsTemplate() {
return SOURCE_ENV_VARS_TEMPLATE;
}
@Override
protected String getScriptTemplate() {
return TemplateHelper.getCompilationBashTemplate().replace("\r\n", "\n");
}
@Override
protected List<String> getAdditionalPathDirs() {
setAdditionalErrorMsg("roscore", defaultErrorMsg("ROS")); setAdditionalErrorMsg("roscore", defaultErrorMsg("ROS"));
setAdditionalErrorMsg("ros2", defaultErrorMsg("ROS2")); setAdditionalErrorMsg("ros2", defaultErrorMsg("ROS2"));
return Arrays.asList("cmake","make"); return Arrays.asList("cmake","make");
} }
@Override @Override
protected String getFileName() { public String getFileName() {
return "compile.sh"; return "compile.sh";
} }
@Override @Override
protected String getNewlineDelimiter() { public String getNewlineDelimiter() {
return "\n"; return "\n";
} }
@Override @Override
protected List<String> getPostSourceExecutables() { public List<String> getPostSourceExecutables() {
ArrayList<String> res = new ArrayList<>(); ArrayList<String> res = new ArrayList<>();
if(useRos()){ if(useRos()){
res.add("roscore"); res.add("roscore");
...@@ -85,7 +54,7 @@ public class BashCompilationGenerator extends CompilationGenerator { ...@@ -85,7 +54,7 @@ public class BashCompilationGenerator extends CompilationGenerator {
} }
@Override @Override
protected List<String> getEnvironmentFiles() { public List<String> getEnvironmentFiles() {
List<String> res = new ArrayList<>(); List<String> res = new ArrayList<>();
if(useRos()){ if(useRos()){
res.add("\"$ROS_HOME\"/setup.bash"); res.add("\"$ROS_HOME\"/setup.bash");
...@@ -97,8 +66,12 @@ public class BashCompilationGenerator extends CompilationGenerator { ...@@ -97,8 +66,12 @@ public class BashCompilationGenerator extends CompilationGenerator {
} }
@Override @Override
protected List<String> getExecutables() { public List<String> getExecutables() {
return Arrays.asList("cmake","make"); List<String> res = new ArrayList<>(Arrays.asList("cmake", "make"));
if(useRos2() && useStructMsgs()){
res.add("colcon");
}
return res;
} }
} }
package de.monticore.lang.monticar.generator.middleware.compile; package de.monticore.lang.monticar.generator.middleware.templates.compile;
import de.monticore.lang.monticar.generator.FileContent; import de.monticore.lang.monticar.generator.FileContent;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
public abstract class CompilationGenerator { public abstract class CompilationGenerator {
private boolean useRos = false; private boolean useRos = false;
private boolean useRos2 = false; private boolean useRos2 = false;
private boolean useStructMsgs = false;
private Map<String, String> additionalErrorMsg = new HashMap<>(); private Map<String, String> additionalErrorMsg = new HashMap<>();
public abstract boolean supportsRos(); public abstract boolean supportsRos();
...@@ -18,28 +18,19 @@ public abstract class CompilationGenerator { ...@@ -18,28 +18,19 @@ public abstract class CompilationGenerator {
return (supportsRos() || !useRos()) && (supportsRos2() || !useRos2()); return (supportsRos() || !useRos()) && (supportsRos2() || !useRos2());
} }
protected void setAdditionalErrorMsg(String executable, String errorMsg) { public void setAdditionalErrorMsg(String executable, String errorMsg) {
additionalErrorMsg.put(executable, errorMsg); additionalErrorMsg.put(executable, errorMsg);
} }
protected String getAdditionalErrorMsg(String executable) { public String getAdditionalErrorMsg(String executable) {
String s = additionalErrorMsg.getOrDefault(executable, defaultErrorMsg(executable)); return additionalErrorMsg.getOrDefault(executable, defaultErrorMsg(executable));
return "\techo \"" + s + "\"" + getNewlineDelimiter();
} }
protected abstract String getPathTemplate(); public abstract List<String> getAdditionalPathDirs();
protected abstract String getCheckExeTemplate(); public abstract String getFileName();
protected abstract String getSourceEnvVarsTemplate(); public abstract String getNewlineDelimiter();
protected abstract String getScriptTemplate();
protected abstract List<String> getAdditionalPathDirs();
protected abstract String getFileName();
protected abstract String getNewlineDelimiter();
public boolean useRos() { public boolean useRos() {
return useRos; return useRos;
...@@ -57,57 +48,30 @@ public abstract class CompilationGenerator { ...@@ -57,57 +48,30 @@ public abstract class CompilationGenerator {
this.useRos2 = useRos2; this.useRos2 = useRos2;
} }
protected String fillPathTemplate(String newExe) { public boolean useStructMsgs() {
return getPathTemplate().replace("<new_exe>", newExe); return useStructMsgs;
}
protected String fillCheckExeTemplate(String exe) {
return getCheckExeTemplate()
.replace("<exe>", exe)
.replace("<additional_error>", getAdditionalErrorMsg(exe));
}
protected String fillSourceEnvVarsTemplate(String envFile) {
return getSourceEnvVarsTemplate().replace("<env_file>", envFile);
} }
protected String fillScriptTemplate(String additional_executables, String executable_checks, String additional_env, String post_executable_checks) { public void setUseStructMsgs(boolean useStructMsgs) {
return getScriptTemplate() this.useStructMsgs = useStructMsgs;
.replace("<additional_executables>", additional_executables)
.replace("<executable_checks>", executable_checks)
.replace("<additional_env>", additional_env)
.replace("<post_executable_checks>", post_executable_checks);
} }
public List<FileContent> getCompilationScripts() { public List<FileContent> getCompilationScripts() {
FileContent res = new FileContent(); List<FileContent> res = new ArrayList<>();
String additional_executables = getAdditionalPathDirs().stream() res.add(new FileContent(getContent(), getFileName()));
.map(this::fillPathTemplate) if(useRos2() && useStructMsgs()) {
.collect(Collectors.joining(getNewlineDelimiter())); res.add(new FileContent("", "src/comps/COLCON_IGNORE"));
}
String executable_checks = getExecutables().stream() return res;
.map(this::fillCheckExeTemplate)
.collect(Collectors.joining(getNewlineDelimiter()));
String additional_env = getEnvironmentFiles().stream()
.map(this::fillSourceEnvVarsTemplate)
.collect(Collectors.joining(getNewlineDelimiter()));
String post_executable_checks = getPostSourceExecutables().stream()
.map(this::fillCheckExeTemplate)
.collect(Collectors.joining(getNewlineDelimiter()));
res.setFileName(getFileName());
res.setFileContent(fillScriptTemplate(additional_executables, executable_checks, additional_env, post_executable_checks));
return Arrays.asList(res);
} }
protected abstract List<String> getPostSourceExecutables(); public abstract String getContent();
public abstract List<String> getPostSourceExecutables();
protected abstract List<String> getEnvironmentFiles(); public abstract List<String> getEnvironmentFiles();
protected abstract List<String> getExecutables(); public abstract List<String> getExecutables();
public static List<CompilationGenerator> getInstanceOfAllGenerators() { public static List<CompilationGenerator> getInstanceOfAllGenerators() {
List<CompilationGenerator> res = new ArrayList<>(); List<CompilationGenerator> res = new ArrayList<>();
...@@ -117,7 +81,7 @@ public abstract class CompilationGenerator { ...@@ -117,7 +81,7 @@ public abstract class CompilationGenerator {
return res; return res;
} }
protected String defaultErrorMsg(String executable) { public String defaultErrorMsg(String executable) {
return "Try setting the environment variable " + executable + "_HOME to the base of your installation or adding it to your PATH!"; return "Try setting the environment variable " + executable + "_HOME to the base of your installation or adding it to your PATH!";
} }
} }
package de.monticore.lang.monticar.generator.middleware.compile; package de.monticore.lang.monticar.generator.middleware.templates.compile;
import de.monticore.lang.monticar.generator.middleware.helpers.TemplateHelper; import de.monticore.lang.monticar.generator.middleware.templates.MiddlewareTemplates;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
...@@ -9,37 +9,42 @@ import java.util.List; ...@@ -9,37 +9,42 @@ import java.util.List;
public class MingwCompilationGenerator extends WindowsCompilationGenerator { public class MingwCompilationGenerator extends WindowsCompilationGenerator {
@Override @Override
public boolean supportsRos2() { public String getContent() {
return false; return MiddlewareTemplates.generateCompileMingw(this);
} }
@Override @Override
protected String getScriptTemplate() { public WinGenKind getKind() {
return TemplateHelper.getCompilationMingwTemplate(); return WinGenKind.MINGW;
}
@Override
public boolean supportsRos2() {
return false;
} }
@Override @Override
protected List<String> getAdditionalPathDirs() { public List<String> getAdditionalPathDirs() {
return Arrays.asList("cmake","make","g++"); return Arrays.asList("cmake","make","g++");
} }
@Override @Override
protected String getFileName() { public String getFileName() {
return "compileMingw.bat"; return "compileMingw.bat";
} }
@Override @Override
protected List<String> getPostSourceExecutables() { public List<String> getPostSourceExecutables() {
return new ArrayList<>(); return new ArrayList<>();
} }
@Override @Override
protected List<String> getEnvironmentFiles() { public List<String> getEnvironmentFiles() {
return new ArrayList<>(); return new ArrayList<>();
} }
@Override @Override
protected List<String> getExecutables() { public List<String> getExecutables() {
return Arrays.asList("cmake","make","g++"); return Arrays.asList("cmake","make","g++");
} }
} }
package de.monticore.lang.monticar.generator.middleware.compile; package de.monticore.lang.monticar.generator.middleware.templates.compile;
import de.monticore.lang.monticar.generator.middleware.helpers.TemplateHelper; import de.monticore.lang.monticar.generator.middleware.templates.MiddlewareTemplates;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
public class MsbuildCompilationGenerator extends WindowsCompilationGenerator { public class MsbuildCompilationGenerator extends WindowsCompilationGenerator {
@Override @Override
public boolean supportsRos2() { public String getContent() {
return true; return MiddlewareTemplates.generateCompileMsbuild(this);
} }
@Override @Override
protected String getScriptTemplate() { public boolean supportsRos2() {
return TemplateHelper.getCompilationMsbuildTemplate(); return true;
} }
@Override @Override
protected List<String> getAdditionalPathDirs() { public List<String> getAdditionalPathDirs() {
setAdditionalErrorMsg("vcvars64.bat", defaultErrorMsg("msbuild")); setAdditionalErrorMsg("vcvars64.bat", defaultErrorMsg("msbuild"));
setAdditionalErrorMsg("ros2", defaultErrorMsg("ROS2")); setAdditionalErrorMsg("ros2", defaultErrorMsg("ROS2"));
return Arrays.asList("cmake","msbuild"); return Arrays.asList("cmake","msbuild");
...@@ -26,12 +27,12 @@ public class MsbuildCompilationGenerator extends WindowsCompilationGenerator { ...@@ -26,12 +27,12 @@ public class MsbuildCompilationGenerator extends WindowsCompilationGenerator {
@Override @Override
protected String getFileName() { public String getFileName() {
return "compileMsbuild.bat"; return "compileMsbuild.bat";
} }
@Override @Override
protected List<String> getPostSourceExecutables() { public List<String> getPostSourceExecutables() {
List<String> res = new ArrayList<>(); List<String> res = new ArrayList<>();
res.add("msbuild"); res.add("msbuild");
if(useRos2()){ if(useRos2()){
...@@ -41,7 +42,7 @@ public class MsbuildCompilationGenerator extends WindowsCompilationGenerator { ...@@ -41,7 +42,7 @@ public class MsbuildCompilationGenerator extends WindowsCompilationGenerator {
} }
@Override @Override
protected List<String> getEnvironmentFiles() { public List<String> getEnvironmentFiles() {
List<String> res = new ArrayList<>(); List<String> res = new ArrayList<>();
res.add("vcvars64.bat"); res.add("vcvars64.bat");
if(useRos2()){ if(useRos2()){
...@@ -51,7 +52,16 @@ public class MsbuildCompilationGenerator extends WindowsCompilationGenerator { ...@@ -51,7 +52,16 @@ public class MsbuildCompilationGenerator extends WindowsCompilationGenerator {
} }
@Override @Override
protected List<String> getExecutables() { public List<String> getExecutables() {
return Arrays.asList("cmake","vcvars64.bat"); List<String> res = new ArrayList<>(Arrays.asList("cmake","vcvars64.bat"));
if(useRos2() && useStructMsgs()){
res.add("colcon");
}
return res;
}
@Override
public WinGenKind getKind() {
return WinGenKind.MSBUILD;
} }
} }
package de.monticore.lang.monticar.generator.middleware.compile; package de.monticore.lang.monticar.generator.middleware.templates.compile;
import de.monticore.lang.monticar.generator.FileContent; import de.monticore.lang.monticar.generator.FileContent;
import de.monticore.lang.monticar.generator.middleware.helpers.TemplateHelper; import de.monticore.lang.monticar.generator.middleware.templates.MiddlewareTemplates;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public abstract class WindowsCompilationGenerator extends CompilationGenerator { public abstract class WindowsCompilationGenerator extends CompilationGenerator {
private String PATH_TEMPLATE = "IF NOT [%<new_exe>_HOME%] == [] (\n" +
"\tset PATH=\"%<new_exe>_HOME%;%PATH%\"\n" +
")";
private String CHECK_EXE_TEMPLATE = "where <exe>\n" +
"IF NOT %ERRORLEVEL% EQU 0 (\n" +
"\techo \"Can not find <exe> in PATH! Aborting.\"\n" +
"<additional_error>" +
"\texit /B 1\n" +
")";
private String SOURCE_ENV_VARS_TEMPLATE = "call <env_file>";
@Override
protected String getPathTemplate() {
return PATH_TEMPLATE;
}
@Override @Override
protected String getCheckExeTemplate() { public String getNewlineDelimiter() {
return CHECK_EXE_TEMPLATE;
}
@Override