Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.robovm.compiler.config.Config Maven / Gradle / Ivy
/*
* Copyright (C) 2012 Trillian AB
*
* 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 2
* 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 .
*/
package org.robovm.compiler.config;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import org.apache.commons.io.IOUtils;
import org.robovm.compiler.Version;
import org.robovm.compiler.clazz.Clazz;
import org.robovm.compiler.clazz.Clazzes;
import org.robovm.compiler.clazz.Path;
import org.robovm.compiler.log.Logger;
import org.robovm.compiler.target.ConsoleTarget;
import org.robovm.compiler.target.Target;
import org.robovm.compiler.target.ios.IOSTarget;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.convert.Converter;
import org.simpleframework.xml.convert.Registry;
import org.simpleframework.xml.convert.RegistryStrategy;
import org.simpleframework.xml.core.Persister;
import org.simpleframework.xml.filter.PlatformFilter;
import org.simpleframework.xml.stream.Format;
import org.simpleframework.xml.stream.InputNode;
import org.simpleframework.xml.stream.OutputNode;
/**
* @author niklas
*
*/
@Root
public class Config {
public enum Cacerts { full };
public enum TargetType { console, ios };
@Element(required = false)
private File installDir = null;
@Element(required = false)
private String executableName = null;
@Element(required = false)
private Boolean useDynamicJni = null;
@Element(required = false)
private Boolean skipRuntimeLib = null;
@Element(required = false)
private File mainJar;
@Element(required = false)
private String mainClass;
@Element(required = false)
private Cacerts cacerts = null;
@Element(required = false)
private OS os = null;
@Element(required = false)
private Arch arch = null;
@ElementList(required = false, entry = "root")
private ArrayList roots;
@ElementList(required = false, entry = "pattern")
private ArrayList forceLinkClasses;
@ElementList(required = false, entry = "lib")
private ArrayList libs;
@ElementList(required = false, entry = "framework")
private ArrayList frameworks;
@ElementList(required = false, entry = "resource")
private ArrayList resources;
@ElementList(required = false, entry = "classpathentry")
private ArrayList bootclasspath;
@ElementList(required = false, entry = "classpathentry")
private ArrayList classpath;
@Element(required = false, name = "target")
private TargetType targetType;
@Element(required = false)
private String iosSdkVersion;
@Element(required = false)
private File iosInfoPList = null;
@Element(required = false)
private File iosResourceRulesPList;
@Element(required = false)
private File iosEntitlementsPList;
@Element(required = false)
private String iosSignIdentity;
private Target target = null;
private Properties properties = new Properties();
private Home home = null;
private File cacheDir = new File(System.getProperty("user.home"), ".robovm/cache");
private File ccBinPath = null;
private boolean clean = false;
private boolean debug = true;
private boolean useDebugLibs = false;
private boolean skipLinking = false;
private boolean skipInstall = false;
private File osArchDepLibDir;
private File tmpDir;
private Clazzes clazzes;
private Logger logger = Logger.NULL_LOGGER;
private List resourcesPaths = new ArrayList();
Config() {
}
public Home getHome() {
return home;
}
public File getInstallDir() {
return installDir;
}
public String getExecutableName() {
return executableName;
}
public File getCacheDir() {
return cacheDir;
}
public File getCcBinPath() {
return ccBinPath;
}
public OS getOs() {
return os;
}
public Arch getArch() {
return arch;
}
public String getTriple() {
return arch.getLlvmName() + "-unknown-" + os;
}
public boolean isClean() {
return clean;
}
public boolean isDebug() {
return debug;
}
public boolean isUseDebugLibs() {
return useDebugLibs;
}
public boolean isSkipRuntimeLib() {
return skipRuntimeLib != null && skipRuntimeLib.booleanValue();
}
public boolean isSkipLinking() {
return skipLinking;
}
public boolean isSkipInstall() {
return skipInstall;
}
public boolean isUseDynamicJni() {
return useDynamicJni != null && useDynamicJni.booleanValue();
}
public File getMainJar() {
return mainJar;
}
public String getMainClass() {
return mainClass;
}
public Cacerts getCacerts() {
return cacerts == null ? Cacerts.full : cacerts;
}
public List getResourcesPaths() {
return resourcesPaths;
}
public void addResourcesPath(Path path) {
resourcesPaths.add(path);
}
public File getTmpDir() {
if (tmpDir == null) {
try {
tmpDir = File.createTempFile("robovm", ".tmp");
} catch (IOException e) {
throw new RuntimeException(e);
}
tmpDir.delete();
tmpDir.mkdirs();
}
return tmpDir;
}
public List getForceLinkClasses() {
return forceLinkClasses == null ? Collections.emptyList()
: Collections.unmodifiableList(forceLinkClasses);
}
public List getLibs() {
List result = new ArrayList();
if (libs != null) {
for (Lib lib : libs) {
result.add(lib.getValue());
}
}
return Collections.unmodifiableList(result);
}
public List getFrameworks() {
return frameworks == null ? Collections.emptyList()
: Collections.unmodifiableList(frameworks);
}
public List getResources() {
return resources == null ? Collections.emptyList()
: Collections.unmodifiableList(resources);
}
public File getOsArchDepLibDir() {
return osArchDepLibDir;
}
public Clazzes getClazzes() {
return clazzes;
}
public List getBootclasspath() {
return bootclasspath;
}
public List getClasspath() {
return classpath;
}
public Properties getProperties() {
return properties;
}
public Logger getLogger() {
return logger;
}
public Target getTarget() {
return target;
}
public String getIosSdkVersion() {
return iosSdkVersion;
}
public File getIosInfoPList() {
return iosInfoPList;
}
public File getIosResourceRulesPList() {
return iosResourceRulesPList;
}
public File getIosEntitlementsPList() {
return iosEntitlementsPList;
}
public String getIosSignIdentity() {
return iosSignIdentity;
}
private static File makeFileRelativeTo(File dir, File f) {
if (f.getParentFile() == null) {
return dir;
}
return new File(makeFileRelativeTo(dir, f.getParentFile()), f.getName());
}
public String getArchiveName(Path path) {
if (path.getFile().isFile()) {
return path.getFile().getName();
} else {
return "classes" + path.getIndex() + ".jar";
}
}
public File getLlFile(Clazz clazz) {
String baseName = clazz.getInternalName().replace('/', File.separatorChar);
return new File(getCacheDir(clazz.getPath()), baseName + ".class.ll");
}
public File getBcFile(Clazz clazz) {
String baseName = clazz.getInternalName().replace('/', File.separatorChar);
return new File(getCacheDir(clazz.getPath()), baseName + ".class.bc");
}
public File getSFile(Clazz clazz) {
String baseName = clazz.getInternalName().replace('/', File.separatorChar);
return new File(getCacheDir(clazz.getPath()), baseName + ".class.s");
}
public File getOFile(Clazz clazz) {
String baseName = clazz.getInternalName().replace('/', File.separatorChar);
return new File(getCacheDir(clazz.getPath()), baseName + ".class.o");
}
public File getDepsFile(Clazz clazz) {
String baseName = clazz.getInternalName().replace('/', File.separatorChar);
return new File(getCacheDir(clazz.getPath()), baseName + ".class.deps");
}
public File getCacheDir(Path path) {
File srcRoot = path.getFile().getParentFile();
String name = path.getFile().getName();
try {
return new File(makeFileRelativeTo(cacheDir, srcRoot.getCanonicalFile()), name);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static Map getManifestAttributes(File jarFile) throws IOException {
JarFile jf = null;
try {
jf = new JarFile(jarFile);
return new HashMap(jf.getManifest().getMainAttributes());
} finally {
jf.close();
}
}
private static String getImplementationVersion(File jarFile) throws IOException {
return (String) getManifestAttributes(jarFile).get(Attributes.Name.IMPLEMENTATION_VERSION);
}
private static String getMainClass(File jarFile) throws IOException {
return (String) getManifestAttributes(jarFile).get(Attributes.Name.MAIN_CLASS);
}
private Config build() throws IOException {
if (home == null) {
home = Home.find();
}
if (bootclasspath == null) {
bootclasspath = new ArrayList();
}
if (classpath == null) {
classpath = new ArrayList();
}
if (mainJar != null) {
mainClass = getMainClass(mainJar);
classpath.add(mainJar);
}
if (!skipLinking && executableName == null && mainClass == null) {
throw new IllegalArgumentException("No target and no main class specified");
}
if (!skipLinking && classpath.isEmpty()) {
throw new IllegalArgumentException("No classpath specified");
}
if (skipLinking) {
skipInstall = true;
}
if (executableName == null) {
executableName = mainClass;
}
List realBootclasspath = bootclasspath == null ? new ArrayList() : bootclasspath;
if (!isSkipRuntimeLib()) {
realBootclasspath = new ArrayList(bootclasspath);
realBootclasspath.add(0, home.rtPath);
}
this.clazzes = new Clazzes(this, realBootclasspath, classpath);
if (!skipInstall) {
if (installDir == null) {
installDir = new File(".", executableName);
}
installDir.mkdirs();
}
if (targetType == TargetType.console) {
target = new ConsoleTarget();
} else if (targetType == TargetType.ios) {
target = new IOSTarget();
} else {
// Auto
if (os == OS.ios) {
target = new IOSTarget();
} else {
target = new ConsoleTarget();
}
}
target.init(this);
os = target.getOs();
arch = target.getArch();
osArchDepLibDir = new File(new File(home.libVmDir, os.toString()),
arch.toString());
File osDir = new File(cacheDir, os.toString());
File archDir = new File(osDir, arch.toString());
cacheDir = new File(archDir, "default");
cacheDir.mkdirs();
return this;
}
public static class Home {
private File binDir = null;
private File libVmDir = null;
private File rtPath = null;
private Map cacertsPath = null;
private boolean dev = false;
public Home(File homeDir) {
validate(homeDir);
binDir = new File(homeDir, "bin");
libVmDir = new File(homeDir, "lib/vm");
rtPath = new File(homeDir, "lib/robovm-rt.jar");
cacertsPath = new HashMap();
cacertsPath.put(Cacerts.full, new File(homeDir, "lib/robovm-cacerts-full.jar"));
}
private Home(File devDir, File binDir, File libVmDir, File rtPath) {
this.binDir = binDir;
this.libVmDir = libVmDir;
this.rtPath = rtPath;
cacertsPath = new HashMap();
cacertsPath.put(Cacerts.full, new File(devDir,
"cacerts/full/target/robovm-cacerts-full-" + Version.getVersion() + ".jar"));
this.dev = true;
}
public boolean isDev() {
return dev;
}
public File getBinDir() {
return binDir;
}
public File getLibVmDir() {
return libVmDir;
}
public File getRtPath() {
return rtPath;
}
public File getCacertsPath(Cacerts cacerts) {
return cacertsPath.get(cacerts);
}
public static Home find() {
// Check if ROBOVM_DEV_ROOT has been set. If set it should be pointing
// at the root of a complete RoboVM source tree.
if (System.getenv("ROBOVM_DEV_ROOT") != null) {
File dir = new File(System.getenv("ROBOVM_DEV_ROOT"));
return validateDevRootDir(dir);
}
if (System.getenv("ROBOVM_HOME") != null) {
File dir = new File(System.getenv("ROBOVM_HOME"));
return new Home(dir);
}
List candidates = new ArrayList();
File userHome = new File(System.getProperty("user.home"));
candidates.add(new File(userHome, "Applications/robovm"));
candidates.add(new File(userHome, ".robovm/home"));
candidates.add(new File("/usr/local/lib/robovm"));
candidates.add(new File("/opt/robovm"));
candidates.add(new File("/usr/lib/robovm"));
for (File dir : candidates) {
if (dir.exists()) {
return new Home(dir);
}
}
throw new IllegalArgumentException("ROBOVM_HOME not set and no RoboVM "
+ "installation found in " + candidates);
}
public static void validate(File dir) {
String error = "Path " + dir + " is not a valid RoboVM install directory: ";
// Check for required dirs and match the compiler version
// with our version.
if (!dir.exists()) {
throw new IllegalArgumentException(error + "no such path");
}
if (!dir.isDirectory()) {
throw new IllegalArgumentException(error + "not a directory");
}
File libDir = new File(dir, "lib");
if (!libDir.exists() || !libDir.isDirectory()) {
throw new IllegalArgumentException(error + "lib/ missing or invalid");
}
File binDir = new File(dir, "bin");
if (!binDir.exists() || !binDir.isDirectory()) {
throw new IllegalArgumentException(error + "bin/ missing or invalid");
}
File libVmDir = new File(libDir, "vm");
if (!libVmDir.exists() || !libVmDir.isDirectory()) {
throw new IllegalArgumentException(error + "lib/vm/ missing or invalid");
}
File rtJarFile = new File(libDir, "robovm-rt.jar");
if (!rtJarFile.exists() || !rtJarFile.isFile()) {
throw new IllegalArgumentException(error
+ "lib/robovm-rt.jar missing or invalid");
}
// Compare the version of this compiler with the version of the
// robovm-rt.jar in the home dir. They have to match.
try {
String thisVersion = Version.getVersion();
String thatVersion = getImplementationVersion(rtJarFile);
if (thisVersion == null || thatVersion == null || !thisVersion.equals(thatVersion)) {
throw new IllegalArgumentException(error + "version mismatch (expected: "
+ thisVersion + ", was: " + thatVersion + ")");
}
} catch (IOException e) {
throw new IllegalArgumentException(error
+ "failed to get version of rt jar", e);
}
}
private static Home validateDevRootDir(File dir) {
String error = "Path " + dir + " is not a valid RoboVM source tree: ";
// Check for required dirs.
if (!dir.exists()) {
throw new IllegalArgumentException(error + "no such path");
}
if (!dir.isDirectory()) {
throw new IllegalArgumentException(error + "not a directory");
}
File vmBinariesDir = new File(dir, "vm/target/binaries");
if (!vmBinariesDir.exists() || !vmBinariesDir.isDirectory()) {
throw new IllegalArgumentException(error + "vm/target/binaries/ missing or invalid");
}
File binDir = new File(dir, "bin");
if (!binDir.exists() || !binDir.isDirectory()) {
throw new IllegalArgumentException(error + "bin/ missing or invalid");
}
String rtJarName = "robovm-rt-" + Version.getVersion() + ".jar";
File rtJar = new File(dir, "rt/target/" + rtJarName);
if (!rtJar.exists() || rtJar.isDirectory()) {
throw new IllegalArgumentException(error
+ "rt/target/" + rtJarName + " missing or invalid");
}
return new Home(dir, binDir, vmBinariesDir, rtJar);
}
}
public static class Builder {
final Config config;
public Builder() {
this.config = new Config();
}
public Builder os(OS os) {
config.os = os;
return this;
}
public Builder arch(Arch arch) {
config.arch = arch;
return this;
}
public Builder clearClasspathEntries() {
if (config.classpath != null) {
config.classpath.clear();
}
return this;
}
public Builder addClasspathEntry(File f) {
if (config.classpath == null) {
config.classpath = new ArrayList();
}
config.classpath.add(f);
return this;
}
public Builder clearBootClasspathEntries() {
if (config.bootclasspath != null) {
config.bootclasspath.clear();
}
return this;
}
public Builder addBootClasspathEntry(File f) {
if (config.bootclasspath == null) {
config.bootclasspath = new ArrayList();
}
config.bootclasspath.add(f);
return this;
}
public Builder mainJar(File f) {
config.mainJar = f;
return this;
}
public Builder installDir(File installDir) {
config.installDir = installDir;
return this;
}
public Builder executableName(String executableName) {
config.executableName = executableName;
return this;
}
public Builder home(Home home) {
config.home = home;
return this;
}
public Builder cacheDir(File cacheDir) {
config.cacheDir = cacheDir;
return this;
}
public Builder clean(boolean b) {
config.clean = b;
return this;
}
public Builder ccBinPath(File ccBinPath) {
config.ccBinPath = ccBinPath;
return this;
}
public Builder debug(boolean b) {
config.debug = b;
return this;
}
public Builder useDebugLibs(boolean b) {
config.useDebugLibs = b;
return this;
}
public Builder skipRuntimeLib(boolean b) {
config.skipRuntimeLib = b;
return this;
}
public Builder skipLinking(boolean b) {
config.skipLinking = b;
return this;
}
public Builder skipInstall(boolean b) {
config.skipInstall = b;
return this;
}
public Builder useDynamicJni(boolean b) {
config.useDynamicJni = b;
return this;
}
public Builder mainClass(String mainClass) {
config.mainClass = mainClass;
return this;
}
public Builder tmpDir(File tmpDir) {
config.tmpDir = tmpDir;
return this;
}
public Builder logger(Logger logger) {
config.logger = logger;
return this;
}
public Builder clearForceLinkClasses() {
if (config.forceLinkClasses != null) {
config.forceLinkClasses.clear();
}
return this;
}
public Builder addForceLinkClass(String pattern) {
if (config.forceLinkClasses == null) {
config.forceLinkClasses = new ArrayList();
}
config.forceLinkClasses.add(pattern);
return this;
}
public Builder clearLibs() {
if (config.libs != null) {
config.libs.clear();
}
return this;
}
public Builder addLib(String lib) {
if (config.libs == null) {
config.libs = new ArrayList();
}
config.libs.add(new Lib(lib));
return this;
}
public Builder clearFrameworks() {
if (config.frameworks != null) {
config.frameworks.clear();
}
return this;
}
public Builder addFramework(String framework) {
if (config.frameworks == null) {
config.frameworks = new ArrayList();
}
config.frameworks.add(framework);
return this;
}
public Builder clearResources() {
if (config.resources != null) {
config.resources.clear();
}
return this;
}
public Builder addResource(File path) {
if (config.resources == null) {
config.resources = new ArrayList();
}
config.resources.add(path);
return this;
}
public Builder targetType(TargetType targetType) {
config.targetType = targetType;
return this;
}
public Builder clearProperties() {
config.properties.clear();
return this;
}
public Builder addProperties(Properties properties) {
config.properties.putAll(properties);
return this;
}
public Builder addProperties(File file) throws IOException {
Properties props = new Properties();
Reader reader = null;
try {
reader = new InputStreamReader(new FileInputStream(file), "utf-8");
props.load(reader);
addProperties(props);
} finally {
IOUtils.closeQuietly(reader);
}
return this;
}
public Builder addProperty(String name, String value) {
config.properties.put(name, value);
return this;
}
public Builder cacerts(Cacerts cacerts) {
config.cacerts = cacerts;
return this;
}
public Builder iosSdkVersion(String sdkVersion) {
config.iosSdkVersion = sdkVersion;
return this;
}
public Builder iosInfoPList(File infoPList) {
config.iosInfoPList = infoPList;
return this;
}
public Builder iosEntitlementsPList(File entitlementsPList) {
config.iosEntitlementsPList = entitlementsPList;
return this;
}
public Builder iosResourceRulesPList(File resourceRulesPList) {
config.iosResourceRulesPList = resourceRulesPList;
return this;
}
public Builder iosSignIdentity(String signIdentity) {
config.iosSignIdentity = signIdentity;
return this;
}
public Config build() throws IOException {
return config.build();
}
public void read(File file) throws Exception {
Reader reader = null;
try {
reader = new InputStreamReader(new FileInputStream(file), "utf-8");
read(reader, file.getAbsoluteFile().getParentFile());
} finally {
IOUtils.closeQuietly(reader);
}
}
public void read(Reader reader, File wd) throws Exception {
Serializer serializer = createSerializer(wd);
serializer.read(config, reader);
// was renamed to but we still support . We need to
// copy to and set to null.
if (config.roots != null && !config.roots.isEmpty()) {
if (config.forceLinkClasses == null) {
config.forceLinkClasses = new ArrayList();
}
config.forceLinkClasses.addAll(config.roots);
config.roots = null;
}
}
public void write(File file) throws Exception {
Writer writer = null;
try {
writer = new OutputStreamWriter(new FileOutputStream(file), "utf-8");
write(writer, file.getAbsoluteFile().getParentFile());
} finally {
IOUtils.closeQuietly(writer);
}
}
public void write(Writer writer, File wd) throws Exception {
Serializer serializer = createSerializer(wd);
serializer.write(config, writer);
}
private Serializer createSerializer(File wd) throws Exception {
Registry registry = new Registry();
RelativeFileConverter fileConverter = new RelativeFileConverter(wd);
registry.bind(File.class, fileConverter);
registry.bind(Lib.class, new RelativeLibConverter(fileConverter));
Serializer serializer = new Persister(new RegistryStrategy(registry),
new PlatformFilter(config.properties), new Format(2));
return serializer;
}
}
private static final class Lib {
private final String value;
public Lib(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
private static final class RelativeLibConverter implements Converter {
private final RelativeFileConverter fileConverter;
public RelativeLibConverter(RelativeFileConverter fileConverter) {
this.fileConverter = fileConverter;
}
@Override
public Lib read(InputNode node) throws Exception {
String value = node.getValue();
if (value == null) {
return null;
}
if (value.endsWith(".a") || value.endsWith(".o")) {
return new Lib(fileConverter.read(value).getAbsolutePath());
} else {
return new Lib(value);
}
}
@Override
public void write(OutputNode node, Lib lib) throws Exception {
String value = lib.getValue();
if (value.endsWith(".a") || value.endsWith(".o")) {
fileConverter.write(node, new File(value));
} else {
node.setValue(value);
}
}
}
private static final class RelativeFileConverter implements Converter {
private final String wdPrefix;
public RelativeFileConverter(File wd) {
if (wd.isFile()) {
wd = wd.getParentFile();
}
String prefix = wd.getAbsolutePath();
if (!prefix.endsWith(File.separator)) {
prefix = prefix + File.separator;
}
wdPrefix = prefix;
}
File read(String value) {
if (value == null) {
return null;
}
File file = new File(value);
if (!file.isAbsolute()) {
file = new File(wdPrefix, value);
}
return file;
}
@Override
public File read(InputNode node) throws Exception {
return read(node.getValue());
}
@Override
public void write(OutputNode node, File value) throws Exception {
String path = value.getAbsolutePath();
if (path.startsWith(wdPrefix)) {
node.setValue(path.substring(wdPrefix.length()));
} else {
node.setValue(path);
}
}
}
}