use of org.lflang.util.LFCommand in project lingua-franca by lf-lang.
the class CCompiler method runCCompiler.
/**
* Run the C compiler by directly invoking a C compiler (gcc by default).
*
* @param file The source file to compile without the .c extension.
* @param noBinary If true, the compiler will create a .o output instead of a binary.
* If false, the compile command will produce a binary.
* @param generator An instance of GenratorBase, only used to report error line numbers
* in the Eclipse IDE.
*
* @return true if compilation succeeds, false otherwise.
*/
public boolean runCCompiler(String file, boolean noBinary, GeneratorBase generator, LFGeneratorContext context) throws IOException {
if (noBinary && context.getMode() == LFGeneratorContext.Mode.STANDALONE) {
errorReporter.reportError("Did not output executable; no main reactor found.");
}
LFCommand compile = compileCCommand(file, noBinary);
if (compile == null) {
return false;
}
int returnCode = compile.run(context.getCancelIndicator());
if (returnCode != 0 && context.getMode() == LFGeneratorContext.Mode.STANDALONE) {
errorReporter.reportError(targetConfig.compiler + " returns error code " + returnCode);
}
// But we still want to mark the IDE.
if (compile.getErrors().toString().length() > 0 && context.getMode() != LFGeneratorContext.Mode.STANDALONE) {
generator.reportCommandErrors(compile.getErrors().toString());
}
if (returnCode == 0 && compile.getErrors().toString().length() == 0) {
System.out.println("SUCCESS: Compiling generated code for " + fileConfig.name + " finished with no errors.");
}
return (returnCode == 0);
}
use of org.lflang.util.LFCommand in project lingua-franca by lf-lang.
the class Validator method getValidationStrategies.
/**
* Return the validation strategies and validation
* commands corresponding to each generated file.
* @return the validation strategies and validation
* commands corresponding to each generated file
*/
private List<Pair<ValidationStrategy, LFCommand>> getValidationStrategies() {
final List<Pair<ValidationStrategy, LFCommand>> commands = new ArrayList<>();
long mostRecentDateModified = codeMaps.keySet().stream().map(it -> it.toFile().lastModified()).reduce(0L, Math::max);
for (Path generatedFile : codeMaps.keySet()) {
if (generatedFile.toFile().lastModified() > mostRecentDateModified - FILE_AGE_THRESHOLD_MILLIS) {
final Pair<ValidationStrategy, LFCommand> p = getValidationStrategy(generatedFile);
if (p.first == null || p.second == null)
continue;
commands.add(p);
if (p.first.isFullBatch())
break;
}
}
return commands;
}
use of org.lflang.util.LFCommand in project lingua-franca by lf-lang.
the class LFGeneratorContext method finish.
/**
* Conclude this build and record the result if necessary.
* @param status The status of the result.
* @param execName The name of the executable produced by this code
* generation process, or {@code null} if no executable was produced.
* @param binPath The directory containing the executable (if applicable).
* @param fileConfig The {@code FileConfig} instance used by the build.
* @param codeMaps The generated files and their corresponding code maps.
* @param interpreter The interpreter needed to run the executable, if
* applicable.
*/
default void finish(GeneratorResult.Status status, String execName, Path binPath, FileConfig fileConfig, Map<Path, CodeMap> codeMaps, String interpreter) {
final boolean isWindows = GeneratorUtils.isHostWindows();
if (execName != null && binPath != null) {
Path executable = binPath.resolve(execName + (isWindows && interpreter == null ? ".exe" : ""));
String relativeExecutable = fileConfig.srcPkgPath.relativize(executable).toString();
LFCommand command = interpreter != null ? LFCommand.get(interpreter, List.of(relativeExecutable), true, fileConfig.srcPkgPath) : LFCommand.get(isWindows ? executable.toString() : relativeExecutable, List.of(), true, fileConfig.srcPkgPath);
finish(new GeneratorResult(status, executable, command, codeMaps));
} else {
finish(new GeneratorResult(status, null, null, codeMaps));
}
}
use of org.lflang.util.LFCommand in project lingua-franca by lf-lang.
the class LFLanguageServerExtension method buildAndRun.
/**
* Completely build the specified LF program and provide information that is sufficient to
* run it.
* @param uri The URI of the LF program to be built.
* @return An array consisting of the directory in which the execute command should be
* executed, the program of the execute command, and the arguments of the execute command.
*/
@JsonNotification("generator/buildAndRun")
public CompletableFuture<String[]> buildAndRun(String uri) {
return new CompletableFuture<String[]>().completeAsync(() -> {
LFCommand result = buildWithProgress(client, uri, true).getCommand();
if (result == null)
return null;
ArrayList<String> ret = new ArrayList<>();
ret.add(result.directory().toString());
ret.addAll(result.command());
return ret.toArray(new String[0]);
});
}
use of org.lflang.util.LFCommand in project lingua-franca by lf-lang.
the class CCmakeCompiler method buildCmakeCommand.
/**
* Return a command to build the specified C file using CMake.
* This produces a C-specific build command.
*
* @note It appears that configuration and build cannot happen in one command.
* Therefore, this is separated into a compile and a build command.
*
* @param fileToCompile The C filename without the .c extension.
* @param noBinary If true, the compiler will create a .o output instead of a binary.
* If false, the compile command will produce a binary.
*/
public LFCommand buildCmakeCommand(String fileToCompile, boolean noBinary) {
// Set the build directory to be "build"
Path buildPath = fileConfig.getSrcGenPath().resolve("build");
String cores = String.valueOf(Runtime.getRuntime().availableProcessors());
LFCommand command = commandFactory.createCommand("cmake", List.of("--build", ".", "--target", "install", "--parallel", cores, "--config", ((targetConfig.cmakeBuildType != null) ? targetConfig.cmakeBuildType.toString() : "Release")), buildPath);
if (command == null) {
errorReporter.reportError("The C/CCpp target requires CMAKE >= 3.5 to compile the generated code. " + "Auto-compiling can be disabled using the \"no-compile: true\" target property.");
}
return command;
}
Aggregations