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

Port to Android Toolchain #4

Merged
merged 3 commits into from
Apr 18, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
target
target/
JOCL.ncb
JOCL.sln
JOCL.suo
JOCL.vcproj.*
/nativeLibrary
nativeLibraries/
JOCL.build/
build/
.*.sw[po]
73 changes: 49 additions & 24 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,58 +11,82 @@ set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX

project(JOCL)


#############################################################################
# Add the dependencies to JNI and the JOCLCommon project
# Add the JNI and OpenGL dependencies
if(NOT ANDROID)
find_package(JNI REQUIRED)
find_package(OpenGL REQUIRED)
link_directories(${OpenGL_LIBRARY_DIRS})
include_directories(${OpenGL_INCLUDE_DIR})
endif()

find_package(JNI REQUIRED)
# Add the JOCLCommon project as a dependency
add_subdirectory(../JOCLCommon
${CMAKE_CURRENT_BINARY_DIR}/JOCLCommon)

#############################################################################
# Add OpenGL Library and Header paths

find_package(OpenGL REQUIRED)
link_directories(${OpenGL_LIBRARY_DIRS})
include_directories(${OpenGL_INCLUDE_DIR})

#############################################################################
# Set the variables that are later used to build the name of the native
# library, e.g. "JOCL-0_2_0-windows-x86_64.dll"

set(JOCL_VERSION "0_2_0")

if(CMAKE_HOST_WIN32)
set(JOCL_HOST "windows")
if(ANDROID)
set(JOCL_TARGET_OS "android")
elseif(CMAKE_HOST_WIN32)
set(JOCL_TARGET_OS "windows")
elseif(CMAKE_HOST_APPLE)
set(JOCL_HOST "apple")
set(JOCL_TARGET_OS "apple")
set(CMAKE_SKIP_RPATH FALSE)
elseif(CMAKE_HOST_UNIX)
set(JOCL_HOST "linux")
set(JOCL_TARGET_OS "linux")
endif()

if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(JOCL_ARCH "x86_64")
if(ANDROID)
# Possible ANDROID_ABI values:
# {
# armeabi, armeabi-v7a,
# armeabi-v7a with NEON, armeabi-v7a with VFPV3, armeabi-v6 with VFP,
# arm64-v8a,
# x86, x86_64,
# mips, mips64
# }
# TODO: Support more than just "arm" in LibUtils
if("${ANDROID_ABI}" MATCHES "^armeabi.*")
set(JOCL_TARGET_ARCH "arm")
elseif("${ANDROID_ABI}" MATCHES "^arm64.*")
set(JOCL_TARGET_ARCH "arm64")
else()
set(JOCL_TARGET_ARCH ANDROID_ABI)
endif()
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(JOCL_TARGET_ARCH "x86_64")
else()
set(JOCL_ARCH "x86")
set(JOCL_TARGET_ARCH "x86")
endif()


#############################################################################
# Compiler settings

if(MSVC)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Wall /wd4514 /wd4820 /wd4710 /wd4711 /wd4350 /wd4668")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Wall /wd4514 /wd4820 /wd4710 /wd4711 /wd4350 /wd4668")
endif()

set(BUILD_SHARED_LIBS ON)


#############################################################################
# Output directories

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/nativeLibraries/Debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/nativeLibraries)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/nativeLibraries)
if(ANDROID)
set(JOCL_OUTPUT_DIR nativeLibraries/${ANDROID_ABI})
else()
set(JOCL_OUTPUT_DIR nativeLibraries)
endif()

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/${JOCL_OUTPUT_DIR}/Debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/${JOCL_OUTPUT_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/${JOCL_OUTPUT_DIR})


#############################################################################
Expand All @@ -76,18 +100,19 @@ include_directories(
${JNI_INCLUDE_DIRS}
)

