From 42fcb39f0fdcb04367d0dbfc6a640384e735d6d2 Mon Sep 17 00:00:00 2001 From: Eugene Ryzhikov Date: Fri, 29 Nov 2019 16:54:55 -0500 Subject: [PATCH 01/11] Split project configuration into public and private --- .../substrate/ProjectConfiguration.java | 246 ++++++++++++++++++ .../substrate/SubstrateDispatcher.java | 44 ++-- ....java => PrivateProjectConfiguration.java} | 98 ++----- .../target/AbstractTargetConfiguration.java | 28 +- .../target/AndroidTargetConfiguration.java | 5 +- .../target/DarwinTargetConfiguration.java | 6 +- .../target/IosTargetConfiguration.java | 7 +- .../target/LinuxTargetConfiguration.java | 6 +- .../substrate/target/TargetConfiguration.java | 3 - .../target/WindowsTargetConfiguration.java | 4 +- .../com/gluonhq/substrate/util/FileDeps.java | 6 +- .../substrate/util/ios/CodeSigning.java | 7 +- .../gluonhq/substrate/util/ios/InfoPlist.java | 6 +- .../com/gluonhq/substrate/SubstrateTest.java | 20 +- 14 files changed, 345 insertions(+), 141 deletions(-) create mode 100644 src/main/java/com/gluonhq/substrate/ProjectConfiguration.java rename src/main/java/com/gluonhq/substrate/model/{ProjectConfiguration.java => PrivateProjectConfiguration.java} (85%) diff --git a/src/main/java/com/gluonhq/substrate/ProjectConfiguration.java b/src/main/java/com/gluonhq/substrate/ProjectConfiguration.java new file mode 100644 index 000000000..9019439da --- /dev/null +++ b/src/main/java/com/gluonhq/substrate/ProjectConfiguration.java @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2019, Gluon + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL GLUON BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.gluonhq.substrate; + +import com.gluonhq.substrate.model.IosSigningConfiguration; +import com.gluonhq.substrate.model.Triplet; + +import java.nio.file.Path; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +/** + * This class contains all public configuration info about the current project (not about the current OS/Arch/vendor etc) + * Instances of this class give hints to where real values should be contained from. + */ +public class ProjectConfiguration { + + private String graalPath; + + private String javafxStaticSdkVersion; + private String javaStaticSdkVersion; + + private boolean usePrismSW = false; + private boolean verbose = false; + + private Triplet targetTriplet; + private Triplet hostTriplet = Triplet.fromCurrentOS(); + + private List bundlesList = Collections.emptyList(); + private List resourcesList = Collections.emptyList(); + private List reflectionList = Collections.emptyList(); + private List jniList = Collections.emptyList(); + + private String appName; + private String mainClassName; + + private IosSigningConfiguration iosSigningConfiguration = new IosSigningConfiguration(); + + public ProjectConfiguration( String mainClassName ) { + this.mainClassName = Objects.requireNonNull(mainClassName, "Main class name is required") + .contains("/") ? + mainClassName.substring( mainClassName.indexOf("/") + 1) : mainClassName; + + } + + public Path getGraalPath() { + return Path.of( Objects.requireNonNull(this.graalPath, "GraalVM Path is not defined")); + } + + public void setGraalPath(String path) { + this.graalPath = path; + } + + + /** + * Sets the Java static SDK version + * @param javaStaticSdkVersion the Java static SDK version + */ + public void setJavaStaticSdkVersion(String javaStaticSdkVersion) { + this.javaStaticSdkVersion = javaStaticSdkVersion; + } + + public String getJavaStaticSdkVersion() { + return Objects.requireNonNull( this.javaStaticSdkVersion, "Java Static SDK version is required" ); + } + + /** + * Sets the JavaFX static SDK version + * @param javafxStaticSdkVersion the JavaFX static SDK version + */ + public void setJavafxStaticSdkVersion(String javafxStaticSdkVersion) { + this.javafxStaticSdkVersion = javafxStaticSdkVersion; + } + + public String getJavafxStaticSdkVersion() { + return Objects.requireNonNull( this.javafxStaticSdkVersion, "JavaFX Static SDK version is required" ); + } + + + public boolean isUsePrismSW() { + return usePrismSW; + } + + public void setUsePrismSW(boolean usePrismSW) { + this.usePrismSW = usePrismSW; + } + + public void setVerbose(boolean verbose) { + this.verbose = verbose; + } + + public boolean isVerbose() { + return verbose; + } + + public Triplet getTargetTriplet() { + return Objects.requireNonNull( targetTriplet, "Target triplet is required") ; + } + + /** + * Sets the target triplet + * @param targetTriplet the target triplet + */ + public void setTarget(Triplet targetTriplet) { + this.targetTriplet = targetTriplet; + } + + /** + * Retrieve the host triplet for this configuration. + * The host triplet is always the triplet for the current runtime, e.g. it should not be set (apart for testing) + * @return the Triplet for the current executing host + * @throws IllegalArgumentException in case the current operating system is not supported + */ + public Triplet getHostTriplet() throws IllegalArgumentException { + return hostTriplet; + } + + public void setHostTriplet(Triplet hostTriplet) { + this.hostTriplet = hostTriplet == null? Triplet.fromCurrentOS(): hostTriplet; + } + + public List getBundlesList() { + return bundlesList; + } + + /** + * Sets additional bundles + * @param bundlesList a list of classes that will be added to the default bundlesList list + */ + public void setBundlesList(List bundlesList) { + this.bundlesList = bundlesList == null? Collections.emptyList(): bundlesList; + } + + /** + * Set additional resources to be included + * @param resourcesList a list of resource patterns that will be included + */ + public void setResourcesList(List resourcesList) { + this.resourcesList = resourcesList == null? Collections.emptyList(): resourcesList; + } + + public List getResourcesList() { + return resourcesList; + } + + public List getReflectionList() { + return reflectionList; + } + + /** + * Sets additional lists + * @param reflectionList a list of classes that will be added to the default reflection list + */ + public void setReflectionList(List reflectionList) { + this.reflectionList = reflectionList == null? Collections.emptyList(): reflectionList; + } + + public List getJniList() { + return jniList; + } + + /** + * Sets additional lists + * @param jniList a list of classes that will be added to the default jni list + */ + public void setJniList(List jniList) { + this.jniList = jniList == null? Collections.emptyList(): jniList; + } + + public String getAppName() { + return Objects.requireNonNull(appName, "App name is required"); + } + + /** + * Sets the app name + * @param appName the name of the application (e.g. demo) + */ + public void setAppName(String appName) { + this.appName = appName; + } + + public String getMainClassName() { + // never null as it is required in constructor and there is no setter + return mainClassName; + } + + public IosSigningConfiguration getIosSigningConfiguration() { + return iosSigningConfiguration; + } + + /** + * Sets some iOS specific parameters + * @param iosSigningConfiguration iOS configuration + */ + public void setIosSigningConfiguration(IosSigningConfiguration iosSigningConfiguration) { + this.iosSigningConfiguration = iosSigningConfiguration == null? + new IosSigningConfiguration(): iosSigningConfiguration; + } + + @Override + public String toString() { + return "ProjectConfiguration{" + + "graalPath='" + graalPath + '\'' + + ", javaStaticSdkVersion='" + javaStaticSdkVersion + '\'' + + ", javafxStaticSdkVersion='" + javafxStaticSdkVersion + '\'' + + ", usePrismSW=" + usePrismSW + + ", verbose=" + verbose + + ", targetTriplet=" + targetTriplet + + ", hostTriplet=" + hostTriplet + + ", bundlesList=" + bundlesList + + ", resourcesList=" + resourcesList + + ", reflectionList=" + reflectionList + + ", jniList=" + jniList + + ", appName='" + appName + '\'' + + ", iosConfiguration='" + iosSigningConfiguration + '\'' + + ", mainClassName='" + mainClassName + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java index 50c4e1754..23a770812 100644 --- a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java +++ b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java @@ -28,7 +28,7 @@ package com.gluonhq.substrate; import com.gluonhq.substrate.model.ProcessPaths; -import com.gluonhq.substrate.model.ProjectConfiguration; +import com.gluonhq.substrate.model.PrivateProjectConfiguration; import com.gluonhq.substrate.model.Triplet; import com.gluonhq.substrate.target.*; import com.gluonhq.substrate.util.Logger; @@ -37,9 +37,7 @@ import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Objects; -import java.util.Optional; +import java.util.*; import java.util.stream.Stream; public class SubstrateDispatcher { @@ -67,25 +65,21 @@ public static void main(String[] args) throws Exception { Triplet targetTriplet = targetProfile != null? new Triplet(Constants.Profile.valueOf(targetProfile.toUpperCase())) :Triplet.fromCurrentOS(); - ProjectConfiguration config = new ProjectConfiguration(); - config.setGraalPath(graalVM); - config.setMainClassName(mainClass); - config.setAppName(appName); - config.setJavafxStaticSdkVersion(Constants.DEFAULT_JAVAFX_STATIC_SDK_VERSION); - config.setTarget(targetTriplet); + ProjectConfiguration publicConfig = new ProjectConfiguration(mainClass); + publicConfig.setGraalPath(graalVM); + publicConfig.setAppName(appName); + publicConfig.setJavafxStaticSdkVersion(Constants.DEFAULT_JAVAFX_STATIC_SDK_VERSION); + publicConfig.setTarget(targetTriplet); + + PrivateProjectConfiguration config = new PrivateProjectConfiguration(publicConfig); + config.setUsePrismSW(usePrismSW); config.getIosSigningConfiguration().setSkipSigning(skipSigning); - Optional.ofNullable(staticLibs).ifPresent(config::setJavaStaticLibs); - Optional.ofNullable(staticJavaFXSDK).ifPresent(config::setJavaFXStaticSDK); - if (reflectionList != null && !reflectionList.trim().isEmpty()) { - config.setReflectionList(Arrays.asList(reflectionList.split(","))); - } - if (jniList != null && !jniList.trim().isEmpty()) { - config.setJniList(Arrays.asList(jniList.split(","))); - } - if (bundlesList != null && !bundlesList.trim().isEmpty()) { - config.setBundlesList(Arrays.asList(bundlesList.split(","))); - } + config.setJavaStaticLibs(staticLibs); + config.setJavaFXStaticSDK(staticJavaFXSDK); + config.setReflectionList(splitString(reflectionList)); + config.setJniList(splitString(jniList)); + config.setBundlesList(splitString(bundlesList)); Path buildRoot = Paths.get(System.getProperty("user.dir"), "build", "autoclient"); @@ -137,6 +131,10 @@ public static void main(String[] args) throws Exception { } } + private static List splitString( String s ) { + return s == null || s.trim().isEmpty()? Collections.emptyList() : Arrays.asList(s.split(",")); + } + private static String requireArg(String argName, String errorMessage ) { String arg = System.getProperty(argName); if (arg == null || arg.trim().isEmpty()) { @@ -150,7 +148,7 @@ private static void printUsage() { System.err.println("Usage:\n java -Dimagecp=... -Dgraalvm=... -Dmainclass=... com.gluonhq.substrate.SubstrateDispatcher"); } - private final ProjectConfiguration config; + private final PrivateProjectConfiguration config; private final ProcessPaths paths; private final TargetConfiguration targetConfiguration; @@ -160,7 +158,7 @@ private static void printUsage() { * @param buildRoot the root, relative to which the compilation step can create object files and temporary files * @param config the ProjectConfiguration, including the target triplet */ - public SubstrateDispatcher(Path buildRoot, ProjectConfiguration config) throws IOException { + public SubstrateDispatcher(Path buildRoot, PrivateProjectConfiguration config) throws IOException { this.config = Objects.requireNonNull(config); this.paths = new ProcessPaths(Objects.requireNonNull(buildRoot), config.getTargetTriplet().getArchOs()); this.targetConfiguration = Objects.requireNonNull(getTargetConfiguration(config.getTargetTriplet()), diff --git a/src/main/java/com/gluonhq/substrate/model/ProjectConfiguration.java b/src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java similarity index 85% rename from src/main/java/com/gluonhq/substrate/model/ProjectConfiguration.java rename to src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java index 25224f23f..96cc676f4 100644 --- a/src/main/java/com/gluonhq/substrate/model/ProjectConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java @@ -28,6 +28,7 @@ package com.gluonhq.substrate.model; import com.gluonhq.substrate.Constants; +import com.gluonhq.substrate.ProjectConfiguration; import java.io.BufferedReader; import java.io.IOException; @@ -39,6 +40,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Optional; /** * This class contains all configuration info about the current project (not about the current OS/Arch/vendor etc) @@ -50,9 +52,8 @@ * If this method has not been called, getJavaStaticLibsPath() will return the default location, taking into account * the value of javaStaticSdkVersion. If that value is not set, the default value is used. */ -public class ProjectConfiguration { +public class PrivateProjectConfiguration { - private String graalPath; private String javaStaticSdkVersion = Constants.DEFAULT_JAVA_STATIC_SDK_VERSION; private String javaStaticLibs; private String javaFXStaticSDK; @@ -83,14 +84,18 @@ public class ProjectConfiguration { private IosSigningConfiguration iosSigningConfiguration = new IosSigningConfiguration(); - public ProjectConfiguration() {} + private ProjectConfiguration publicConfig; - public String getGraalPath() { - return this.graalPath; + /** + * Private projects configuration, which includes everythign, including public settings + * @param config public project configuration + */ + public PrivateProjectConfiguration( ProjectConfiguration config ) { + this.publicConfig = Objects.requireNonNull(config); } - public void setGraalPath(String path) { - this.graalPath = path; + public Path getGraalPath() { + return this.publicConfig.getGraalPath(); } /** @@ -100,20 +105,7 @@ public void setGraalPath(String path) { * @return the specified JavaStaticSDK version, or the default */ public String getJavaStaticSdkVersion() { - return javaStaticSdkVersion; - } - - /** - * Sets the Java static SDK version - * This is only relevant when no specific custom location - * for the Java static libs is provided via - * setJavaStaticLibs - * If this method is not called, calls to - * getJavaStaticSdkVersion will return a default value. - * @param javaStaticSdkVersion the Java static SDK version - */ - public void setJavaStaticSdkVersion(String javaStaticSdkVersion) { - this.javaStaticSdkVersion = javaStaticSdkVersion; + return publicConfig.getJavaStaticSdkVersion(); } /** @@ -208,15 +200,7 @@ public Path getJavafxStaticLibsPath() { } public String getJavafxStaticSdkVersion() { - return javafxStaticSdkVersion; - } - - /** - * Sets the JavaFX static SDK version - * @param javafxStaticSdkVersion the JavaFX static SDK version - */ - public void setJavafxStaticSdkVersion(String javafxStaticSdkVersion) { - this.javafxStaticSdkVersion = javafxStaticSdkVersion; + return publicConfig.getJavafxStaticSdkVersion(); } public String getLlcPath() { @@ -276,16 +260,9 @@ public void setEnableCheckHash(boolean enableCheckHash) { } public Triplet getTargetTriplet() { - return targetTriplet; + return publicConfig.getTargetTriplet(); } - /** - * Sets the target triplet - * @param targetTriplet the target triplet - */ - public void setTarget(Triplet targetTriplet) { - this.targetTriplet = targetTriplet; - } /** * Retrieve the host triplet for this configuration. @@ -294,15 +271,9 @@ public void setTarget(Triplet targetTriplet) { * @throws IllegalArgumentException in case the current operating system is not supported */ public Triplet getHostTriplet() throws IllegalArgumentException { - if (hostTriplet == null) { - hostTriplet = Triplet.fromCurrentOS(); - } - return hostTriplet; + return publicConfig.getHostTriplet(); } - public void setHostTriplet(Triplet hostTriplet) { - this.hostTriplet = hostTriplet; - } public String getBackend() { return backend; @@ -401,28 +372,12 @@ public void setRuntimeArgsList(List runtimeArgsList) { } public String getAppName() { - return appName; + return publicConfig.getAppName(); } - /** - * Sets the app name - * @param appName the name of the application (e.g. demo) - */ - public void setAppName(String appName) { - this.appName = appName; - } public String getMainClassName() { - return mainClassName; - } - - /** - * Sets the FQN of the mainclass (e.g. com.gluonhq.demo.Application) - * @param mainClassName the FQN of the mainclass - */ - public void setMainClassName(String mainClassName) { - this.mainClassName = Objects.requireNonNull(mainClassName, "Main class name can't be null").contains("/") ? - mainClassName.substring(mainClassName.indexOf("/") + 1) : mainClassName; + return publicConfig.getMainClassName(); } public IosSigningConfiguration getIosSigningConfiguration() { @@ -444,16 +399,15 @@ public void setIosSigningConfiguration(IosSigningConfiguration iosSigningConfigu * @throws IOException when the path to bin/native-image doesn't exist */ public void canRunNativeImage() throws IOException { - String graalPathString = getGraalPath(); - if (graalPathString == null) throw new IllegalArgumentException("There is no GraalVM in the projectConfiguration"); - Path graalPath = Path.of(graalPathString); - if (!Files.exists(graalPath)) throw new IOException("Path provided for GraalVM doesn't exist: " + graalPathString); + + Path graalPath = getGraalPath();//Path.of(graalPathString); + if (!Files.exists(graalPath)) throw new IOException("Path provided for GraalVM doesn't exist: " + graalPath); Path binPath = graalPath.resolve("bin"); - if (!Files.exists(binPath)) throw new IOException("Path provided for GraalVM doesn't contain a bin directory: " + graalPathString); + if (!Files.exists(binPath)) throw new IOException("Path provided for GraalVM doesn't contain a bin directory: " + graalPath); Path niPath = Constants.OS_WINDOWS.equals(getHostTriplet().getOs()) ? binPath.resolve("native-image.cmd") : binPath.resolve("native-image"); - if (!Files.exists(niPath)) throw new IOException("Path provided for GraalVM doesn't contain bin/native-image: " + graalPathString + "\n" + + if (!Files.exists(niPath)) throw new IOException("Path provided for GraalVM doesn't contain bin/native-image: " + graalPath + "\n" + "You can use gu to install it running: \n${GRAALVM_HOME}/bin/gu install native-image"); Path javacmd = binPath.resolve("java"); ProcessBuilder processBuilder = new ProcessBuilder(javacmd.toFile().getAbsolutePath()); @@ -463,15 +417,15 @@ public void canRunNativeImage() throws IOException { InputStream is = process.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String l = br.readLine(); - if (l == null) throw new IllegalArgumentException("java -version failed to return a value for GraalVM in " + graalPathString); - if (l.indexOf("1.8") > 0) throw new IllegalArgumentException("You are using an old version of GraalVM in " + graalPathString+ + if (l == null) throw new IllegalArgumentException("java -version failed to return a value for GraalVM in " + graalPath); + if (l.indexOf("1.8") > 0) throw new IllegalArgumentException("You are using an old version of GraalVM in " + graalPath + " which uses Java version "+l+"\nUse GraalVM 19.3 or later"); } @Override public String toString() { return "ProjectConfiguration{" + - "graalPath='" + graalPath + '\'' + + "graalPath='" + publicConfig.getGraalPath() + '\'' + ", javaStaticSdkVersion='" + javaStaticSdkVersion + '\'' + ", javafxStaticSdkVersion='" + javafxStaticSdkVersion + '\'' + ", llcPath='" + llcPath + '\'' + diff --git a/src/main/java/com/gluonhq/substrate/target/AbstractTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/AbstractTargetConfiguration.java index 313ab7c48..f015471de 100644 --- a/src/main/java/com/gluonhq/substrate/target/AbstractTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/AbstractTargetConfiguration.java @@ -30,8 +30,8 @@ import com.gluonhq.substrate.Constants; import com.gluonhq.substrate.gluon.AttachResolver; import com.gluonhq.substrate.gluon.GlistenResolver; +import com.gluonhq.substrate.model.PrivateProjectConfiguration; import com.gluonhq.substrate.model.ProcessPaths; -import com.gluonhq.substrate.model.ProjectConfiguration; import com.gluonhq.substrate.model.Triplet; import com.gluonhq.substrate.util.FileDeps; import com.gluonhq.substrate.util.FileOps; @@ -58,14 +58,14 @@ public abstract class AbstractTargetConfiguration implements TargetConfiguration { final FileDeps fileDeps; - final ProjectConfiguration projectConfiguration; + final PrivateProjectConfiguration projectConfiguration; final ProcessPaths paths; private List attachList = Collections.emptyList(); private List defaultAdditionalSourceFiles = Collections.singletonList("launcher.c"); private boolean useGlisten = false; - public AbstractTargetConfiguration( ProcessPaths paths, ProjectConfiguration configuration ) { + public AbstractTargetConfiguration( ProcessPaths paths, PrivateProjectConfiguration configuration ) { this.projectConfiguration = configuration; this.fileDeps = new FileDeps(configuration); this.paths = paths; @@ -173,8 +173,9 @@ private String getJniPlatform( String os ) { * not exist. In that case, retrieve the libs from our download site. */ private void ensureClibs() throws IOException { + Triplet target = projectConfiguration.getTargetTriplet(); - Path clibPath = Path.of(projectConfiguration.getGraalPath(), "lib", "svm", "clibraries", target.getOsArch2()); + Path clibPath = getCLibPath(); if (!Files.exists(clibPath)) { String url = URL_CLIBS_ZIP.replace("${osarch}", target.getOsArch()); fileDeps.downloadZip(url, clibPath); @@ -182,6 +183,15 @@ private void ensureClibs() throws IOException { if (!Files.exists(clibPath)) throw new IOException("No clibraries found for the required architecture in "+clibPath); } + private Path getCLibPath( ) { + Triplet target = projectConfiguration.getTargetTriplet(); + return projectConfiguration.getGraalPath() + .resolve("lib") + .resolve("svm") + .resolve("clibraries") + .resolve(target.getOsArch2()); + } + @Override public boolean link() throws IOException, InterruptedException { @@ -232,8 +242,7 @@ public boolean link() throws IOException, InterruptedException { } private void addGraalStaticLibsPathToLinkProcess(ProcessBuilder linkBuilder) { - Triplet target = projectConfiguration.getTargetTriplet(); - linkBuilder.command().add(getLinkLibraryPathOption() + Path.of(projectConfiguration.getGraalPath(), "lib", "svm", "clibraries", target.getOsArch2())); // darwin-amd64"); + linkBuilder.command().add(getLinkLibraryPathOption() + getCLibPath()); } private void addJavaStaticLibsPathToLinkProcess(ProcessBuilder linkBuilder) throws IOException { @@ -267,9 +276,10 @@ private void printFromInputStream(InputStream inputStream) throws IOException { } private String getNativeImagePath() { - String graalPath = projectConfiguration.getGraalPath(); - Path path = Path.of(graalPath, "bin", getNativeImageCommand()); - return path.toString(); + return projectConfiguration.getGraalPath() + .resolve("bin") + .resolve(getNativeImageCommand()) + .toString(); } private Process startAppProcess( Path appPath, String appName ) throws IOException { diff --git a/src/main/java/com/gluonhq/substrate/target/AndroidTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/AndroidTargetConfiguration.java index fbf49b863..30f8810e1 100644 --- a/src/main/java/com/gluonhq/substrate/target/AndroidTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/AndroidTargetConfiguration.java @@ -29,8 +29,7 @@ import com.gluonhq.substrate.Constants; import com.gluonhq.substrate.model.ProcessPaths; -import com.gluonhq.substrate.model.ProjectConfiguration; -import com.gluonhq.substrate.util.FileDeps; +import com.gluonhq.substrate.model.PrivateProjectConfiguration; import com.gluonhq.substrate.util.FileOps; import java.io.File; @@ -61,7 +60,7 @@ public class AndroidTargetConfiguration extends AbstractTargetConfiguration { "-lGLESv2", "-lEGL", "-lfreetype"); - public AndroidTargetConfiguration( ProcessPaths paths, ProjectConfiguration configuration ) { + public AndroidTargetConfiguration( ProcessPaths paths, PrivateProjectConfiguration configuration ) { super(paths,configuration); // for now, we need to have an ANDROID_NDK // we will fail fast whenever a method is invoked that uses it (e.g. compile) diff --git a/src/main/java/com/gluonhq/substrate/target/DarwinTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/DarwinTargetConfiguration.java index 17256fb89..4040cf202 100644 --- a/src/main/java/com/gluonhq/substrate/target/DarwinTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/DarwinTargetConfiguration.java @@ -27,8 +27,8 @@ */ package com.gluonhq.substrate.target; +import com.gluonhq.substrate.model.PrivateProjectConfiguration; import com.gluonhq.substrate.model.ProcessPaths; -import com.gluonhq.substrate.model.ProjectConfiguration; import java.nio.file.Path; import java.util.ArrayList; @@ -41,7 +41,7 @@ public class DarwinTargetConfiguration extends AbstractTargetConfiguration { "-llibchelper", "-lpthread", "-Wl,-framework,Foundation", "-Wl,-framework,AppKit"); - public DarwinTargetConfiguration(ProcessPaths paths, ProjectConfiguration configuration ) { + public DarwinTargetConfiguration(ProcessPaths paths, PrivateProjectConfiguration configuration ) { super(paths, configuration); } @@ -75,7 +75,7 @@ List getTargetSpecificLinkFlags(boolean useJavaFX, boolean usePrismSW) { List getTargetSpecificLinkLibraries() { List defaultLinkFlags = new ArrayList<>(super.getTargetSpecificLinkLibraries()); defaultLinkFlags.addAll(Arrays.asList("-Wl,-force_load," + - Path.of(projectConfiguration.getGraalPath(), "lib", "libnet.a").toString(), + projectConfiguration.getGraalPath().resolve("lib").resolve("libnet.a"), "-lextnet", "-lstdc++")); return defaultLinkFlags; } diff --git a/src/main/java/com/gluonhq/substrate/target/IosTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/IosTargetConfiguration.java index 99dc0bf8b..0cd6b94ae 100644 --- a/src/main/java/com/gluonhq/substrate/target/IosTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/IosTargetConfiguration.java @@ -28,9 +28,8 @@ package com.gluonhq.substrate.target; import com.gluonhq.substrate.Constants; +import com.gluonhq.substrate.model.PrivateProjectConfiguration; import com.gluonhq.substrate.model.ProcessPaths; -import com.gluonhq.substrate.model.ProjectConfiguration; -import com.gluonhq.substrate.util.FileDeps; import com.gluonhq.substrate.util.FileOps; import com.gluonhq.substrate.util.Logger; import com.gluonhq.substrate.util.XcodeUtils; @@ -67,7 +66,7 @@ public class IosTargetConfiguration extends AbstractTargetConfiguration { "-Wl,-framework,OpenGLES", "-Wl,-framework,CoreText", "-Wl,-framework,QuartzCore", "-Wl,-framework,ImageIO"); - public IosTargetConfiguration(ProcessPaths paths, ProjectConfiguration configuration ) { + public IosTargetConfiguration(ProcessPaths paths, PrivateProjectConfiguration configuration ) { super(paths, configuration); } @@ -225,7 +224,7 @@ private boolean isSimulator() { return Constants.ARCH_AMD64.equals(projectConfiguration.getTargetTriplet().getArch()); } - private void createInfoPlist(ProcessPaths paths, ProjectConfiguration projectConfiguration) { + private void createInfoPlist(ProcessPaths paths, PrivateProjectConfiguration projectConfiguration) { try { InfoPlist infoPlist = new InfoPlist(paths, projectConfiguration, isSimulator() ? XcodeUtils.SDKS.IPHONESIMULATOR : XcodeUtils.SDKS.IPHONEOS); diff --git a/src/main/java/com/gluonhq/substrate/target/LinuxTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/LinuxTargetConfiguration.java index cd7a2310a..cb743b51f 100644 --- a/src/main/java/com/gluonhq/substrate/target/LinuxTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/LinuxTargetConfiguration.java @@ -28,7 +28,7 @@ package com.gluonhq.substrate.target; import com.gluonhq.substrate.model.ProcessPaths; -import com.gluonhq.substrate.model.ProjectConfiguration; +import com.gluonhq.substrate.model.PrivateProjectConfiguration; import com.gluonhq.substrate.util.Logger; import com.gluonhq.substrate.util.Version; import com.gluonhq.substrate.util.VersionParser; @@ -48,7 +48,7 @@ public class LinuxTargetConfiguration extends AbstractTargetConfiguration { private static final Version COMPILER_MINIMAL_VERSION = new Version(6); private static final Version LINKER_MINIMAL_VERSION = new Version(2, 26); - public LinuxTargetConfiguration( ProcessPaths paths, ProjectConfiguration configuration ) { + public LinuxTargetConfiguration( ProcessPaths paths, PrivateProjectConfiguration configuration ) { super(paths, configuration); } @@ -78,7 +78,7 @@ public boolean link() throws IOException, InterruptedException { List getTargetSpecificLinkLibraries() { List defaultLinkFlags = new ArrayList<>(super.getTargetSpecificLinkLibraries()); defaultLinkFlags.addAll(Arrays.asList("-Wl,--whole-archive", - Path.of(projectConfiguration.getGraalPath(), "lib", "libnet.a").toString(), + projectConfiguration.getGraalPath().resolve("lib").resolve("libnet.a").toString(), "-Wl,--no-whole-archive", "-lextnet", "-lstdc++")); return defaultLinkFlags; } diff --git a/src/main/java/com/gluonhq/substrate/target/TargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/TargetConfiguration.java index 95b1b3c17..e7f4770a5 100644 --- a/src/main/java/com/gluonhq/substrate/target/TargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/TargetConfiguration.java @@ -27,9 +27,6 @@ */ package com.gluonhq.substrate.target; -import com.gluonhq.substrate.model.ProcessPaths; -import com.gluonhq.substrate.model.ProjectConfiguration; - import java.io.IOException; import java.nio.file.Path; diff --git a/src/main/java/com/gluonhq/substrate/target/WindowsTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/WindowsTargetConfiguration.java index 2ab598c29..85c564640 100644 --- a/src/main/java/com/gluonhq/substrate/target/WindowsTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/WindowsTargetConfiguration.java @@ -27,8 +27,8 @@ */ package com.gluonhq.substrate.target; +import com.gluonhq.substrate.model.PrivateProjectConfiguration; import com.gluonhq.substrate.model.ProcessPaths; -import com.gluonhq.substrate.model.ProjectConfiguration; import java.util.Arrays; import java.util.Collections; @@ -37,7 +37,7 @@ public class WindowsTargetConfiguration extends AbstractTargetConfiguration { - public WindowsTargetConfiguration(ProcessPaths paths, ProjectConfiguration configuration ) { + public WindowsTargetConfiguration(ProcessPaths paths, PrivateProjectConfiguration configuration ) { super(paths, configuration); } diff --git a/src/main/java/com/gluonhq/substrate/util/FileDeps.java b/src/main/java/com/gluonhq/substrate/util/FileDeps.java index 77b817b66..f02b77ad7 100644 --- a/src/main/java/com/gluonhq/substrate/util/FileDeps.java +++ b/src/main/java/com/gluonhq/substrate/util/FileDeps.java @@ -29,7 +29,7 @@ import com.gluonhq.substrate.Constants; -import com.gluonhq.substrate.model.ProjectConfiguration; +import com.gluonhq.substrate.model.PrivateProjectConfiguration; import java.io.File; import java.io.FileInputStream; @@ -74,9 +74,9 @@ public final class FileDeps { "libglass.a" ); - private final ProjectConfiguration configuration; + private final PrivateProjectConfiguration configuration; - public FileDeps( ProjectConfiguration config ) { + public FileDeps( PrivateProjectConfiguration config ) { this.configuration = Objects.requireNonNull(config); } diff --git a/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java b/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java index 2021bb624..b7286ec2f 100644 --- a/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java +++ b/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java @@ -27,8 +27,8 @@ */ package com.gluonhq.substrate.util.ios; +import com.gluonhq.substrate.model.PrivateProjectConfiguration; import com.gluonhq.substrate.model.ProcessPaths; -import com.gluonhq.substrate.model.ProjectConfiguration; import com.gluonhq.substrate.util.FileOps; import com.gluonhq.substrate.util.Logger; import com.gluonhq.substrate.util.ProcessRunner; @@ -48,7 +48,6 @@ import java.util.Locale; import java.util.Objects; import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -80,13 +79,13 @@ public class CodeSigning { private String bundleId; private final ProcessPaths paths; - private final ProjectConfiguration projectConfiguration; + private final PrivateProjectConfiguration projectConfiguration; private final String sourceOS; private final Path appPath; private final Path tmpPath; - public CodeSigning(ProcessPaths paths, ProjectConfiguration projectConfiguration) { + public CodeSigning(ProcessPaths paths, PrivateProjectConfiguration projectConfiguration) { this.paths = paths; this.projectConfiguration = projectConfiguration; this.sourceOS = projectConfiguration.getTargetTriplet().getOs(); diff --git a/src/main/java/com/gluonhq/substrate/util/ios/InfoPlist.java b/src/main/java/com/gluonhq/substrate/util/ios/InfoPlist.java index 75e38907a..87ed791dc 100644 --- a/src/main/java/com/gluonhq/substrate/util/ios/InfoPlist.java +++ b/src/main/java/com/gluonhq/substrate/util/ios/InfoPlist.java @@ -33,7 +33,7 @@ import com.dd.plist.PropertyListParser; import com.gluonhq.substrate.Constants; import com.gluonhq.substrate.model.ProcessPaths; -import com.gluonhq.substrate.model.ProjectConfiguration; +import com.gluonhq.substrate.model.PrivateProjectConfiguration; import com.gluonhq.substrate.util.FileOps; import com.gluonhq.substrate.util.Logger; import com.gluonhq.substrate.util.ProcessRunner; @@ -71,7 +71,7 @@ public class InfoPlist { )); private final XcodeUtils.SDKS sdk; - private final ProjectConfiguration projectConfiguration; + private final PrivateProjectConfiguration projectConfiguration; private final ProcessPaths paths; private final String sourceOS; private final XcodeUtils xcodeUtil; @@ -84,7 +84,7 @@ public class InfoPlist { private String bundleId; private String minOSVersion = "11.0"; - public InfoPlist(ProcessPaths paths, ProjectConfiguration projectConfiguration, XcodeUtils.SDKS sdk) throws IOException { + public InfoPlist(ProcessPaths paths, PrivateProjectConfiguration projectConfiguration, XcodeUtils.SDKS sdk) throws IOException { this.paths = Objects.requireNonNull(paths); this.projectConfiguration = Objects.requireNonNull(projectConfiguration); this.sourceOS = projectConfiguration.getTargetTriplet().getOs(); diff --git a/src/test/java/com/gluonhq/substrate/SubstrateTest.java b/src/test/java/com/gluonhq/substrate/SubstrateTest.java index ff7b469cf..5a1059764 100644 --- a/src/test/java/com/gluonhq/substrate/SubstrateTest.java +++ b/src/test/java/com/gluonhq/substrate/SubstrateTest.java @@ -27,7 +27,7 @@ */ package com.gluonhq.substrate; -import com.gluonhq.substrate.model.ProjectConfiguration; +import com.gluonhq.substrate.model.PrivateProjectConfiguration; import com.gluonhq.substrate.model.Triplet; import org.junit.jupiter.api.Test; @@ -64,8 +64,10 @@ void testWindowsTriplet() { void testIOSTriplet() throws IOException { Triplet iosTriplet = new Triplet(Constants.Profile.IOS); Triplet currentOsTriplet = Triplet.fromCurrentOS(); - ProjectConfiguration config = new ProjectConfiguration(); - config.setTarget(iosTriplet); + ProjectConfiguration publicConfig = new ProjectConfiguration(""); + publicConfig.setTarget(iosTriplet); + PrivateProjectConfiguration config = new PrivateProjectConfiguration(publicConfig); + // when on linux, nativeCompile should throw an illegalArgumentException if (currentOsTriplet.getOs().indexOf("nux") > 0) { var dispatcher = new SubstrateDispatcher(Path.of(System.getProperty("user.home")), config); @@ -75,17 +77,17 @@ void testIOSTriplet() throws IOException { @Test void testAssertGraal() { - ProjectConfiguration config = new ProjectConfiguration(); - assertThrows(IllegalArgumentException.class, config::canRunNativeImage); + ProjectConfiguration publicConfig = new ProjectConfiguration(""); + PrivateProjectConfiguration config = new PrivateProjectConfiguration(publicConfig); + assertThrows(NullPointerException.class, config::canRunNativeImage); } @Test void testMainClassName() { - ProjectConfiguration config = new ProjectConfiguration(); - assertThrows(NullPointerException.class, () -> config.setMainClassName(null)); - config.setMainClassName("a.b.Foo"); + assertThrows(NullPointerException.class, () -> new ProjectConfiguration(null));; + var config = new PrivateProjectConfiguration( new ProjectConfiguration("a.b.Foo")); assertEquals("a.b.Foo", config.getMainClassName()); - config.setMainClassName("name/a.b.Foo"); + config = new PrivateProjectConfiguration( new ProjectConfiguration("name/a.b.Foo")); assertEquals("a.b.Foo", config.getMainClassName()); } } From 495e0d8be58bb416af97d9e730e0f23e81ba1470 Mon Sep 17 00:00:00 2001 From: Eugene Ryzhikov Date: Fri, 29 Nov 2019 17:34:53 -0500 Subject: [PATCH 02/11] Fix tests --- src/test/java/com/gluonhq/substrate/SubstrateTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/gluonhq/substrate/SubstrateTest.java b/src/test/java/com/gluonhq/substrate/SubstrateTest.java index 5a1059764..9b84831aa 100644 --- a/src/test/java/com/gluonhq/substrate/SubstrateTest.java +++ b/src/test/java/com/gluonhq/substrate/SubstrateTest.java @@ -71,7 +71,7 @@ void testIOSTriplet() throws IOException { // when on linux, nativeCompile should throw an illegalArgumentException if (currentOsTriplet.getOs().indexOf("nux") > 0) { var dispatcher = new SubstrateDispatcher(Path.of(System.getProperty("user.home")), config); - assertThrows(IllegalArgumentException.class, () -> dispatcher.nativeCompile(null)); + assertThrows(NullPointerException.class, () -> dispatcher.nativeCompile(null)); } } From 186f50ffa351ac33d313434f8337fd03680fddb2 Mon Sep 17 00:00:00 2001 From: Eugene Ryzhikov Date: Sat, 30 Nov 2019 08:13:37 -0500 Subject: [PATCH 03/11] Adjust default behavior for retrieving static Java and JavaFX SDK versions --- src/main/java/com/gluonhq/substrate/ProjectConfiguration.java | 4 ++-- src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/gluonhq/substrate/ProjectConfiguration.java b/src/main/java/com/gluonhq/substrate/ProjectConfiguration.java index 9019439da..c00a59fa8 100644 --- a/src/main/java/com/gluonhq/substrate/ProjectConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/ProjectConfiguration.java @@ -88,7 +88,7 @@ public void setJavaStaticSdkVersion(String javaStaticSdkVersion) { } public String getJavaStaticSdkVersion() { - return Objects.requireNonNull( this.javaStaticSdkVersion, "Java Static SDK version is required" ); + return Optional.ofNullable(this.javaStaticSdkVersion).orElse(Constants.DEFAULT_JAVA_STATIC_SDK_VERSION); } /** @@ -100,7 +100,7 @@ public void setJavafxStaticSdkVersion(String javafxStaticSdkVersion) { } public String getJavafxStaticSdkVersion() { - return Objects.requireNonNull( this.javafxStaticSdkVersion, "JavaFX Static SDK version is required" ); + return Optional.ofNullable(this.javaStaticSdkVersion).orElse(Constants.DEFAULT_JAVAFX_STATIC_SDK_VERSION); } diff --git a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java index 23a770812..cbb6f3afd 100644 --- a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java +++ b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java @@ -68,7 +68,6 @@ public static void main(String[] args) throws Exception { ProjectConfiguration publicConfig = new ProjectConfiguration(mainClass); publicConfig.setGraalPath(graalVM); publicConfig.setAppName(appName); - publicConfig.setJavafxStaticSdkVersion(Constants.DEFAULT_JAVAFX_STATIC_SDK_VERSION); publicConfig.setTarget(targetTriplet); PrivateProjectConfiguration config = new PrivateProjectConfiguration(publicConfig); From 40fcd67533848ba9ccdcdc2ffa427b148b27e3d4 Mon Sep 17 00:00:00 2001 From: Eugene Ryzhikov Date: Sat, 30 Nov 2019 08:53:36 -0500 Subject: [PATCH 04/11] Use targetTriplet and hostTriplet from public configuration --- .../substrate/model/PrivateProjectConfiguration.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java b/src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java index 96cc676f4..5c9b507a1 100644 --- a/src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java @@ -68,8 +68,6 @@ public class PrivateProjectConfiguration { private boolean enableCheckHash = true; private boolean verbose = false; - private Triplet targetTriplet; - private Triplet hostTriplet; private String backend; private List bundlesList = Collections.emptyList(); private List resourcesList = Collections.emptyList(); @@ -151,7 +149,7 @@ public Path getDefaultJavaStaticPath() { Path answer = Constants.USER_SUBSTRATE_PATH .resolve("javaStaticSdk") .resolve(getJavaStaticSdkVersion()) - .resolve(targetTriplet.getOsArch()) + .resolve(getTargetTriplet().getOsArch()) .resolve("labs-staticjdk"); return answer; } @@ -190,7 +188,7 @@ Path getDefaultJavafxStaticPath() { Path answer = Constants.USER_SUBSTRATE_PATH .resolve("javafxStaticSdk") .resolve(getJavafxStaticSdkVersion()) - .resolve(targetTriplet.getOsArch()) + .resolve(getTargetTriplet().getOsArch()) .resolve("sdk"); return answer; } @@ -435,8 +433,8 @@ public String toString() { ", usePrismSW=" + usePrismSW + ", enableCheckHash=" + enableCheckHash + ", verbose=" + verbose + - ", targetTriplet=" + targetTriplet + - ", hostTriplet=" + hostTriplet + + ", targetTriplet=" + getTargetTriplet() + + ", hostTriplet=" + getHostTriplet() + ", backend='" + backend + '\'' + ", bundlesList=" + bundlesList + ", resourcesList=" + resourcesList + From 5b04abffbf99829b1156952dccc89f9cda432983 Mon Sep 17 00:00:00 2001 From: Eugene Ryzhikov Date: Sat, 30 Nov 2019 09:14:19 -0500 Subject: [PATCH 05/11] Hide private project configuration within SubstrateDispatcher --- .../substrate/SubstrateDispatcher.java | 46 +++++-------------- .../model/PrivateProjectConfiguration.java | 43 ++++++++++------- 2 files changed, 39 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java index cbb6f3afd..52acf7e19 100644 --- a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java +++ b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java @@ -48,37 +48,20 @@ public static void main(String[] args) throws Exception { String classPath = requireArg("imagecp","Use -Dimagecp=/path/to/classes"); String graalVM = requireArg( "graalvm","Use -Dgraalvm=/path/to/graalvm"); + String mainClass = requireArg( "mainclass", "Use -Dmainclass=main.class.name" ); String appName = Optional.ofNullable(System.getProperty("appname")).orElse("anonymousApp"); - String reflectionList = System.getProperty("reflectionlist"); - String jniList = System.getProperty("jnilist"); - String bundlesList = System.getProperty("bundleslist"); String targetProfile = System.getProperty("targetProfile"); - boolean usePrismSW = Boolean.parseBoolean(System.getProperty("prism.sw", "false")); - boolean skipCompile = Boolean.parseBoolean(System.getProperty("skipcompile", "false")); - boolean skipSigning = Boolean.parseBoolean(System.getProperty("skipsigning", "false")); - String staticLibs = System.getProperty("javalibspath"); - String staticJavaFXSDK = System.getProperty("javafxsdk"); - - String expected = System.getProperty("expected"); Triplet targetTriplet = targetProfile != null? new Triplet(Constants.Profile.valueOf(targetProfile.toUpperCase())) :Triplet.fromCurrentOS(); - ProjectConfiguration publicConfig = new ProjectConfiguration(mainClass); - publicConfig.setGraalPath(graalVM); - publicConfig.setAppName(appName); - publicConfig.setTarget(targetTriplet); - - PrivateProjectConfiguration config = new PrivateProjectConfiguration(publicConfig); + String expected = System.getProperty("expected"); - config.setUsePrismSW(usePrismSW); - config.getIosSigningConfiguration().setSkipSigning(skipSigning); - config.setJavaStaticLibs(staticLibs); - config.setJavaFXStaticSDK(staticJavaFXSDK); - config.setReflectionList(splitString(reflectionList)); - config.setJniList(splitString(jniList)); - config.setBundlesList(splitString(bundlesList)); + ProjectConfiguration config = new ProjectConfiguration(mainClass); + config.setGraalPath(graalVM); + config.setAppName(appName); + config.setTarget(targetTriplet); Path buildRoot = Paths.get(System.getProperty("user.dir"), "build", "autoclient"); @@ -129,11 +112,6 @@ public static void main(String[] args) throws Exception { dispatcher.nativeRun(); } } - - private static List splitString( String s ) { - return s == null || s.trim().isEmpty()? Collections.emptyList() : Arrays.asList(s.split(",")); - } - private static String requireArg(String argName, String errorMessage ) { String arg = System.getProperty(argName); if (arg == null || arg.trim().isEmpty()) { @@ -157,20 +135,20 @@ private static void printUsage() { * @param buildRoot the root, relative to which the compilation step can create object files and temporary files * @param config the ProjectConfiguration, including the target triplet */ - public SubstrateDispatcher(Path buildRoot, PrivateProjectConfiguration config) throws IOException { - this.config = Objects.requireNonNull(config); + public SubstrateDispatcher(Path buildRoot, ProjectConfiguration config) throws IOException { + this.config = new PrivateProjectConfiguration(config); this.paths = new ProcessPaths(Objects.requireNonNull(buildRoot), config.getTargetTriplet().getArchOs()); this.targetConfiguration = Objects.requireNonNull(getTargetConfiguration(config.getTargetTriplet()), "Error: Target Configuration was null"); } private TargetConfiguration getTargetConfiguration( Triplet targetTriplet ) { switch (targetTriplet.getOs()) { - case Constants.OS_LINUX : return new LinuxTargetConfiguration(paths, config); - case Constants.OS_DARWIN: return new DarwinTargetConfiguration(paths, config); + case Constants.OS_LINUX : return new LinuxTargetConfiguration(paths, config); + case Constants.OS_DARWIN : return new DarwinTargetConfiguration(paths, config); case Constants.OS_WINDOWS: return new WindowsTargetConfiguration(paths, config); - case Constants.OS_IOS: return new IosTargetConfiguration(paths, config); + case Constants.OS_IOS : return new IosTargetConfiguration(paths, config); case Constants.OS_ANDROID: return new AndroidTargetConfiguration(paths, config); - default: return null; + default : return null; } } diff --git a/src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java b/src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java index 5c9b507a1..efdcafa73 100644 --- a/src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java @@ -37,10 +37,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Optional; +import java.util.*; /** * This class contains all configuration info about the current project (not about the current OS/Arch/vendor etc) @@ -54,14 +51,11 @@ */ public class PrivateProjectConfiguration { - private String javaStaticSdkVersion = Constants.DEFAULT_JAVA_STATIC_SDK_VERSION; private String javaStaticLibs; private String javaFXStaticSDK; - private String javafxStaticSdkVersion; - private String llcPath; - private String StaticRoot; + private String staticRoot; private boolean useJNI = true; private boolean useJavaFX = false; private boolean usePrismSW = false; @@ -77,9 +71,6 @@ public class PrivateProjectConfiguration { private List runtimeArgsList; private List releaseSymbolsList; - private String appName; - private String mainClassName; - private IosSigningConfiguration iosSigningConfiguration = new IosSigningConfiguration(); private ProjectConfiguration publicConfig; @@ -89,7 +80,27 @@ public class PrivateProjectConfiguration { * @param config public project configuration */ public PrivateProjectConfiguration( ProjectConfiguration config ) { + this.publicConfig = Objects.requireNonNull(config); + + boolean usePrismSW = Boolean.parseBoolean(System.getProperty("prism.sw", "false")); + boolean skipCompile = Boolean.parseBoolean(System.getProperty("skipcompile", "false")); + boolean skipSigning = Boolean.parseBoolean(System.getProperty("skipsigning", "false")); + + setUsePrismSW(usePrismSW); + getIosSigningConfiguration().setSkipSigning(skipSigning); + + setJavaStaticLibs(System.getProperty("javalibspath")); // this can be safely set even if null. Default will be used in that case + setJavaFXStaticSDK(System.getProperty("javafxsdk")); // this can be safely set even if null. Default will be used in that case + + setReflectionList(splitString(System.getProperty("reflectionlist"))); + setJniList(splitString(System.getProperty("jnilist"))); + setBundlesList(splitString(System.getProperty("bundleslist"))); + + } + + private static List splitString( String s ) { + return s == null || s.trim().isEmpty()? Collections.emptyList() : Arrays.asList(s.split(",")); } public Path getGraalPath() { @@ -424,10 +435,10 @@ public void canRunNativeImage() throws IOException { public String toString() { return "ProjectConfiguration{" + "graalPath='" + publicConfig.getGraalPath() + '\'' + - ", javaStaticSdkVersion='" + javaStaticSdkVersion + '\'' + - ", javafxStaticSdkVersion='" + javafxStaticSdkVersion + '\'' + + ", javaStaticSdkVersion='" + getJavaStaticSdkVersion() + '\'' + + ", javafxStaticSdkVersion='" + getJavafxStaticSdkVersion() + '\'' + ", llcPath='" + llcPath + '\'' + - ", StaticRoot='" + StaticRoot + '\'' + + ", StaticRoot='" + staticRoot + '\'' + ", useJNI=" + useJNI + ", useJavaFX=" + useJavaFX + ", usePrismSW=" + usePrismSW + @@ -443,9 +454,9 @@ public String toString() { ", delayInitList=" + delayInitList + ", runtimeArgsList=" + runtimeArgsList + ", releaseSymbolsList=" + releaseSymbolsList + - ", appName='" + appName + '\'' + + ", appName='" + getAppName() + '\'' + ", iosConfiguration='" + iosSigningConfiguration + '\'' + - ", mainClassName='" + mainClassName + '\'' + + ", mainClassName='" + getMainClassName() + '\'' + '}'; } } From 42805feaae105f38c43407e47b5dd08331b70524 Mon Sep 17 00:00:00 2001 From: Eugene Ryzhikov Date: Sat, 30 Nov 2019 09:20:44 -0500 Subject: [PATCH 06/11] Small tweaks to Logger API --- .../java/com/gluonhq/substrate/SubstrateDispatcher.java | 9 +++++---- src/main/java/com/gluonhq/substrate/util/Logger.java | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java index 52acf7e19..3934e3818 100644 --- a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java +++ b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java @@ -31,7 +31,6 @@ import com.gluonhq.substrate.model.PrivateProjectConfiguration; import com.gluonhq.substrate.model.Triplet; import com.gluonhq.substrate.target.*; -import com.gluonhq.substrate.util.Logger; import java.io.File; import java.io.IOException; @@ -40,6 +39,8 @@ import java.util.*; import java.util.stream.Stream; +import static com.gluonhq.substrate.util.Logger.*; + public class SubstrateDispatcher { private static volatile boolean run = true; @@ -178,7 +179,7 @@ public boolean nativeCompile(String classPath) throws Exception { if (targetConfiguration == null) { throw new IllegalArgumentException("We don't have a configuration to compile "+targetTriplet); } - Logger.logInit(paths.getLogPath().toString(), "==================== COMPILE TASK ====================", + logInit(paths.getLogPath().toString(), title("COMPILE TASK"), config.isVerbose()); System.err.println("We will now compile your code for "+targetTriplet.toString()+". This may take some time."); boolean compile = targetConfiguration.compile(classPath); @@ -191,7 +192,7 @@ public boolean nativeCompile(String classPath) throws Exception { } public boolean nativeLink() throws IOException, InterruptedException { - Logger.logInit(paths.getLogPath().toString(), "==================== LINK TASK ====================", + logInit(paths.getLogPath().toString(), title("LINK TASK"), config.isVerbose()); if (targetConfiguration == null) { throw new IllegalArgumentException("We don't have a configuration to link " + config.getTargetTriplet()); @@ -200,7 +201,7 @@ public boolean nativeLink() throws IOException, InterruptedException { } public void nativeRun() throws IOException, InterruptedException { - Logger.logInit(paths.getLogPath().toString(), "==================== RUN TASK ====================", + logInit(paths.getLogPath().toString(), title("RUN TASK"), config.isVerbose()); targetConfiguration.runUntilEnd(); } diff --git a/src/main/java/com/gluonhq/substrate/util/Logger.java b/src/main/java/com/gluonhq/substrate/util/Logger.java index c455c4e82..912063b59 100644 --- a/src/main/java/com/gluonhq/substrate/util/Logger.java +++ b/src/main/java/com/gluonhq/substrate/util/Logger.java @@ -98,4 +98,8 @@ public static void logInit(String logPath, String message, boolean verbose) { LOGGER.fine(message); } + public static String title( String text ) { + return "==================== " + (text == null? "": text) +" ===================="; + } + } From 64ec60eee30799175a3d6888747c232d88d0aed8 Mon Sep 17 00:00:00 2001 From: Eugene Ryzhikov Date: Sat, 30 Nov 2019 09:28:59 -0500 Subject: [PATCH 07/11] Fix unit tests --- src/test/java/com/gluonhq/substrate/SubstrateTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/gluonhq/substrate/SubstrateTest.java b/src/test/java/com/gluonhq/substrate/SubstrateTest.java index 9b84831aa..a77a2df32 100644 --- a/src/test/java/com/gluonhq/substrate/SubstrateTest.java +++ b/src/test/java/com/gluonhq/substrate/SubstrateTest.java @@ -64,9 +64,8 @@ void testWindowsTriplet() { void testIOSTriplet() throws IOException { Triplet iosTriplet = new Triplet(Constants.Profile.IOS); Triplet currentOsTriplet = Triplet.fromCurrentOS(); - ProjectConfiguration publicConfig = new ProjectConfiguration(""); - publicConfig.setTarget(iosTriplet); - PrivateProjectConfiguration config = new PrivateProjectConfiguration(publicConfig); + ProjectConfiguration config = new ProjectConfiguration(""); + config.setTarget(iosTriplet); // when on linux, nativeCompile should throw an illegalArgumentException if (currentOsTriplet.getOs().indexOf("nux") > 0) { From 1c31f21080a35058c7ce8559c24e33c2cb3066ce Mon Sep 17 00:00:00 2001 From: Eugene Ryzhikov Date: Sun, 1 Dec 2019 12:57:10 -0500 Subject: [PATCH 08/11] Remove wildcard imports --- .../gluonhq/substrate/SubstrateDispatcher.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java index 3934e3818..57efbc372 100644 --- a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java +++ b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java @@ -27,19 +27,26 @@ */ package com.gluonhq.substrate; -import com.gluonhq.substrate.model.ProcessPaths; import com.gluonhq.substrate.model.PrivateProjectConfiguration; +import com.gluonhq.substrate.model.ProcessPaths; import com.gluonhq.substrate.model.Triplet; -import com.gluonhq.substrate.target.*; +import com.gluonhq.substrate.target.AndroidTargetConfiguration; +import com.gluonhq.substrate.target.DarwinTargetConfiguration; +import com.gluonhq.substrate.target.IosTargetConfiguration; +import com.gluonhq.substrate.target.LinuxTargetConfiguration; +import com.gluonhq.substrate.target.TargetConfiguration; +import com.gluonhq.substrate.target.WindowsTargetConfiguration; import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.*; +import java.util.Objects; +import java.util.Optional; import java.util.stream.Stream; -import static com.gluonhq.substrate.util.Logger.*; +import static com.gluonhq.substrate.util.Logger.logInit; +import static com.gluonhq.substrate.util.Logger.title; public class SubstrateDispatcher { From ce18a5f0057d67dbb6c8cc35904900faffc10033 Mon Sep 17 00:00:00 2001 From: Eugene Ryzhikov Date: Sun, 1 Dec 2019 12:58:29 -0500 Subject: [PATCH 09/11] Rename PrivateProjectConfiguration to InternalProjectConfiguration --- .../java/com/gluonhq/substrate/SubstrateDispatcher.java | 6 +++--- ...nfiguration.java => InternalProjectConfiguration.java} | 4 ++-- .../substrate/target/AbstractTargetConfiguration.java | 6 +++--- .../substrate/target/AndroidTargetConfiguration.java | 4 ++-- .../substrate/target/DarwinTargetConfiguration.java | 5 ++--- .../gluonhq/substrate/target/IosTargetConfiguration.java | 6 +++--- .../substrate/target/LinuxTargetConfiguration.java | 5 ++--- .../substrate/target/WindowsTargetConfiguration.java | 4 ++-- src/main/java/com/gluonhq/substrate/util/FileDeps.java | 6 +++--- .../java/com/gluonhq/substrate/util/ios/CodeSigning.java | 6 +++--- .../java/com/gluonhq/substrate/util/ios/InfoPlist.java | 6 +++--- src/test/java/com/gluonhq/substrate/SubstrateTest.java | 8 ++++---- 12 files changed, 32 insertions(+), 34 deletions(-) rename src/main/java/com/gluonhq/substrate/model/{PrivateProjectConfiguration.java => InternalProjectConfiguration.java} (99%) diff --git a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java index 57efbc372..119eaed65 100644 --- a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java +++ b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java @@ -27,7 +27,7 @@ */ package com.gluonhq.substrate; -import com.gluonhq.substrate.model.PrivateProjectConfiguration; +import com.gluonhq.substrate.model.InternalProjectConfiguration; import com.gluonhq.substrate.model.ProcessPaths; import com.gluonhq.substrate.model.Triplet; import com.gluonhq.substrate.target.AndroidTargetConfiguration; @@ -133,7 +133,7 @@ private static void printUsage() { System.err.println("Usage:\n java -Dimagecp=... -Dgraalvm=... -Dmainclass=... com.gluonhq.substrate.SubstrateDispatcher"); } - private final PrivateProjectConfiguration config; + private final InternalProjectConfiguration config; private final ProcessPaths paths; private final TargetConfiguration targetConfiguration; @@ -144,7 +144,7 @@ private static void printUsage() { * @param config the ProjectConfiguration, including the target triplet */ public SubstrateDispatcher(Path buildRoot, ProjectConfiguration config) throws IOException { - this.config = new PrivateProjectConfiguration(config); + this.config = new InternalProjectConfiguration(config); this.paths = new ProcessPaths(Objects.requireNonNull(buildRoot), config.getTargetTriplet().getArchOs()); this.targetConfiguration = Objects.requireNonNull(getTargetConfiguration(config.getTargetTriplet()), "Error: Target Configuration was null"); diff --git a/src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java b/src/main/java/com/gluonhq/substrate/model/InternalProjectConfiguration.java similarity index 99% rename from src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java rename to src/main/java/com/gluonhq/substrate/model/InternalProjectConfiguration.java index efdcafa73..5513855ea 100644 --- a/src/main/java/com/gluonhq/substrate/model/PrivateProjectConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/model/InternalProjectConfiguration.java @@ -49,7 +49,7 @@ * If this method has not been called, getJavaStaticLibsPath() will return the default location, taking into account * the value of javaStaticSdkVersion. If that value is not set, the default value is used. */ -public class PrivateProjectConfiguration { +public class InternalProjectConfiguration { private String javaStaticLibs; private String javaFXStaticSDK; @@ -79,7 +79,7 @@ public class PrivateProjectConfiguration { * Private projects configuration, which includes everythign, including public settings * @param config public project configuration */ - public PrivateProjectConfiguration( ProjectConfiguration config ) { + public InternalProjectConfiguration(ProjectConfiguration config ) { this.publicConfig = Objects.requireNonNull(config); diff --git a/src/main/java/com/gluonhq/substrate/target/AbstractTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/AbstractTargetConfiguration.java index f015471de..d09e5739f 100644 --- a/src/main/java/com/gluonhq/substrate/target/AbstractTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/AbstractTargetConfiguration.java @@ -30,7 +30,7 @@ import com.gluonhq.substrate.Constants; import com.gluonhq.substrate.gluon.AttachResolver; import com.gluonhq.substrate.gluon.GlistenResolver; -import com.gluonhq.substrate.model.PrivateProjectConfiguration; +import com.gluonhq.substrate.model.InternalProjectConfiguration; import com.gluonhq.substrate.model.ProcessPaths; import com.gluonhq.substrate.model.Triplet; import com.gluonhq.substrate.util.FileDeps; @@ -58,14 +58,14 @@ public abstract class AbstractTargetConfiguration implements TargetConfiguration { final FileDeps fileDeps; - final PrivateProjectConfiguration projectConfiguration; + final InternalProjectConfiguration projectConfiguration; final ProcessPaths paths; private List attachList = Collections.emptyList(); private List defaultAdditionalSourceFiles = Collections.singletonList("launcher.c"); private boolean useGlisten = false; - public AbstractTargetConfiguration( ProcessPaths paths, PrivateProjectConfiguration configuration ) { + public AbstractTargetConfiguration( ProcessPaths paths, InternalProjectConfiguration configuration ) { this.projectConfiguration = configuration; this.fileDeps = new FileDeps(configuration); this.paths = paths; diff --git a/src/main/java/com/gluonhq/substrate/target/AndroidTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/AndroidTargetConfiguration.java index 30f8810e1..f5a80e9b7 100644 --- a/src/main/java/com/gluonhq/substrate/target/AndroidTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/AndroidTargetConfiguration.java @@ -29,7 +29,7 @@ import com.gluonhq.substrate.Constants; import com.gluonhq.substrate.model.ProcessPaths; -import com.gluonhq.substrate.model.PrivateProjectConfiguration; +import com.gluonhq.substrate.model.InternalProjectConfiguration; import com.gluonhq.substrate.util.FileOps; import java.io.File; @@ -60,7 +60,7 @@ public class AndroidTargetConfiguration extends AbstractTargetConfiguration { "-lGLESv2", "-lEGL", "-lfreetype"); - public AndroidTargetConfiguration( ProcessPaths paths, PrivateProjectConfiguration configuration ) { + public AndroidTargetConfiguration( ProcessPaths paths, InternalProjectConfiguration configuration ) { super(paths,configuration); // for now, we need to have an ANDROID_NDK // we will fail fast whenever a method is invoked that uses it (e.g. compile) diff --git a/src/main/java/com/gluonhq/substrate/target/DarwinTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/DarwinTargetConfiguration.java index 4040cf202..af1e56dcd 100644 --- a/src/main/java/com/gluonhq/substrate/target/DarwinTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/DarwinTargetConfiguration.java @@ -27,10 +27,9 @@ */ package com.gluonhq.substrate.target; -import com.gluonhq.substrate.model.PrivateProjectConfiguration; +import com.gluonhq.substrate.model.InternalProjectConfiguration; import com.gluonhq.substrate.model.ProcessPaths; -import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -41,7 +40,7 @@ public class DarwinTargetConfiguration extends AbstractTargetConfiguration { "-llibchelper", "-lpthread", "-Wl,-framework,Foundation", "-Wl,-framework,AppKit"); - public DarwinTargetConfiguration(ProcessPaths paths, PrivateProjectConfiguration configuration ) { + public DarwinTargetConfiguration(ProcessPaths paths, InternalProjectConfiguration configuration ) { super(paths, configuration); } diff --git a/src/main/java/com/gluonhq/substrate/target/IosTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/IosTargetConfiguration.java index 0cd6b94ae..e8345d45d 100644 --- a/src/main/java/com/gluonhq/substrate/target/IosTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/IosTargetConfiguration.java @@ -28,7 +28,7 @@ package com.gluonhq.substrate.target; import com.gluonhq.substrate.Constants; -import com.gluonhq.substrate.model.PrivateProjectConfiguration; +import com.gluonhq.substrate.model.InternalProjectConfiguration; import com.gluonhq.substrate.model.ProcessPaths; import com.gluonhq.substrate.util.FileOps; import com.gluonhq.substrate.util.Logger; @@ -66,7 +66,7 @@ public class IosTargetConfiguration extends AbstractTargetConfiguration { "-Wl,-framework,OpenGLES", "-Wl,-framework,CoreText", "-Wl,-framework,QuartzCore", "-Wl,-framework,ImageIO"); - public IosTargetConfiguration(ProcessPaths paths, PrivateProjectConfiguration configuration ) { + public IosTargetConfiguration(ProcessPaths paths, InternalProjectConfiguration configuration ) { super(paths, configuration); } @@ -224,7 +224,7 @@ private boolean isSimulator() { return Constants.ARCH_AMD64.equals(projectConfiguration.getTargetTriplet().getArch()); } - private void createInfoPlist(ProcessPaths paths, PrivateProjectConfiguration projectConfiguration) { + private void createInfoPlist(ProcessPaths paths, InternalProjectConfiguration projectConfiguration) { try { InfoPlist infoPlist = new InfoPlist(paths, projectConfiguration, isSimulator() ? XcodeUtils.SDKS.IPHONESIMULATOR : XcodeUtils.SDKS.IPHONEOS); diff --git a/src/main/java/com/gluonhq/substrate/target/LinuxTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/LinuxTargetConfiguration.java index cb743b51f..6308f4ce7 100644 --- a/src/main/java/com/gluonhq/substrate/target/LinuxTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/LinuxTargetConfiguration.java @@ -28,7 +28,7 @@ package com.gluonhq.substrate.target; import com.gluonhq.substrate.model.ProcessPaths; -import com.gluonhq.substrate.model.PrivateProjectConfiguration; +import com.gluonhq.substrate.model.InternalProjectConfiguration; import com.gluonhq.substrate.util.Logger; import com.gluonhq.substrate.util.Version; import com.gluonhq.substrate.util.VersionParser; @@ -37,7 +37,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; @@ -48,7 +47,7 @@ public class LinuxTargetConfiguration extends AbstractTargetConfiguration { private static final Version COMPILER_MINIMAL_VERSION = new Version(6); private static final Version LINKER_MINIMAL_VERSION = new Version(2, 26); - public LinuxTargetConfiguration( ProcessPaths paths, PrivateProjectConfiguration configuration ) { + public LinuxTargetConfiguration( ProcessPaths paths, InternalProjectConfiguration configuration ) { super(paths, configuration); } diff --git a/src/main/java/com/gluonhq/substrate/target/WindowsTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/WindowsTargetConfiguration.java index 85c564640..ff8fd3841 100644 --- a/src/main/java/com/gluonhq/substrate/target/WindowsTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/WindowsTargetConfiguration.java @@ -27,7 +27,7 @@ */ package com.gluonhq.substrate.target; -import com.gluonhq.substrate.model.PrivateProjectConfiguration; +import com.gluonhq.substrate.model.InternalProjectConfiguration; import com.gluonhq.substrate.model.ProcessPaths; import java.util.Arrays; @@ -37,7 +37,7 @@ public class WindowsTargetConfiguration extends AbstractTargetConfiguration { - public WindowsTargetConfiguration(ProcessPaths paths, PrivateProjectConfiguration configuration ) { + public WindowsTargetConfiguration(ProcessPaths paths, InternalProjectConfiguration configuration ) { super(paths, configuration); } diff --git a/src/main/java/com/gluonhq/substrate/util/FileDeps.java b/src/main/java/com/gluonhq/substrate/util/FileDeps.java index f02b77ad7..3c9038776 100644 --- a/src/main/java/com/gluonhq/substrate/util/FileDeps.java +++ b/src/main/java/com/gluonhq/substrate/util/FileDeps.java @@ -29,7 +29,7 @@ import com.gluonhq.substrate.Constants; -import com.gluonhq.substrate.model.PrivateProjectConfiguration; +import com.gluonhq.substrate.model.InternalProjectConfiguration; import java.io.File; import java.io.FileInputStream; @@ -74,9 +74,9 @@ public final class FileDeps { "libglass.a" ); - private final PrivateProjectConfiguration configuration; + private final InternalProjectConfiguration configuration; - public FileDeps( PrivateProjectConfiguration config ) { + public FileDeps( InternalProjectConfiguration config ) { this.configuration = Objects.requireNonNull(config); } diff --git a/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java b/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java index b7286ec2f..7f11a7114 100644 --- a/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java +++ b/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java @@ -27,7 +27,7 @@ */ package com.gluonhq.substrate.util.ios; -import com.gluonhq.substrate.model.PrivateProjectConfiguration; +import com.gluonhq.substrate.model.InternalProjectConfiguration; import com.gluonhq.substrate.model.ProcessPaths; import com.gluonhq.substrate.util.FileOps; import com.gluonhq.substrate.util.Logger; @@ -79,13 +79,13 @@ public class CodeSigning { private String bundleId; private final ProcessPaths paths; - private final PrivateProjectConfiguration projectConfiguration; + private final InternalProjectConfiguration projectConfiguration; private final String sourceOS; private final Path appPath; private final Path tmpPath; - public CodeSigning(ProcessPaths paths, PrivateProjectConfiguration projectConfiguration) { + public CodeSigning(ProcessPaths paths, InternalProjectConfiguration projectConfiguration) { this.paths = paths; this.projectConfiguration = projectConfiguration; this.sourceOS = projectConfiguration.getTargetTriplet().getOs(); diff --git a/src/main/java/com/gluonhq/substrate/util/ios/InfoPlist.java b/src/main/java/com/gluonhq/substrate/util/ios/InfoPlist.java index 87ed791dc..35bd49406 100644 --- a/src/main/java/com/gluonhq/substrate/util/ios/InfoPlist.java +++ b/src/main/java/com/gluonhq/substrate/util/ios/InfoPlist.java @@ -33,7 +33,7 @@ import com.dd.plist.PropertyListParser; import com.gluonhq.substrate.Constants; import com.gluonhq.substrate.model.ProcessPaths; -import com.gluonhq.substrate.model.PrivateProjectConfiguration; +import com.gluonhq.substrate.model.InternalProjectConfiguration; import com.gluonhq.substrate.util.FileOps; import com.gluonhq.substrate.util.Logger; import com.gluonhq.substrate.util.ProcessRunner; @@ -71,7 +71,7 @@ public class InfoPlist { )); private final XcodeUtils.SDKS sdk; - private final PrivateProjectConfiguration projectConfiguration; + private final InternalProjectConfiguration projectConfiguration; private final ProcessPaths paths; private final String sourceOS; private final XcodeUtils xcodeUtil; @@ -84,7 +84,7 @@ public class InfoPlist { private String bundleId; private String minOSVersion = "11.0"; - public InfoPlist(ProcessPaths paths, PrivateProjectConfiguration projectConfiguration, XcodeUtils.SDKS sdk) throws IOException { + public InfoPlist(ProcessPaths paths, InternalProjectConfiguration projectConfiguration, XcodeUtils.SDKS sdk) throws IOException { this.paths = Objects.requireNonNull(paths); this.projectConfiguration = Objects.requireNonNull(projectConfiguration); this.sourceOS = projectConfiguration.getTargetTriplet().getOs(); diff --git a/src/test/java/com/gluonhq/substrate/SubstrateTest.java b/src/test/java/com/gluonhq/substrate/SubstrateTest.java index a77a2df32..7d1dd577e 100644 --- a/src/test/java/com/gluonhq/substrate/SubstrateTest.java +++ b/src/test/java/com/gluonhq/substrate/SubstrateTest.java @@ -27,7 +27,7 @@ */ package com.gluonhq.substrate; -import com.gluonhq.substrate.model.PrivateProjectConfiguration; +import com.gluonhq.substrate.model.InternalProjectConfiguration; import com.gluonhq.substrate.model.Triplet; import org.junit.jupiter.api.Test; @@ -77,16 +77,16 @@ void testIOSTriplet() throws IOException { @Test void testAssertGraal() { ProjectConfiguration publicConfig = new ProjectConfiguration(""); - PrivateProjectConfiguration config = new PrivateProjectConfiguration(publicConfig); + InternalProjectConfiguration config = new InternalProjectConfiguration(publicConfig); assertThrows(NullPointerException.class, config::canRunNativeImage); } @Test void testMainClassName() { assertThrows(NullPointerException.class, () -> new ProjectConfiguration(null));; - var config = new PrivateProjectConfiguration( new ProjectConfiguration("a.b.Foo")); + var config = new InternalProjectConfiguration( new ProjectConfiguration("a.b.Foo")); assertEquals("a.b.Foo", config.getMainClassName()); - config = new PrivateProjectConfiguration( new ProjectConfiguration("name/a.b.Foo")); + config = new InternalProjectConfiguration( new ProjectConfiguration("name/a.b.Foo")); assertEquals("a.b.Foo", config.getMainClassName()); } } From 02d42e7ca4ecf43b1a9a3ee5eb2b178b76f15a7e Mon Sep 17 00:00:00 2001 From: Eugene Ryzhikov Date: Sun, 1 Dec 2019 12:59:31 -0500 Subject: [PATCH 10/11] Fix typo in the docs --- .../gluonhq/substrate/model/InternalProjectConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/gluonhq/substrate/model/InternalProjectConfiguration.java b/src/main/java/com/gluonhq/substrate/model/InternalProjectConfiguration.java index 5513855ea..b8ba2db08 100644 --- a/src/main/java/com/gluonhq/substrate/model/InternalProjectConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/model/InternalProjectConfiguration.java @@ -76,7 +76,7 @@ public class InternalProjectConfiguration { private ProjectConfiguration publicConfig; /** - * Private projects configuration, which includes everythign, including public settings + * Private projects configuration, which includes everything, including public settings * @param config public project configuration */ public InternalProjectConfiguration(ProjectConfiguration config ) { From 16d88e18e830482fd7a002c9016f28949f22d42a Mon Sep 17 00:00:00 2001 From: Eugene Ryzhikov Date: Fri, 27 Dec 2019 19:52:22 -0500 Subject: [PATCH 11/11] Refactor Architecture, OS, Vendor and TripletProfile into enums with useful methods. --- .../java/com/gluonhq/substrate/Constants.java | 46 --------- .../substrate/SubstrateDispatcher.java | 17 +--- .../model/InternalProjectConfiguration.java | 3 +- .../com/gluonhq/substrate/model/Triplet.java | 98 +++++-------------- .../target/AbstractTargetConfiguration.java | 13 +-- .../substrate/target/Architecture.java | 21 ++++ .../target/IosTargetConfiguration.java | 10 +- .../java/com/gluonhq/substrate/target/OS.java | 62 ++++++++++++ .../substrate/target/TripletProfile.java | 42 ++++++++ .../com/gluonhq/substrate/target/Vendor.java | 18 ++++ .../substrate/util/ios/CodeSigning.java | 2 +- .../gluonhq/substrate/util/ios/InfoPlist.java | 2 +- .../com/gluonhq/substrate/SubstrateTest.java | 32 +++--- 13 files changed, 196 insertions(+), 170 deletions(-) create mode 100644 src/main/java/com/gluonhq/substrate/target/Architecture.java create mode 100644 src/main/java/com/gluonhq/substrate/target/OS.java create mode 100644 src/main/java/com/gluonhq/substrate/target/TripletProfile.java create mode 100644 src/main/java/com/gluonhq/substrate/target/Vendor.java diff --git a/src/main/java/com/gluonhq/substrate/Constants.java b/src/main/java/com/gluonhq/substrate/Constants.java index 84ca68161..54c3091c7 100644 --- a/src/main/java/com/gluonhq/substrate/Constants.java +++ b/src/main/java/com/gluonhq/substrate/Constants.java @@ -35,41 +35,6 @@ public class Constants { public static final Path USER_SUBSTRATE_PATH = Path.of(System.getProperty("user.home")) .resolve(".gluon").resolve("substrate"); - /** - * Triplet architecture - */ - public static final String ARCH_AMD64 = "x86_64"; - public static final String ARCH_ARM64 = "arm64"; - public static final String ARCH_AARCH64 = "aarch64"; - - /** - * Triplet vendor - */ - public static final String VENDOR_APPLE = "apple"; - public static final String VENDOR_LINUX = "linux"; - public static final String VENDOR_MICROSOFT = "microsoft"; - - /** - * Triplet OS - */ - public static final String OS_DARWIN = "darwin"; - public static final String OS_IOS = "ios"; - public static final String OS_LINUX = "linux"; - public static final String OS_WINDOWS = "windows"; - public static final String OS_ANDROID = "android"; - - /** - * Predefined Profiles - */ - public enum Profile { - LINUX, // (x86_64-linux-linux) - MACOS, // (x86_64-apple-darwin) - WINDOWS, // (x86_64-windows-windows) - IOS, // (aarch64-apple-ios) - IOS_SIM, // (x86_64-apple-ios) - ANDROID // (aarch64-linux-android); - }; - /** * Supported hosts * @@ -88,17 +53,6 @@ public enum Profile { @Deprecated public static final String TARGET_IOS = "ios"; @Deprecated public static final String TARGET_IOS_SIM = "ios-sim"; - /** - * Supported profiles - * - */ - public static final String PROFILE_HOST = "host"; // either mac or linux, based on host - public static final String PROFILE_MAC = "macos"; - public static final String PROFILE_LINUX = "linux"; - public static final String PROFILE_IOS = "ios"; - public static final String PROFILE_IOS_SIM = "ios-sim"; - public static final String PROFILE_ANDROID = "android"; - public static final String DEFAULT_JAVA_STATIC_SDK_VERSION = "14-ea+5"; public static final String DEFAULT_JAVAFX_STATIC_SDK_VERSION = "14-ea+gvm2"; diff --git a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java index a1e692034..e33bfd566 100644 --- a/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java +++ b/src/main/java/com/gluonhq/substrate/SubstrateDispatcher.java @@ -31,12 +31,8 @@ import com.gluonhq.substrate.model.InternalProjectConfiguration; import com.gluonhq.substrate.model.ProcessPaths; import com.gluonhq.substrate.model.Triplet; -import com.gluonhq.substrate.target.AndroidTargetConfiguration; -import com.gluonhq.substrate.target.DarwinTargetConfiguration; -import com.gluonhq.substrate.target.IosTargetConfiguration; -import com.gluonhq.substrate.target.LinuxTargetConfiguration; import com.gluonhq.substrate.target.TargetConfiguration; -import com.gluonhq.substrate.target.WindowsTargetConfiguration; +import com.gluonhq.substrate.target.TripletProfile; import com.gluonhq.substrate.util.Strings; import java.io.IOException; @@ -61,7 +57,7 @@ public static void main(String[] args) throws Exception { String appName = Optional.ofNullable(System.getProperty("appname")).orElse("anonymousApp"); String targetProfile = System.getProperty("targetProfile"); - Triplet targetTriplet = targetProfile != null? new Triplet(Constants.Profile.valueOf(targetProfile.toUpperCase())) + Triplet targetTriplet = targetProfile != null? new Triplet(TripletProfile.valueOf(targetProfile.toUpperCase())) :Triplet.fromCurrentOS(); String expected = System.getProperty("expected"); @@ -156,14 +152,7 @@ public SubstrateDispatcher(Path buildRoot, ProjectConfiguration config) throws I } private TargetConfiguration getTargetConfiguration(Triplet targetTriplet) { - switch (targetTriplet.getOs()) { - case Constants.OS_LINUX : return new LinuxTargetConfiguration(paths, config); - case Constants.OS_DARWIN : return new DarwinTargetConfiguration(paths, config); - case Constants.OS_WINDOWS: return new WindowsTargetConfiguration(paths, config); - case Constants.OS_IOS : return new IosTargetConfiguration(paths, config); - case Constants.OS_ANDROID: return new AndroidTargetConfiguration(paths, config); - default : return null; - } + return targetTriplet.getOs().getTargetConfiguration(paths, config); } diff --git a/src/main/java/com/gluonhq/substrate/model/InternalProjectConfiguration.java b/src/main/java/com/gluonhq/substrate/model/InternalProjectConfiguration.java index 2ce11def3..52b649843 100644 --- a/src/main/java/com/gluonhq/substrate/model/InternalProjectConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/model/InternalProjectConfiguration.java @@ -29,6 +29,7 @@ import com.gluonhq.substrate.Constants; import com.gluonhq.substrate.ProjectConfiguration; +import com.gluonhq.substrate.target.OS; import com.gluonhq.substrate.util.Strings; import java.io.BufferedReader; @@ -374,7 +375,7 @@ public void canRunNativeImage() throws IOException { if (!Files.exists(graalPath)) throw new IOException("Path provided for GraalVM doesn't exist: " + graalPath); Path binPath = graalPath.resolve("bin"); if (!Files.exists(binPath)) throw new IOException("Path provided for GraalVM doesn't contain a bin directory: " + graalPath); - Path niPath = Constants.OS_WINDOWS.equals(getHostTriplet().getOs()) ? + Path niPath = OS.WINDOWS.equals(getHostTriplet().getOs()) ? binPath.resolve("native-image.cmd") : binPath.resolve("native-image"); if (!Files.exists(niPath)) throw new IOException("Path provided for GraalVM doesn't contain bin/native-image: " + graalPath + "\n" + diff --git a/src/main/java/com/gluonhq/substrate/model/Triplet.java b/src/main/java/com/gluonhq/substrate/model/Triplet.java index 5306c1cf4..ffc30df58 100644 --- a/src/main/java/com/gluonhq/substrate/model/Triplet.java +++ b/src/main/java/com/gluonhq/substrate/model/Triplet.java @@ -27,18 +27,15 @@ */ package com.gluonhq.substrate.model; -import com.gluonhq.substrate.Constants; import com.gluonhq.substrate.target.*; -import java.util.Locale; - -import static com.gluonhq.substrate.Constants.*; +import java.util.Objects; public class Triplet { - private String arch; - private String vendor; - private String os; + private Architecture arch; + private OS os; + private Vendor vendor; /** * Creates a new triplet for the current runtime @@ -46,60 +43,21 @@ public class Triplet { * @throws IllegalArgumentException in case the current operating system is not supported */ public static Triplet fromCurrentOS() throws IllegalArgumentException { - String osName = System.getProperty("os.name").toLowerCase(Locale.ROOT); - - if (osName.contains("mac")) { - return new Triplet(Constants.Profile.MACOS); - } else if (osName.contains("nux")) { - return new Triplet(Constants.Profile.LINUX); - } else if (osName.contains("windows")) { - return new Triplet(Constants.Profile.WINDOWS); - } else { - throw new IllegalArgumentException("OS " + osName + " not supported"); - } + return new Triplet( TripletProfile.fromCurrentOS()); } public Triplet(String arch, String vendor, String os) { - this.arch = arch; - this.vendor = vendor; - this.os = os; + + // following should throw exception for unsupported parts + this.arch = Architecture.valueOf(arch); + this.os = OS.valueOf(os); + this.vendor = Vendor.valueOf(vendor); } - public Triplet(Constants.Profile profile) { - switch (profile) { - case LINUX: - this.arch = ARCH_AMD64; - this.vendor = VENDOR_LINUX; - this.os = OS_LINUX; - break; - case MACOS: - this.arch = ARCH_AMD64; - this.vendor = VENDOR_APPLE; - this.os = OS_DARWIN; - break; - case WINDOWS: - this.arch = ARCH_AMD64; - this.vendor = VENDOR_MICROSOFT; - this.os = OS_WINDOWS; - break; - case IOS: - this.arch = ARCH_ARM64; - this.vendor = VENDOR_APPLE; - this.os = OS_IOS; - break; - case IOS_SIM: - this.arch = ARCH_AMD64; - this.vendor = VENDOR_APPLE; - this.os = OS_IOS; - break; - case ANDROID: - this.arch = ARCH_AARCH64; - this.vendor = VENDOR_LINUX; - this.os = OS_ANDROID; - break; - default: - throw new IllegalArgumentException("Triplet for profile "+profile+" is not supported yet"); - } + public Triplet(TripletProfile profile) { + Objects.requireNonNull(profile); + this.arch = profile.getArch(); + this.os = profile.getOs(); } /* @@ -111,34 +69,22 @@ public boolean canCompileTo(Triplet target) { if (getOs().equals(target.getOs())) return true; // if host is linux and target is ios, fail - return (!Constants.OS_LINUX.equals(getOs()) && !Constants.OS_WINDOWS.equals(getOs())) || - !Constants.OS_IOS.equals(target.getOs()); + return (!OS.LINUX.equals(getOs()) && !OS.WINDOWS.equals(getOs())) || + !OS.IOS.equals(target.getOs()); } - public String getArch() { + public Architecture getArch() { return arch; } - public void setArch(String arch) { - this.arch = arch; - } - - public String getVendor() { + public Vendor getVendor() { return vendor; } - public void setVendor(String vendor) { - this.vendor = vendor; - } - - public String getOs() { + public OS getOs() { return os; } - public void setOs(String os) { - this.os = os; - } - public String getArchOs() { return this.arch+"-"+this.os; } @@ -153,8 +99,8 @@ public String getOsArch() { * @return */ public String getOsArch2() { - String myarch = this.arch; - if (myarch.equals("x86_64")) { + String myarch = this.arch.toString(); + if ( "x86_64".equals(myarch)) { myarch = "amd64"; } return this.os+"-"+myarch; @@ -162,6 +108,6 @@ public String getOsArch2() { @Override public String toString() { - return arch + '-' + vendor + '-' + os; + return arch.toString() + '-' + vendor + '-' + os; } } diff --git a/src/main/java/com/gluonhq/substrate/target/AbstractTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/AbstractTargetConfiguration.java index 6bdf30ab5..f7a38ce01 100644 --- a/src/main/java/com/gluonhq/substrate/target/AbstractTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/AbstractTargetConfiguration.java @@ -108,7 +108,7 @@ public boolean compile(String cp) throws IOException, InterruptedException { extractNativeLibs(cp); Triplet target = projectConfiguration.getTargetTriplet(); String suffix = target.getArchOs(); - String jniPlatform = getJniPlatform(target.getOs()); + String jniPlatform = target.getOs().getJniPlatform(); if (!compileAdditionalSources()) { return false; } @@ -326,17 +326,6 @@ private boolean compileAdditionalSources() return true; } - private String getJniPlatform( String os ) { - switch (os) { - case Constants.OS_LINUX: return "LINUX_AMD64"; - case Constants.OS_IOS:return "DARWIN_AARCH64"; - case Constants.OS_DARWIN: return "DARWIN_AMD64"; - case Constants.OS_WINDOWS: return "WINDOWS_AMD64"; - case Constants.OS_ANDROID: return "LINUX_AARCH64"; - default: throw new IllegalArgumentException("No support yet for " + os); - } - } - /* * Make sure the clibraries needed for linking are available for this particular configuration. * The clibraries path is available by default in GraalVM, but the directory for cross-platform libs may diff --git a/src/main/java/com/gluonhq/substrate/target/Architecture.java b/src/main/java/com/gluonhq/substrate/target/Architecture.java new file mode 100644 index 000000000..2a03f0250 --- /dev/null +++ b/src/main/java/com/gluonhq/substrate/target/Architecture.java @@ -0,0 +1,21 @@ +package com.gluonhq.substrate.target; + +/** + * Triplet architecture + */ +public enum Architecture { + AMD64("x86_64"), + ARM64("arm64"), + AARCH64("aarch64"); + + private final String id; + + private Architecture(String id ) { + this.id = id.toLowerCase(); + } + + @Override + public String toString() { + return id; + } +} diff --git a/src/main/java/com/gluonhq/substrate/target/IosTargetConfiguration.java b/src/main/java/com/gluonhq/substrate/target/IosTargetConfiguration.java index e182cea44..f5c76a3ea 100644 --- a/src/main/java/com/gluonhq/substrate/target/IosTargetConfiguration.java +++ b/src/main/java/com/gluonhq/substrate/target/IosTargetConfiguration.java @@ -83,7 +83,7 @@ List getTargetSpecificLinkLibraries() { @Override List getTargetSpecificLinkFlags(boolean useJavaFX, boolean usePrismSW) { List linkFlags = new ArrayList<>(Arrays.asList("-w", "-fPIC", - "-arch", Constants.ARCH_ARM64, + "-arch", Architecture.ARM64.toString(), "-mios-version-min=11.0", "-isysroot", getSysroot())); if (useJavaFX) { @@ -101,7 +101,7 @@ List getTargetSpecificLinkFlags(boolean useJavaFX, boolean usePrismSW) { @Override List getTargetSpecificCCompileFlags() { return Arrays.asList("-xobjective-c", - "-arch", getArch(), + "-arch", getArch().toString(), "-isysroot", getSysroot()); } @@ -222,7 +222,7 @@ String processClassPath(String classPath) throws IOException { fileDeps.getJavaFXSDKLibsPath(),"javafx-graphics","javafx-controls" ); } - private String getArch() { + private Architecture getArch() { return projectConfiguration.getTargetTriplet().getArch(); } @@ -232,7 +232,7 @@ private String getSysroot() { } private boolean isSimulator() { - return Constants.ARCH_AMD64.equals(projectConfiguration.getTargetTriplet().getArch()); + return Architecture.AMD64.equals(projectConfiguration.getTargetTriplet().getArch()); } private void createInfoPlist(ProcessPaths paths) throws IOException { @@ -248,7 +248,7 @@ private void createInfoPlist(ProcessPaths paths) throws IOException { private boolean lipoMatch(Path path) { try { - return lipoInfo(path).indexOf(getArch()) > 0; + return lipoInfo(path).indexOf(getArch().toString()) > 0; } catch (IOException | InterruptedException e) { Logger.logSevere("Error processing lipo for " + path); } diff --git a/src/main/java/com/gluonhq/substrate/target/OS.java b/src/main/java/com/gluonhq/substrate/target/OS.java new file mode 100644 index 000000000..f094085a6 --- /dev/null +++ b/src/main/java/com/gluonhq/substrate/target/OS.java @@ -0,0 +1,62 @@ +package com.gluonhq.substrate.target; + +import com.gluonhq.substrate.model.InternalProjectConfiguration; +import com.gluonhq.substrate.model.ProcessPaths; + +import java.util.Locale; +import java.util.function.BiFunction; + +public enum OS { + + DARWIN("darwin", "DARWIN_AMD64", Vendor.APPLE, DarwinTargetConfiguration::new), + IOS("ios", "DARWIN_AARCH64", Vendor.APPLE, IosTargetConfiguration::new), + LINUX("linux", "LINUX_AMD64", Vendor.LINUX, LinuxTargetConfiguration::new), + WINDOWS("windows", "WINDOWS_AMD64", Vendor.MICROSOFT, WindowsTargetConfiguration::new), + ANDROID("android", "LINUX_AARCH64", Vendor.LINUX, AndroidTargetConfiguration::new); + + private final String id; + private final String jniPlatform; + private final Vendor vendor; + private final BiFunction targetConfiguration; + + public static OS current() { + String osName = System.getProperty("os.name").toLowerCase(Locale.ROOT); + + if (osName.contains("mac")) { + return DARWIN; + } else if (osName.contains("nux")) { + return LINUX; + } else if (osName.contains("windows")) { + return WINDOWS; + } else { + throw new IllegalArgumentException("OS " + osName + " not supported"); + } + } + + private OS(String id, + String jniPlatform, + Vendor vendor, + BiFunction targetConfiguration) { + this.id = id.toLowerCase(); + this.jniPlatform = jniPlatform; + this.vendor = vendor; + this.targetConfiguration = targetConfiguration; + } + + public Vendor getVendor() { + return vendor; + } + + public String getJniPlatform() { + return jniPlatform; + } + + public TargetConfiguration getTargetConfiguration(ProcessPaths paths, InternalProjectConfiguration configuration ) { + return targetConfiguration.apply(paths, configuration); + } + + @Override + public String toString() { + return id; + } +} diff --git a/src/main/java/com/gluonhq/substrate/target/TripletProfile.java b/src/main/java/com/gluonhq/substrate/target/TripletProfile.java new file mode 100644 index 000000000..da7ad4f11 --- /dev/null +++ b/src/main/java/com/gluonhq/substrate/target/TripletProfile.java @@ -0,0 +1,42 @@ +package com.gluonhq.substrate.target; + +import com.gluonhq.substrate.Constants; + +/** + * Predefined Profiles + */ +public enum TripletProfile { + LINUX(Architecture.AMD64, OS.LINUX), // (x86_64-linux-linux) + MACOS(Architecture.AMD64, OS.DARWIN), // (x86_64-apple-darwin) + WINDOWS(Architecture.AMD64, OS.WINDOWS), // (x86_64-windows-windows) + IOS(Architecture.ARM64, OS.IOS), // (aarch64-apple-ios) + IOS_SIM(Architecture.AMD64, OS.IOS), // (x86_64-apple-ios) + ANDROID(Architecture.AARCH64,OS.ANDROID); // (aarch64-linux-android) + + private final Architecture arch; + private final OS os; + + public static TripletProfile fromCurrentOS() { + switch (OS.current()) { + case DARWIN: return TripletProfile.MACOS; + case IOS: return TripletProfile.IOS; + case LINUX: return TripletProfile.LINUX; + case WINDOWS: return TripletProfile.WINDOWS; + case ANDROID: return TripletProfile.ANDROID; + default: throw new IllegalArgumentException("Unsupported OS"); + } + } + + TripletProfile(Architecture arch, OS os ) { + this.arch = arch; + this.os = os; + } + + public Architecture getArch() { + return arch; + } + + public OS getOs() { + return os; + } +} diff --git a/src/main/java/com/gluonhq/substrate/target/Vendor.java b/src/main/java/com/gluonhq/substrate/target/Vendor.java new file mode 100644 index 000000000..e12c6920a --- /dev/null +++ b/src/main/java/com/gluonhq/substrate/target/Vendor.java @@ -0,0 +1,18 @@ +package com.gluonhq.substrate.target; + +public enum Vendor { + APPLE("apple"), + LINUX("linux"), + MICROSOFT("microsoft"); + + private final String id; + + private Vendor(String id ) { + this.id = id.toLowerCase(); + } + @Override + public String toString() { + return id; + } + +} diff --git a/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java b/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java index 7f11a7114..12b776426 100644 --- a/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java +++ b/src/main/java/com/gluonhq/substrate/util/ios/CodeSigning.java @@ -88,7 +88,7 @@ public class CodeSigning { public CodeSigning(ProcessPaths paths, InternalProjectConfiguration projectConfiguration) { this.paths = paths; this.projectConfiguration = projectConfiguration; - this.sourceOS = projectConfiguration.getTargetTriplet().getOs(); + this.sourceOS = projectConfiguration.getTargetTriplet().getOs().toString(); this.bundleId = InfoPlist.getBundleId(InfoPlist.getPlistPath(paths, sourceOS), sourceOS); appPath = paths.getAppPath().resolve(projectConfiguration.getAppName() + ".app"); diff --git a/src/main/java/com/gluonhq/substrate/util/ios/InfoPlist.java b/src/main/java/com/gluonhq/substrate/util/ios/InfoPlist.java index 35bd49406..9a6bc276d 100644 --- a/src/main/java/com/gluonhq/substrate/util/ios/InfoPlist.java +++ b/src/main/java/com/gluonhq/substrate/util/ios/InfoPlist.java @@ -87,7 +87,7 @@ public class InfoPlist { public InfoPlist(ProcessPaths paths, InternalProjectConfiguration projectConfiguration, XcodeUtils.SDKS sdk) throws IOException { this.paths = Objects.requireNonNull(paths); this.projectConfiguration = Objects.requireNonNull(projectConfiguration); - this.sourceOS = projectConfiguration.getTargetTriplet().getOs(); + this.sourceOS = projectConfiguration.getTargetTriplet().getOs().toString(); this.sdk = sdk; this.xcodeUtil = new XcodeUtils(sdk); appPath = paths.getAppPath().resolve(projectConfiguration.getAppName() + ".app"); diff --git a/src/test/java/com/gluonhq/substrate/SubstrateTest.java b/src/test/java/com/gluonhq/substrate/SubstrateTest.java index 7d1dd577e..acef7d6e6 100644 --- a/src/test/java/com/gluonhq/substrate/SubstrateTest.java +++ b/src/test/java/com/gluonhq/substrate/SubstrateTest.java @@ -29,6 +29,10 @@ import com.gluonhq.substrate.model.InternalProjectConfiguration; import com.gluonhq.substrate.model.Triplet; +import com.gluonhq.substrate.target.Architecture; +import com.gluonhq.substrate.target.OS; +import com.gluonhq.substrate.target.TripletProfile; +import com.gluonhq.substrate.target.Vendor; import org.junit.jupiter.api.Test; import java.io.IOException; @@ -41,34 +45,34 @@ class SubstrateTest { @Test void testTriplets() { - Triplet triplet = new Triplet(Constants.Profile.LINUX); - assertEquals(triplet.getArch(), Constants.ARCH_AMD64); - assertEquals(triplet.getVendor(), Constants.VENDOR_LINUX); - assertEquals(triplet.getOs(), Constants.OS_LINUX); + Triplet triplet = new Triplet(TripletProfile.LINUX); + assertEquals(triplet.getArch(), Architecture.AMD64); + assertEquals(triplet.getVendor(), Vendor.LINUX); + assertEquals(triplet.getOs(), OS.LINUX); - triplet = new Triplet(Constants.Profile.MACOS); - assertEquals(triplet.getArch(), Constants.ARCH_AMD64); - assertEquals(triplet.getVendor(), Constants.VENDOR_APPLE); - assertEquals(triplet.getOs(), Constants.OS_DARWIN); + triplet = new Triplet(TripletProfile.MACOS); + assertEquals(triplet.getArch(), Architecture.AMD64); + assertEquals(triplet.getVendor(), Vendor.APPLE); + assertEquals(triplet.getOs(), OS.DARWIN); } @Test void testWindowsTriplet() { - Triplet triplet = new Triplet(Constants.Profile.WINDOWS); - assertEquals(triplet.getArch(), Constants.ARCH_AMD64); - assertEquals(triplet.getVendor(), Constants.VENDOR_MICROSOFT); - assertEquals(triplet.getOs(), Constants.OS_WINDOWS); + Triplet triplet = new Triplet(TripletProfile.WINDOWS); + assertEquals(triplet.getArch(), Architecture.AMD64); + assertEquals(triplet.getVendor(), Vendor.MICROSOFT); + assertEquals(triplet.getOs(), OS.WINDOWS); } @Test void testIOSTriplet() throws IOException { - Triplet iosTriplet = new Triplet(Constants.Profile.IOS); + Triplet iosTriplet = new Triplet(TripletProfile.IOS); Triplet currentOsTriplet = Triplet.fromCurrentOS(); ProjectConfiguration config = new ProjectConfiguration(""); config.setTarget(iosTriplet); // when on linux, nativeCompile should throw an illegalArgumentException - if (currentOsTriplet.getOs().indexOf("nux") > 0) { + if (currentOsTriplet.getOs().toString().indexOf("nux") > 0) { var dispatcher = new SubstrateDispatcher(Path.of(System.getProperty("user.home")), config); assertThrows(NullPointerException.class, () -> dispatcher.nativeCompile(null)); }