From 839e7c5c22c9dfd8f75d0632da05d0be6be5d071 Mon Sep 17 00:00:00 2001 From: Boshen Date: Mon, 5 Feb 2024 20:58:16 +0800 Subject: [PATCH] feat(napi/parser): add more linux-musl targets --- .github/workflows/release_napi_parser.yml | 48 +++++++++++++++++--- napi/parser/index.d.ts | 4 ++ napi/parser/index.js | 45 +++++++++++++++++- napi/parser/package.json | 4 +- napi/parser/pnpm-lock.yaml | 12 +++-- npm/oxc-parser/package.json | 18 +++++--- npm/oxc-parser/scripts/generate-packages.mjs | 32 ++++++++----- npm/oxlint/scripts/generate-packages.mjs | 6 +-- 8 files changed, 134 insertions(+), 35 deletions(-) diff --git a/.github/workflows/release_napi_parser.yml b/.github/workflows/release_napi_parser.yml index e71972ffaddc7..ec5f5efe98a9a 100644 --- a/.github/workflows/release_napi_parser.yml +++ b/.github/workflows/release_napi_parser.yml @@ -62,11 +62,19 @@ jobs: target: aarch64-unknown-linux-gnu code-target: linux-arm64-gnu - - os: macos-14 + - os: ubuntu-latest + target: x86_64-unknown-linux-musl + code-target: linux-x64-musl + + - os: ubuntu-latest + target: aarch64-unknown-linux-musl + code-target: linux-arm64-musl + + - os: macos-latest target: x86_64-apple-darwin code-target: darwin-x64 - - os: macos-14 + - os: macos-latest target: aarch64-apple-darwin code-target: darwin-arm64 @@ -75,14 +83,41 @@ jobs: steps: - uses: actions/checkout@v4 + ### install musl dependencies ### + # + - uses: goto-bus-stop/setup-zig@v2 + if: ${{ contains(matrix.target, 'musl') }} + with: + version: 0.11.0 + + - name: Install cargo-zigbuild + if: ${{ contains(matrix.target, 'musl') }} + uses: taiki-e/install-action@v2 + with: + tool: cargo-zigbuild + + ### install non-musl dependencies ### + - name: Install cross + if: ${{ !contains(matrix.target, 'musl') }} uses: taiki-e/install-action@cross + ### Build + - name: Add Rust Target run: rustup target add ${{ matrix.target }} - name: Build with cross - run: cross build -p oxc_napi_parser --release --target=${{ matrix.target }} + if: ${{ !contains(matrix.target, 'musl') }} + run: cross build --release -p oxc_parser_napi --target=${{ matrix.target }} + + - name: Build with zig + if: ${{ contains(matrix.target, 'musl') }} + env: + RUSTFLAGS: "-C target-feature=-crt-static" + run: cargo zigbuild --release -p oxc_parser_napi --target=${{ matrix.target }} + + ### Build Done - name: Move file on ${{ matrix.os }} shell: bash @@ -94,7 +129,7 @@ jobs: - name: Test working-directory: napi/parser - if: ${{ contains(matrix.target, 'x86') }} # Need docker for aarch64 + if: ${{ contains(matrix.target, 'x86') && !contains(matrix.target, 'musl') }} # Need docker for aarch64 run: | ls node test.mjs @@ -115,7 +150,7 @@ jobs: uses: actions/upload-artifact@v4 with: if-no-files-found: error - name: binaries + name: binaries-${{ matrix.code-target }} path: | *.zip *.tar.gz @@ -124,7 +159,6 @@ jobs: name: Publish NAPI runs-on: ubuntu-latest permissions: - contents: write # for softprops/action-gh-release@v1 id-token: write # for `npm publish --provenance` needs: - build @@ -140,7 +174,7 @@ jobs: - name: Download Artifacts uses: actions/download-artifact@v4 with: - name: binaries + merge-multiple: true - name: Unzip uses: montudor/action-zip@v1 diff --git a/napi/parser/index.d.ts b/napi/parser/index.d.ts index 33839a5476860..11ed4b548bf7d 100644 --- a/napi/parser/index.d.ts +++ b/napi/parser/index.d.ts @@ -36,6 +36,10 @@ export function parseSync(sourceText: string, options?: ParserOptions | undefine /** * Returns a binary AST in flexbuffers format. * This is a POC API. Error handling is not done yet. + * # Panics + * + * * File extension is invalid + * * FlexbufferSerializer serialization error */ export function parseSyncBuffer(sourceText: string, options?: ParserOptions | undefined | null): Buffer /** diff --git a/napi/parser/index.js b/napi/parser/index.js index 04ba67650636e..4b1b9d040c71a 100644 --- a/napi/parser/index.js +++ b/napi/parser/index.js @@ -17,7 +17,7 @@ function isMusl() { // For Node 10 if (!process.report || typeof process.report.getReport !== 'function') { try { - const lddPath = require('child_process').execSync('which ldd').toString().trim(); + const lddPath = require('child_process').execSync('which ldd').toString().trim() return readFileSync(lddPath, 'utf8').includes('musl') } catch (e) { return true @@ -237,6 +237,49 @@ switch (platform) { loadError = e } break + case 'riscv64': + if (isMusl()) { + localFileExisted = existsSync( + join(__dirname, 'parser.linux-riscv64-musl.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./parser.linux-riscv64-musl.node') + } else { + nativeBinding = require('@oxc-parser/binding-linux-riscv64-musl') + } + } catch (e) { + loadError = e + } + } else { + localFileExisted = existsSync( + join(__dirname, 'parser.linux-riscv64-gnu.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./parser.linux-riscv64-gnu.node') + } else { + nativeBinding = require('@oxc-parser/binding-linux-riscv64-gnu') + } + } catch (e) { + loadError = e + } + } + break + case 's390x': + localFileExisted = existsSync( + join(__dirname, 'parser.linux-s390x-gnu.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./parser.linux-s390x-gnu.node') + } else { + nativeBinding = require('@oxc-parser/binding-linux-s390x-gnu') + } + } catch (e) { + loadError = e + } + break default: throw new Error(`Unsupported architecture on Linux: ${arch}`) } diff --git a/napi/parser/package.json b/napi/parser/package.json index bb83b71694f20..12a42dfbf646a 100644 --- a/napi/parser/package.json +++ b/napi/parser/package.json @@ -6,7 +6,7 @@ "test": "node test.mjs" }, "devDependencies": { - "@napi-rs/cli": "^2.15.2", + "@napi-rs/cli": "^2.18.0", "flatbuffers": "^23.5.26" }, "engines": { @@ -22,6 +22,8 @@ "aarch64-pc-windows-msvc", "x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", + "aarch64-unknown-linux-musl", "x86_64-apple-darwin", "aarch64-apple-darwin" ] diff --git a/napi/parser/pnpm-lock.yaml b/napi/parser/pnpm-lock.yaml index 692536a9e0d9f..0050cba45c9b0 100644 --- a/napi/parser/pnpm-lock.yaml +++ b/napi/parser/pnpm-lock.yaml @@ -1,17 +1,21 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + devDependencies: '@napi-rs/cli': - specifier: ^2.15.2 - version: 2.15.2 + specifier: ^2.18.0 + version: 2.18.0 flatbuffers: specifier: ^23.5.26 version: 23.5.26 packages: - /@napi-rs/cli@2.15.2: - resolution: {integrity: sha512-80tBCtCnEhAmFtB9oPM0FL74uW7fAmtpeqjvERH7Q1z/aZzCAs/iNfE7U3ehpwg9Q07Ob2Eh/+1guyCdX/p24w==} + /@napi-rs/cli@2.18.0: + resolution: {integrity: sha512-lfSRT7cs3iC4L+kv9suGYQEezn5Nii7Kpu+THsYVI0tA1Vh59LH45p4QADaD7hvIkmOz79eEGtoKQ9nAkAPkzA==} engines: {node: '>= 10'} hasBin: true dev: true diff --git a/npm/oxc-parser/package.json b/npm/oxc-parser/package.json index 3d17153221250..2a8d58c80378e 100644 --- a/npm/oxc-parser/package.json +++ b/npm/oxc-parser/package.json @@ -1,13 +1,12 @@ { "name": "oxc-parser", - "version": "0.2.0", + "version": "0.3.0-alpha.0", "description": "Oxc Parser Node API", - "main": "index.js", - "files": [ - "index.d.ts", - "index.js" - ], + "keywords": ["Parser"], + "author": "Boshen and oxc contributors", "license": "MIT", + "homepage": "https://oxc-project.github.io", + "bugs": "https://github.com/oxc-project/oxc/issues", "repository": { "type": "git", "url": "https://github.com/oxc-project/oxc.git", @@ -15,5 +14,10 @@ }, "funding": { "url": "https://github.com/sponsors/Boshen" - } + }, + "main": "index.js", + "files": [ + "index.d.ts", + "index.js" + ] } diff --git a/npm/oxc-parser/scripts/generate-packages.mjs b/npm/oxc-parser/scripts/generate-packages.mjs index 9b56e1cc80ce5..459e1d4f5d846 100644 --- a/npm/oxc-parser/scripts/generate-packages.mjs +++ b/npm/oxc-parser/scripts/generate-packages.mjs @@ -14,6 +14,11 @@ console.log('PACKAGES_ROOT', PACKAGES_ROOT); console.log('BINARY_ROOT', BINARY_ROOT); console.log('MANIFEST_PATH', MANIFEST_PATH); +const LIBC_MAPPING = { + "gnu": "glibc", + "musl": "musl", +} + const rootManifest = JSON.parse( fs.readFileSync(MANIFEST_PATH).toString("utf-8") ); @@ -21,7 +26,6 @@ const rootManifest = JSON.parse( function package_name(target) { return `@oxc-parser/binding-${target}` } - function generateNativePackage(target) { const binaryName = `parser.${target}.node`; @@ -38,24 +42,25 @@ function generateNativePackage(target) { fs.mkdirSync(packageRoot); // Generate the package.json manifest - const { version, license, repository } = rootManifest; + const { version, author, license, homepage, bugs, repository } = rootManifest; - const [os, cpu, third] = target.split("-"); + const triple = target.split("-"); + const platform = triple[0]; + const arch = triple[1]; + const libc = triple[2] && { libc: [LIBC_MAPPING[triple[2]]] } const manifest = { name: package_name(target), version, - main: binaryName, - files: [binaryName], - os: [os], - cpu: [cpu], + author, license, - repository + homepage, + bugs, + repository, + os: [platform], + cpu: [arch], + ...libc }; - if (cpu == "linux" && third == "gnu") { - manifest.libc = ["glibc"]; - } - const manifestPath = resolve(packageRoot, "package.json"); console.log(`Create manifest ${manifestPath}`); fs.writeFileSync(manifestPath, JSON.stringify(manifest)); @@ -94,11 +99,14 @@ function writeManifest() { } } +// NOTE: Must update npm/oxc-parser/package.json const TARGETS = [ "win32-x64-msvc", "win32-arm64-msvc", "linux-x64-gnu", "linux-arm64-gnu", + "linux-x64-musl", + "linux-arm64-musl", "darwin-x64", "darwin-arm64", ]; diff --git a/npm/oxlint/scripts/generate-packages.mjs b/npm/oxlint/scripts/generate-packages.mjs index 3852362fa8f17..00245d8be1f68 100644 --- a/npm/oxlint/scripts/generate-packages.mjs +++ b/npm/oxlint/scripts/generate-packages.mjs @@ -38,7 +38,7 @@ function generateNativePackage(target) { const platform = triple[0]; const arch = triple[1]; const libc = triple[2] && { libc: [LIBC_MAPPING[triple[2]]] } - const manifest = JSON.stringify({ + const manifest = { name: packageName, version, author, @@ -49,11 +49,11 @@ function generateNativePackage(target) { os: [platform], cpu: [arch], ...libc - }); + }; const manifestPath = resolve(packageRoot, "package.json"); console.log(`Create manifest ${manifestPath}`); - fs.writeFileSync(manifestPath, manifest); + fs.writeFileSync(manifestPath, JSON.stringify(manifest)); // Copy the binary const ext = platform === "win32" ? ".exe" : "";