use of org.bytedeco.javacpp.ClassProperties in project bigbluebutton by bigbluebutton.
the class Builder method build.
/**
* Starts the build process and returns an array of {@link File} produced.
*
* @return the array of File produced
* @throws IOException
* @throws InterruptedException
* @throws ParserException
*/
public File[] build() throws IOException, InterruptedException, ParserException {
if (classScanner.getClasses().isEmpty()) {
return null;
}
List<File> outputFiles = new ArrayList<File>();
Map<String, LinkedHashSet<Class>> map = new LinkedHashMap<String, LinkedHashSet<Class>>();
for (Class c : classScanner.getClasses()) {
if (Loader.getEnclosingClass(c) != c) {
continue;
}
ClassProperties p = Loader.loadProperties(c, properties, false);
if (!p.isLoaded()) {
logger.warn("Could not load platform properties for " + c);
continue;
}
String target = p.getProperty("target");
if (target != null && !c.getName().equals(target)) {
File f = parse(classScanner.getClassLoader().getPaths(), c);
if (f != null) {
outputFiles.add(f);
}
continue;
}
String libraryName = outputName != null ? outputName : p.getProperty("platform.library", "");
if (libraryName.length() == 0) {
continue;
}
LinkedHashSet<Class> classList = map.get(libraryName);
if (classList == null) {
map.put(libraryName, classList = new LinkedHashSet<Class>());
}
classList.addAll(p.getEffectiveClasses());
}
for (String libraryName : map.keySet()) {
LinkedHashSet<Class> classSet = map.get(libraryName);
Class[] classArray = classSet.toArray(new Class[classSet.size()]);
File f = generateAndCompile(classArray, libraryName);
if (f != null) {
outputFiles.add(f);
if (copyLibs) {
// Do not copy library files from inherit properties ...
ClassProperties p = Loader.loadProperties(classArray, properties, false);
List<String> preloads = new ArrayList<String>();
preloads.addAll(p.get("platform.preload"));
preloads.addAll(p.get("platform.link"));
// ... but we should use all the inherited paths!
p = Loader.loadProperties(classArray, properties, true);
File directory = f.getParentFile();
for (String s : preloads) {
URL[] urls = Loader.findLibrary(null, p, s, true);
File fi;
try {
fi = new File(urls[0].toURI());
} catch (Exception e) {
continue;
}
File fo = new File(directory, fi.getName());
if (fi.exists() && !outputFiles.contains(fo)) {
logger.info("Copying " + fi);
FileInputStream fis = new FileInputStream(fi);
FileOutputStream fos = new FileOutputStream(fo);
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) != -1) {
fos.write(buffer, 0, length);
}
fos.close();
fis.close();
outputFiles.add(fo);
}
}
}
}
}
File[] files = outputFiles.toArray(new File[outputFiles.size()]);
if (jarPrefix != null && files.length > 0) {
File jarFile = new File(jarPrefix + "-" + properties.get("platform") + ".jar");
File d = jarFile.getParentFile();
if (d != null && !d.exists()) {
d.mkdir();
}
createJar(jarFile, outputDirectory == null ? classScanner.getClassLoader().getPaths() : null, files);
}
// reset the load flag to let users load compiled libraries
System.setProperty("org.bytedeco.javacpp.loadlibraries", "true");
return files;
}
use of org.bytedeco.javacpp.ClassProperties in project javacpp by bytedeco.
the class Builder method build.
/**
* Starts the build process and returns an array of {@link File} produced.
*
* @return the array of File produced
* @throws IOException
* @throws InterruptedException
* @throws ParserException
*/
public File[] build() throws IOException, InterruptedException, ParserException {
if (buildCommand != null && buildCommand.length > 0) {
List<String> command = Arrays.asList(buildCommand);
String platform = Loader.getPlatform();
boolean windows = platform.startsWith("windows");
for (int i = 0; i < command.size(); i++) {
String arg = command.get(i);
if (arg == null) {
arg = "";
}
if (arg.trim().isEmpty() && windows) {
// seems to be the only way to pass empty arguments on Windows?
arg = "\"\"";
}
command.set(i, arg);
}
String text = "";
for (String s : command) {
boolean hasSpaces = s.indexOf(" ") > 0 || s.isEmpty();
if (hasSpaces) {
text += windows ? "\"" : "'";
}
text += s;
if (hasSpaces) {
text += windows ? "\"" : "'";
}
text += " ";
}
logger.info(text);
ProcessBuilder pb = new ProcessBuilder(command);
if (workingDirectory != null) {
pb.directory(workingDirectory);
}
if (environmentVariables != null) {
pb.environment().putAll(environmentVariables);
}
String paths = properties.getProperty("platform.buildpath", "");
String links = properties.getProperty("platform.linkresource", "");
String resources = properties.getProperty("platform.buildresource", "");
String separator = properties.getProperty("platform.path.separator");
if (paths.length() > 0 || resources.length() > 0) {
// Get all native libraries for classes on the class path.
List<String> libs = new ArrayList<String>();
ClassProperties libProperties = null;
for (Class c : classScanner.getClasses()) {
if (Loader.getEnclosingClass(c) != c) {
continue;
}
libProperties = Loader.loadProperties(c, properties, true);
if (!libProperties.isLoaded()) {
logger.warn("Could not load platform properties for " + c);
continue;
}
libs.addAll(libProperties.get("platform.preload"));
libs.addAll(libProperties.get("platform.link"));
}
// Extract the required resources.
for (String s : resources.split(separator)) {
for (File f : Loader.cacheResources(s)) {
String path = f.getCanonicalPath();
if (paths.length() > 0 && !paths.endsWith(separator)) {
paths += separator;
}
paths += path;
// Also create symbolic links for native libraries found there.
List<String> linkPaths = new ArrayList<String>();
for (String s2 : links.split(separator)) {
for (File f2 : Loader.cacheResources(s2)) {
String path2 = f2.getCanonicalPath();
if (path2.startsWith(path) && !path2.equals(path)) {
linkPaths.add(path2);
}
}
}
File[] files = f.listFiles();
if (files != null && libProperties != null) {
for (File file : files) {
Loader.createLibraryLink(file.getAbsolutePath(), libProperties, null, linkPaths.toArray(new String[linkPaths.size()]));
}
}
}
}
if (paths.length() > 0) {
pb.environment().put("BUILD_PATH", paths);
pb.environment().put("BUILD_PATH_SEPARATOR", separator);
}
}
int exitValue = pb.inheritIO().start().waitFor();
if (exitValue != 0) {
throw new RuntimeException("Process exited with an error: " + exitValue);
}
return null;
}
if (classScanner.getClasses().isEmpty()) {
return null;
}
List<File> outputFiles = new ArrayList<File>();
Map<String, LinkedHashSet<Class>> map = new LinkedHashMap<String, LinkedHashSet<Class>>();
for (Class c : classScanner.getClasses()) {
if (Loader.getEnclosingClass(c) != c) {
continue;
}
ClassProperties p = Loader.loadProperties(c, properties, false);
if (!p.isLoaded()) {
logger.warn("Could not load platform properties for " + c);
continue;
}
try {
if (Arrays.asList(c.getInterfaces()).contains(BuildEnabled.class)) {
((BuildEnabled) c.newInstance()).init(logger, properties, encoding);
}
} catch (ClassCastException | InstantiationException | IllegalAccessException e) {
// fail silently as if the interface wasn't implemented
}
String target = p.getProperty("target");
if (target != null && !c.getName().equals(target)) {
File f = parse(classScanner.getClassLoader().getPaths(), c);
if (f != null) {
outputFiles.add(f);
}
continue;
}
String libraryName = outputName != null ? outputName : p.getProperty("platform.library", "");
if (libraryName.length() == 0) {
continue;
}
LinkedHashSet<Class> classList = map.get(libraryName);
if (classList == null) {
map.put(libraryName, classList = new LinkedHashSet<Class>());
}
classList.addAll(p.getEffectiveClasses());
}
int count = 0;
for (String libraryName : map.keySet()) {
LinkedHashSet<Class> classSet = map.get(libraryName);
Class[] classArray = classSet.toArray(new Class[classSet.size()]);
File[] files = generateAndCompile(classArray, libraryName, count == 0, count == map.size() - 1);
if (files != null && files.length > 0) {
// files[0] might be null if "jnijavacpp" was not generated and compiled
File directory = files[files.length - 1].getParentFile();
outputFiles.addAll(Arrays.asList(files));
if (copyLibs) {
// Do not copy library files from inherit properties ...
ClassProperties p = Loader.loadProperties(classArray, properties, false);
List<String> preloads = new ArrayList<String>();
preloads.addAll(p.get("platform.preload"));
preloads.addAll(p.get("platform.link"));
// ... but we should try to use all the inherited paths!
ClassProperties p2 = Loader.loadProperties(classArray, properties, true);
for (String s : preloads) {
if (s.trim().endsWith("#")) {
// the user specified an empty destination to skip the copy
continue;
}
URL[] urls = Loader.findLibrary(null, p, s);
File fi;
try {
fi = new File(urls[0].toURI());
} catch (Exception e) {
// try with inherited paths as well
urls = Loader.findLibrary(null, p2, s);
try {
fi = new File(urls[0].toURI());
} catch (Exception e2) {
logger.warn("Could not find library " + s);
continue;
}
}
File fo = new File(directory, fi.getName());
if (fi.exists() && !outputFiles.contains(fo)) {
logger.info("Copying " + fi);
FileInputStream fis = new FileInputStream(fi);
FileOutputStream fos = new FileOutputStream(fo);
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) != -1) {
fos.write(buffer, 0, length);
}
fos.close();
fis.close();
outputFiles.add(fo);
}
}
}
if (copyResources) {
// Do not copy resources from inherit properties ...
ClassProperties p = Loader.loadProperties(classArray, properties, false);
List<String> resources = p.get("platform.resource");
// ... but we should use all the inherited paths!
p = Loader.loadProperties(classArray, properties, true);
List<String> paths = p.get("platform.resourcepath");
Path directoryPath = directory.toPath();
for (String resource : resources) {
final Path target = directoryPath.resolve(resource);
if (!Files.exists(target)) {
Files.createDirectories(target);
}
for (String path : paths) {
final Path source = Paths.get(path, resource);
if (Files.exists(source)) {
logger.info("Copying " + source);
Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
Path targetdir = target.resolve(source.relativize(dir));
try {
Files.copy(dir, targetdir, StandardCopyOption.REPLACE_EXISTING);
} catch (DirectoryNotEmptyException | FileAlreadyExistsException e) {
if (!Files.isDirectory(targetdir)) {
throw e;
}
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.copy(file, target.resolve(source.relativize(file)), StandardCopyOption.REPLACE_EXISTING);
return FileVisitResult.CONTINUE;
}
});
}
}
}
}
}
count++;
}
File[] files = outputFiles.toArray(new File[outputFiles.size()]);
if (jarPrefix != null && files.length > 0) {
File jarFile = new File(jarPrefix + "-" + properties.getProperty("platform") + properties.getProperty("platform.extension", "") + ".jar");
File d = jarFile.getParentFile();
if (d != null && !d.exists()) {
d.mkdir();
}
createJar(jarFile, outputDirectory == null ? classScanner.getClassLoader().getPaths() : null, files);
}
// reset the load flag to let users load compiled libraries
System.setProperty("org.bytedeco.javacpp.loadlibraries", "true");
return files;
}
use of org.bytedeco.javacpp.ClassProperties in project bigbluebutton by bigbluebutton.
the class Builder method generateAndCompile.
/**
* Generates a C++ source file for classes, and compiles everything in
* one shared library when {@code compile == true}.
*
* @param classes the Class objects as input to Generator
* @param outputName the output name of the shared library
* @return the actual File generated, either the compiled library or its source
* @throws IOException
* @throws InterruptedException
*/
File generateAndCompile(Class[] classes, String outputName) throws IOException, InterruptedException {
File outputFile = null, outputPath = outputDirectory;
ClassProperties p = Loader.loadProperties(classes, properties, true);
String platform = p.getProperty("platform");
String sourcePrefix = new File(outputPath, outputName).getPath();
String sourceSuffix = p.getProperty("platform.source.suffix", ".cpp");
String libraryPath = p.getProperty("platform.library.path", "");
String libraryName = p.getProperty("platform.library.prefix", "") + outputName + p.getProperty("platform.library.suffix", "");
if (outputPath == null) {
URI uri = null;
try {
String resourceName = '/' + classes[classes.length - 1].getName().replace('.', '/') + ".class";
String resourceURL = classes[classes.length - 1].getResource(resourceName).toString();
File packageDir = new File(uri = new URI(resourceURL.substring(0, resourceURL.lastIndexOf('/') + 1)));
File targetDir = libraryPath.length() > 0 ? new File(uri = new URI(resourceURL.substring(0, resourceURL.length() - resourceName.length() + 1))) : new File(packageDir, platform);
outputPath = new File(targetDir, libraryPath);
sourcePrefix = new File(packageDir, outputName).getPath();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e + ": " + uri);
}
}
if (!outputPath.exists()) {
outputPath.mkdirs();
}
Generator generator = new Generator(logger, p);
String sourceFilename = sourcePrefix + sourceSuffix;
String headerFilename = header ? sourcePrefix + ".h" : null;
String classPath = System.getProperty("java.class.path");
for (String s : classScanner.getClassLoader().getPaths()) {
classPath += File.pathSeparator + s;
}
logger.info("Generating " + sourceFilename);
if (generator.generate(sourceFilename, headerFilename, classPath, classes)) {
generator.close();
if (compile) {
logger.info("Compiling " + outputPath.getPath() + File.separator + libraryName);
int exitValue = compile(sourceFilename, libraryName, p, outputPath);
if (exitValue == 0) {
if (deleteJniFiles) {
logger.info("Deleting " + sourceFilename);
new File(sourceFilename).delete();
} else {
logger.info("Keeping " + sourceFilename);
}
outputFile = new File(outputPath, libraryName);
} else {
System.exit(exitValue);
}
} else {
outputFile = new File(sourceFilename);
}
} else {
logger.info("Nothing generated for " + sourceFilename);
}
return outputFile;
}
use of org.bytedeco.javacpp.ClassProperties in project bigbluebutton by bigbluebutton.
the class Generator method checkPlatform.
boolean checkPlatform(Class<?> cls) {
// check in priority this class for platform information, before the enclosing class
Class<?> enclosingClass = Loader.getEnclosingClass(cls);
while (!cls.isAnnotationPresent(org.bytedeco.javacpp.annotation.Properties.class) && !cls.isAnnotationPresent(Platform.class) && cls.getSuperclass() != null) {
if (enclosingClass != null && cls.getSuperclass() == Object.class) {
cls = enclosingClass;
enclosingClass = null;
} else {
cls = cls.getSuperclass();
}
}
org.bytedeco.javacpp.annotation.Properties classProperties = cls.getAnnotation(org.bytedeco.javacpp.annotation.Properties.class);
if (classProperties != null) {
Class[] classes = classProperties.inherit();
// get default platform names, searching in inherited classes as well
String[] defaultNames = classProperties.names();
Deque<Class> queue = new ArrayDeque<Class>(Arrays.asList(classes));
while (queue.size() > 0 && (defaultNames == null || defaultNames.length == 0)) {
Class<?> c = queue.removeFirst();
org.bytedeco.javacpp.annotation.Properties p = c.getAnnotation(org.bytedeco.javacpp.annotation.Properties.class);
if (p != null) {
defaultNames = p.names();
queue.addAll(Arrays.asList(p.inherit()));
}
}
// check in priority the platforms inside our properties annotation, before inherited ones
Platform[] platforms = classProperties.value();
if (platforms != null) {
for (Platform p : platforms) {
if (checkPlatform(p, defaultNames)) {
return true;
}
}
} else if (classes != null) {
for (Class c : classes) {
if (checkPlatform(c)) {
return true;
}
}
}
} else if (checkPlatform(cls.getAnnotation(Platform.class), null)) {
return true;
}
return false;
}
use of org.bytedeco.javacpp.ClassProperties in project bigbluebutton by bigbluebutton.
the class Parser method parse.
public File parse(File outputDirectory, String[] classPath, Class cls) throws IOException, ParserException {
ClassProperties allProperties = Loader.loadProperties(cls, properties, true);
ClassProperties clsProperties = Loader.loadProperties(cls, properties, false);
// Capture c-includes from "class" and "all" properties
List<String> cIncludes = new ArrayList<>();
cIncludes.addAll(clsProperties.get("platform.cinclude"));
cIncludes.addAll(allProperties.get("platform.cinclude"));
// Capture class includes
List<String> clsIncludes = new ArrayList<String>();
clsIncludes.addAll(clsProperties.get("platform.include"));
clsIncludes.addAll(clsProperties.get("platform.cinclude"));
// Capture all includes
List<String> allIncludes = new ArrayList<String>();
allIncludes.addAll(allProperties.get("platform.include"));
allIncludes.addAll(allProperties.get("platform.cinclude"));
List<String> allTargets = allProperties.get("target");
List<String> clsTargets = clsProperties.get("target");
List<String> clsHelpers = clsProperties.get("helper");
// there can only be one
String target = clsTargets.get(0);
List<Class> allInherited = allProperties.getInheritedClasses();
infoMap = new InfoMap();
for (Class c : allInherited) {
try {
((InfoMapper) c.newInstance()).map(infoMap);
} catch (ClassCastException | InstantiationException | IllegalAccessException e) {
// fail silently as if the interface wasn't implemented
}
}
leafInfoMap = new InfoMap();
try {
((InfoMapper) cls.newInstance()).map(leafInfoMap);
} catch (ClassCastException | InstantiationException | IllegalAccessException e) {
// fail silently as if the interface wasn't implemented
}
infoMap.putAll(leafInfoMap);
String version = Generator.class.getPackage().getImplementationVersion();
if (version == null) {
version = "unknown";
}
String text = "// Targeted by JavaCPP version " + version + ": DO NOT EDIT THIS FILE\n\n";
int n = target.lastIndexOf('.');
if (n >= 0) {
text += "package " + target.substring(0, n) + ";\n\n";
}
List<Info> infoList = leafInfoMap.get(null);
for (Info info : infoList) {
if (info.javaText != null && info.javaText.startsWith("import")) {
text += info.javaText + "\n";
}
}
text += "import java.nio.*;\n" + "import org.bytedeco.javacpp.*;\n" + "import org.bytedeco.javacpp.annotation.*;\n\n";
for (String s : allTargets) {
if (!target.equals(s)) {
text += "import static " + s + ".*;\n";
}
}
if (allTargets.size() > 1) {
text += "\n";
}
text += "public class " + target.substring(n + 1) + " extends " + (clsHelpers.size() > 0 && clsIncludes.size() > 0 ? clsHelpers.get(0) : cls.getCanonicalName()) + " {\n" + " static { Loader.load(); }\n";
String targetPath = target.replace('.', File.separatorChar);
File targetFile = new File(outputDirectory, targetPath + ".java");
logger.info("Targeting " + targetFile);
Context context = new Context();
context.infoMap = infoMap;
String[] includePath = classPath;
n = targetPath.lastIndexOf(File.separatorChar);
if (n >= 0) {
includePath = classPath.clone();
for (int i = 0; i < includePath.length; i++) {
includePath[i] += File.separator + targetPath.substring(0, n);
}
}
List<String> paths = allProperties.get("platform.includepath");
String[] includePaths = paths.toArray(new String[paths.size() + includePath.length]);
System.arraycopy(includePath, 0, includePaths, paths.size(), includePath.length);
DeclarationList declList = new DeclarationList();
for (String include : allIncludes) {
if (!clsIncludes.contains(include)) {
boolean isCFile = cIncludes.contains(include);
parse(context, declList, includePaths, include, isCFile);
}
}
declList = new DeclarationList(declList);
if (clsIncludes.size() > 0) {
containers(context, declList);
for (String include : clsIncludes) {
if (allIncludes.contains(include)) {
boolean isCFile = cIncludes.contains(include);
parse(context, declList, includePaths, include, isCFile);
}
}
}
final String newline = lineSeparator != null ? lineSeparator : "\n";
try (Writer out = new FileWriter(targetFile) {
@Override
public Writer append(CharSequence text) throws IOException {
return super.append(((String) text).replace("\n", newline).replace("\\u", "\\u005Cu"));
}
}) {
out.append(text);
for (Info info : infoList) {
if (info.javaText != null && !info.javaText.startsWith("import")) {
out.append(info.javaText + "\n");
}
}
for (Declaration d : declList) {
out.append(d.text);
}
out.append("\n}\n").close();
}
return targetFile;
}
Aggregations