Skip to content

Commit

Permalink
Released version 0.6
Browse files Browse the repository at this point in the history
 * Added new very preliminary `Parser` to produce Java interface files almost automatically from C/C++ header files; please refer to the new JavaCPP Presets subproject for details
  • Loading branch information
saudet committed Sep 15, 2013
1 parent 605e77b commit 55b2a62
Show file tree
Hide file tree
Showing 25 changed files with 1,651 additions and 10 deletions.
9 changes: 7 additions & 2 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
==Introduction==
JavaCPP provides efficient access to native C++ inside Java, not unlike the way some C/C++ compilers interact with assembly language. No need to invent new languages such as [http://www.ecma-international.org/publications/standards/Ecma-372.htm C++/CLI] or [http://www.cython.org/ Cython]. Under the hood, it uses JNI, so it works with all Java implementations, [#Instructions_for_Android including Android]. In contrast to other approaches ([http://www.swig.org/ SWIG], [http://www.itk.org/ITK/resources/CableSwig.html CableSwig], [http://www.eclipse.org/swt/jnigen.php JNIGeneratorApp], [http://www.teamdev.com/jniwrapper/ JNIWrapper], [http://msdn.microsoft.com/en-us/library/0h9e9t7d.aspx Platform Invoke], [http://jogamp.org/gluegen/www/ GlueGen], [http://homepage.mac.com/pcbeard/JNIDirect/ JNIDirect], [https://github.com/twall/jna JNA], [http://www.innowhere.com/ JNIEasy], [http://flinflon.brandonu.ca/Dueck/SystemsProgramming/JniMarshall/ JniMarshall], [http://jnative.free.fr/ JNative], [http://www.jinvoke.com/ J/Invoke], [http://hawtjni.fusesource.org/ HawtJNI], [http://code.google.com/p/bridj/ BridJ], etc.), it supports naturally and efficiently many features of the C++ language often considered problematic, including overloaded operators, template classes and functions, member function pointers, callback functions, functors, nested struct definitions, variable length arguments, nested namespaces, large data structures containing arbitrary cycles, multiple inheritance, passing/returning by value/reference/vector, anonymous unions, bit fields, exceptions, destructors and garbage collection. Obviously, neatly supporting the whole of C++ would require more work (although one could argue about the intrinsic neatness of C++), but I am releasing it here as a proof of concept. I have already used it to produce complete interfaces to OpenCV, FFmpeg, libdc1394, PGR FlyCapture, OpenKinect, videoInput, and ARToolKitPlus as part of [http://code.google.com/p/javacv/ JavaCV].

The new [http://code.google.com/p/javacpp/source/browse/?repo=presets JavaCPP Presets] subproject also demonstrates early parsing capabilities of C/C++ header files that already show promising and useful results with at least FFmpeg and libdc1394.


==Required Software==
To use JavaCPP, you will need to download and install the following software:
Expand Down Expand Up @@ -53,7 +55,7 @@ namespace LegacyLibrary {
}
}}}

