diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index f09aa672..00000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,25 +0,0 @@ -[target.arm-unknown-linux-gnueabihf] -linker = "arm-linux-gnueabihf-gcc" -rustflags = [ - "-L", - "/usr/lib/arm-linux-gnueabihf", - "-L", - "/usr/arm-linux-gnueabihf/lib", -] - -[target.aarch64-unknown-linux-gnu] -linker = "aarch64-linux-gnu-gcc" - -[target.x86_64-unknown-linux-gnu] -linker = "x86_64-linux-gnu-gcc" - - -[target.x86_64-unknown-linux-musl] -rustflags = [ - "-C", - "target-feature=-crt-static", -] - -[target.aarch64-unknown-linux-musl] -linker = "aarch64-linux-musl-gcc" -rustflags = ["-C", "target-feature=-crt-static"] diff --git a/.editorconfig b/.editorconfig index 856ace39..ec118333 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,17 +5,14 @@ root = true [*] indent_style = space -indent_size = 4 +indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -[*.js] -indent_size = 2 - -[*.mjs] -indent_size = 2 +[*.rs] +indent_size = 4 [*.md] trim_trailing_whitespace = false diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index dca454da..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,142 +0,0 @@ -name: build -env: - DEBUG: napi:* - APP_NAME: node-web-audio-api - MACOSX_DEPLOYMENT_TARGET: '10.13' -on: - create: - tags: - - v* - pull_request: null - workflow_dispatch: - -jobs: - checks: - runs-on: ubuntu-latest - steps: - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@stable - with: - toolchain: stable - components: clippy - - - name: Install ALSA and Jack dependencies - run: | - sudo apt-get update && sudo apt-get install -y libasound2-dev libjack-jackd2-dev - - - name: Check out repository - uses: actions/checkout@v4 - - - name: Generate Cargo.lock - run: cargo generate-lockfile - - - name: Clippy - run: cargo clippy --all-features -- -D warnings - - # - name: Lint - # run: npm run lint - - build: - needs: checks - if: "!contains(github.event.head_commit.message, 'skip ci')" - strategy: - fail-fast: false - matrix: - settings: - # --------------------------------------------------------- - # MAC - # --------------------------------------------------------- - - # Intel x86_64 - - host: macos-latest - target: x86_64-apple-darwin - architecture: x64 - build: | - npm run build -- --target x86_64-apple-darwin - strip -x *.node - - # ARM64 - - host: macos-latest - target: aarch64-apple-darwin - architecture: x64 - build: | - npm run build -- --target aarch64-apple-darwin - strip -x *.node - - # --------------------------------------------------------- - # WINDOWS - # --------------------------------------------------------- - - # Intel x86_64 - - host: windows-latest - target: x86_64-pc-windows-msvc - architecture: x64 - build: npm run build - - # ARM64 - - host: windows-latest - target: aarch64-pc-windows-msvc - architecture: x64 - build: npm run build -- --target aarch64-pc-windows-msvc - - # --------------------------------------------------------- - # Linux requires libasound2-dev which is a mess to do remotely - # in particular for RPi, do it locally and workaround... - # --------------------------------------------------------- - - name: stable - ${{ matrix.settings.target }} - node@22.1 - runs-on: ${{ matrix.settings.host }} - steps: - - uses: actions/checkout@v4 - - name: Setup node - uses: actions/setup-node@v4 - with: - node-version: 22.1 - check-latest: true - architecture: ${{ matrix.settings.architecture }} - - - name: Setup Rust toolchain - uses: dtolnay/rust-toolchain@stable - with: - toolchain: stable - targets: ${{ matrix.settings.target }} - - - name: Generate Cargo.lock - run: cargo generate-lockfile - - - name: Cache cargo - uses: actions/cache@v4 - with: - path: | - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - .cargo-cache - target/ - key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.host }} - - - name: Pull latest image - run: ${{ matrix.settings.docker }} - env: - DOCKER_REGISTRY_URL: ghcr.io - if: ${{ matrix.settings.docker }} - - - name: Setup toolchain - run: ${{ matrix.settings.setup }} - if: ${{ matrix.settings.setup }} - shell: bash - - - name: Install dependencies - run: npm install - - - name: Build - run: ${{ matrix.settings.build }} - shell: bash - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: bindings-${{ matrix.settings.target }} - path: ${{ env.APP_NAME }}.*.node - if-no-files-found: error - diff --git a/.github/workflows/matrix-build.yaml b/.github/workflows/matrix-build.yaml new file mode 100644 index 00000000..2ef06762 --- /dev/null +++ b/.github/workflows/matrix-build.yaml @@ -0,0 +1,140 @@ +name: matrix-build +env: + DEBUG: napi:* + PROJECT_NAME: node-web-audio-api + CARGO_BUILD_NAME: node_web_audio_api + MACOSX_DEPLOYMENT_TARGET: '10.13' + CARGO_TERM_COLOR: always + +on: + push: + tags: + - '*' + workflow_dispatch: + +jobs: + verify-build: + uses: ./.github/workflows/verify-build.yaml + + matrix-build: + needs: verify-build + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - name: darwin-arm64 + runner: macos-latest + target: aarch64-apple-darwin + command: cargo + + - name: darwin-x64 + runner: macos-latest + target: x86_64-apple-darwin + command: cargo + + - name: win32-arm64-msvc + runner: windows-latest + target: aarch64-pc-windows-msvc + command: cargo + + - name: win32-x64-msvc + runner: windows-latest + target: x86_64-pc-windows-msvc + command: cargo + + - name: linux-arm64-gnu + runner: ubuntu-latest + target: aarch64-unknown-linux-gnu + command: cross + + - name: linux-x64-gnu + runner: ubuntu-latest + target: x86_64-unknown-linux-gnu + command: cross + + - name: linux-arm-gnueabihf + runner: ubuntu-latest + target: armv7-unknown-linux-gnueabihf + command: cross + + name: build - ${{ matrix.name }} + steps: + - name: Check out repository + uses: actions/checkout@v4 + + # node is only used to generate the files, can use host architecture + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + + # only install cross (via cargo-binstall) if we need it + - name: Install Cross + if: matrix.command == 'cross' + shell: bash + run: | + curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash + cargo binstall --no-confirm cross + + - name: Generate Cargo.lock + run: cargo generate-lockfile + + - name: Install Deps + run: npm install + + - name: Re-generate files from IDL + run: npm run generate + + - name: Build Binary + shell: bash + run: | + rustup target add ${{ matrix.target }} + + if [[ "${{ matrix.runner }}" == "ubuntu-latest" ]]; then + echo "Build with Jack feature" + ${{ matrix.command }} build --locked --features jack --release --target ${{ matrix.target }} + else + ${{ matrix.command }} build --locked --release --target ${{ matrix.target }} + fi + + - name: Rename Binary + shell: bash + run: | + BIN_PREFIX="" + BIN_SUFFIX="" + + if [[ "${{ matrix.runner }}" == "windows-latest" ]]; then + BIN_PREFIX="" + BIN_SUFFIX=".dll" + elif [[ "${{ matrix.runner }}" == "macos-latest" ]]; then + BIN_PREFIX="lib" + BIN_SUFFIX=".dylib" + elif [[ "${{ matrix.runner }}" == "ubuntu-latest" ]]; then + BIN_PREFIX="lib" + BIN_SUFFIX=".so" + fi + + ls -al target/${{ matrix.target }}/release/ + + # The built binary output location + BIN_OUTPUT="target/${{ matrix.target }}/release/${BIN_PREFIX}${CARGO_BUILD_NAME}${BIN_SUFFIX}" + + # Define a better name for the final binary + BIN_RELEASE="${PROJECT_NAME}.${{ matrix.name }}.node" + + # Move the built binary where you want it + mv "${BIN_OUTPUT}" "./${BIN_RELEASE}" + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: bindings-${{ matrix.name }} + path: ${{ env.PROJECT_NAME }}.${{ matrix.name }}.node + if-no-files-found: error + diff --git a/.github/workflows/verify-build.yaml b/.github/workflows/verify-build.yaml new file mode 100644 index 00000000..50f782a9 --- /dev/null +++ b/.github/workflows/verify-build.yaml @@ -0,0 +1,66 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow + +name: verify-build +env: + MACOSX_DEPLOYMENT_TARGET: '10.13' + CARGO_TERM_COLOR: always + +# read-only repo token, no access to secrets +permissions: + contents: read + +# no access to secrets +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + workflow_call: # make the job callable by matrix-build + +jobs: + verify-build: + # run on macos-latest which seems to have a soundcard available + runs-on: macos-latest + + steps: + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: clippy, rustfmt + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Check out repository + uses: actions/checkout@v4 + + - name: Generate Cargo.lock + run: cargo generate-lockfile + + # restore cargo cache from previous runs + - name: Rust Cache + uses: Swatinem/rust-cache@v2 + with: + # The cache should not be shared between different workflows and jobs. + shared-key: ${{ github.workflow }}-${{ github.job }} + + - name: Install Deps + run: npm install + + # check it builds + - name: Build + run: npm run build + + # run checks and tests + - name: Clippy + # run: cargo clippy --all-features -- -D warnings + run: cargo clippy --all-targets -- -D warnings + - name: Fmt + run: cargo fmt -- --check --color always + - name: Lint + run: npm run lint + - name: Test + run: npm run test:ci + diff --git a/.gitignore b/.gitignore index 0e35d7bd..d1041132 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ NOTES.md /generator/src .DS_Store +_* + # Working files TODOS.md NOTES.md diff --git a/.scripts/BUILD_NOTES.md b/.scripts/BUILD_NOTES.md deleted file mode 100644 index 17e9c901..00000000 --- a/.scripts/BUILD_NOTES.md +++ /dev/null @@ -1,42 +0,0 @@ -# Prepare RPi build systems - -## Install rust - -[https://www.rust-lang.org/tools/install](https://www.rust-lang.org/tools/install) - -```sh -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -``` - -### RPI 4 w/ 32 system - -Choose custom installation: - -``` -1) Proceed with installation (default) -2) Customize installation -3) Cancel installation ->2 - -I'm going to ask you the value of each of these installation options. -You may simply press the Enter key to leave unchanged. - -Default host triple? [aarch64-unknown-linux-gnu] -armv7-unknown-linux-gnueabihf -Default toolchain? (stable/beta/nightly/none) [stable] -Profile (which tools and data to install)? (minimal/default/complete) [default] -``` - -## Install dev libs - -```sh -sudo apt-get install -y libjack-jackd2-dev libasound2-dev -``` - - -# Docker image - -``` -cd ./.scripts/docker_x86_64-unknown-linux-gnu/ -docker build -t bbmmaa/build-x86_64 . -``` diff --git a/.scripts/build-linux-arm32-rpi.mjs b/.scripts/build-linux-arm32-rpi.mjs deleted file mode 100644 index 2fb1b9f3..00000000 --- a/.scripts/build-linux-arm32-rpi.mjs +++ /dev/null @@ -1,106 +0,0 @@ -import * as dotenv from 'dotenv'; -import ping from 'ping'; -import { NodeSSH } from 'node-ssh'; -import fs from 'node:fs'; -import path from 'node:path'; -import { execSync } from 'child_process'; - -dotenv.config({ debug: false }); - -const rpiHostname = process.env.RPI_32_HOSTNAME; -const rpiUser = process.env.RPI_32_USER; -const rpiPrivKey = process.env.RPI_32_PRIVKEY; -const rpiCwd = process.env.RPI_32_CWD; -const binaryFilename = 'node-web-audio-api.linux-arm-gnueabihf.node'; - -console.log(`Check ${rpiHostname} is alive`); -const isAlive = await new Promise((resolve, reject) => { - ping.sys.probe(rpiHostname, resolve, { timeout: 5 }); -}); - -if (!isAlive) { - console.log('Cannot connect to host:', rpiHostname); - console.log('aborting...'); - process.exit(1); -} - -const ssh = new NodeSSH(); - -const conn = await ssh.connect({ - host: rpiHostname, - username: rpiUser, - privateKeyPath: rpiPrivKey, -}); - -let res; - -function logResult(res) { - if (res.stderr !== '') { - console.log('[rpi stderr]', res.stderr); - } - - if (res.stdout !== '') { - console.log('[rpi sdtout]', res.stdout); - } -} - -// @note: by default RPi .bashrc exits early if not in interactive more, some -// lines must be commented on the RPi side -// cf. https://github.com/mscdex/ssh2/issues/77 -console.log('> check node'); -res = await conn.execCommand(`which node`); -logResult(res); - -if (res.stdout == '') { - console.log('node not found, exiting...'); - process.exit(1) -} - -console.log('> check cargo'); -res = await conn.execCommand(`which cargo`); -logResult(res); - -if (res.stdout == '') { - console.log('cargo not found, exiting...'); - process.exit(1) -} - -console.log('> pull source on main'); -res = await conn.execCommand(`git pull origin main`, { cwd: rpiCwd }); -logResult(res); - -console.log('> reinstall node_modules'); -res = await conn.execCommand(`rm -Rf node_modules`, { cwd: rpiCwd }); -logResult(res); -res = await conn.execCommand(`npm install`, { cwd: rpiCwd }); -logResult(res); - -console.log('> rustup upgrade'); -res = await conn.execCommand(`rustup upgrade`, { cwd: rpiCwd }); -logResult(res); - -console.log('> cargo update'); -res = await conn.execCommand(`cargo update`, { cwd: rpiCwd }); -logResult(res); - -console.log('> build binary'); -res = await conn.execCommand(`npm run build:jack`, { cwd: rpiCwd }); -logResult(res); - -console.log('> strip symbols'); -res = await conn.execCommand(`arm-linux-gnueabihf-strip ${binaryFilename}`, { cwd: rpiCwd }); -logResult(res); - -console.log('> list files'); -res = await conn.execCommand(`ls -al`, { cwd: rpiCwd }); -logResult(res); - -console.log('> download binary'); -const remoteFile = path.join(rpiCwd, binaryFilename); -res = execSync(`scp ${rpiUser}@${rpiHostname}:${remoteFile} ${process.cwd()}`); -console.log(res.toString()); - -console.log('Done!'); - -conn.dispose(); - diff --git a/.scripts/build-linux-arm64-rpi.mjs b/.scripts/build-linux-arm64-rpi.mjs deleted file mode 100644 index 21cf73a6..00000000 --- a/.scripts/build-linux-arm64-rpi.mjs +++ /dev/null @@ -1,107 +0,0 @@ -import * as dotenv from 'dotenv'; -import ping from 'ping'; -import { NodeSSH } from 'node-ssh'; -import fs from 'node:fs'; -import path from 'node:path'; -import { execSync } from 'child_process'; - -dotenv.config({ debug: false }); - -const rpiHostname = process.env.RPI_64_HOSTNAME; -const rpiUser = process.env.RPI_64_USER; -const rpiPrivKey = process.env.RPI_64_PRIVKEY; -const rpiCwd = process.env.RPI_64_CWD; -const binaryFilename = 'node-web-audio-api.linux-arm64-gnu.node'; - -console.log(`Check ${rpiHostname} is alive`); -const isAlive = await new Promise((resolve, reject) => { - ping.sys.probe(rpiHostname, resolve, { timeout: 5 }); -}); - -if (!isAlive) { - console.log('Cannot connect to host:', rpiHostname); - console.log('aborting...'); - process.exit(1); -} - -const ssh = new NodeSSH(); - -const conn = await ssh.connect({ - host: rpiHostname, - username: rpiUser, - privateKeyPath: rpiPrivKey, -}); - -let res; - -function logResult(res) { - if (res.stderr !== '') { - console.log('[rpi stderr]', res.stderr); - } - - if (res.stdout !== '') { - console.log('[rpi sdtout]', res.stdout); - } -} - -// @note: by default RPi .bashrc exits early if not in interactive more, some -// lines must be commented on the RPi side -// cf. https://github.com/mscdex/ssh2/issues/77 -console.log('> check node'); -res = await conn.execCommand(`which node`); -logResult(res); - -if (res.stdout == '') { - console.log('node not found, exiting...'); - process.exit(1) -} - -console.log('> check cargo'); -res = await conn.execCommand(`which cargo`); -logResult(res); - -if (res.stdout == '') { - console.log('cargo not found, exiting...'); - process.exit(1) -} - -console.log('> pull source on main'); -res = await conn.execCommand(`git pull origin main`, { cwd: rpiCwd }); -logResult(res); - -console.log('> reinstall node_modules'); -res = await conn.execCommand(`rm -Rf node_modules`, { cwd: rpiCwd }); -logResult(res); -res = await conn.execCommand(`npm install`, { cwd: rpiCwd }); -logResult(res); - -console.log('> rustup upgrade'); -res = await conn.execCommand(`rustup upgrade`, { cwd: rpiCwd }); -logResult(res); - -console.log('> cargo update'); -res = await conn.execCommand(`cargo update`, { cwd: rpiCwd }); -logResult(res); - -console.log('> build binary'); -res = await conn.execCommand(`npm run build:jack`, { cwd: rpiCwd }); -logResult(res); - -console.log('> strip symbols'); -res = await conn.execCommand(`aarch64-linux-gnu-strip ${binaryFilename}`, { cwd: rpiCwd }); -logResult(res); - -console.log('> list files'); -res = await conn.execCommand(`ls -al`, { cwd: rpiCwd }); -logResult(res); - -console.log('> download binary'); -const remoteFile = path.join(rpiCwd, binaryFilename); -res = execSync(`scp ${rpiUser}@${rpiHostname}:${remoteFile} ${process.cwd()}`); -console.log(res.toString()); - -console.log('Done!'); - -conn.dispose(); - - diff --git a/.scripts/build-linux-gnu-docker.mjs b/.scripts/build-linux-gnu-docker.mjs deleted file mode 100644 index db3adf8f..00000000 --- a/.scripts/build-linux-gnu-docker.mjs +++ /dev/null @@ -1,23 +0,0 @@ -import { execSync } from 'node:child_process'; - -const cwd = process.cwd(); -console.log(`> executing docker command in dir ${cwd}`); - -// the source code directory is shared with the docker image, -// so every thing is always up to date - -// @todo - rebuild docket image -// cd ./.scripts/docker_x86_64-unknown-linux-gnu/ -// docker build -t bbmmaa/build-x86_64 . - -execSync(`docker run --rm \ - -v ~/.cargo/git:/root/.cargo/git \ - -v ~/.cargo/registry:/root/.cargo/registry \ - -v ${cwd}:/sources \ - -w /sources \ - bbmmaa/build-x86_64 \ - bash -c " - yarn build:jack --target x86_64-unknown-linux-gnu && \ - x86_64-linux-gnu-strip *.linux-x64-gnu.node && \ - ls -al /sources" -`, { stdio: 'inherit' }); diff --git a/.scripts/docker_x86_64-unknown-linux-gnu/Dockerfile b/.scripts/docker_x86_64-unknown-linux-gnu/Dockerfile deleted file mode 100644 index b8303d07..00000000 --- a/.scripts/docker_x86_64-unknown-linux-gnu/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -FROM node:20 - -ENV RUSTUP_HOME=/usr/local/rustup \ - CARGO_HOME=/usr/local/cargo \ - PATH=/usr/local/cargo/bin:$PATH \ - CC=clang \ - CXX=clang++ \ - PKG_CONFIG_ALLOW_CROSS=1 \ - RUST_TARGET=x86_64-unknown-linux-gnueabi - -RUN dpkg --add-architecture amd64 && \ - apt-get update && \ - apt-get install -y \ - curl \ - pkg-config \ - libasound2-dev \ - libasound2-dev:amd64 \ - libjack-jackd2-dev \ - libjack-jackd2-dev:amd64 \ - gcc \ - g++ \ - g++-x86-64-linux-gnu \ - libc6-dev \ - libc6-dev:amd64 \ - libc6-dev-amd64-cross \ - ca-certificates \ - qemu-user \ - make \ - file \ - clang \ - && \ - curl https://sh.rustup.rs -sSf | sh -s -- -y - -RUN rustup target add x86_64-unknown-linux-gnu diff --git a/.scripts/move-artifact.mjs b/.scripts/move-artifact.mjs new file mode 100644 index 00000000..4d89b9f3 --- /dev/null +++ b/.scripts/move-artifact.mjs @@ -0,0 +1,45 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +const { platform } = process; +const profile = process.argv.includes('--release') ? 'release' : 'debug'; + +const pkg = fs.readFileSync(path.join('package.json')); +const PROJECT_NAME = JSON.parse(pkg).name; +const CARGO_BUILD_NAME = PROJECT_NAME.replace(/-/g, '_'); + +let buildPrefix = ''; +let buildSuffix = ''; + +switch (platform) { + case 'win32': + buildPrefix = ''; + buildSuffix = '.dll'; + break; + case 'darwin': + buildPrefix = 'lib'; + buildSuffix = '.dylib'; + break; + default: // let's hope all linux like have same prefix and suffix... + buildPrefix = 'lib'; + buildSuffix = '.so'; + break; +} + +const destReleaseFile = `${PROJECT_NAME}.build-release.node`; +const destDebugFile = `${PROJECT_NAME}.build-debug.node`; + +if (fs.existsSync(destReleaseFile)) { + fs.rmSync(destReleaseFile, { force: true }); +} + +if (fs.existsSync(destDebugFile)) { + fs.rmSync(destDebugFile, { force: true }); +} + +let srcFile = path.join('target', profile, `${buildPrefix}${CARGO_BUILD_NAME}${buildSuffix}`); +let destFile = profile === 'release' ? destReleaseFile : destDebugFile; + +console.log(`> move artifact "${srcFile}" to "${destFile}"`); + +fs.copyFileSync(srcFile, destFile); diff --git a/.scripts/build-retrieve-from-github.mjs b/.scripts/retrieve-artifacts.mjs similarity index 97% rename from .scripts/build-retrieve-from-github.mjs rename to .scripts/retrieve-artifacts.mjs index 7add4510..24d1e2f5 100644 --- a/.scripts/build-retrieve-from-github.mjs +++ b/.scripts/retrieve-artifacts.mjs @@ -9,8 +9,8 @@ const owner = process.env.REPO_OWNER; const repo = process.env.REPO_NAME; const ghToken = process.env.GITHUB_TOKEN; -const workflowName = 'build'; -const numArtifacts = 4; // 2 Mac, 2 windows +const workflowName = 'matrix-build'; +const numArtifacts = 7; // 2 Mac, 2 windows, 3 linux // need a key for downloading job artifacts const octokit = new Octokit({ auth: ghToken }); diff --git a/Cargo.toml b/Cargo.toml index 48875267..03909780 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,8 +23,12 @@ mimalloc = {version = "0.1"} [build-dependencies] napi-build = "1" +[profile.dev] +opt-level = 3 + [profile.release] lto = true +strip = true [features] jack = ["web-audio-api/cpal-jack"] diff --git a/Cross.toml b/Cross.toml new file mode 100644 index 00000000..c5be2fd3 --- /dev/null +++ b/Cross.toml @@ -0,0 +1,17 @@ +[target.aarch64-unknown-linux-gnu] +pre-build = [ + "dpkg --add-architecture $CROSS_DEB_ARCH", + "apt-get update && apt-get --assume-yes install libasound2-dev:$CROSS_DEB_ARCH libjack-jackd2-dev:$CROSS_DEB_ARCH" +] + +[target.armv7-unknown-linux-gnueabihf] +pre-build = [ + "dpkg --add-architecture $CROSS_DEB_ARCH", + "apt-get update && apt-get --assume-yes install libasound2-dev:$CROSS_DEB_ARCH libjack-jackd2-dev:$CROSS_DEB_ARCH" +] + +[target.x86_64-unknown-linux-gnu] +pre-build = [ + "dpkg --add-architecture $CROSS_DEB_ARCH", + "apt-get update && apt-get --assume-yes install libasound2-dev:$CROSS_DEB_ARCH libjack-jackd2-dev:$CROSS_DEB_ARCH" +] diff --git a/js/OfflineAudioContext.js b/js/OfflineAudioContext.js index 04ea2aec..972025cb 100644 --- a/js/OfflineAudioContext.js +++ b/js/OfflineAudioContext.js @@ -139,7 +139,6 @@ module.exports = function patchOfflineAudioContext(jsExport, nativeBinding) { await this.audioWorklet[kCheckProcessorsCreated](); // keep this to highlight the workaround w/ the oncomplete event - let _nativeAudioBuffer; try { diff --git a/load-native.cjs b/load-native.cjs index 9a1031d0..9e1842f6 100644 --- a/load-native.cjs +++ b/load-native.cjs @@ -1,3 +1,4 @@ +const fs = require('node:fs'); const { platform, arch } = process; let nativeBinding = null; @@ -21,7 +22,7 @@ switch (platform) { } break; default: - throw new Error(`Unsupported architecture on Windows: ${arch}`); + loadError = new Error(`Unsupported architecture on Windows: ${arch}`); } break; case 'darwin': @@ -41,11 +42,15 @@ switch (platform) { } break; default: - throw new Error(`Unsupported architecture on macOS: ${arch}`); + loadError = new Error(`Unsupported architecture on macOS: ${arch}`); } break; + // case 'freebsd': x64 only case 'linux': switch (arch) { + // @todo + // - support riscv64 arch + // - support musl C lib case 'x64': try { nativeBinding = require('./node-web-audio-api.linux-x64-gnu.node'); @@ -68,11 +73,20 @@ switch (platform) { } break; default: - throw new Error(`Unsupported architecture on Linux: ${arch}`); + loadError = new Error(`Unsupported architecture on Linux: ${arch}`); } break; default: - throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`); + loadError = new Error(`Unsupported OS: ${platform}, architecture: ${arch}`); +} + +// use local build if exists +if (fs.existsSync('node-web-audio-api.build-release.node')) { + nativeBinding = require('./node-web-audio-api.build-release.node'); +} + +if (fs.existsSync('node-web-audio-api.build-debug.node')) { + nativeBinding = require('./node-web-audio-api.build-debug.node'); } if (!nativeBinding) { diff --git a/package.json b/package.json index c0375949..837b8f60 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "node-web-audio-api", "version": "0.21.5", "author": "Benjamin Matuszewski", - "description": "Node.js bindings for web-audio-api-rs using napi-rs", + "description": "Web Audio API implementation for Node.js", "exports": { "import": "./index.mjs", "require": "./index.cjs", @@ -21,7 +21,7 @@ "music", "dsp", "rust", - "n-api" + "node-api" ], "engines": { "node": ">= 14" @@ -35,17 +35,17 @@ "access": "public" }, "scripts": { - "artifacts": "napi artifacts", - "build": "npm run generate && napi build --platform --release", - "build:jack": "npm run generate && napi build --platform --features jack --release", - "build:debug": "npm run generate && napi build --platform", - "build:only": "napi build --platform --release", + "build": "npm run generate && cargo build --release && node ./.scripts/move-artifact.mjs --release", + "build:jack": "npm run generate && cargo build --features jack --release && node ./.scripts/move-artifact.mjs --release", + "build:debug":"npm run generate && cargo build && node ./.scripts/move-artifact.mjs", + "build:only": "cargo build --release && node ./.scripts/move-artifact.mjs --release", "check": "cargo fmt && cargo clippy", "generate": "node generator/index.mjs && cargo fmt", "lint": "npx eslint index.cjs index.mjs && npx eslint js/*.js && npx eslint examples/*.mjs", - "preversion": "yarn install && npm run generate", + "preversion": "npm install && npm run generate", "postversion": "cargo bump $npm_package_version && git commit -am \"v$npm_package_version\" && node .scripts/check-changelog.mjs", "test": "mocha tests/*.spec.mjs", + "test:ci": "mocha tests/*.spec.mjs -- --ci", "test:only": "mocha", "wpt": "npm run build && node ./.scripts/wpt-harness.mjs", "wpt:only": "node ./.scripts/wpt-harness.mjs" @@ -73,8 +73,6 @@ "wpt-runner": "^5.0.0" }, "dependencies": { - "@napi-rs/cli": "^2.14.3", - "@node-rs/helper": "^1.3.3", "caller": "^1.1.0", "node-fetch": "^3.3.2", "webidl-conversions": "^7.0.0" diff --git a/tests/getUserMedia.spec.mjs b/tests/getUserMedia.spec.mjs index 97a0faa2..1a6f2d2f 100644 --- a/tests/getUserMedia.spec.mjs +++ b/tests/getUserMedia.spec.mjs @@ -3,6 +3,8 @@ import { sleep } from '@ircam/sc-utils'; import { mediaDevices, AudioContext, MediaStreamAudioSourceNode } from '../index.mjs'; +const CI = process.argv.includes('--ci'); + describe('# mediaDevices.getUserMedia(options)', () => { it('should fail if no argument given', async () => { let failed = false; @@ -48,6 +50,12 @@ describe('# mediaDevices.getUserMedia(options)', () => { }); it('should not fail if options.audio = true', async () => { + // accessing microphone in CI make the process stuck + if (CI) { + console.log('Run in CI, aborting...'); + return; + } + let failed = false; const audioContext = new AudioContext(); @@ -67,6 +75,12 @@ describe('# mediaDevices.getUserMedia(options)', () => { }); it('should work with MediaStreamAudioSourceNode [1 factory] (make some noise)', async () => { + // accessing microphone in CI make the process stuck + if (CI) { + console.log('Run in CI, aborting...'); + return; + } + let failed = false; const audioContext = new AudioContext(); @@ -89,6 +103,12 @@ describe('# mediaDevices.getUserMedia(options)', () => { }); it('should work with MediaStreamAudioSourceNode [2 ctor] (make some noise)', async () => { + // accessing microphone in CI make the process stuck + if (CI) { + console.log('Run in CI, aborting...'); + return; + } + let failed = false; const audioContext = new AudioContext();