From 810a662998ee1434eed3ba492a6fbf8a103a8735 Mon Sep 17 00:00:00 2001 From: dengribar Date: Mon, 19 Dec 2022 14:04:51 +0400 Subject: [PATCH] feat: add "musl" builds for Alpine Linux --- .cargo/config.toml | 3 ++ .github/workflows/CI.yml | 86 ++++++++++++++++++++++++++++++- README.md | 6 ++- index.js | 72 ++++++++++++++++++++------ npm/linux-arm64-musl/README.md | 3 ++ npm/linux-arm64-musl/package.json | 21 ++++++++ npm/linux-x64-musl/README.md | 3 ++ npm/linux-x64-musl/package.json | 21 ++++++++ package.json | 4 +- 9 files changed, 199 insertions(+), 20 deletions(-) create mode 100644 npm/linux-arm64-musl/README.md create mode 100644 npm/linux-arm64-musl/package.json create mode 100644 npm/linux-x64-musl/README.md create mode 100644 npm/linux-x64-musl/package.json diff --git a/.cargo/config.toml b/.cargo/config.toml index 3c32d25..2afeb28 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,5 @@ [target.aarch64-unknown-linux-gnu] linker = "aarch64-linux-gnu-gcc" +[target.aarch64-unknown-linux-musl] +linker = "aarch64-linux-musl-gcc" +rustflags = ["-C", "target-feature=-crt-static"] diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 51d8ee6..3518d50 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -18,7 +18,7 @@ env: pull_request: null jobs: build: - if: '!contains(github.event.head_commit.message, ''skip ci'')' + if: "!contains(github.event.head_commit.message, 'skip ci')" strategy: fail-fast: false matrix: @@ -42,6 +42,10 @@ jobs: rustup target add x86_64-unknown-linux-gnu && npm run build -- --target x86_64-unknown-linux-gnu --zig --zig-abi-suffix 2.12 && llvm-strip -x *.node + - host: ubuntu-latest + target: x86_64-unknown-linux-musl + docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine + build: set -e && npm run build && strip *.node - host: macos-latest architecture: x64 target: aarch64-apple-darwin @@ -62,6 +66,14 @@ jobs: rustup target add aarch64-unknown-linux-gnu && npm run build -- --target aarch64-unknown-linux-gnu --zig --zig-abi-suffix 2.17 && llvm-strip -x *.node + - host: ubuntu-latest + target: aarch64-unknown-linux-musl + docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine + build: |- + set -e && + rustup target add aarch64-unknown-linux-musl && + npm run build -- --target aarch64-unknown-linux-musl && + /aarch64-linux-musl-cross/bin/aarch64-linux-musl-strip *.node name: stable - ${{ matrix.settings.target }} - node@16 runs-on: ${{ matrix.settings.host }} steps: @@ -204,6 +216,44 @@ jobs: shell: bash - name: Test bindings run: docker run --rm -v $(pwd):/build -w /build node:${{ matrix.node }}-slim npm test + test-linux-x64-musl-binding: + name: Test bindings on x86_64-unknown-linux-musl - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + node: + - '12' + - '14' + - '16' + - '18' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node }} + check-latest: true + cache: npm + - name: Cache NPM dependencies + uses: actions/cache@v3 + with: + path: node_modules + key: npm-cache-test-x86_64-unknown-linux-musl-${{ matrix.node }}-${{ hashFiles('package-lock.json') }} + - name: Install dependencies + run: npm clean-install --ignore-scripts + - name: Download artifacts + uses: actions/download-artifact@v3 + with: + name: bindings-x86_64-unknown-linux-musl + path: . + - name: List packages + run: ls -R . + shell: bash + - name: Test bindings + run: docker run --rm -v $(pwd):/build -w /build node:${{ matrix.node }}-alpine npm test test-linux-aarch64-gnu-binding: name: Test bindings on aarch64-unknown-linux-gnu - node@${{ matrix.node }} needs: @@ -244,13 +294,47 @@ jobs: set -e npm test ls -la + test-linux-aarch64-musl-binding: + name: Test bindings on aarch64-unknown-linux-musl - node@${{ matrix.node }} + needs: + - build + runs-on: ubuntu-latest + steps: + - run: docker run --rm --privileged multiarch/qemu-user-static:register --reset + - uses: actions/checkout@v3 + - name: Download artifacts + uses: actions/download-artifact@v3 + with: + name: bindings-aarch64-unknown-linux-musl + path: . + - name: List packages + run: ls -R . + shell: bash + - name: Cache NPM dependencies + uses: actions/cache@v3 + with: + path: node_modules + key: npm-cache-test-linux-aarch64-musl-${{ matrix.node }}-${{ hashFiles('package-lock.json') }} + - name: Install dependencies + run: npm clean-install --ignore-scripts + - name: Setup and run tests + uses: addnab/docker-run-action@v3 + with: + image: multiarch/alpine:aarch64-latest-stable + options: '-v ${{ github.workspace }}:/build -w /build' + run: | + set -e + apk add nodejs npm + npm test publish: name: Publish runs-on: ubuntu-latest needs: - test-macOS-windows-binding - test-linux-x64-gnu-binding + - test-linux-x64-musl-binding - test-linux-aarch64-gnu-binding + - test-linux-aarch64-musl-binding steps: - uses: actions/checkout@v3 - name: Setup node diff --git a/README.md b/README.md index f721b12..12fe1a8 100644 --- a/README.md +++ b/README.md @@ -20,12 +20,14 @@ npm install @mongodb-js/zstd | Linux x64 gnu | ✓ | ✓ | ✓ | ✓ | | Linux arm gnu | ✓ | ✓ | ✓ | ✓ | | Linux arm64 gnu | ✓ | ✓ | ✓ | ✓ | +| Linux x64 musl | ✓ | ✓ | ✓ | ✓ | +| Linux arm64 musl | ✓ | ✓ | ✓ | ✓ | ## API ```ts -export function compress(buffer: Buffer | ArrayBuffer | Uint8Array, level: number): Promise -export function decompress(buffer: Buffer): Promise +export function compress(buffer: Buffer | ArrayBuffer | Uint8Array, level: number): Promise; +export function decompress(buffer: Buffer): Promise; ``` ### Bugs / Feature Requests diff --git a/index.js b/index.js index 64354f1..e411226 100644 --- a/index.js +++ b/index.js @@ -7,6 +7,20 @@ let nativeBinding = null; let localFileExisted = false; let loadError = null; +function isMusl() { + // For Node 10 + if (!process.report || typeof process.report.getReport !== 'function') { + try { + return readFileSync('/usr/bin/ldd', 'utf8').includes('musl'); + } catch (e) { + return true; + } + } else { + const { glibcVersionRuntime } = process.report.getReport().header; + return !glibcVersionRuntime; + } +} + switch (platform) { case 'win32': switch (arch) { @@ -59,27 +73,53 @@ switch (platform) { case 'linux': switch (arch) { case 'x64': - localFileExisted = existsSync(join(__dirname, 'zstd.linux-x64-gnu.node')); - try { - if (localFileExisted) { - nativeBinding = require('./zstd.linux-x64-gnu.node'); - } else { - nativeBinding = require('@mongodb-js/zstd-linux-x64-gnu'); + if (isMusl()) { + localFileExisted = existsSync(join(__dirname, 'zstd.linux-x64-musl.node')); + try { + if (localFileExisted) { + nativeBinding = require('./zstd.linux-x64-musl.node'); + } else { + nativeBinding = require('@mongodb-js/zstd-linux-x64-musl'); + } + } catch (e) { + loadError = e; + } + } else { + localFileExisted = existsSync(join(__dirname, 'zstd.linux-x64-gnu.node')); + try { + if (localFileExisted) { + nativeBinding = require('./zstd.linux-x64-gnu.node'); + } else { + nativeBinding = require('@mongodb-js/zstd-linux-x64-gnu'); + } + } catch (e) { + loadError = e; } - } catch (e) { - loadError = e; } break; case 'arm64': - localFileExisted = existsSync(join(__dirname, 'zstd.linux-arm64-gnu.node')); - try { - if (localFileExisted) { - nativeBinding = require('./zstd.linux-arm64-gnu.node'); - } else { - nativeBinding = require('@mongodb-js/zstd-linux-arm64-gnu'); + if (isMusl()) { + localFileExisted = existsSync(join(__dirname, 'zstd.linux-arm64-musl.node')); + try { + if (localFileExisted) { + nativeBinding = require('./zstd.linux-arm64-musl.node'); + } else { + nativeBinding = require('@mongodb-js/zstd-linux-arm64-musl'); + } + } catch (e) { + loadError = e; + } + } else { + localFileExisted = existsSync(join(__dirname, 'zstd.linux-arm64-gnu.node')); + try { + if (localFileExisted) { + nativeBinding = require('./zstd.linux-arm64-gnu.node'); + } else { + nativeBinding = require('@mongodb-js/zstd-linux-arm64-gnu'); + } + } catch (e) { + loadError = e; } - } catch (e) { - loadError = e; } break; case 'arm': diff --git a/npm/linux-arm64-musl/README.md b/npm/linux-arm64-musl/README.md new file mode 100644 index 0000000..7547d39 --- /dev/null +++ b/npm/linux-arm64-musl/README.md @@ -0,0 +1,3 @@ +# `@mongodb-js/zstd-linux-arm64-musl` + +This is the **aarch64-unknown-linux-musl** binary for `@mongodb-js/zstd` diff --git a/npm/linux-arm64-musl/package.json b/npm/linux-arm64-musl/package.json new file mode 100644 index 0000000..9088e85 --- /dev/null +++ b/npm/linux-arm64-musl/package.json @@ -0,0 +1,21 @@ +{ + "name": "@mongodb-js/zstd-linux-arm64-musl", + "version": "0.0.0", + "os": [ + "linux" + ], + "cpu": [ + "arm64" + ], + "main": "zstd.linux-arm64-musl.node", + "files": [ + "zstd.linux-arm64-musl.node" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "libc": [ + "musl" + ] +} diff --git a/npm/linux-x64-musl/README.md b/npm/linux-x64-musl/README.md new file mode 100644 index 0000000..d656011 --- /dev/null +++ b/npm/linux-x64-musl/README.md @@ -0,0 +1,3 @@ +# `@mongodb-js/zstd-linux-x64-musl` + +This is the **x86_64-unknown-linux-musl** binary for `@mongodb-js/zstd` diff --git a/npm/linux-x64-musl/package.json b/npm/linux-x64-musl/package.json new file mode 100644 index 0000000..ebcebe2 --- /dev/null +++ b/npm/linux-x64-musl/package.json @@ -0,0 +1,21 @@ +{ + "name": "@mongodb-js/zstd-linux-x64-musl", + "version": "0.0.0", + "os": [ + "linux" + ], + "cpu": [ + "x64" + ], + "main": "zstd.linux-x64-musl.node", + "files": [ + "zstd.linux-x64-musl.node" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "libc": [ + "musl" + ] +} diff --git a/package.json b/package.json index cac8cf9..a3a8c1d 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,9 @@ "defaults": true, "additional": [ "aarch64-apple-darwin", - "aarch64-unknown-linux-gnu" + "aarch64-unknown-linux-gnu", + "aarch64-unknown-linux-musl", + "x86_64-unknown-linux-musl" ] } },