mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
C: allow to run external tool after successful incremental build
This commit is contained in:
parent
054db3e8d1
commit
7a99258cab
|
@ -15,11 +15,14 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.tooling.c.incremental;
|
package org.teavm.tooling.c.incremental;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -27,6 +30,7 @@ import java.util.Collections;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import org.teavm.backend.c.CTarget;
|
import org.teavm.backend.c.CTarget;
|
||||||
import org.teavm.backend.c.generate.SimpleStringPool;
|
import org.teavm.backend.c.generate.SimpleStringPool;
|
||||||
|
@ -61,6 +65,8 @@ public class IncrementalCBuilder {
|
||||||
private String[] classPath;
|
private String[] classPath;
|
||||||
private int minHeapSize = 32;
|
private int minHeapSize = 32;
|
||||||
private String targetPath;
|
private String targetPath;
|
||||||
|
private String externalTool;
|
||||||
|
private String externalToolWorkingDir;
|
||||||
|
|
||||||
private IncrementalDirectoryBuildTarget buildTarget;
|
private IncrementalDirectoryBuildTarget buildTarget;
|
||||||
private FileSystemWatcher watcher;
|
private FileSystemWatcher watcher;
|
||||||
|
@ -87,6 +93,8 @@ public class IncrementalCBuilder {
|
||||||
private boolean waiting;
|
private boolean waiting;
|
||||||
private Thread buildThread;
|
private Thread buildThread;
|
||||||
|
|
||||||
|
private boolean needsExternalTool;
|
||||||
|
|
||||||
public void setMainClass(String mainClass) {
|
public void setMainClass(String mainClass) {
|
||||||
this.mainClass = mainClass;
|
this.mainClass = mainClass;
|
||||||
}
|
}
|
||||||
|
@ -107,6 +115,14 @@ public class IncrementalCBuilder {
|
||||||
this.log = log;
|
this.log = log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setExternalTool(String externalTool) {
|
||||||
|
this.externalTool = externalTool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExternalToolWorkingDir(String externalToolWorkingDir) {
|
||||||
|
this.externalToolWorkingDir = externalToolWorkingDir;
|
||||||
|
}
|
||||||
|
|
||||||
public void addProgressHandler(ProgressHandler handler) {
|
public void addProgressHandler(ProgressHandler handler) {
|
||||||
synchronized (progressHandlers) {
|
synchronized (progressHandlers) {
|
||||||
progressHandlers.add(handler);
|
progressHandlers.add(handler);
|
||||||
|
@ -316,9 +332,12 @@ public class IncrementalCBuilder {
|
||||||
vm.build(buildTarget, "");
|
vm.build(buildTarget, "");
|
||||||
|
|
||||||
postBuild(vm, startTime);
|
postBuild(vm, startTime);
|
||||||
|
|
||||||
|
runExternalTool();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postBuild(TeaVM vm, long startTime) {
|
private void postBuild(TeaVM vm, long startTime) {
|
||||||
|
needsExternalTool = false;
|
||||||
if (!vm.wasCancelled()) {
|
if (!vm.wasCancelled()) {
|
||||||
log.info("Recompiled stale methods: " + programCache.getPendingItemsCount());
|
log.info("Recompiled stale methods: " + programCache.getPendingItemsCount());
|
||||||
fireBuildComplete(vm);
|
fireBuildComplete(vm);
|
||||||
|
@ -329,6 +348,7 @@ public class IncrementalCBuilder {
|
||||||
programCache.commit();
|
programCache.commit();
|
||||||
astCache.commit();
|
astCache.commit();
|
||||||
reportCompilationComplete(true);
|
reportCompilationComplete(true);
|
||||||
|
needsExternalTool = true;
|
||||||
} else {
|
} else {
|
||||||
log.info("Build complete with errors");
|
log.info("Build complete with errors");
|
||||||
reportCompilationComplete(false);
|
reportCompilationComplete(false);
|
||||||
|
@ -363,6 +383,46 @@ public class IncrementalCBuilder {
|
||||||
log.info("Compilation took " + (System.currentTimeMillis() - startTime) + " ms");
|
log.info("Compilation took " + (System.currentTimeMillis() - startTime) + " ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void runExternalTool() {
|
||||||
|
if (externalTool == null || !needsExternalTool) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
log.info("Running external tool");
|
||||||
|
ProcessBuilder pb = new ProcessBuilder(externalTool);
|
||||||
|
if (externalToolWorkingDir != null) {
|
||||||
|
pb.directory(new File(externalToolWorkingDir));
|
||||||
|
}
|
||||||
|
Process process = pb.start();
|
||||||
|
BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(process.getInputStream(),
|
||||||
|
StandardCharsets.UTF_8));
|
||||||
|
BufferedReader stderrReader = new BufferedReader(new InputStreamReader(process.getErrorStream(),
|
||||||
|
StandardCharsets.UTF_8));
|
||||||
|
daemon("external tool stdout watcher", new ExternalOutputWatcher(stdoutReader,
|
||||||
|
s -> log.info("[external tool] " + s)));
|
||||||
|
daemon("external tool stderr watcher", new ExternalOutputWatcher(stderrReader,
|
||||||
|
s -> log.error("[external tool] " + s)));
|
||||||
|
|
||||||
|
int code = process.waitFor();
|
||||||
|
if (code != 0) {
|
||||||
|
log.error("External tool returned non-zero code: " + code);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Could not start external tool", e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.info("Interrupted while running external tool");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Thread daemon(String name, Runnable runnable) {
|
||||||
|
Thread thread = new Thread(runnable);
|
||||||
|
thread.setDaemon(true);
|
||||||
|
thread.setName(name);
|
||||||
|
thread.start();
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
private ClassReaderSource packClasses(ClassReaderSource source, Collection<? extends String> classNames) {
|
private ClassReaderSource packClasses(ClassReaderSource source, Collection<? extends String> classNames) {
|
||||||
MemoryCachedClassReaderSource packedSource = createCachedSource();
|
MemoryCachedClassReaderSource packedSource = createCachedSource();
|
||||||
packedSource.setProvider(source::get);
|
packedSource.setProvider(source::get);
|
||||||
|
@ -507,4 +567,29 @@ public class IncrementalCBuilder {
|
||||||
return TeaVMProgressFeedback.CONTINUE;
|
return TeaVMProgressFeedback.CONTINUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ExternalOutputWatcher implements Runnable {
|
||||||
|
private BufferedReader reader;
|
||||||
|
private Consumer<String> consumer;
|
||||||
|
|
||||||
|
ExternalOutputWatcher(BufferedReader reader, Consumer<String> consumer) {
|
||||||
|
this.reader = reader;
|
||||||
|
this.consumer = consumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
String line = reader.readLine();
|
||||||
|
if (line == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
consumer.accept(line);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error reading build daemon output", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,18 @@ public class TeaVMCBuilderRunner {
|
||||||
.hasArg()
|
.hasArg()
|
||||||
.withDescription("Minimum heap size in bytes")
|
.withDescription("Minimum heap size in bytes")
|
||||||
.create());
|
.create());
|
||||||
|
options.addOption(OptionBuilder
|
||||||
|
.withLongOpt("external-tool")
|
||||||
|
.withArgName("path")
|
||||||
|
.hasArg()
|
||||||
|
.withDescription("Process to run after successful build")
|
||||||
|
.create());
|
||||||
|
options.addOption(OptionBuilder
|
||||||
|
.withLongOpt("external-tool-workdir")
|
||||||
|
.withArgName("path")
|
||||||
|
.hasArg()
|
||||||
|
.withDescription("Working directory of process")
|
||||||
|
.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
private TeaVMCBuilderRunner(CommandLine commandLine) {
|
private TeaVMCBuilderRunner(CommandLine commandLine) {
|
||||||
|
@ -88,6 +100,7 @@ public class TeaVMCBuilderRunner {
|
||||||
parseClassPathOptions();
|
parseClassPathOptions();
|
||||||
parseOutputOptions();
|
parseOutputOptions();
|
||||||
parseHeap();
|
parseHeap();
|
||||||
|
parseExternalTool();
|
||||||
|
|
||||||
builder.setLog(new ConsoleTeaVMToolLog(commandLine.hasOption('v')));
|
builder.setLog(new ConsoleTeaVMToolLog(commandLine.hasOption('v')));
|
||||||
|
|
||||||
|
@ -100,6 +113,22 @@ public class TeaVMCBuilderRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void parseExternalTool() {
|
||||||
|
boolean hasExternalTool = false;
|
||||||
|
if (commandLine.hasOption("external-tool")) {
|
||||||
|
builder.setExternalTool(commandLine.getOptionValue("external-tool"));
|
||||||
|
hasExternalTool = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commandLine.hasOption("external-tool-workdir")) {
|
||||||
|
if (!hasExternalTool) {
|
||||||
|
System.err.println("Redundant 'external-tool-workdir' option: no external tool specified");
|
||||||
|
} else {
|
||||||
|
builder.setExternalToolWorkingDir(commandLine.getOptionValue("external-tool-workdir"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void parseOutputOptions() {
|
private void parseOutputOptions() {
|
||||||
if (commandLine.hasOption("d")) {
|
if (commandLine.hasOption("d")) {
|
||||||
builder.setTargetPath(commandLine.getOptionValue("d"));
|
builder.setTargetPath(commandLine.getOptionValue("d"));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user