To get the job done with JavaCPP, we can easily define a Java class such as this one (although having an IDE generate that code for us would be even better):
To get the job done with JavaCPP, we can easily define a Java class such as this one--although one could use the `Parser` to produce it from the header file as demonstrated by the [http://code.google.com/p/javacpp/source/browse/?repo=presets JavaCPP Presets] subproject:
{{{
import com.googlecode.javacpp.*;
import com.googlecode.javacpp.annotation.*;
Expand Down Expand Up @@ -283,6 +285,9 @@ This project was conceived at the Okutomi & Tanaka Laboratory, Tokyo Institute o


==Changes==

===September 15, 2013 version 0.6===
* Added new very preliminary `Parser` to produce Java interface files almost automatically from C/C++ header files; please refer to the new JavaCPP Presets subproject for details
* When catching a C++ exception, the first class declared after `throws` now gets thrown (issue #36) instead of `RuntimeException`, which is still used by default
* Fixed Java resource leak after catching a C++ exception
* Upgraded references of the Android NDK to version r9
Expand All @@ -291,7 +296,7 @@ This project was conceived at the Okutomi & Tanaka Laboratory, Tokyo Institute o
* Refactored the loading code for `@Properties()` into a neat `Loader.ClassProperties` class, among a few other small changes in `Loader`, `Builder`, `Generator`, and the properties
* Included often used directories such as `/usr/local/include/` and `/usr/local/lib/` to `compiler.includepath` and `compiler.linkpath` default properties
* New `@Properties(inherit={Class})` value lets users specify properties in common on a similarly annotated shared config class of sorts
* Fixed callbacks when used with custom class loaders such as with Web containers
* Fixed callbacks when used with custom class loaders such as with Web containers or frameworks like Tomcat and Play
* Fixed using `@StdString` (or other `@Adapter` with `@Cast` annotations) on callbacks (issue #34), incidentally allowing them to return a `String`
* By default, `Builder` now links to the `jvm` library only when required, when using the `-header` command line option (issue #33)
* Incorporated missing explicit cast on return values when using the `@Cast` annotation
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.googlecode.javacpp</groupId>
<artifactId>javacpp</artifactId>
<version>0.5</version>
<version>0.6</version>
<packaging>maven-plugin</packaging>

<name>JavaCPP</name>
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/com/googlecode/javacpp/BuildMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import org.apache.maven.plugin.MojoExecutionException;

/**
* A Maven Mojo to call the {@link Builder} (Java class -> C++ JNI -> native library).
* A Maven Mojo to call the {@link Builder} (C++ header file -> Java class -> C++ JNI -> native library).
* Can also be seen as an example of how to use the Builder programmatically.
*
* @goal build
Expand Down Expand Up @@ -128,6 +128,12 @@ public class BuildMojo extends AbstractMojo {
*/
private String[] compilerOptions = null;

/**
* Skip the execution.
* @parameter expression="${skip}" default-value="false"
*/
private boolean skip = false;

@Override public void execute() throws MojoExecutionException {
try {
getLog().info("Executing JavaCPP Builder");
Expand All @@ -147,6 +153,12 @@ public class BuildMojo extends AbstractMojo {
getLog().debug("classOrPackageNames: " + Arrays.deepToString(classOrPackageNames));
getLog().debug("environmentVariables: " + environmentVariables);
getLog().debug("compilerOptions: " + Arrays.deepToString(compilerOptions));
getLog().debug("skip: " + skip);
}

if (skip) {
getLog().info("Skipped execution of JavaCPP Builder");
return;
}

if (classPaths != null && classPath != null) {
Expand Down
42 changes: 37 additions & 5 deletions src/main/java/com/googlecode/javacpp/Builder.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,30 @@
*/
public class Builder {

/**
* Calls {@link Parser#parse(File, Class)} after creating an instance of the
* Class and running {@link Parser.InfoMapper#map(Parser.InfoMap)}.
*
* @param cls The class annotated with {@link com.googlecode.javacpp.annotation.Properties}
* and implementing {@link Parser.InfoMapper}
* @return the target File produced
* @throws IOException on Java target file writing error
* @throws Parser.Exception on C/C++ header file parsing error
*/
public File parse(Class cls) throws IOException, Parser.Exception {
Parser.InfoMap infoMap = new Parser.InfoMap();
try {
Object obj = cls.newInstance();
if (obj instanceof Parser.InfoMapper) {
((Parser.InfoMapper)obj).map(infoMap);
}
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
// fail silently as if the interface wasn't implemented
}
return new Parser(properties, infoMap).parse(outputDirectory, cls);
}

/**
* Tries to find automatically include paths for {@code jni.h} and {@code jni_md.h},
* as well as the link and library paths for the {@code jvm} library.
Expand Down Expand Up @@ -201,7 +225,7 @@ public int compile(String sourceFilename, String outputFilename, Loader.ClassPro
command.add(sourceFilename);

Collection<String> allOptions = properties.get("compiler.options");
if (allOptions.isEmpty() && properties.getProperty("compiler.options.default") != null) {
if (allOptions.isEmpty()) {
allOptions.add("default");
}
for (String s : allOptions) {
Expand All @@ -210,10 +234,10 @@ public int compile(String sourceFilename, String outputFilename, Loader.ClassPro
}
String p = "compiler.options." + s;
String options = properties.getProperty(p);
if (options == null || options.length() == 0) {
System.err.println("Warning: Could not get the property named \"" + p + "\"");
} else {
if (options != null && options.length() > 0) {
command.addAll(Arrays.asList(options.split(" ")));
} else if (!"default".equals(s)) {
System.err.println("Warning: Could not get the property named \"" + p + "\"");
}
}

Expand Down Expand Up @@ -729,7 +753,7 @@ public Builder compilerOptions(String ... options) {
* @throws IOException
* @throws InterruptedException
*/
public File[] build() throws IOException, InterruptedException {
public File[] build() throws IOException, InterruptedException, Parser.Exception {
if (classScanner.getClasses().isEmpty()) {
return null;
}
Expand All @@ -741,6 +765,14 @@ public File[] build() throws IOException, InterruptedException {
continue;
}
Loader.ClassProperties p = Loader.loadProperties(c, properties, false);
String target = p.getProperty("parser.target");
if (target != null && !c.getName().equals(target)) {
File f = parse(c);
if (f != null) {
outputFiles.add(f);
}
continue;
}
String libraryName = outputName != null ? outputName : p.getProperty("loader.library", "");
if (libraryName.length() == 0) {
continue;
Expand Down
35 changes: 35 additions & 0 deletions src/main/java/com/googlecode/javacpp/Loader.java
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,10 @@ public String setProperty(String key, String value) {

public void load(Class cls, boolean inherit) {
Class<?> c = getEnclosingClass(cls);
while (!c.isAnnotationPresent(com.googlecode.javacpp.annotation.Properties.class)
&& !c.isAnnotationPresent(Platform.class) && c.getSuperclass() != null) {
c = c.getSuperclass();
}
com.googlecode.javacpp.annotation.Properties classProperties =
c.getAnnotation(com.googlecode.javacpp.annotation.Properties.class);
Platform[] platforms;
Expand All @@ -273,6 +277,10 @@ public void load(Class cls, boolean inherit) {
load(c2, inherit);
}
}
String target = classProperties.target();
if (target.length() > 0) {
addAll("parser.target", target);
}
platforms = classProperties.value();
if (platforms == null) {
return;
Expand Down Expand Up @@ -319,6 +327,33 @@ public void load(Class cls, boolean inherit) {
addAll("loader.preload", preload);
setProperty("loader.library", library);
}

LinkedList<File> getHeaderFiles() {
LinkedList<String> paths = get("compiler.includepath");
LinkedList<String> includes = new LinkedList<String>();
includes.addAll(get("generator.include"));
includes.addAll(get("generator.cinclude"));
LinkedList<File> files = new LinkedList<File>();
for (String include : includes) {
if (include.startsWith("<") && include.endsWith(">")) {
include = include.substring(1, include.length() - 1);
} else {
File f = new File(include);
if (f.exists()) {
files.add(f);
continue;
}
}
for (String path : paths) {
File f = new File(path, include);
if (f.exists()) {
files.add(f);
break;
}
}
}
return files;
}
}

/**
Expand Down
Loading

0 comments on commit 55b2a62

Please sign in to comment.