diff --git a/build.gradle.kts b/build.gradle.kts index 30114a0..7bbd7fc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -115,7 +115,23 @@ android { } val buildSecp256k1 by tasks.creating { group = "build" } -fun creatingBuildSecp256k1(target: String, cross: String? = null, env: String = "", configuration: Task.() -> Unit = {}) = tasks.creating(Exec::class) { +sealed class Cross { + abstract fun cmd(target: String, nativeDir: File): List + class DockCross(val cross: String) : Cross() { + override fun cmd(target: String, nativeDir: File): List = listOf("./dockcross-$cross", "bash", "-c", "TARGET=$target ./build.sh") + } + class MultiArch(val crossTriple: String) : Cross() { + override fun cmd(target: String, nativeDir: File): List { + val uid = Runtime.getRuntime().exec("id -u").inputStream.use { it.reader().readText() }.trim().toInt() + return listOf( + "docker", "run", "--rm", "-v", "${nativeDir.absolutePath}:/workdir", + "-e", "CROSS_TRIPLE=$crossTriple", "-e", "TARGET=$target", "-e", "TO_UID=$uid", + "multiarch/crossbuild", "./build.sh" + ) + } + } +} +fun creatingBuildSecp256k1(target: String, cross: Cross?) = tasks.creating(Exec::class) { group = "build" buildSecp256k1.dependsOn(this) @@ -124,15 +140,11 @@ fun creatingBuildSecp256k1(target: String, cross: String? = null, env: String = workingDir = projectDir.resolve("native") environment("TARGET", target) - if (cross == null) commandLine("./build.sh") - else commandLine("./dockcross-$cross", "bash", "-c", "TARGET=$target ./build.sh") - - configuration() + commandLine((cross?.cmd(target, workingDir) ?: emptyList()) + "./build.sh") } - -val buildSecp256k1Darwin by creatingBuildSecp256k1("darwin") -val buildSecp256k1Linux by creatingBuildSecp256k1("linux", cross = if (currentOs.isMacOsX) "linux-x64" else null) -val buildSecp256k1Mingw by creatingBuildSecp256k1("mingw", cross = "windows-x64", env = "CONF_OPTS=--host=x86_64-w64-mingw32") +val buildSecp256k1Darwin by creatingBuildSecp256k1("darwin", if (currentOs.isMacOsX) null else Cross.MultiArch("x86_64-apple-darwin")) +val buildSecp256k1Linux by creatingBuildSecp256k1("linux", if (currentOs.isLinux) null else Cross.DockCross("linux-x64")) +val buildSecp256k1Mingw by creatingBuildSecp256k1("mingw", if (currentOs.isWindows) null else Cross.DockCross("windows-x64")) val copyJni by tasks.creating(Sync::class) { dependsOn(buildSecp256k1) @@ -146,6 +158,8 @@ val buildSecp256k1Ios by tasks.creating(Exec::class) { group = "build" buildSecp256k1.dependsOn(this) + onlyIf { currentOs.isMacOsX } + inputs.files(projectDir.resolve("native/build-ios.sh")) outputs.dir(projectDir.resolve("native/build/ios")) @@ -153,7 +167,10 @@ val buildSecp256k1Ios by tasks.creating(Exec::class) { commandLine("./build-ios.sh") } -val buildSecp256k1Android by tasks.creating { group = "build" } +val buildSecp256k1Android by tasks.creating { + group = "build" + buildSecp256k1.dependsOn(this) +} fun creatingBuildSecp256k1Android(arch: String) = tasks.creating(Exec::class) { group = "build" buildSecp256k1Android.dependsOn(this) @@ -164,8 +181,10 @@ fun creatingBuildSecp256k1Android(arch: String) = tasks.creating(Exec::class) { workingDir = projectDir.resolve("native") val toolchain = when { + currentOs.isLinux -> "linux-x86_64" currentOs.isMacOsX -> "darwin-x86_64" - else -> error("Cannot build for Android on this OS") + currentOs.isWindows -> "windows-x86_64" + else -> error("No Android toolchain defined for this OS: $currentOs") } environment("TOOLCHAIN", toolchain) environment("ARCH", arch) diff --git a/native/build-android.sh b/native/build-android.sh index d57acdc..d36522f 100755 --- a/native/build-android.sh +++ b/native/build-android.sh @@ -1,9 +1,6 @@ #!/usr/bin/env bash set -e -ANDROID_NDK=/Users/salomonbrys/Library/Android/sdk/ndk/21.3.6528147 -TOOLCHAIN=darwin-x86_64 - [[ -z "$ANDROID_NDK" ]] && echo "Please set the ANDROID_NDK variable" && exit 1 [[ -z "$ARCH" ]] && echo "Please set the ARCH variable" && exit 1 [[ -z "$TOOLCHAIN" ]] && echo "Please set the TOOLCHAIN variable" && exit 1 diff --git a/native/build.sh b/native/build.sh index 3f891c8..94fb98c 100755 --- a/native/build.sh +++ b/native/build.sh @@ -1,7 +1,11 @@ #!/usr/bin/env bash set -e -[[ -z "$TARGET" ]] && echo "Please set the PLATFORM variable" && exit 1 +[[ -z "$TARGET" ]] && echo "Please set the TARGET variable" && exit 1 + +if [ "$(id -u)" == "0" ]; then + [[ -z "$TO_UID" ]] && echo "Please set the TO_UID variable" && exit 1 +fi cd secp256k1 @@ -9,6 +13,8 @@ if [ "$TARGET" == "mingw" ]; then CONF_OPTS="CFLAGS=-fpic --host=x86_64-w64-mingw32" elif [ "$TARGET" == "linux" ]; then CONF_OPTS="CFLAGS=-fpic" +elif [ "$TARGET" == "darwin" ]; then + CONF_OPTS="--host=x86_64-w64-darwin" fi ./autogen.sh @@ -16,19 +22,26 @@ fi make clean make +[[ ! -z "$TO_UID" ]] && chown -R $TO_UID:$TO_UID . + cd .. mkdir -p build/$TARGET cp -v secp256k1/.libs/libsecp256k1.a build/$TARGET/ +[[ ! -z "$TO_UID" ]] && chown -R $TO_UID:$TO_UID build + CC=gcc JNI_HEADERS=$TARGET if [ "$TARGET" == "linux" ]; then OUTFILE=libsecp256k1-jni.so + ADD_LIB=-lgmp elif [ "$TARGET" == "darwin" ]; then OUTFILE=libsecp256k1-jni.dylib - ADD_LIB=-lgmp + if [ -z "$CROSS_TRIPLE" ]; then + ADD_LIB=-lgmp + fi elif [ "$TARGET" == "mingw" ]; then OUTFILE=secp256k1-jni.dll CC=/usr/src/mxe/usr/bin/x86_64-w64-mingw32.static-gcc @@ -37,3 +50,7 @@ elif [ "$TARGET" == "mingw" ]; then fi $CC -shared $CC_OPTS -o build/$TARGET/$OUTFILE jni/src/org_bitcoin_NativeSecp256k1.c jni/src/org_bitcoin_Secp256k1Context.c -Ijni/headers/ -Ijni/headers/$JNI_HEADERS/ -Isecp256k1/ -lsecp256k1 -Lbuild/$TARGET/ $ADD_LIB + +[[ ! -z "$TO_UID" ]] && chown -R $TO_UID:$TO_UID build + +echo "Build done for $TARGET" diff --git a/src/nativeInterop/cinterop/libsecp256k1.def b/src/nativeInterop/cinterop/libsecp256k1.def index 849e578..eec43c9 100644 --- a/src/nativeInterop/cinterop/libsecp256k1.def +++ b/src/nativeInterop/cinterop/libsecp256k1.def @@ -5,7 +5,7 @@ headerFilter = secp256k1/** secp256k1_ecdh.h secp256k1_recovery.h secp256k1.h staticLibraries.linux = libsecp256k1.a libraryPaths.linux = c/secp256k1/build/linux/ -linkerOpts.linux = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib +linkerOpts.linux = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -lgmp staticLibraries.ios = libsecp256k1.a libraryPaths.ios = c/secp256k1/build/ios/ /usr/local/lib