Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java bindings #2100

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f46f48f
Initial commit in Java bindings
Vasniktel Nov 1, 2019
837a47c
Make Java binding for cli util compile
Vasniktel Nov 16, 2019
7803774
Removed *.class files
Vasniktel Nov 16, 2019
ab85f8c
Updated .gitignore
Vasniktel Nov 16, 2019
18f829a
Remove VSCode related files
Vasniktel Nov 16, 2019
8c6ed19
Fix javacpp generation bug
Vasniktel Nov 17, 2019
9cb524c
Add missing includes
Vasniktel Nov 17, 2019
a86f37c
Add more utility functions; fix bugs
Vasniktel Nov 17, 2019
06bf060
Add unittests
Vasniktel Nov 17, 2019
09ada4d
Add more bindings; use nd4j 1.0.0-beta5
Vasniktel Nov 23, 2019
19ac81f
Update tests
Vasniktel Nov 23, 2019
2a3b08c
Add support for model parameters
Vasniktel Nov 26, 2019
6f565d7
Add support for categorical matrices
Vasniktel Nov 26, 2019
5aa8ebc
Add support for binding generation
Vasniktel Nov 27, 2019
a042098
Implement ProgramCall
Vasniktel Nov 28, 2019
c01572d
Fix minor bugs
Vasniktel Nov 28, 2019
2962965
Add bindings for methods; fix compilation bugs
Vasniktel Nov 28, 2019
c63c599
Introduce JAVA_VERSION cmake variable
Vasniktel Nov 28, 2019
4567b12
Fix style issues
Vasniktel Nov 30, 2019
ba7dd79
Fix bugs for row and col bindings
Vasniktel Dec 1, 2019
5afe1d7
Merge remote-tracking branch 'upstream/master' into java-bindings
Vasniktel Jan 10, 2020
ffdd622
Fix cmake issues
Vasniktel Jan 10, 2020
6574dc8
Remove unused includes
Vasniktel Jan 10, 2020
e3aef86
Remove needless templates
Vasniktel Feb 21, 2020
77d28a5
Fix indentation
Vasniktel Feb 21, 2020
ba37472
Rename utility methods to be similar to java types
Vasniktel Feb 21, 2020
b40716e
Add support for custom prefix to mlpack::util::HyphenateString
Vasniktel Feb 21, 2020
81ab8ee
Improve generation process
Vasniktel Feb 21, 2020
876a580
Fix incorrect arguments
Vasniktel Feb 21, 2020
e495358
Don't use auto
Vasniktel Feb 21, 2020
1741959
Improve docs
Vasniktel Feb 21, 2020
3b89355
Make target specification optional
Vasniktel Feb 22, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ xcode*
src/mlpack/core/util/gitversion.hpp
src/mlpack/core/util/arma_config.hpp
.idea
.vscode/*
cmake-build-*
*.pyc
Testing/
11 changes: 8 additions & 3 deletions CMake/GenerateBinding.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
# This script depends on the following arguments:
#
# GENERATE_BINDING_PROGRAM: the program to run to generate the binding file.
# BINDING_OUTPUT_FILE: the file to store the output in.
execute_process(COMMAND ${GENERATE_BINDING_PROGRAM}
OUTPUT_FILE ${BINDING_OUTPUT_FILE})
# BINDING_OUTPUT_FILE: the file to store the output in. (optional)

if (${BINDING_OUTPUT_FILE})
execute_process(COMMAND ${GENERATE_BINDING_PROGRAM}
OUTPUT_FILE ${BINDING_OUTPUT_FILE})
else()
execute_process(COMMAND ${GENERATE_BINDING_PROGRAM})
endif()
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ else ()
"Compile shared libraries (if OFF, static libraries are compiled)." ON)
endif()

option(BUILD_JAVA_BINDINGS "Build Java bindings" OFF)

# Build Markdown bindings for documentation. This is used as part of website
# generation.
option(BUILD_MARKDOWN_BINDINGS "Build Markdown bindings for website documentation." OFF)
Expand Down
1 change: 1 addition & 0 deletions src/mlpack/bindings/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# All we have to do is recurse into the subdirectories.
set(DIRS
cli
java
julia
markdown
python
Expand Down
4 changes: 4 additions & 0 deletions src/mlpack/bindings/java/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
maven/.classpath
maven/.project
maven/target/*
maven/.settings/*
173 changes: 173 additions & 0 deletions src/mlpack/bindings/java/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
macro (not_found_return message)
message(STATUS "${message}")
macro (add_java_binding name)
# Do nothing.
endmacro ()

return()
endmacro ()

# If we are not supposed to make Java bindings, define the macro so it does
# nothing and leave this file.
if (NOT BUILD_JAVA_BINDINGS)
not_found_return("Not building Java bindings.")
endif ()

# Check that JDK is installed
set(JAVA_VERSION 1.7)
find_package(Java ${JAVA_VERSION} REQUIRED COMPONENTS Development)
if (Java_FOUND)
include(UseJava)
else()
not_found_return("Java components weren't found; Java bindings will not be built.")
endif()

# Check that JNI exists
find_package(JNI REQUIRED)
if (NOT JNI_FOUND)
not_found_return("JNI wasn't found; Java bindings will not be built.")
endif()

# Check if target platform is specified (TODO: test on different platforms)
if (NOT MLPACK_JAVA_TARGET_PLATFORM)
#not_found_return("[JAVA BINDINGS] Target platform should be specified (e.g. linux-x86_64)")
message(STATUS "[JAVA BINDINGS] Building for this platform")
endif()

# Check that maven is installed
if (WIN32)
find_program(MAVEN_BIN mvn.bat REQUIRED)
else()
find_program(MAVEN_BIN mvn REQUIRED)
endif()

# Check that maven exists
if (MAVEN_BIN)
message(STATUS "Found maven: ${MAVEN_BIN}")
else()
not_found_return("Maven not found; Java bindings will not be built.")
endif()

set(MAVEN ${MAVEN_BIN} CACHE INTERNAL "")

add_custom_target(java_configure ALL)
add_custom_target(java ALL DEPENDS java_configure)

# Create directory structure for maven project
set(MAVEN_BUILD_DIR ${CMAKE_BINARY_DIR}/src/mlpack/bindings/java/maven CACHE INTERNAL "")
Vasniktel marked this conversation as resolved.
Show resolved Hide resolved
add_custom_command(TARGET java_configure PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${MAVEN_BUILD_DIR}/src/main/java/org/mlpack)

# Create directory for bindings generators
set(BUILD_BIN_DIR ${CMAKE_BINARY_DIR}/src/mlpack/bindings/java/build/bin CACHE INTERNAL "")
add_custom_command(TARGET java_configure PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${BUILD_BIN_DIR})

# Create directory for sources for bindings generators
set(BUILD_SRC_DIR ${CMAKE_BINARY_DIR}/src/mlpack/bindings/java/build/src CACHE INTERNAL "")
add_custom_command(TARGET java_configure PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${BUILD_SRC_DIR})

# Configure pom.xml
set(MLPACK_JAVA_INCLUDE_PATH ${MLPACK_INCLUDE_DIRS} ${CMAKE_BINARY_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR})
set(MLPACK_JAVA_LINK_PATH ${MLPACK_LIBRARY_DIRS} ${CMAKE_BINARY_DIR}/lib)

# TODO: make sure that all flags are being passed here (-D flags are not ATM)
string(REPLACE " " ";" MLPACK_JAVA_COMPILER_OPTIONS_RAW "${CMAKE_CXX_FLAGS}")
set(MLPACK_JAVA_COMPILER_OPTIONS "<param>-Wno-unused-parameter</param><param>-DBINDING_TYPE=BINDING_TYPE_JAVA</param>")
foreach (flag ${MLPACK_JAVA_COMPILER_OPTIONS_RAW})
set(MLPACK_JAVA_COMPILER_OPTIONS "${MLPACK_JAVA_COMPILER_OPTIONS}<param>${flag}</param>")
endforeach()

if (NOT WIN32)
string(REPLACE ";" ":" MLPACK_JAVA_INCLUDE_PATH "${MLPACK_JAVA_INCLUDE_PATH}")
string(REPLACE ";" ":" MLPACK_JAVA_LINK_PATH "${MLPACK_JAVA_LINK_PATH}")
endif()

file(READ "${CMAKE_SOURCE_DIR}/src/mlpack/core/util/version.hpp"
VERSION_HPP_CONTENTS)
string(REGEX REPLACE ".*#define MLPACK_VERSION_MAJOR ([0-9]+).*" "\\1"
MLPACK_VERSION_MAJOR "${VERSION_HPP_CONTENTS}")
string(REGEX REPLACE ".*#define MLPACK_VERSION_MINOR ([0-9]+).*" "\\1"
MLPACK_VERSION_MINOR "${VERSION_HPP_CONTENTS}")
string(REGEX REPLACE ".*#define MLPACK_VERSION_PATCH [\"]?([0-9x]+)[\"]?.*"
"\\1" MLPACK_VERSION_PATCH "${VERSION_HPP_CONTENTS}")
set(PACKAGE_VERSION
"${MLPACK_VERSION_MAJOR}.${MLPACK_VERSION_MINOR}.${MLPACK_VERSION_PATCH}")

configure_file(maven/pom.xml.in ${MAVEN_BUILD_DIR}/pom.xml @ONLY)

# Compile cli_util library for java
add_custom_target(java_cli_util ALL
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/maven/CLI.java
${MAVEN_BUILD_DIR}/src/main/java/org/mlpack/CLI.java
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/maven/MatrixWithInfo.java
${MAVEN_BUILD_DIR}/src/main/java/org/mlpack/MatrixWithInfo.java
DEPENDS java_configure)

# Group some commonly used files into a single library
# so that we don't need to recompile the every time
add_library(java_generate_parts STATIC
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/java/strip_type.hpp
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/java/print_param_defn.hpp
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/java/print_output_param.hpp
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/java/print_java.cpp
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/java/print_java.hpp
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/java/print_input_param.hpp
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/java/print_doc_functions.hpp
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/java/java_option.hpp
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/java/get_java_type.hpp
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/java/util.hpp
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/java/util.cpp)

# Create *.jar file when bindings are generated
add_custom_target(java_package ALL
COMMAND ${MAVEN} package
WORKING_DIRECTORY ${MAVEN_BUILD_DIR}
DEPENDS java_cli_util)

add_dependencies(java java_package)

macro(add_java_binding method_name)
# Generate sources for bindings generator
add_custom_command(OUTPUT ${BUILD_SRC_DIR}/generate_java_${method_name}.cpp
COMMAND ${CMAKE_COMMAND}
-DMETHOD_NAME=${method_name}
-DMETHOD_PATH=${CMAKE_CURRENT_SOURCE_DIR}
-DGENERATE_CPP_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/java/generate_java.cpp.in
-DGENERATE_CPP_OUT=${BUILD_SRC_DIR}/generate_java_${method_name}.cpp
-DPROGRAM_MAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${method_name}_main.cpp
-P ${CMAKE_SOURCE_DIR}/CMake/ConfigureGenerate.cmake
DEPENDS ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/java/generate_java.cpp.in
${CMAKE_SOURCE_DIR}/CMake/ConfigureGenerate.cmake)

# Compile bindings generator
add_executable(generate_java_${method_name}
${BUILD_SRC_DIR}/generate_java_${method_name}.cpp)

add_dependencies(generate_java_${method_name} java_configure)

target_link_libraries(generate_java_${method_name}
mlpack
java_generate_parts
${MLPACK_LIBRARIES})

set_target_properties(generate_java_${method_name} PROPERTIES
COMPILE_FLAGS -DBINDING_TYPE=BINDING_TYPE_JAVA
RUNTIME_OUTPUT_DIRECTORY "${BUILD_BIN_DIR}")

# Run generator to generate bindings (*.java files)
add_custom_command(TARGET generate_java_${method_name} POST_BUILD
COMMAND ${CMAKE_COMMAND}
-DGENERATE_BINDING_PROGRAM="${BUILD_BIN_DIR}/generate_java_${method_name}"
-P ${CMAKE_SOURCE_DIR}/CMake/GenerateBinding.cmake
WORKING_DIRECTORY ${MAVEN_BUILD_DIR}/src/main/java/org/mlpack/)

add_dependencies(java_package generate_java_${method_name})
endmacro()

if (BUILD_TESTS)
add_subdirectory(tests)
endif()