I am using Swig to produce a Java binding for a C library. The build system is written in CMake in order to achieve platform neutrality. I wish to produce a JAR file containing the Java bindings (i.e. the .class files resulting from the compilation of the .java files created by Swig). I am trying to use the Cmake add_jar()
command to perform the compilation and produce the JAR file.
My problem is that Swig produces a set of Java files at build time, but add_jar()
requires a list of source files at the time cmake is executed. I am currently working around the problem using a UNIX wildcard (which is passed literally to the javac command line).
# How do I avoid the shell wildcard?
add_jar(ExampleJNI ${CMAKE_SWIG_OUTDIR}/*.java)
Is there a better way?
I include below a complete example (comprising of three files) that illustrates my approach. If you want to try for yourself, put the three files in a directory, then invoke cmake . ; make VERBOSE=1
.
cmake_minimum_required (VERSION 2.8)
find_package(Swig REQUIRED)
find_package(Java REQUIRED)
find_package(JNI REQUIRED)
include(UseJava)
include(UseSWIG)
project (Example)
add_library (Example example.c)
set(CMAKE_SWIG_FLAGS -package org.mycompany)
set(CMAKE_SWIG_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}/src/main/java/org/mycompany)
swig_add_module(ExampleSWIG java example.i)
include_directories(${JNI_INCLUDE_DIRS})
swig_link_libraries(ExampleSWIG Example)
# How do I avoid the wildcard?
add_jar(ExampleJNI ${CMAKE_SWIG_OUTDIR}/*.java)
add_dependencies(ExampleJNI ExampleSWIG)
int foo() {
return 0;
}
%module example
%inline %{
extern int foo();
%}
I am using:
This post is old but I had the same problem today and found a nice solution.
My current approach distinguish between buildsystem generation time and build-time. Instead of using wildcards (what does not seem to work with add_jar on windows). I use add_custom_command() to generate a JAR with the generated java classes at build-time. I know the name of this JAR at buildsystem generation time. And so i can use the name as INCLUDE_JAR parameter for add_jar() function. I will refer to the JAR containing the java files generated by SWIG as Native.jar.
Here is a example how you can achieve CMake + Java + SWIG
First we need to find the necessary packages:
FIND_PACKAGE(SWIG REQUIRED)
FIND_PACKAGE(JNI REQUIRED)
FIND_PACKAGE(Java REQUIRED)
INCLUDE(UseSWIG)
INCLUDE(UseJava)
Then we need to define our SWIG Module:
SET(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/java")
SET_PROPERTY(SOURCE "native-interface.i" PROPERTY CPLUSPLUS ON)
SWIG_ADD_MODULE(Native java "native-interface.i"
"algorithm.hpp"
"algorithm-listener.hpp"
"simple-methods.hpp" "simple-methods.cpp"
)
TARGET_INCLUDE_DIRECTORIES(Native
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${JAVA_INCLUDE_PATH}
PRIVATE ${JAVA_INCLUDE_PATH2})
As you can see I use a java subdirectory to store the java files. I will also add a subdirectory for class files and then register POST_BUILD Events to build the Native.jar:
FILE(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/classes")
ADD_CUSTOM_COMMAND(TARGET Native POST_BUILD
COMMAND "${Java_JAVAC_EXECUTABLE}" -d classes java/*.java
COMMAND "${Java_JAR_EXECUTABLE}" -cfM Native.jar -C classes .
)
# Store Path to native JAR in variable:
SET(NATIVE_JAR "${CMAKE_CURRENT_BINARY_DIR}/Native.jar")
In the next step we will generate a java project using add_jar() function:
ADD_JAR(ConsoleApp
SOURCES "NativeInvoker.java"
INCLUDE_JARS ${NATIVE_JAR})
SET(CMAKE_JAVA_COMPILE_FLAGS "-source" "1.8" "-target" "1.8")
If you use different folder for your project (like have native in one subdirectory and java stuff in another). You must copy the Native.dll to the same folder like your java application or ensure that it is found by Java. To do this in CMake u can use add_custom_command() again.
ADD_CUSTOM_COMMAND(TARGET ConsoleApp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Native> ${CMAKE_CURRENT_BINARY_DIR})
Hope this is helpful for a lot of you guys.
Greetings Tim
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With