diff --git a/src/secp256k1/CMakeLists.txt b/src/secp256k1/CMakeLists.txt --- a/src/secp256k1/CMakeLists.txt +++ b/src/secp256k1/CMakeLists.txt @@ -152,6 +152,26 @@ target_sources(secp256k1-object PRIVATE ecmult_static_context.h) endif() +# Build the Java binding +option(SECP256K1_ENABLE_JNI "Enable the Java Native Interface binding" OFF) +if(SECP256K1_ENABLE_JNI) + if(NOT SECP256K1_ENABLE_MODULE_ECDH) + message(FATAL_ERROR "The secp256k1 JNI support requires ECDH. Try again with -DSECP256K1_ENABLE_MODULE_ECDH=ON.") + endif() + + find_package(Java REQUIRED) + find_package(JNI REQUIRED) + include(UseJava) + + set(SECP256K1_JNI_SOURCES + src/java/org_bitcoin_NativeSecp256k1.c + src/java/org_bitcoin_Secp256k1Context.c + ) + + target_sources(secp256k1-object PRIVATE ${SECP256K1_JNI_SOURCES}) + target_include_directories(secp256k1-object PRIVATE ${JNI_INCLUDE_DIRS}) +endif() + # Generate the config configure_file(src/libsecp256k1-config.h.cmake.in src/libsecp256k1-config.h ESCAPE_QUOTES) target_compile_definitions(secp256k1-object PRIVATE HAVE_CONFIG_H SECP256K1_BUILD) @@ -171,8 +191,10 @@ # Build the static secp256k1 library build_secp256k1_library(secp256k1 STATIC) +option(SECP256K1_BUILD_TEST "Build secp256k1's unit tests" ON) option(SECP256K1_BUILD_SHARED "Build secp256k1 as a shared library" OFF) -if(SECP256K1_BUILD_SHARED) +# The Java tests require a shared secp256k1 library +if(SECP256K1_BUILD_SHARED OR (SECP256K1_ENABLE_JNI AND SECP256K1_BUILD_TEST)) # CMake will automatically set the PIC option to the shared library, but not # when building the object library files, causing a linker failure. set_target_properties(secp256k1-object PROPERTIES POSITION_INDEPENDENT_CODE ON) @@ -180,7 +202,6 @@ endif() # Tests -option(SECP256K1_BUILD_TEST "Build secp256k1's unit tests" ON) if(SECP256K1_BUILD_TEST) include(TestSuite) create_test_suite(secp256k1) @@ -197,6 +218,47 @@ # This should not be enabled at the same time as coverage is. # TODO: support coverage. target_compile_definitions(exhaustive_tests PRIVATE VERIFY) + + if(SECP256K1_ENABLE_JNI) + set(SECP256K1_JAVA_TEST_SOURCES + src/java/org/bitcoin/NativeSecp256k1.java + src/java/org/bitcoin/NativeSecp256k1Test.java + src/java/org/bitcoin/NativeSecp256k1Util.java + src/java/org/bitcoin/Secp256k1Context.java + ) + set(SECP256k1_JNI_TEST_JAR "secp256k1-jni-test") + + set(CMAKE_JNI_TARGET TRUE) + add_jar(secp256k1-jni-test-jar + SOURCES ${SECP256K1_JAVA_TEST_SOURCES} + ENTRY_POINT org/bitcoin/NativeSecp256k1Test + OUTPUT_NAME "${SECP256k1_JNI_TEST_JAR}" + ) + add_dependencies(secp256k1-jni-test-jar secp256k1-shared) + + set(SECP256K1_JAVA_TEST_COMMAND + "${Java_JAVA_EXECUTABLE}" + "-Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}" + "-jar" + "${SECP256k1_JNI_TEST_JAR}.jar" + ) + + add_custom_target(secp256k1-check-java + COMMAND + ${SECP256K1_JAVA_TEST_COMMAND} + WORKING_DIRECTORY + "${CMAKE_CURRENT_BINARY_DIR}" + ) + add_dependencies(secp256k1-check-java secp256k1-jni-test-jar) + + add_test(NAME secp256k1-java-test + COMMAND + ${SECP256K1_JAVA_TEST_COMMAND} + WORKING_DIRECTORY + "${CMAKE_CURRENT_BINARY_DIR}" + ) + add_dependencies(check-secp256k1 secp256k1-jni-test-jar) + endif() endif(SECP256K1_BUILD_TEST) # Benchmarks