feat(napi/parser): add more linux-musl targets

This commit is contained in:
Boshen 2024-02-05 20:58:16 +08:00
parent 6fe9300880
commit 839e7c5c22
No known key found for this signature in database
GPG key ID: 234DA6A7079C6801
8 changed files with 134 additions and 35 deletions

View file

@ -62,11 +62,19 @@ jobs:
target: aarch64-unknown-linux-gnu target: aarch64-unknown-linux-gnu
code-target: linux-arm64-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 target: x86_64-apple-darwin
code-target: darwin-x64 code-target: darwin-x64
- os: macos-14 - os: macos-latest
target: aarch64-apple-darwin target: aarch64-apple-darwin
code-target: darwin-arm64 code-target: darwin-arm64
@ -75,14 +83,41 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - 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 - name: Install cross
if: ${{ !contains(matrix.target, 'musl') }}
uses: taiki-e/install-action@cross uses: taiki-e/install-action@cross
### Build
- name: Add Rust Target - name: Add Rust Target
run: rustup target add ${{ matrix.target }} run: rustup target add ${{ matrix.target }}
- name: Build with cross - 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 }} - name: Move file on ${{ matrix.os }}
shell: bash shell: bash
@ -94,7 +129,7 @@ jobs:
- name: Test - name: Test
working-directory: napi/parser 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: | run: |
ls ls
node test.mjs node test.mjs
@ -115,7 +150,7 @@ jobs:
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
if-no-files-found: error if-no-files-found: error
name: binaries name: binaries-${{ matrix.code-target }}
path: | path: |
*.zip *.zip
*.tar.gz *.tar.gz
@ -124,7 +159,6 @@ jobs:
name: Publish NAPI name: Publish NAPI
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: write # for softprops/action-gh-release@v1
id-token: write # for `npm publish --provenance` id-token: write # for `npm publish --provenance`
needs: needs:
- build - build
@ -140,7 +174,7 @@ jobs:
- name: Download Artifacts - name: Download Artifacts
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: binaries merge-multiple: true
- name: Unzip - name: Unzip
uses: montudor/action-zip@v1 uses: montudor/action-zip@v1

View file

