private void copyJniHeaders (String jniDir) { final String pack = "com/badlogic/gdx/jnigen/resources/headers"; String files[] = {"classfile_constants.h", "jawt.h", "jdwpTransport.h", "jni.h", "linux/jawt_md.h", "linux/jni_md.h", "mac/jni_md.h", "win32/jawt_md.h", "win32/jni_md.h"}; for (String file : files) { new FileDescriptor(pack, FileType.Classpath).child(file).copyTo( new FileDescriptor(jniDir).child("jni-headers").child(file)); } }
static private void copyDirectory (FileDescriptor sourceDir, FileDescriptor destDir) { destDir.mkdirs(); FileDescriptor[] files = sourceDir.list(); for (int i = 0, n = files.length; i < n; i++) { FileDescriptor srcFile = files[i]; FileDescriptor destFile = destDir.child(srcFile.name()); if (srcFile.isDirectory()) copyDirectory(srcFile, destFile); else copyFile(srcFile, destFile); } } }
/** Moves this file to the specified file, overwriting the file if it already exists. * @throw RuntimeException if the source or destination file handle is a {@link FileType#Classpath} or FileType#Internal file. */ public void moveTo (FileDescriptor dest) { if (type == FileType.Classpath) throw new RuntimeException("Cannot move a classpath file: " + file); copyTo(dest); delete(); }
/** Deletes this file or directory and all children, recursively. * @throw RuntimeException if this file handle is a {@link FileType#Classpath} or FileType#Internal file. */ public boolean deleteDirectory () { if (type == FileType.Classpath) throw new RuntimeException("Cannot delete a classpath file: " + file); return deleteDirectory(file()); }
private void processDirectory (FileDescriptor dir) throws Exception { FileDescriptor[] files = dir.list(); for (FileDescriptor file : files) { if (file.isDirectory()) { if (file.path().contains(".svn")) continue; if (excludes != null && matcher.match(file.path(), excludes)) continue; processDirectory(file); } else { if (file.extension().equals("java")) { if (file.name().contains("NativeCodeGenerator")) continue; if (includes != null && !matcher.match(file.path(), includes)) continue; if (excludes != null && matcher.match(file.path(), excludes)) continue; String className = getFullyQualifiedClassName(file); FileDescriptor hFile = new FileDescriptor(jniDir.path() + "/" + className + ".h"); FileDescriptor cppFile = new FileDescriptor(jniDir + "/" + className + ".cpp"); if (file.lastModified() < cppFile.lastModified()) { System.out.println("C/C++ for '" + file.path() + "' up to date"); continue; String javaContent = file.readString(); if (javaContent.contains(JNI_METHOD_MARKER)) { ArrayList<JavaSegment> javaSegments = javaMethodParser.parse(javaContent);
if (!config.libsDir.exists()) { if (!config.libsDir.mkdirs()) throw new RuntimeException("Couldn't create directory for shared library files in '" + config.libsDir + "'"); if (!config.jniDir.exists()) { if (!config.jniDir.mkdirs()) throw new RuntimeException("Couldn't create native code directory '" + config.jniDir + "'"); FileDescriptor application = config.jniDir.child("Application.mk"); application.writeString(new FileDescriptor("com/badlogic/gdx/jnigen/resources/scripts/Application.mk.template", FileType.Classpath).readString(), false); String template = new FileDescriptor("com/badlogic/gdx/jnigen/resources/scripts/Android.mk.template", FileType.Classpath) .readString(); srcFiles.append(files.get(i).path().replace('\\', '/').replace(config.jniDir.toString() + "/", "")); if (i < files.size() - 1) srcFiles.append("\\\n"); template = template.replace("%srcFiles%", srcFiles); config.jniDir.child("Android.mk").writeString(template, false);
if (!config.libsDir.exists()) { if (!config.libsDir.mkdirs()) throw new RuntimeException("Couldn't create directory for shared library files in '" + config.libsDir + "'"); if (!config.jniDir.exists()) { if (!config.jniDir.mkdirs()) throw new RuntimeException("Couldn't create native code directory '" + config.jniDir + "'"); copyJniHeaders(config.jniDir.path()); if (config.jniDir.child("memcpy_wrap.c").exists() == false) { new FileDescriptor("com/badlogic/gdx/jnigen/resources/scripts/memcpy_wrap.c", FileType.Classpath).copyTo(config.jniDir .child("memcpy_wrap.c")); FileDescriptor libsDir = new FileDescriptor(getLibsDirectory(config, target)); if (!libsDir.exists()) { if (!libsDir.mkdirs()) throw new RuntimeException("Couldn't create libs directory '" + libsDir + "'"); config.jniDir.child(buildFileName).writeString(buildFile, false); System.out.println("Wrote target '" + target.os + (target.is64Bit ? "64" : "") + "' build script '" + config.jniDir.child(buildFileName) + "'"); libsDirs.add("../" + libsDir.path().replace('\\', '/')); String template = new FileDescriptor("com/badlogic/gdx/jnigen/resources/scripts/build.xml.template", FileType.Classpath) .readString(); StringBuilder clean = new StringBuilder(); StringBuilder compile = new StringBuilder();
/** Copies this file or directory to the specified file or directory. If this handle is a file, then 1) if the destination is a * file, it is overwritten, or 2) if the destination is a directory, this file is copied into it, or 3) if the destination * doesn't exist, {@link #mkdirs()} is called on the destination's parent and this file is copied into it with a new name. If * this handle is a directory, then 1) if the destination is a file, RuntimeException is thrown, or 2) if the destination is a * directory, this directory is copied recursively into it as a subdirectory, overwriting existing files, or 3) if the * destination doesn't exist, {@link #mkdirs()} is called on the destination and this directory is copied recursively into it * as a subdirectory. * @throw RuntimeException if the destination file handle is a {@link FileType#Classpath} or FileType#Internal file, or copying * failed. */ public void copyTo (FileDescriptor dest) { if (!isDirectory()) { if (dest.isDirectory()) dest = dest.child(name()); copyFile(this, dest); return; } if (dest.exists()) { if (!dest.isDirectory()) throw new RuntimeException("Destination exists but is not a directory: " + dest); } else { dest.mkdirs(); if (!dest.isDirectory()) throw new RuntimeException("Destination directory cannot be created: " + dest); } dest = dest.child(name()); copyDirectory(this, dest); }
/** Returns a stream for writing to this file. Parent directories will be created if necessary. * @param append If false, this file will be overwritten if it exists, otherwise it will be appended. * @throw RuntimeException if this file handle represents a directory, if it is a {@link FileType#Classpath} or * FileType#Internal file, or if it could not be written. */ public OutputStream write (boolean append) { if (type == FileType.Classpath) throw new RuntimeException("Cannot write to a classpath file: " + file); parent().mkdirs(); try { return new FileOutputStream(file(), append); } catch (FileNotFoundException ex) { if (file().isDirectory()) throw new RuntimeException("Cannot open a stream to a directory: " + file + " (" + type + ")", ex); throw new RuntimeException("Error writing file: " + file + " (" + type + ")", ex); } }
int lineNumber = getLineNumber(line) - 1; if (fileName != null && lineNumber >= 0) { FileDescriptor file = new FileDescriptor(fileName); if (file.exists()) { String[] content = file.readString().split("\n"); if (lineNumber < content.length) { for (int i = lineNumber; i >= 0; i--) { System.out.flush(); if (line.contains("warning")) { System.out.println("(" + file.nameWithoutExtension() + ".java:" + (javaLineNumber + (lineNumber - i) - 1) + "): " + error + ", original: " + line); System.out.flush(); } else { System.err.println("(" + file.nameWithoutExtension() + ".java:" + (javaLineNumber + (lineNumber - i) - 1) + "): " + error + ", original: " + line); System.err.flush();
String template = new FileDescriptor("com/badlogic/gdx/jnigen/resources/scripts/build-android.xml.template", FileType.Classpath).readString(); template = template.replace("%precompile%", target.preCompileTask == null ? "" : target.preCompileTask); template = template.replace("%postcompile%", target.postCompileTask == null ? "" : target.postCompileTask); template = new FileDescriptor("com/badlogic/gdx/jnigen/resources/scripts/build-ios.xml.template", FileType.Classpath) .readString(); } else { template = new FileDescriptor("com/badlogic/gdx/jnigen/resources/scripts/build-target.xml.template", FileType.Classpath) .readString(); template = template.replace("%buildDir%", config.buildDir.child(targetFolder).path().replace('\\', '/')); template = template.replace("%libsDir%", "../" + getLibsDirectory(config, target)); template = template.replace("%libName%", libName);
/** Execute the Ant script file with the given parameters. * @param buildFile * @param params * @return whether the Ant succeeded */ public static boolean executeAnt (String buildFile, String params) { FileDescriptor build = new FileDescriptor(buildFile); String ant = System.getProperty("os.name").contains("Windows") ? "ant.bat" : "ant"; String command = ant + " -f \"" + build.file().getAbsolutePath() + "\" " + params; System.out.println("Executing '" + command + "'"); return startProcess(command, build.parent().file()); }
/** Generates .h/.cpp fiels from the Java files found in <code>sourceDir</code>, with their .class files being in * <code>classpath</code>. The generated files will be stored in <code>jniDir</code>. The <code>includes</code> and * <code>excludes</code> parameters allow to specify directories and files that should be included/excluded from the * generation. These can be given in the Ant path format. All paths are relative to the applications working directory. * @param sourceDir the directory containing the Java files * @param classpath the directory containing the .class files * @param jniDir the output directory * @param includes files/directories to include, can be null (all files are used) * @param excludes files/directories to exclude, can be null (no files are excluded) * @throws Exception */ public void generate (String sourceDir, String classpath, String jniDir, String[] includes, String[] excludes) throws Exception { this.sourceDir = new FileDescriptor(sourceDir); this.jniDir = new FileDescriptor(jniDir); this.classpath = classpath; this.includes = includes; this.excludes = excludes; // check if source directory exists if (!this.sourceDir.exists()) { throw new Exception("Java source directory '" + sourceDir + "' does not exist"); } // generate jni directory if necessary if (!this.jniDir.exists()) { if (!this.jniDir.mkdirs()) { throw new Exception("Couldn't create JNI directory '" + jniDir + "'"); } } // process the source directory, emitting c/c++ files to jniDir processDirectory(this.sourceDir); }
/** Returns the paths to the children of this directory. Returns an empty list if this file handle represents a file and not a * directory. On the desktop, an FileType#Internal handle to a directory on the classpath will return a zero length array. * @throw RuntimeException if this file is an {@link FileType#Classpath} file. */ public FileDescriptor[] list () { if (type == FileType.Classpath) throw new RuntimeException("Cannot list a classpath directory: " + file); String[] relativePaths = file().list(); if (relativePaths == null) return new FileDescriptor[0]; FileDescriptor[] handles = new FileDescriptor[relativePaths.length]; for (int i = 0, n = relativePaths.length; i < n; i++) handles[i] = child(relativePaths[i]); return handles; }
/** Returns true if this file is a directory. Always returns false for classpath files. On Android, an FileType#Internal handle * to an empty directory will return false. On the desktop, an FileType#Internal handle to a directory on the classpath will * return false. */ public boolean isDirectory () { if (type == FileType.Classpath) return false; return file().isDirectory(); }
/** Creates a new BuildConfig. The build directory, the libs directory and the jni directory are assumed to be "target", "libs" * and "jni". All paths are relative to the application's working directory. * @param sharedLibName the shared library name, without prefix or suffix, e.g. 'gdx', 'bullet' */ public BuildConfig (String sharedLibName) { this.sharedLibName = sharedLibName; this.buildDir = new FileDescriptor("target"); this.libsDir = new FileDescriptor("libs"); this.jniDir = new FileDescriptor("jni"); }
/** Execute ndk-build in the given directory * @param directory */ public static void executeNdk (String directory) { FileDescriptor build = new FileDescriptor(directory); String command = "ndk-build"; startProcess(command, build.file()); }
/** Returns the length in bytes of this file, or 0 if this file is a directory, does not exist, or the size cannot otherwise be * determined. */ public long length () { if (type == FileType.Classpath || !file.exists()) { InputStream input = read(); try { return input.available(); } catch (Exception ignored) { } finally { try { input.close(); } catch (IOException ignored) { } } return 0; } return file().length(); }
static private boolean deleteDirectory (File file) { if (file.exists()) { File[] files = file.listFiles(); if (files != null) { for (int i = 0, n = files.length; i < n; i++) { if (files[i].isDirectory()) deleteDirectory(files[i]); else files[i].delete(); } } } return file.delete(); }