Skip to content
nyabkun edited this page Jun 8, 2022 · 6 revisions

A guide on how to run JavaCPP together with Maven 2 or 3.

Created Mar 1, 2012 by adam.waldenberg

Introduction

JavaCPP has been uploaded to the Central Repository at https://oss.sonatype.org/content/groups/public/org/bytedeco/javacpp/ , so we do not need to specify an additional repository on top of the dependency and settings of JavaCPP itself.

Getting Started

To use JavaCPP with a Maven project, add the following sections to the project's pom.xml file:

<dependencies>
  <dependency>
    <groupId>org.bytedeco.javacpp</groupId>
    <artifactId>javacpp</artifactId>
    <version>0.10</version>
  </dependency>
</dependencies>

After adding this (and letting Maven download), we should be able to access JavaCPP classes and annotations.

Running JavaCPP at Build Time

To build the native bindings, we also need to execute JavaCPP from within the Maven lifecycle, This can be accomplished by using the Maven dependency and exec plugins, or alternatively with the built-in mojo plugin of JavaCPP.

Running with the JavaCPP build plugin

To use the built in JavaCPP plugin add this to your pom file

<plugin>
  <groupId>org.bytedeco</groupId>
  <artifactId>javacpp</artifactId>
  <version>${project.parent.version}</version>
  <configuration>
    <properties>${javacpp.platform}</properties>
    <propertyKeysAndValues>
      <property>
        <name>platform.root</name>
        <value>${javacpp.platform.root}</value>
      </property>
      <property>
        <name>platform.compiler</name>
        <value>${javacpp.platform.compiler}</value>
      </property>
    </propertyKeysAndValues>
    <classPath>${project.build.outputDirectory}</classPath>
    <includePath>${basedir}/cppbuild/${javacpp.platform}/include/</includePath>
    <linkPath>${basedir}/cppbuild/${javacpp.platform}/lib/</linkPath>
    <preloadPath>${basedir}/cppbuild/${javacpp.platform}/bin/</preloadPath>
  </configuration>
  <executions>
    <execution>
      <id>javacpp.parser</id>
      <phase>generate-sources</phase>
      <goals>
        <goal>build</goal>
      </goals>
      <configuration>
        <skip>${javacpp.parser.skip}</skip>
        <outputDirectory>${project.build.sourceDirectory}</outputDirectory>
        <classOrPackageName>org.bytedeco.javacpp.presets.*</classOrPackageName>
      </configuration>
    </execution>
    <execution>
      <id>javacpp.compiler</id>
      <phase>process-classes</phase>
      <goals>
        <goal>build</goal>
      </goals>
      <configuration>
        <skip>${javacpp.compiler.skip}</skip>
        <classOrPackageName>org.bytedeco.javacpp.*</classOrPackageName>
        <copyLibs>true</copyLibs>
      </configuration>
    </execution>
  </executions>
</plugin>

Add this to your properties to make it easier to skip parts of the build. If this is not needed you can also remove the skip values from the configuration in the above plugin.

<properties>
  <javacpp.cppbuild.skip>false</javacpp.cppbuild.skip> <!-- To skip execution of cppbuild.sh: -Djavacpp.cppbuild.skip=true -->
  <javacpp.parser.skip>false</javacpp.parser.skip>     <!-- To skip header file parsing phase: -Djavacpp.parser.skip=true  -->
  <javacpp.compiler.skip>false</javacpp.compiler.skip> <!-- To skip native compilation phase: -Djavacpp.compiler.skip=true -->
</properties>

Use Dependency and execute maven plugin

To use the former set of plugins, we can add the following section to the pom.xml file:

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.3</version>
    <executions>
      <execution>
        <goals>
          <goal>properties</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.2.1</version>
  </plugin>
</plugins>

Further, JavaCPP can be invoked by adding an execution block under the exec plugin that looks something like this:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>1.2.1</version>
  <executions>
    <execution>
      <id>javacpp</id>
      <phase>process-classes</phase>
      <goals>
        <goal>exec</goal>
      </goals>
      <configuration>
        <executable>java</executable>
        <arguments>
          <argument>-jar</argument>       <argument>${org.bytedeco.javacpp:javacpp:jar}</argument>
          <argument>-classpath</argument> <argument>${project.build.outputDirectory}</argument>
          <argument>-d</argument>         <argument>${project.build.outputDirectory}/lib/</argument>
        </arguments>
      </configuration>
    </execution>
  </executions>
</plugin>

We might also need to reference the appropriate properties file for the target platform. To compile for something like Android, we would add the following:

<argument>-properties</argument> <argument>android-arm</argument>

Of course, depending on what we are compiling with, we might have to tweak some of the default properties of JavaCPP. For example, in the case of Android, we would have to give the root of the NDK to platform.root. This can be done by adding something like the following under the arguments:

<argument>-Dplatform.root=${env.ANDROID_NDK_HOME}</argument>

Assuming that the environment variable ANDROID_NDK_HOME points in the right direction.