@ -36,6 +36,10 @@ export function parseSync(sourceText: string, options?: ParserOptions | undefine
/** /**
* Returns a binary AST in flexbuffers format. * Returns a binary AST in flexbuffers format.
* This is a POC API. Error handling is not done yet. * 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 export function parseSyncBuffer(sourceText: string, options?: ParserOptions | undefined | null): Buffer
/** /**

View file

@ -17,7 +17,7 @@ function isMusl() {
// For Node 10 // For Node 10
if (!process.report || typeof process.report.getReport !== 'function') { if (!process.report || typeof process.report.getReport !== 'function') {
try { 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') return readFileSync(lddPath, 'utf8').includes('musl')
} catch (e) { } catch (e) {
return true return true
@ -237,6 +237,49 @@ switch (platform) {
loadError = e loadError = e
} }
break 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: default:
throw new Error(`Unsupported architecture on Linux: ${arch}`) throw new Error(`Unsupported architecture on Linux: ${arch}`)
} }

View file

@ -6,7 +6,7 @@
"test": "node test.mjs" "test": "node test.mjs"
}, },
"devDependencies": { "devDependencies": {
"@napi-rs/cli": "^2.15.2", "@napi-rs/cli": "^2.18.0",
"flatbuffers": "^23.5.26" "flatbuffers": "^23.5.26"
}, },
"engines": { "engines": {
@ -22,6 +22,8 @@
"aarch64-pc-windows-msvc", "aarch64-pc-windows-msvc",
"x86_64-unknown-linux-gnu", "x86_64-unknown-linux-gnu",
"aarch64-unknown-linux-gnu", "aarch64-unknown-linux-gnu",
"x86_64-unknown-linux-musl",
"aarch64-unknown-linux-musl",
"x86_64-apple-darwin", "x86_64-apple-darwin",
"aarch64-apple-darwin" "aarch64-apple-darwin"
] ]

View file

@ -1,17 +1,21 @@
lockfileVersion: '6.0' lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
devDependencies: devDependencies:
'@napi-rs/cli': '@napi-rs/cli':
specifier: ^2.15.2 specifier: ^2.18.0
version: 2.15.2 version: 2.18.0
flatbuffers: flatbuffers:
specifier: ^23.5.26 specifier: ^23.5.26
version: 23.5.26 version: 23.5.26
packages: packages:
/@napi-rs/cli@2.15.2: /@napi-rs/cli@2.18.0:
resolution: {integrity: sha512-80tBCtCnEhAmFtB9oPM0FL74uW7fAmtpeqjvERH7Q1z/aZzCAs/iNfE7U3ehpwg9Q07Ob2Eh/+1guyCdX/p24w==} resolution: {integrity: sha512-lfSRT7cs3iC4L+kv9suGYQEezn5Nii7Kpu+THsYVI0tA1Vh59LH45p4QADaD7hvIkmOz79eEGtoKQ9nAkAPkzA==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
hasBin: true hasBin: true
dev: true dev: true

View file

@ -1,13 +1,12 @@
{ {
"name": "oxc-parser", "name": "oxc-parser",
"version": "0.2.0", "version": "0.3.0-alpha.0",
"description": "Oxc Parser Node API", "description": "Oxc Parser Node API",
"main": "index.js", "keywords": ["Parser"],
"files": [ "author": "Boshen and oxc contributors",
"index.d.ts",
"index.js"
],
"license": "MIT", "license": "MIT",
"homepage": "https://oxc-project.github.io",
"bugs": "https://github.com/oxc-project/oxc/issues",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/oxc-project/oxc.git", "url": "https://github.com/oxc-project/oxc.git",
@ -15,5 +14,10 @@
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/Boshen" "url": "https://github.com/sponsors/Boshen"
} },
"main": "index.js",
"files": [
"index.d.ts",
"index.js"
]
} }

View file

@ -14,6 +14,11 @@ console.log('PACKAGES_ROOT', PACKAGES_ROOT);
console.log('BINARY_ROOT', BINARY_ROOT); console.log('BINARY_ROOT', BINARY_ROOT);
console.log('MANIFEST_PATH', MANIFEST_PATH); console.log('MANIFEST_PATH', MANIFEST_PATH);
const LIBC_MAPPING = {
"gnu": "glibc",
"musl": "musl",
}
const rootManifest = JSON.parse( const rootManifest = JSON.parse(
fs.readFileSync(MANIFEST_PATH).toString("utf-8") fs.readFileSync(MANIFEST_PATH).toString("utf-8")
); );
@ -21,7 +26,6 @@ const rootManifest = JSON.parse(
function package_name(target) { function package_name(target) {
return `@oxc-parser/binding-${target}` return `@oxc-parser/binding-${target}`
} }
function generateNativePackage(target) { function generateNativePackage(target) {
const binaryName = `parser.${target}.node`; const binaryName = `parser.${target}.node`;
@ -38,24 +42,25 @@ function generateNativePackage(target) {
fs.mkdirSync(packageRoot); fs.mkdirSync(packageRoot);
// Generate the package.json manifest // 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 = { const manifest = {
name: package_name(target), name: package_name(target),
version, version,
main: binaryName, author,
files: [binaryName],
os: [os],
cpu: [cpu],
license, license,
repository homepage,
bugs,
repository,
os: [platform],
cpu: [arch],
...libc
}; };
if (cpu == "linux" && third == "gnu") {
manifest.libc = ["glibc"];
}
const manifestPath = resolve(packageRoot, "package.json"); const manifestPath = resolve(packageRoot, "package.json");
console.log(`Create manifest ${manifestPath}`); console.log(`Create manifest ${manifestPath}`);
fs.writeFileSync(manifestPath, JSON.stringify(manifest)); fs.writeFileSync(manifestPath, JSON.stringify(manifest));
@ -94,11 +99,14 @@ function writeManifest() {
} }
} }
// NOTE: Must update npm/oxc-parser/package.json
const TARGETS = [ const TARGETS = [
"win32-x64-msvc", "win32-x64-msvc",
"win32-arm64-msvc", "win32-arm64-msvc",
"linux-x64-gnu", "linux-x64-gnu",
"linux-arm64-gnu", "linux-arm64-gnu",
"linux-x64-musl",
"linux-arm64-musl",
"darwin-x64", "darwin-x64",
"darwin-arm64", "darwin-arm64",
]; ];

View file

@ -38,7 +38,7 @@ function generateNativePackage(target) {
const platform = triple[0]; const platform = triple[0];
const arch = triple[1]; const arch = triple[1];
const libc = triple[2] && { libc: [LIBC_MAPPING[triple[2]]] } const libc = triple[2] && { libc: [LIBC_MAPPING[triple[2]]] }
const manifest = JSON.stringify({ const manifest = {
name: packageName, name: packageName,
version, version,
author, author,
@ -49,11 +49,11 @@ function generateNativePackage(target) {
os: [platform], os: [platform],
cpu: [arch], cpu: [arch],
...libc ...libc
}); };
const manifestPath = resolve(packageRoot, "package.json"); const manifestPath = resolve(packageRoot, "package.json");
console.log(`Create manifest ${manifestPath}`); console.log(`Create manifest ${manifestPath}`);
fs.writeFileSync(manifestPath, manifest); fs.writeFileSync(manifestPath, JSON.stringify(manifest));
// Copy the binary // Copy the binary
const ext = platform === "win32" ? ".exe" : ""; const ext = platform === "win32" ? ".exe" : "";