add_library(JOCL_${JOCL_VERSION}-${JOCL_HOST}-${JOCL_ARCH}
add_library(JOCL_${JOCL_VERSION}-${JOCL_TARGET_OS}-${JOCL_TARGET_ARCH}
src/main/native/JOCL.cpp
src/main/native/CLFunctions.cpp
src/main/native/FunctionPointerUtils.cpp
src/main/native/FunctionPointerUtils_Linux.cpp
src/main/native/FunctionPointerUtils_Win.cpp
src/main/native/Sizeof.cpp
)

target_link_libraries(
JOCL_${JOCL_VERSION}-${JOCL_HOST}-${JOCL_ARCH}
JOCL_${JOCL_VERSION}-${JOCL_TARGET_OS}-${JOCL_TARGET_ARCH}
JOCLCommon)

#############################################################################
# Enable C++11 features
set_property(TARGET JOCL_${JOCL_VERSION}-${JOCL_HOST}-${JOCL_ARCH} PROPERTY CXX_STANDARD 11)
set_property(TARGET JOCL_${JOCL_VERSION}-${JOCL_TARGET_OS}-${JOCL_TARGET_ARCH} PROPERTY CXX_STANDARD 11)
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,32 @@ JAR files, and finally place all libraries into the
`C:\JOCLRoot\JOCL\target` directory.



**Building for Android**

Compiling native code for Android is a bit of a pain, so we use [android-cmake](https://github.com/taka-no-me/android-cmake)
to make our lives a bit easier. We first begin by installing the android-cmake
toolchain file into our cmake modules path. On Linux, this is likely
`/usr/share/cmake-3.2/Modules/`.

cd /usr/share/cmake-3.2/Modules
sudo wget https://github.com/taka-no-me/android-cmake/raw/master/android.toolchain.cmake

Next, we want to configure the build for our particular Android target.

cd JOCL
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=android.toolchain \
-DANDROID_ABI=armeabi-v7a \
-DANDROID_NATIVE_API_LEVEL=21 \
-DCMAKE_BUILD_TYPE=Release \
..

This should be enough to get you started. For more advanced configuration,
refer to the [android-cmake](https://github.com/taka-no-me/android-cmake)
documentation.

Finally, when building the final .jar file, we would like to avoid running the
local tests, as the Android native libraries won't run on your local machine.

mvn clean install -DskipTests
47 changes: 38 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,6 @@
<goals>
<goal>jar</goal>
</goals>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
</execution>
</executions>
</plugin>
Expand All @@ -149,11 +146,43 @@
<scope>test</scope>
</dependency>
</dependencies>
</project>






<!-- Fix for jdk.version < 1.8 -->
<!-- http://stackoverflow.com/a/22981151 -->
<profiles>
<profile>
<id>doclint-java8-disable</id>
<activation>
<jdk>[1.8,)</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.3</version>
<configuration>
<reportPlugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
</plugin>
</reportPlugins>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
70 changes: 47 additions & 23 deletions src/main/java/org/jocl/LibInitializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* JOCL - Java bindings for OpenCL
*
* Copyright (c) 2009-2015 Marco Hutter - http://www.jocl.org
*
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
Expand All @@ -11,10 +11,10 @@
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand All @@ -35,44 +35,68 @@ class LibInitializer
{
/**
* Initialize the native library by passing the name of the OpenCL
* implementation to the {@link CL#initNativeLibrary(String)}
* implementation to the {@link CL#initNativeLibrary(String)}
* method.
*
* @throws UnsatisfiedLinkError If the implementation library
*
* @throws UnsatisfiedLinkError If the implementation library
* could not be loaded.
*/
static void initNativeLibrary()
{
String implementationName = createImplementationName();
boolean initialized =
CL.initNativeLibrary(implementationName);
String[] libCandidates = openCLLibraryCandidates();

boolean initialized = false;
for (int i = 0; i < libCandidates.length && !initialized; i++) {
System.out.println("Trying library candidate: " + libCandidates[i]);
initialized = CL.initNativeLibrary(libCandidates[i]);
}

if (!initialized)
{
throw new UnsatisfiedLinkError(
"Could not initialize native library. Implementation " +
"library '"+implementationName+"' could not be loaded");
"Could not initialize native OpenCL library. Implementation " +
"library could not be loaded");
}
}

/**
* Create the name for the OpenCL implementation that will be passed
* to the dlopen/LoadLibrary call on native side. For Windows and
* Linux, this will be the name of the OpenCL library itself.
* For MacOS, it will be the path to the OpenCL framework.
*
* @return The name of the implementation library
* Create a list of OpenCL shared library candidates that will be
* passed to the dlopen/LoadLibrary call on native side. For Windows
* and Linux, this will be the name of the OpenCL library itself.
* For MacOS, it will be the path to the OpenCL framework. For Android,
* this will be an absolute path to the shared library.
*
* @return {String[]} A list of candidate paths / names.
*/
private static String createImplementationName()
private static String[] openCLLibraryCandidates()
{
String defaultLibName = LibUtils.createLibraryFileName("OpenCL");
OSType osType = LibUtils.calculateOS();
if (OSType.APPLE.equals(osType))
{
return "/System/Library/Frameworks/OpenCL.framework/" +
"Versions/Current/OpenCL";
return new String[] {
"/System/Library/Frameworks/OpenCL.framework/Versions/Current/OpenCL",
defaultLibName
};
} else if (OSType.ANDROID.equals(osType))
{
return new String[]
{
"/system/vendor/lib/libOpenCL.so", // Qualcomm
"/system/vendor/lib/egl/libGLES_mali.so", // ARM MALI SDK
"/system/vendor/lib/libPVROCL.so", // PowerVR SDK
"/system/lib/libOpenCL.so",
"/system/lib/egl/libGLES_mali.so",
"/system/lib/libPVROCL.so",
defaultLibName
};
}
return LibUtils.createLibraryFileName("OpenCL");
return new String[]
{
defaultLibName
};
}

/**
* Private constructor to prevent instantiation
*/
Expand Down
Loading