major changes underway to rework library handling for different architectures

This commit is contained in:
Ben Fry
2022-01-22 11:43:25 -05:00
parent 5fef895e84
commit f2e584b819
9 changed files with 277 additions and 180 deletions
+58 -35
View File
@@ -26,7 +26,7 @@ package processing.mode.java;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import processing.app.Base;
import processing.app.Platform;
@@ -37,6 +37,7 @@ import processing.app.SketchException;
import processing.app.Util;
import processing.app.contrib.ModeContribution;
import processing.core.PApplet;
import processing.data.StringDict;
import processing.mode.java.runner.Runner;
@@ -54,12 +55,13 @@ public class Commander implements RunnerListener {
static final String outputArg = "--output=";
static final String exportApplicationArg = "--export";
static final String noJavaArg = "--no-java";
static final String platformArg = "--platform=";
static final String bitsArg = "--bits=";
// static final String platformArg = "--platform=";
// static final String bitsArg = "--bits=";
// static final String preferencesArg = "--preferences=";
static final String variantArg = "--variant=";
static final int HELP = -1;
static final int PREPROCESS = 0;
// static final int PREPROCESS = 0;
static final int BUILD = 1;
static final int RUN = 2;
static final int PRESENT = 3;
@@ -80,27 +82,23 @@ public class Commander implements RunnerListener {
boolean outputSet = false; // set an output folder
boolean force = false; // replace that no good output folder
// String preferencesPath = null;
int platform = PApplet.platform; // default to this platform
// int platform = PApplet.platform; // default to this platform
// int platformBits = Base.getNativeBits();
String variant = Platform.getVariant();
int task = HELP;
boolean embedJava = true;
try {
if (Platform.isWindows()) {
// On Windows, it needs to use the default system encoding.
// https://github.com/processing/processing/issues/1633
systemOut = new PrintStream(System.out, true);
systemErr = new PrintStream(System.err, true);
} else {
// On OS X, the output goes as MacRoman or something else useless.
// http://code.google.com/p/processing/issues/detail?id=1418
// (Not sure about Linux, but this has worked since 2.0)
systemOut = new PrintStream(System.out, true, "UTF-8");
systemErr = new PrintStream(System.err, true, "UTF-8");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
System.exit(1);
if (Platform.isWindows()) {
// On Windows, it needs to use the default system encoding.
// https://github.com/processing/processing/issues/1633
systemOut = new PrintStream(System.out, true);
systemErr = new PrintStream(System.err, true);
} else {
// OS X formerly used MacRoman or something else useless.
// (Not sure about Linux, but this has worked since 2.0)
// https://github.com/processing/processing/issues/1456
systemOut = new PrintStream(System.out, true, StandardCharsets.UTF_8);
systemErr = new PrintStream(System.err, true, StandardCharsets.UTF_8);
}
int argOffset = 0;
@@ -135,13 +133,11 @@ public class Commander implements RunnerListener {
} else if (arg.equals(noJavaArg)) {
embedJava = false;
} else if (arg.startsWith(platformArg)) {
String platformStr = arg.substring(platformArg.length());
platform = Platform.getIndex(platformStr);
if (platform == -1) {
complainAndQuit(platformStr + " should instead be " +
"'windows', 'macosx', or 'linux'.", true);
}
} else if (arg.startsWith("--platform")) {
complainAndQuit("Use --variant instead of --platform with Processing 4.", true);
} else if (arg.startsWith(variantArg)) {
variant = arg.substring(variantArg.length());
} else if (arg.startsWith(sketchArg)) {
sketchPath = arg.substring(sketchArg.length());
@@ -258,8 +254,7 @@ public class Commander implements RunnerListener {
JavaBuild build = new JavaBuild(sketch);
build.build(true);
if (build != null) {
String variant = Platform.getVariant();
success = build.exportApplication(outputFolder, platform, variant, embedJava);
success = build.exportApplication(outputFolder, variant, embedJava);
}
}
}
@@ -349,18 +344,46 @@ public class Commander implements RunnerListener {
out.println("--present Preprocess, compile, and run a sketch in presentation mode.");
out.println();
out.println("--export Export an application.");
out.println("--no-java Do not embed Java. Use at your own risk!");
out.println("--platform Specify the platform (export to application only).");
out.println(" Should be one of 'windows', 'macosx', or 'linux'.");
// out.println("--platform Specify the platform (export to application only).");
// out.println(" Should be one of 'windows', 'macosx', or 'linux'.");
out.println("--variant Specify the platform and architecture (Export only).");
out.println("--no-java Do not embed Java.");
out.println();
out.println("Starting with 4.0, the --platform option has been removed");
out.println("because of the variety of platforms and architectures now available.");
out.println("Use the --variant option instead, for instance:");
out.println();
/*
out.println("platform variant");
out.println("--------------------------- -------------");
out.println("macOS (Intel 64-bit) macos-x86_64");
out.println("macOS (Apple Silicon) macos-aarch64");
out.println("Windows (Intel 64-bit) windows-amd64");
out.println("Linux (Intel 64-bit) linux-amd64");
out.println("Linux (Raspberry Pi 32-bit) linux-arm");
out.println("Linux (Raspberry Pi 64-bit) linux-aarch64");
*/
out.println("variant platform");
out.println("------------- ---------------------------");
StringDict variants = Platform.getSupportedVariants();
for (String key : variants.keys()) {
out.print(key);
int spaces = 15 - key.length(); // 13 dashes, two spaces
for (int i = 0; i < spaces; i++) {
System.out.print(" ");
}
System.out.println(variants.get(key));
}
out.println();
out.println("The --build, --run, --present, or --export must be the final parameter");
out.println("passed to Processing. Arguments passed following one of those four will");
out.println("be passed through to the sketch itself, and therefore available to the");
out.println("sketch via the 'args' field. To pass options understood by PApplet.main(),");
out.println("write a custom main() method so that the preprocessor does not add one.");
out.println("https://github.com/processing/processing/wiki/Command-Line");
out.println();
}
+6 -11
View File
@@ -574,7 +574,7 @@ public class JavaBuild {
File folder = null;
for (String platformName : PConstants.platformNames) {
int platform = Platform.getIndex(platformName);
// int platform = Platform.getIndex(platformName);
// Can only embed Java on the native platform
boolean embedJava = (platform == PApplet.platform) &&
@@ -633,20 +633,15 @@ public class JavaBuild {
* Export to application without GUI. Also called by the Commander.
*/
protected boolean exportApplication(File destFolder,
int exportPlatform,
String exportVariant,
boolean embedJava) throws IOException, SketchException {
// TODO this should probably be a dialog box instead of a warning
// on the terminal. And the message should be written better than this.
// http://code.google.com/p/processing/issues/detail?id=884
for (Library library : importedLibraries) {
if (!library.supportsArch(exportPlatform, exportVariant)) {
String pn = PConstants.platformNames[exportPlatform];
if (library.isUnsupported(exportVariant)) {
Messages.showWarning("Quibbles 'n Bits",
"The application." + pn + exportVariant +
" folder will not be created\n" +
"because no " + exportVariant + " version of " +
library.getName() + " is available for " + pn, null);
"The application will not be exported for\n" +
Platform.getSupportedVariants().get(exportVariant) +
" because " + library.getName() + "\n" +
"does not support " + exportVariant + ".", null);
return true; // don't cancel all exports for this, just move along
}
}
@@ -707,9 +707,9 @@ public class JavaEditor extends Editor {
if (Platform.isMacOS()) {
platformName = "macOS";
} else if (Platform.isWindows()) {
platformName = "Windows (" + Platform.getNativeBits() + "-bit)";
platformName = "Windows";
} else if (Platform.isLinux()) {
platformName = "Linux (" + Platform.getNativeBits() + "-bit)";
platformName = "Linux";
}
final boolean embed =
@@ -108,20 +108,11 @@ public class Runner implements MessageConsumer {
}
// Make sure all the imported libraries will actually run with this setup.
int bits = Platform.getNativeBits();
// int bits = Platform.getNativeBits();
String variant = Platform.getVariant();
for (Library library : build.getImportedLibraries()) {
if (!library.supportsArch(PApplet.platform, variant)) {
if (library.isUnsupported(variant)) {
sketchErr.println(library.getName() + " does not run on this architecture: " + variant);
int opposite = (bits == 32) ? 64 : 32;
if (Platform.isMacOS()) {
throw new SketchException("To use " + library.getName() + ", " +
"switch to " + opposite + "-bit mode in Preferences.");
} else {
throw new SketchException(library.getName() + " is only compatible " +
"with the " + opposite + "-bit download of Processing.");
}
}
}
}
@@ -466,7 +457,7 @@ public class Runner implements MessageConsumer {
Point editorLocation = editor.getLocation();
params.append(PApplet.ARGS_EDITOR_LOCATION + "=" +
editorLocation.x + "," + editorLocation.y);
} else {
// } else {
// The sketch's main() will set a location centered on the new
// display. It has to happen in main() because the width/height
// of the sketch are not known here.
@@ -743,7 +734,7 @@ public class Runner implements MessageConsumer {
final PrintStream err) {
if (exceptionClass.equals("java.lang.OutOfMemoryError")) {
if (message.contains("exceeds VM budget")) {
// TODO this is a kludge for Android, since there's no memory preference
// TODO this is a kludge for Android, since there is no memory preference
listener.statusError("OutOfMemoryError: This code attempts to use more memory than available.");
err.println("An OutOfMemoryError means that your code is either using up too much memory");
err.println("because of a bug (e.g. creating an array that's too large, or unintentionally");
@@ -758,13 +749,8 @@ public class Runner implements MessageConsumer {
err.println("you can increase the memory available to your sketch using the Preferences window.");
}
} else if (exceptionClass.equals("java.lang.UnsatisfiedLinkError")) {
listener.statusError("A library used by this sketch is not installed properly.");
if (PApplet.platform == PConstants.LINUX) {
err.println(message);
}
err.println("A library relies on native code that's not available.");
err.println("Or only works properly when the sketch is run as a " +
((Platform.getNativeBits() == 32) ? "64-bit" : "32-bit") + " application.");
err.println("A library used by this sketch relies on native code that is not available.");
err.println(message);
} else if (exceptionClass.equals("java.lang.StackOverflowError")) {
listener.statusError("StackOverflowError: This sketch is attempting too much recursion.");
@@ -791,9 +777,9 @@ public class Runner implements MessageConsumer {
}
// TODO: This may be called more than one time per error in the VM,
// presumably because exceptions might be wrapped inside others,
// and this will fire for both.
// TODO This may be called more than one time per error in the VM,
// presumably because exceptions may be wrapped inside others,
// and this will fire for both.
protected void reportException(String message, ObjectReference or, ThreadReference thread) {
listener.statusError(findException(message, or, thread));
}