diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 026e9aa1..433e0a87 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -150,6 +150,15 @@ jobs: export CXX=aarch64-linux-android24-clang++ export CMAKE_TOOLCHAIN_FILE_aarch64_linux_android="$(pwd)/cmake/android-determine.cmake" yarn build --target aarch64-linux-android + - host: ubuntu-latest + target: 'riscv64gc-unknown-linux-gnu' + downloadTarget: 'riscv64gc-unknown-linux-gnu' + build: | + sudo apt-get update + sudo apt-get install gcc-riscv64-linux-gnu g++-riscv64-linux-gnu -y + export CC=riscv64-linux-gnu-gcc + export CXX=riscv64-linux-gnu-g++ + yarn build --target riscv64gc-unknown-linux-gnu name: stable - ${{ matrix.settings.target }} - node@20 runs-on: ${{ matrix.settings.host }} @@ -231,13 +240,13 @@ jobs: fail-fast: false matrix: settings: - - host: macos-14 + - host: macos-latest target: 'x86_64-apple-darwin' - - host: macos-14 + - host: macos-latest target: 'aarch64-apple-darwin' - host: windows-latest target: 'x86_64-pc-windows-msvc' - node: ['18', '20'] + node: ['18', '20', '22'] runs-on: ${{ matrix.settings.host }} steps: @@ -300,7 +309,7 @@ jobs: strategy: fail-fast: false matrix: - node: ['18', '20'] + node: ['18', '20', '22'] runs-on: ubuntu-latest steps: @@ -351,7 +360,7 @@ jobs: strategy: fail-fast: false matrix: - node: ['18', '20'] + node: ['18', '20', '22'] runs-on: ubuntu-latest steps: @@ -404,7 +413,7 @@ jobs: strategy: fail-fast: false matrix: - node: ['20', '21'] + node: ['20', '22'] runs-on: ubuntu-latest steps: @@ -523,7 +532,7 @@ jobs: strategy: fail-fast: false matrix: - node: ['18', '20'] + node: ['18', '20', '22'] runs-on: ubuntu-latest steps: @@ -579,7 +588,7 @@ jobs: rust-test: name: stable - macOS - cargo - test - runs-on: macos-14 + runs-on: macos-latest steps: - uses: actions/checkout@v4 @@ -589,13 +598,13 @@ jobs: - name: Install uses: ./.github/actions/setup-rust with: - targets: x86_64-apple-darwin + targets: aarch64-apple-darwin - name: Install dependencies run: yarn install --immutable --mode=skip-build - - name: Install nasm - run: brew install nasm llvm + - name: Install llvm + run: brew install llvm - name: Download skia binary run: node ./scripts/release-skia-binary.mjs --download diff --git a/.github/workflows/skia.yaml b/.github/workflows/skia.yaml index 548406e8..15adfcf8 100644 --- a/.github/workflows/skia.yaml +++ b/.github/workflows/skia.yaml @@ -292,6 +292,11 @@ jobs: run: echo "${PWD}/depot_tools" >> $GITHUB_PATH shell: bash + - name: Install build tools + run: | + sudo apt-get update + sudo apt-get install ninja-build -y + - name: Set up QEMU uses: docker/setup-qemu-action@v3 with: @@ -353,6 +358,11 @@ jobs: run: echo "${PWD}/depot_tools" >> $GITHUB_PATH shell: bash + - name: Install build tools + run: | + sudo apt-get update + sudo apt-get install ninja-build -y + - name: Compile skia run: node ./scripts/build-skia.js --target=aarch64-linux-android @@ -363,3 +373,40 @@ jobs: run: node ./scripts/release-skia-binary.mjs --upload --target=aarch64-linux-android env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + build-riscv64-linux-gnu: + if: "!contains(github.event.head_commit.message, 'skip skia')" + name: stable - riscv64-linux-gnu - build skia + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'yarn' + - uses: actions/setup-python@v5 + with: + python-version: '3.x' + architecture: 'x64' + - name: Set env + run: echo "${PWD}/depot_tools" >> $GITHUB_PATH + shell: bash + - name: Install cross compile tools + run: | + sudo apt-get update + sudo apt-get install ninja-build gcc-riscv64-linux-gnu g++-riscv64-linux-gnu -y + - name: Compile skia + run: node ./scripts/build-skia.js --target=riscv64gc-unknown-linux-gnu + env: + CC: riscv64-linux-gnu-gcc + CXX: riscv64-linux-gnu-g++ + - name: Install dependencies + run: yarn install --immutable --mode=skip-build + + - name: Upload release + run: node ./scripts/release-skia-binary.mjs --upload --target=riscv64gc-unknown-linux-gnu + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/build.rs b/build.rs index be98ef63..74213e9a 100644 --- a/build.rs +++ b/build.rs @@ -161,10 +161,9 @@ fn main() { if compile_target_env != "gnu" { build.cpp_set_stdlib("stdc++"); } else { - build.cpp_set_stdlib("c++").flag("-static"); - println!("cargo:rustc-link-lib=static=c++"); match compile_target_arch.as_str() { "aarch64" => { + link_libcxx(&mut build); build .include( "/usr/aarch64-unknown-linux-gnu/aarch64-unknown-linux-gnu/sysroot/usr/include", @@ -176,10 +175,16 @@ fn main() { println!("cargo:rustc-link-search=/usr/aarch64-unknown-linux-gnu/lib/gcc/aarch64-unknown-linux-gnu/4.8.5"); } "x86_64" => { + link_libcxx(&mut build); build.include("/usr/lib/llvm-18/include/c++/v1"); println!("cargo:rustc-link-search=/usr/lib/llvm-18/lib"); } + "riscv64" => { + println!("cargo:rustc-link-search=/usr/lib/gcc-cross/riscv64-linux-gnu/11"); + println!("cargo:rustc-link-lib=static=atomic"); + } "arm" => { + link_libcxx(&mut build); let gcc_version = String::from_utf8( process::Command::new("ls") .arg("/usr/arm-linux-gnueabihf/include/c++") @@ -242,3 +247,8 @@ fn main() { println!("cargo:rustc-link-lib=static=skshaper"); napi_build::setup(); } + +fn link_libcxx(build: &mut cc::Build) { + build.cpp_set_stdlib("c++").flag("-static"); + println!("cargo:rustc-link-lib=static=c++"); +} diff --git a/js-binding.js b/js-binding.js index f83f4421..dbaeff88 100644 --- a/js-binding.js +++ b/js-binding.js @@ -203,6 +203,18 @@ switch (platform) { loadError = e } break + case 'riscv64': + localFileExisted = existsSync(join(__dirname, 'skia.linux-riscv64-gnu.node')) + try { + if (localFileExisted) { + nativeBinding = require('./skia.linux-riscv64-gnu.node') + } else { + nativeBinding = require('@napi-rs/canvas-linux-riscv64-gnu') + } + } catch (e) { + loadError = e + } + break default: throw new Error(`Unsupported architecture on Linux: ${arch}`) } diff --git a/npm/linux-arm64-gnu/package.json b/npm/linux-arm64-gnu/package.json index 2998ac30..ca232671 100644 --- a/npm/linux-arm64-gnu/package.json +++ b/npm/linux-arm64-gnu/package.json @@ -7,9 +7,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "main": "skia.linux-arm64-gnu.node", "files": [ "skia.linux-arm64-gnu.node" @@ -39,5 +36,8 @@ "repository": { "type": "git", "url": "git+https://github.com/Brooooooklyn/canvas.git" - } + }, + "libc": [ + "glibc" + ] } \ No newline at end of file diff --git a/npm/linux-arm64-musl/package.json b/npm/linux-arm64-musl/package.json index 354d7357..3b5b24f3 100644 --- a/npm/linux-arm64-musl/package.json +++ b/npm/linux-arm64-musl/package.json @@ -7,9 +7,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "main": "skia.linux-arm64-musl.node", "files": [ "skia.linux-arm64-musl.node" @@ -39,5 +36,8 @@ "repository": { "type": "git", "url": "git+https://github.com/Brooooooklyn/canvas.git" - } + }, + "libc": [ + "musl" + ] } \ No newline at end of file diff --git a/npm/linux-riscv64-gnu/README.md b/npm/linux-riscv64-gnu/README.md new file mode 100644 index 00000000..b0b791c3 --- /dev/null +++ b/npm/linux-riscv64-gnu/README.md @@ -0,0 +1,3 @@ +# `@napi-rs/canvas-linux-riscv64-gnu` + +This is the **riscv64-unknown-linux-gnu** binary for `@napi-rs/canvas` diff --git a/npm/linux-riscv64-gnu/package.json b/npm/linux-riscv64-gnu/package.json new file mode 100644 index 00000000..e3a2a2d4 --- /dev/null +++ b/npm/linux-riscv64-gnu/package.json @@ -0,0 +1,43 @@ +{ + "name": "@napi-rs/canvas-linux-riscv64-gnu", + "version": "0.1.62", + "os": [ + "linux" + ], + "cpu": [ + "riscv64" + ], + "main": "skia.linux-riscv64-gnu.node", + "files": [ + "skia.linux-riscv64-gnu.node" + ], + "description": "Canvas for Node.js with skia backend", + "keywords": [ + "napi-rs", + "NAPI", + "N-API", + "Rust", + "node-addon", + "node-addon-api", + "canvas", + "image", + "pdf", + "svg", + "skia" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org/", + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Brooooooklyn/canvas.git" + }, + "libc": [ + "glibc" + ] +} \ No newline at end of file diff --git a/npm/linux-x64-gnu/package.json b/npm/linux-x64-gnu/package.json index df2bc6b5..a5bd2b6d 100644 --- a/npm/linux-x64-gnu/package.json +++ b/npm/linux-x64-gnu/package.json @@ -7,9 +7,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "main": "skia.linux-x64-gnu.node", "files": [ "skia.linux-x64-gnu.node" @@ -39,5 +36,8 @@ "repository": { "type": "git", "url": "git+https://github.com/Brooooooklyn/canvas.git" - } + }, + "libc": [ + "glibc" + ] } \ No newline at end of file diff --git a/npm/linux-x64-musl/package.json b/npm/linux-x64-musl/package.json index d000606b..de951db6 100644 --- a/npm/linux-x64-musl/package.json +++ b/npm/linux-x64-musl/package.json @@ -8,9 +8,6 @@ "x64" ], "main": "skia.linux-x64-musl.node", - "libc": [ - "musl" - ], "files": [ "skia.linux-x64-musl.node" ], @@ -39,5 +36,8 @@ "repository": { "type": "git", "url": "git+https://github.com/Brooooooklyn/canvas.git" - } + }, + "libc": [ + "musl" + ] } \ No newline at end of file diff --git a/npm/win32-x64-msvc/package.json b/npm/win32-x64-msvc/package.json index 18c3d48d..59a92d84 100644 --- a/npm/win32-x64-msvc/package.json +++ b/npm/win32-x64-msvc/package.json @@ -9,8 +9,7 @@ ], "main": "skia.win32-x64-msvc.node", "files": [ - "skia.win32-x64-msvc.node", - "icudtl.dat" + "skia.win32-x64-msvc.node" ], "description": "Canvas for Node.js with skia backend", "keywords": [ diff --git a/package.json b/package.json index 4f9448ff..1f165a5a 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,8 @@ "aarch64-unknown-linux-gnu", "aarch64-unknown-linux-musl", "aarch64-apple-darwin", - "aarch64-linux-android" + "aarch64-linux-android", + "riscv64-unknown-linux-gnu" ] } }, diff --git a/scripts/build-skia.js b/scripts/build-skia.js index bbca58b3..8b44bec6 100644 --- a/scripts/build-skia.js +++ b/scripts/build-skia.js @@ -29,8 +29,8 @@ if (process.env.SKIP_SYNC_SK_DEPS !== 'false' && process.env.SKIP_SYNC_SK_DEPS ! exec('python ./tools/git-sync-deps') } -const CC = PLATFORM_NAME === 'win32' ? '\\"clang-cl\\"' : '"clang"' -const CXX = PLATFORM_NAME === 'win32' ? '\\"clang-cpp\\"' : '"clang++"' +let CC = PLATFORM_NAME === 'win32' ? '\\"clang-cl\\"' : '"clang"' +let CXX = PLATFORM_NAME === 'win32' ? '\\"clang-cpp\\"' : '"clang++"' let ExtraCflagsCC = '' let ExtraSkiaBuildFlag = '' let ExtraCflags @@ -233,6 +233,11 @@ switch (TARGET_TRIPLE) { break case '': break + case 'riscv64gc-unknown-linux-gnu': + ExtraSkiaBuildFlag += ' target_cpu="riscv64" target_os="linux"' + CC = '"riscv64-linux-gnu-gcc"' + CXX = '"riscv64-linux-gnu-g++"' + break; default: throw new TypeError(`[${TARGET_TRIPLE}] is not a valid target`) } diff --git a/scripts/utils.mjs b/scripts/utils.mjs index bf6df7f8..b3bfaaaa 100644 --- a/scripts/utils.mjs +++ b/scripts/utils.mjs @@ -56,6 +56,9 @@ export function libPath(lib, hostPlatform, triple, tag = TAG) { case 'aarch64-linux-android': platformName = `lib${lib}-android-aarch64.a` break + case 'riscv64gc-unknown-linux-gnu': + platformName = `lib${lib}-linux-riscv64-gnu.a` + break default: throw new TypeError(`[${triple}] is not a valid target`) }