diff --git a/.github/workflows/deploy-javadoc.yml b/.github/workflows/deploy-javadoc.yml index de0d8e1f..e49c5b04 100644 --- a/.github/workflows/deploy-javadoc.yml +++ b/.github/workflows/deploy-javadoc.yml @@ -12,14 +12,20 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up JDK 8 - uses: actions/setup-java@v3 + - uses: actions/cache@v4 with: - java-version: '8' - distribution: 'temurin' - + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + ~/.rustup + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main - name: Generate Javadoc - run: gradle aggregateJavadoc + run: nix develop --command bash -c "./gradlew aggregateJavadoc" - name: Deploy uses: JamesIves/github-pages-deploy-action@v4 diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml index 088123f0..98365962 100644 --- a/.github/workflows/gradle-build.yml +++ b/.github/workflows/gradle-build.yml @@ -15,14 +15,22 @@ jobs: packages: write steps: - - name: Output GLIBC Version - run: ldd --version - - uses: actions/checkout@v3 - - name: Set up JDK 8 - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 with: - java-version: '8' - distribution: 'temurin' - + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + ~/.rustup + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main - name: Build with Gradle - run: gradle -i build + run: nix develop --ignore-environment --command bash -c "./gradlew build" + env: + USERNAME: ${{ github.actor }} + TOKEN: ${{ secrets.GITHUB_TOKEN }} + diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 185ec5ca..ba76c617 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -17,20 +17,21 @@ jobs: packages: write steps: - - uses: actions/checkout@v3 - - name: Set up JDK 8 - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 with: - java-version: '8' - distribution: 'temurin' - + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + ~/.rustup + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main - name: Build with Gradle - run: gradle -i build - - # The USERNAME and TOKEN need to correspond to the credentials environment variables used in - # the publishing section of your build.gradle - - name: Publish to GitHub Packages - run: gradle publish + run: nix develop --ignore-environment --keep USERNAME --keep TOKEN --command bash -c "./gradlew build && ./gradlew publish" env: USERNAME: ${{ github.actor }} TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/crypto/build.gradle b/crypto/build.gradle index e7896913..8f055957 100644 --- a/crypto/build.gradle +++ b/crypto/build.gradle @@ -13,24 +13,41 @@ test { task compileRust { project.logger.info("#####################" + System.getProperty("os.name").toLowerCase()) doLast { - if(System.getProperty("os.name").toLowerCase().contains("linux")) { + // nix build detection + if (System.getenv('NIX_CC') != null) { exec { workingDir 'src/jni-crypto' - commandLine 'cargo', 'build', '--release', '--target=x86_64-unknown-linux-gnu', '--target-dir=../../build/jni-crypto' + commandLine 'cargo', 'build', '--release', '--target=aarch64-unknown-linux-gnu', '--target-dir=../../build/jni-crypto' } - } - else if (System.getProperty("os.name").toLowerCase().contains("windows")) { exec { workingDir 'src/jni-crypto' - commandLine 'cargo', 'build', '--release', '--target=x86_64-pc-windows-gnu', '--target-dir=../../build/jni-crypto' + commandLine 'cargo', 'build', '--release', '--target=x86_64-unknown-linux-gnu', '--target-dir=../../build/jni-crypto' } - } - // Does not cover solaris, just MacOS. See potential return types here: - // https://docs.gradle.org/current/javadoc/org/gradle/nativeplatform/platform/OperatingSystem.html - else { exec { workingDir 'src/jni-crypto' - commandLine 'cargo', 'build', '--release', '--target-dir=../../build/jni-crypto' + commandLine 'cargo', 'build', '--release', '--target=x86_64-pc-windows-gnu', '--target-dir=../../build/jni-crypto' + environment RUSTFLAGS: "-L ${System.getenv('PTHREAD_LOCATION')}" + } + } else { + // keep the old build behavior while not running in nix shell + if (System.getProperty("os.name").toLowerCase().contains("linux")) { + exec { + workingDir 'src/jni-crypto' + commandLine 'cargo', 'build', '--release', '--target=x86_64-unknown-linux-gnu', '--target-dir=../../build/jni-crypto' + } + } else if (System.getProperty("os.name").toLowerCase().contains("windows")) { + exec { + workingDir 'src/jni-crypto' + commandLine 'cargo', 'build', '--release', '--target=x86_64-pc-windows-gnu', '--target-dir=../../build/jni-crypto' + } + } + // Does not cover solaris, just MacOS. See potential return types here: + // https://docs.gradle.org/current/javadoc/org/gradle/nativeplatform/platform/OperatingSystem.html + else { + exec { + workingDir 'src/jni-crypto' + commandLine 'cargo', 'build', '--release', '--target-dir=../../build/jni-crypto' + } } } } @@ -44,7 +61,11 @@ processResources { include '*.dylib' } from("${buildDir}/jni-crypto/x86_64-unknown-linux-gnu/release") { - into "include/linux" + into "include/x86_64-linux" + include '*.so' + } + from("${buildDir}/jni-crypto/aarch64-unknown-linux-gnu/release") { + into "include/aarch64-linux" include '*.so' } from("${buildDir}/jni-crypto/x86_64-pc-windows-gnu/release") { diff --git a/crypto/readme.md b/crypto/readme.md index f001d4d6..9cafc47e 100644 --- a/crypto/readme.md +++ b/crypto/readme.md @@ -1,4 +1,5 @@ // TODO write readme.md :) Preparation: `rustup target add x86_64-pc-windows-gnu` -`sudo apt install gcc-mingw-w64-x86-64` \ No newline at end of file +`rustup target add aarch64-unknown-linux-gnu` +`sudo apt install gcc-mingw-w64-x86-64` diff --git a/crypto/src/main/java/com/strategyobject/substrateclient/crypto/sr25519/Native.java b/crypto/src/main/java/com/strategyobject/substrateclient/crypto/sr25519/Native.java index 817cae37..fae76da1 100644 --- a/crypto/src/main/java/com/strategyobject/substrateclient/crypto/sr25519/Native.java +++ b/crypto/src/main/java/com/strategyobject/substrateclient/crypto/sr25519/Native.java @@ -22,9 +22,12 @@ class Native { private static final String LIB_PATH = "SUBSTRATE_CLIENT_CRYPTO_LIB_PATH"; private static final String LIB_NAME = "jni_crypto"; private static final String OS_NAME = System.getProperty("os.name").toLowerCase(); + private static final String ARCH_NAME = System.getProperty("os.arch").toLowerCase(); private static final boolean IS_WINDOWS = OS_NAME.contains("win"); private static final boolean IS_MAC = OS_NAME.contains("mac"); private static final boolean IS_LINUX = OS_NAME.contains("linux"); + private static final boolean IS_AMD64 = ARCH_NAME.contains("amd64") || ARCH_NAME.contains("x86_64"); + private static final boolean IS_AARCH64 = ARCH_NAME.contains("aarch64"); static { try { @@ -49,9 +52,11 @@ private static String copyLibraryFromResourcesToTempDir() throws IOException { String osDir; if (IS_WINDOWS) { osDir = "windows"; - } else if (IS_LINUX) { - osDir = "linux"; - } else if (IS_MAC) { // TODO 'MasOS support problem' + } else if (IS_LINUX && IS_AMD64) { + osDir = "x86_64-linux"; + } else if (IS_LINUX && IS_AARCH64) { + osDir = "aarch64-linux"; + } else if (IS_MAC) { // TODO 'MacOS support problem' osDir = "macos"; } else { throw new RuntimeException("JNI library can't be loaded because OS wasn't detected as supported."); diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..35cfdb9f --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1709961763, + "narHash": "sha256-6H95HGJHhEZtyYA3rIQpvamMKAGoa8Yh2rFV29QnuGw=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "3030f185ba6a4bf4f18b87f345f104e6a6961f34", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..21a4484e --- /dev/null +++ b/flake.nix @@ -0,0 +1,35 @@ +{ + description = "Environment flake"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { inherit system; }; + + mkLinkerPath = {cc, ...}: "${cc}/bin/${cc.targetPrefix}cc"; + in + { + devShells.default = with pkgs; mkShell { + + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER = mkLinkerPath pkgsCross.aarch64-multiplatform.stdenv; + CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER = mkLinkerPath pkgsCross.gnu64.stdenv; + CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER = mkLinkerPath pkgsCross.mingwW64.stdenv; + + # for mingw compilation + PTHREAD_LOCATION = "${pkgs.pkgsCross.mingwW64.windows.pthreads}/lib"; + + shellHook = "rustup show"; + + packages = [ + temurin-bin-8 + rustup + ]; + }; + } + ); +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..84037350 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,5 @@ +[toolchain] +channel = "nightly-2024-02-04" +components = [ "rustc" ] +targets = [ "x86_64-pc-windows-gnu", "aarch64-unknown-linux-gnu", "x86_64-pc-windows-gnu" ] +profile = "minimal"