diff --git a/.gitignore b/.gitignore index eae14efd..ab027f57 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ **/pom.xml.versionsBackup **/logs /test_wallets +external-libs +*.log +*.swp diff --git a/CMakeLists.txt b/CMakeLists.txt index 79642a7a..36cc75ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,25 +1,37 @@ cmake_minimum_required(VERSION 3.4.1) +project(monero-java-jni) + if (WIN32) add_definitions( "-D_GLIBCXX_USE_NANOSLEEP=1" ) add_definitions( "-DWIN32_LEAN_AND_MEAN" ) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -O2 -fPIC -std=c++14 -F/Library/Frameworks -pthread -lcrypto -lcrypt32 -lbcrypt") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -O2 -fPIC -std=c++14 -pthread -lcrypto -lcrypt32 -lbcrypt") else() - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -std=c++14 -F/Library/Frameworks -pthread") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -std=c++14 -pthread") endif() -#SET(CMAKE_C_COMPILER /path/to/c/compiler) -#SET(CMAKE_CXX_COMPILER /path/to/cpp/compiler) +set(PLATFORM "") +if (DEFINED DEPENDS) + if (NOT DEFINED TARGET) + message(FATAL_ERROR "TARGET triplet arg is missing. TARGET is required in order to find the correct headers.") + elseif (${TARGET} MATCHES "apple") + set(PLATFORM "darwin") + elseif (${TARGET} MATCHES "linux") + set(PLATFORM "linux") + else() + set(PLATFORM "win32") + endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -F${CMAKE_SOURCE_DIR}/external/monero-cpp/external/monero-project/contrib/depends/${TARGET}/native/SDK/System/Library/Frameworks") +else() + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -F/Library/Frameworks") +endif() -project(monero-java-jni) ############# # System ############# set(MONERO_CPP "${CMAKE_SOURCE_DIR}/external/monero-cpp") -message(STATUS MONERO_CPP : ${MONERO_CPP} : ${MONERO_CPP}) - set(MONERO_CPP_SRC "${MONERO_CPP}/src") set(MONERO_PROJECT ${MONERO_CPP}/external/monero-project) set(MONERO_PROJECT_SRC "${MONERO_PROJECT}/src") @@ -29,12 +41,15 @@ if(NOT DEFINED ENV{JAVA_HOME} OR "$ENV{JAVA_HOME}" STREQUAL "") message(FATAL_ERROR "JAVA_HOME variable not set, for example: export JAVA_HOME=/path/to/jdk") endif() + # TODO: remove TRUEs, how are APPLE, DEPENDS, etc initialized? if (TRUE OR HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED) if (APPLE) if(TRUE OR DEPENDS) + # Building for Apple on Linux list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework IOKit -framework AppKit") else() + # Building for Apple on Mac find_library(COREFOUNDATION CoreFoundation) find_library(IOKIT IOKit) find_library(APPKIT AppKit) @@ -93,6 +108,7 @@ endif() add_library(monero-cpp SHARED IMPORTED) # import shared c++ library + if (APPLE) set_target_properties(monero-cpp PROPERTIES IMPORTED_LOCATION ./libmonero-cpp.dylib) elseif (WIN32) @@ -103,7 +119,7 @@ else() endif() ############################################### -# Build Java dynamic library for JNI +# Build Monero-Java native bridge ############################################### set( @@ -112,6 +128,7 @@ set( ) add_library(monero-java SHARED ${MONERO_JNI_SRC_FILES}) +message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") target_include_directories(monero-java PUBLIC "$ENV{JAVA_HOME}" "$ENV{JAVA_HOME}/include" @@ -131,7 +148,11 @@ target_include_directories(monero-java PUBLIC ${OPENSSL_INCLUDE_DIR} ) -if (APPLE) +# Support building for other Platforms from Linux +# TODO: Add the windows and linux headers to this directory +if (DEFINED DEPENDS) + target_include_directories(monero-java PUBLIC "${CMAKE_SOURCE_DIR}/include/jdk@21/${PLATFORM}") +elseif (APPLE) target_include_directories(monero-java PUBLIC "$ENV{JAVA_HOME}/include/darwin") elseif (WIN32) target_include_directories(monero-java PUBLIC "$ENV{JAVA_HOME}/include/win32") @@ -161,7 +182,7 @@ INSTALL(TARGETS monero-java # search for libmonero-cpp.dylib in same directory as libmonero-java.dylib on mac for portability # command: install_name_tool -add_rpath @loader_path/ ./libmonero-java.dylib -if (APPLE) +if (APPLE AND NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") add_custom_command(TARGET monero-java POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath "@loader_path/" diff --git a/bin/build_libmonero_java.sh b/bin/build_libmonero_java.sh index eacd0c88..ad00d4e9 100755 --- a/bin/build_libmonero_java.sh +++ b/bin/build_libmonero_java.sh @@ -1,20 +1,153 @@ -#!/bin/sh +#!/bin/bash #EMCC_DEBUG=1 +################### +# Set Global Vars +################### + +CURRENT_ARCH=`uname -m` +CURRENT_OS=`uname -s` HOST_NCORES=$(nproc 2>/dev/null || shell nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 1) +TOOLCHAIN_FILE="" +BUILD_BOTH_ARCHS=0 +OS="" +VENDOR="" + +# Set TARGET if it is not supplied. +TEMPTARGET=$TARGET +if [ -z $TARGET ]; then + if [ $CURRENT_OS == "Linux" ]; then + TEMPTARGET="linux" + elif [ $CURRENT_OS == "Darwin" ]; then + TEMPTARGET="darwin" + else + TEMPTARGET="MSYS" + fi +fi +TARGET=$TEMPTARGET + +if [ "${TARGET}" == "darwin" ]; then + OS="darwin11" + VENDOR="apple" + if [ -z "${ARCH}" ] && [ $CURRENT_OS == "Linux" ]; then + BUILD_BOTH_ARCHS=1 + fi +elif [ "${TARGET}" == "MSYS" ] || [ "${TARGET}" == "MINGW64_NT" ]; then + OS="mingw32" + VENDOR="w64" +else + OS="gnu" + VENDOR="linux" +fi + +CPU="" +if [ -n "${ARCH}" ]; then + CPU="${ARCH}" +else + CPU=$CURRENT_ARCH +fi +VERSION="${CPU}-${VENDOR}-${OS}" + + +################### +# Build Stuff +################### + +# Build monero-cpp and installed it +# "./build" is created here also. +if [ -z $SKIP_MCPP ]; then + rm -rf build + printf "\nlibmonero-java build script: Building libmonero-cpp shared library\n" + if [ $BUILD_BOTH_ARCHS == 1 ]; then + cd ./external/monero-cpp/ && + SKIP_MP=$SKIP_MP TARGET=$TARGET ./bin/build_libmonero_cpp.sh || exit 1 + cd ../.. + else + cd ./external/monero-cpp/ && + ARCH=$CPU SKIP_MP=$SKIP_MP TARGET=$TARGET ./bin/build_libmonero_cpp.sh || exit 1 + cd ../.. + fi + mkdir build + if [ $BUILD_BOTH_ARCHS == 1 ]; then + cp external/monero-cpp/build/darwin/release/libmonero-cpp.dylib ./build || exit 1 + else + cp external/monero-cpp/build/${VERSION}/release/libmonero-cpp* ./build || exit 1 + fi +else + mkdir temp_cpp + mv build/libmonero-cpp* temp_cpp + rm -rf build + mv temp_cpp build +fi + +# Build monero-java-jni-bridge +mkdir -p build/${VERSION}/release + +# Building on Linux using Depends +if [ $CURRENT_OS == "Linux" ] && ( + [ $TARGET == "linux" ] && [ $CURRENT_ARCH != $CPU ] || + [ $TARGET != "linux" ]); then + + toolchainBuildJNI () { + # $1 is the target triplet. + # CWD is the project root. + # dependencies are already in their proper place. + + printf "\nBuilding monero-java-jni for ${1} using Depends\n" + TOOLCHAIN_FILE="external/monero-cpp/external/monero-project/contrib/depends/${1}/share/toolchain.cmake" + cd "build/${1}/release" && + cmake -D TARGET=$1 -D CMAKE_BUILD_TYPE=Release -D CMAKE_TOOLCHAIN_FILE=../../../$TOOLCHAIN_FILE ../../.. && + make -j$HOST_NCORES + cd ../../.. + } + + # Build using Depends + + if [ $BUILD_BOTH_ARCHS == 1 ]; then + mkdir -p "build/x86_64-${VENDOR}-${OS}/release" + mkdir -p "build/aarch64-${VENDOR}-${OS}/release" + + # x86_64 + cp build/libmonero-cpp.dylib "build/x86_64-${VENDOR}-${OS}/release" + toolchainBuildJNI "x86_64-apple-darwin11" + + # aarch64 + cp build/libmonero-cpp.dylib "build/aarch64-${VENDOR}-${OS}/release" + toolchainBuildJNI "aarch64-apple-darwin11" + + # lipo it together and store correctly + mkdir -p build/darwin/release + external/monero-cpp/external/monero-project/contrib/depends/${CURRENT_ARCH}-apple-darwin11/native/bin/${CURRENT_ARCH}-apple-darwin11-lipo -create -output build/darwin/release/libmonero-java.dylib build/aarch64-${VENDOR}-${OS}/release/libmonero-java.dylib build/x86_64-${VENDOR}-${OS}/release/libmonero-java.dylib + + else + # Build 1 archive using Depends + if [ $TARGET == "linux" ]; then + cp build/libmonero-cpp.so build/${VERSION}/release + elif [ $TARGET == "darwin" ]; then + cp build/libmonero-cpp.dylib build/${VERSION}/release + else + cp build/libmonero-cpp.dll build/${VERSION}/release + fi + toolchainBuildJNI $VERSION + fi -# build libmonero-cpp shared library -cd ./external/monero-cpp/ && -./bin/build_libmonero_cpp.sh && +else + # Build monero-java-jni-bridge without using Depends + # Only build for the current platform -# copy libmonero-cpp shared library to ./build -cd ../../ && -mkdir -p ./build && -cp ./external/monero-cpp/build/libmonero-cpp.* ./build && + printf "\nBuilding monero-java-jni for ${VERSION} without Depends\n" -# build libmonero-java shared library to ./build cd build && cmake .. && -cmake --build . -j$HOST_NCORES && -make . \ No newline at end of file +cmake --build . --verbose +cd .. + cp build/libmonero-java* build/${VERSION}/release + if [ $TARGET == "linux" ]; then + cp build/libmonero-cpp.so build/${VERSION}/release + elif [ $TARGET == "darwin" ]; then + cp build/libmonero-cpp.dylib build/${VERSION}/release + else + cp build/libmonero-cpp.dll build/${VERSION}/release + fi +fi diff --git a/bin/clean.sh b/bin/clean.sh new file mode 100755 index 00000000..eef5c15f --- /dev/null +++ b/bin/clean.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +rm -rf build +cd external/monero-cpp +bin/clean.sh || exit 1 + diff --git a/include/jdk@21/darwin/jawt_md.h b/include/jdk@21/darwin/jawt_md.h new file mode 100644 index 00000000..94a13c9a --- /dev/null +++ b/include/jdk@21/darwin/jawt_md.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef _JAVASOFT_JAWT_MD_H_ +#define _JAVASOFT_JAWT_MD_H_ + +#include "jawt.h" + +#ifdef __OBJC__ +#import +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * MacOS specific declarations for AWT native interface. + * See notes in jawt.h for an example of use. + */ + +/* + * When calling JAWT_GetAWT with a JAWT version less than 1.7, you must pass this + * flag or you will not be able to get a valid drawing surface and JAWT_GetAWT will + * return false. This is to maintain compatibility with applications that used the + * interface with Java 6 which had multiple rendering models. This flag is not necessary + * when JAWT version 1.7 or greater is used as this is the only supported rendering mode. + * + * Example: + * JAWT awt; + * awt.version = JAWT_VERSION_1_4 | JAWT_MACOSX_USE_CALAYER; + * jboolean success = JAWT_GetAWT(env, &awt); + */ +#define JAWT_MACOSX_USE_CALAYER 0x80000000 + +/* + * When the native Cocoa toolkit is in use, the pointer stored in + * JAWT_DrawingSurfaceInfo->platformInfo points to a NSObject that conforms to the + * JAWT_SurfaceLayers protocol. Setting the layer property of this object will cause the + * specified layer to be overlaid on the Components rectangle. If the window the + * Component belongs to has a CALayer attached to it, this layer will be accessible via + * the windowLayer property. + */ +#ifdef __OBJC__ +@protocol JAWT_SurfaceLayers +@property (readwrite, retain) CALayer *layer; +@property (readonly) CALayer *windowLayer; +@end +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !_JAVASOFT_JAWT_MD_H_ */ diff --git a/include/jdk@21/darwin/jni_md.h b/include/jdk@21/darwin/jni_md.h new file mode 100644 index 00000000..6e583da7 --- /dev/null +++ b/include/jdk@21/darwin/jni_md.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef _JAVASOFT_JNI_MD_H_ +#define _JAVASOFT_JNI_MD_H_ + +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#ifndef JNIEXPORT + #if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) + #ifdef ARM + #define JNIEXPORT __attribute__((externally_visible,visibility("default"))) + #else + #define JNIEXPORT __attribute__((visibility("default"))) + #endif + #else + #define JNIEXPORT + #endif +#endif + +#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) + #ifdef ARM + #define JNIIMPORT __attribute__((externally_visible,visibility("default"))) + #else + #define JNIIMPORT __attribute__((visibility("default"))) + #endif +#else + #define JNIIMPORT +#endif + +#define JNICALL + +typedef int jint; +#ifdef _LP64 +typedef long jlong; +#else +typedef long long jlong; +#endif + +typedef signed char jbyte; + +#endif /* !_JAVASOFT_JNI_MD_H_ */ diff --git a/include/jdk@21/linux/jawt_md.h b/include/jdk@21/linux/jawt_md.h new file mode 100644 index 00000000..94a13c9a --- /dev/null +++ b/include/jdk@21/linux/jawt_md.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef _JAVASOFT_JAWT_MD_H_ +#define _JAVASOFT_JAWT_MD_H_ + +#include "jawt.h" + +#ifdef __OBJC__ +#import +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * MacOS specific declarations for AWT native interface. + * See notes in jawt.h for an example of use. + */ + +/* + * When calling JAWT_GetAWT with a JAWT version less than 1.7, you must pass this + * flag or you will not be able to get a valid drawing surface and JAWT_GetAWT will + * return false. This is to maintain compatibility with applications that used the + * interface with Java 6 which had multiple rendering models. This flag is not necessary + * when JAWT version 1.7 or greater is used as this is the only supported rendering mode. + * + * Example: + * JAWT awt; + * awt.version = JAWT_VERSION_1_4 | JAWT_MACOSX_USE_CALAYER; + * jboolean success = JAWT_GetAWT(env, &awt); + */ +#define JAWT_MACOSX_USE_CALAYER 0x80000000 + +/* + * When the native Cocoa toolkit is in use, the pointer stored in + * JAWT_DrawingSurfaceInfo->platformInfo points to a NSObject that conforms to the + * JAWT_SurfaceLayers protocol. Setting the layer property of this object will cause the + * specified layer to be overlaid on the Components rectangle. If the window the + * Component belongs to has a CALayer attached to it, this layer will be accessible via + * the windowLayer property. + */ +#ifdef __OBJC__ +@protocol JAWT_SurfaceLayers +@property (readwrite, retain) CALayer *layer; +@property (readonly) CALayer *windowLayer; +@end +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !_JAVASOFT_JAWT_MD_H_ */ diff --git a/include/jdk@21/linux/jni_md.h b/include/jdk@21/linux/jni_md.h new file mode 100644 index 00000000..6e583da7 --- /dev/null +++ b/include/jdk@21/linux/jni_md.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef _JAVASOFT_JNI_MD_H_ +#define _JAVASOFT_JNI_MD_H_ + +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#ifndef JNIEXPORT + #if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) + #ifdef ARM + #define JNIEXPORT __attribute__((externally_visible,visibility("default"))) + #else + #define JNIEXPORT __attribute__((visibility("default"))) + #endif + #else + #define JNIEXPORT + #endif +#endif + +#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) + #ifdef ARM + #define JNIIMPORT __attribute__((externally_visible,visibility("default"))) + #else + #define JNIIMPORT __attribute__((visibility("default"))) + #endif +#else + #define JNIIMPORT +#endif + +#define JNICALL + +typedef int jint; +#ifdef _LP64 +typedef long jlong; +#else +typedef long long jlong; +#endif + +typedef signed char jbyte; + +#endif /* !_JAVASOFT_JNI_MD_H_ */ diff --git a/src/main/java/monero/common/MoneroUtils.java b/src/main/java/monero/common/MoneroUtils.java index da6fc9ef..e558e9bd 100644 --- a/src/main/java/monero/common/MoneroUtils.java +++ b/src/main/java/monero/common/MoneroUtils.java @@ -146,7 +146,7 @@ public static boolean isNativeLibraryLoaded() { } } - public static final int RING_SIZE = 12; // network-enforced ring size + public static final int RING_SIZE = 16; // network-enforced ring size private static int LOG_LEVEL = 0; private static long AU_PER_XMR = 1000000000000l;