From 6afdace08795ca1eb0e7b60498b3a379b6cc6abf Mon Sep 17 00:00:00 2001 From: Mahdi Sharifi Date: Tue, 9 Apr 2024 14:28:27 +0330 Subject: [PATCH] Add cross compilation --- .github/workflows/linux-daily-check.yml | 66 ++++++++++++++--------- .github/workflows/macos-daily-check.yml | 33 +++++++----- .github/workflows/windows-daily-check.yml | 13 ++--- index.js | 32 +++++++---- qemu-wrapper.c | 27 ++++++++++ 5 files changed, 117 insertions(+), 54 deletions(-) create mode 100644 qemu-wrapper.c diff --git a/.github/workflows/linux-daily-check.yml b/.github/workflows/linux-daily-check.yml index 610b789..3eb27f4 100644 --- a/.github/workflows/linux-daily-check.yml +++ b/.github/workflows/linux-daily-check.yml @@ -1,4 +1,4 @@ -name: Linux daily check +name: Linux on: schedule: @@ -7,34 +7,52 @@ on: jobs: update: - name: Linux daily check + name: Linux runs-on: ubuntu-latest strategy: matrix: arch: [amd64, arm64] + include: + - arch: arm64 + is_arm: true steps: - - name: Update system - run: sudo apt-get update && sudo apt-get --yes upgrade - - - name: Install Nodejs 21 repo - run: sudo apt-get install --yes ca-certificates curl gnupg && curl -sL https://deb.nodesource.com/setup_21.x | sudo bash - && sudo apt-get update - - - name: Install building tools - run: sudo apt-get install --yes git python3 python3-pip gcc g++ make ninja-build nodejs sudo - - - name: Clone the repo - run: git clone https://github.com/devraymondsh/libnode-distributable - - - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.4 - - - name: Run the script + - name: Setup ccache + uses: actions/cache@v4 + with: + key: ${{ github.workflow }}-${{ matrix.arch }} + path: .ccache + + - if: ${{ matrix.is_arm }} + uses: pguyot/arm-runner-action@v2 + with: + base_image: https://dietpi.com/downloads/images/testing/DietPi_RPi5-ARMv8-Bookworm.img.xz + image_additional_mb: 10240 + commands: | + export ARCH="arm64" + export CC="ccache -d .ccache gcc" + export CXX="ccache -d .ccache g++" + sudo apt-get update + sudo apt-get install --yes ca-certificates curl gnupg && curl -sL https://deb.nodesource.com/setup_21.x | sudo bash - && sudo apt-get update + sudo apt-get install --yes git nodejs python3 python3-pip build-essential ccache linux-headers-generic + git clone https://github.com/devraymondsh/libnode-distributable + cd libnode-distributable && node index.js + ls libnode-distributable/node/out/Release + + - if: ${{ ! matrix.is_arm }} + name: Install building tools + run: | + sudo apt-get install --yes ca-certificates curl gnupg && curl -sL https://deb.nodesource.com/setup_21.x | bash - + sudo apt-get update + sudo apt-get install --yes git nodejs python3 python3-pip build-essential ccache linux-headers-generic + + - if: ${{ ! matrix.is_arm }} + name: Run the script env: - CC: "sccache gcc" - CXX: "sccache g++" ARCH: ${{ matrix.arch }} - SCCACHE_GHA_ENABLED: "true" - run: cd libnode-distributable && node index.js + CC: "ccache -d .ccache gcc" + CXX: "ccache -d .ccache g++" + run: cd ${{ github.action_path }} && node index.js - - name: Find the shared library - run: find libnode-distributable/node -name libnode.so\* -not -name '*.TOC' -not -name '*.toc' -exec ls {} \; + - if: ${{ ! matrix.is_arm }} + name: Find the shared library + run: ls ${{ github.action_path }}/node/out/Release diff --git a/.github/workflows/macos-daily-check.yml b/.github/workflows/macos-daily-check.yml index 4519324..52abd32 100644 --- a/.github/workflows/macos-daily-check.yml +++ b/.github/workflows/macos-daily-check.yml @@ -1,4 +1,4 @@ -name: Macos daily check +name: Macos on: schedule: @@ -7,28 +7,33 @@ on: jobs: update: - name: Macos daily check - runs-on: macos-latest + name: Macos strategy: matrix: arch: [amd64, arm64] + include: + - arch: arm64 + os: macos-14 + is_arm: true + - arch: amd64 + os: macos-13 + runs-on: ${{ matrix.os }} steps: - name: Install building tools - run: brew install node python ninja nasm git + run: brew install node python ninja nasm git ccache - - name: Clone the repo - run: git clone https://github.com/devraymondsh/libnode-distributable - - - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.4 + - name: Setup ccache + uses: actions/cache@v4 + with: + key: ${{ github.workflow }}-${{ matrix.arch }} + path: .ccache - name: Run the script env: - CC: "sccache cc" - CXX: "sccache c++" ARCH: ${{ matrix.arch }} - SCCACHE_GHA_ENABLED: "true" - run: cd libnode-distributable && node index.js + CC: "ccache -d .ccache cc" + CXX: "ccache -d .ccache c++" + run: cd ${{ github.action_path }} && node index.js - name: Find the shared library - run: find libnode-distributable/node -name libnode.so\* -not -name '*.TOC' -not -name '*.toc' -exec ls {} \; + run: ls ${{ github.action_path }}/node/out/Release diff --git a/.github/workflows/windows-daily-check.yml b/.github/workflows/windows-daily-check.yml index 0db1bde..5c9bc3b 100644 --- a/.github/workflows/windows-daily-check.yml +++ b/.github/workflows/windows-daily-check.yml @@ -1,4 +1,4 @@ -name: Windows daily check +name: Windows on: schedule: @@ -7,7 +7,7 @@ on: jobs: update: - name: Windows daily check + name: Windows runs-on: windows-latest strategy: matrix: @@ -19,7 +19,6 @@ jobs: - uses: MinoruSekine/setup-scoop@v3 with: - buckets: extras update_path: true run_as_admin: true scoop_update: true @@ -30,13 +29,15 @@ jobs: - name: Clone the repo run: git clone https://github.com/devraymondsh/libnode-distributable - - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.4 + - name: Run ccache-cache + uses: hendrikmuhs/ccache-action@v1.2 + with: + # create-symlink: true + key: ${{ github.workflow }}-${{ matrix.arch }} - name: Run the script env: ARCH: ${{ matrix.arch }} - SCCACHE_GHA_ENABLED: "true" run: cd libnode-distributable ; node index.js - name: Find the shared library diff --git a/index.js b/index.js index 858192f..c046fca 100644 --- a/index.js +++ b/index.js @@ -3,16 +3,11 @@ import { cpus } from "node:os"; import fs from "node:fs/promises"; import { spawn } from "node:child_process"; -let CC = process.env.CC; -let CXX = process.env.CXX; let ARCH = process.env.ARCH; -if (!CC) CC = "gcc"; -if (!CXX) CXX = "g++"; -if (!ARCH) ARCH = "amd64"; +const arch = ARCH == "amd64" ? "x64" : "arm64"; const coreCount = cpus().length; const threadCount = coreCount * 2; -const arch = ARCH == "amd64" ? "x64" : "arm64"; let os; switch (process.platform) { case "darwin": @@ -57,7 +52,7 @@ const isANewerVersion = (oldVer, newVer) => { const spawnAsync = (program, args, cwd) => new Promise((resolve, reject) => { - console.log([program, ...args].join(" ")); + console.log("Running:", [program, ...args].join(" ")); const child = spawn(program, args, cwd ? { cwd } : {}); @@ -85,16 +80,33 @@ if (!syncFs.existsSync("node")) { `v${latestNodeVersion}`, "--depth=1", ], - undefined + undefined, + {} ); } +let extraArgs = []; if (process.platform == "win32") { - await spawnAsync("vcbuild.bat", [arch, "dll"], "node"); + await spawnAsync( + ".\\vcbuild.bat", + [ + arch, + "dll", + // "/p:CLToolExe=cl.exe /p:CLToolPath=C:\\Users\\runneradmin\\.cargo\\bin\\cl.exe", + ], + "node" + ); } else { + if (arch === "arm64") { + extraArgs.push("--with-arm-float-abi"); + extraArgs.push("hard"); + extraArgs.push("--with-arm-fpu"); + extraArgs.push("neon"); + } + await spawnAsync( "./configure", - ["--ninja", "--shared", "--dest-cpu", arch, "--dest-os", os], + ["--shared", "--dest-cpu", arch, "--dest-os", os, ...extraArgs], "node" ); await spawnAsync("make", [`-j${threadCount}`], "node"); diff --git a/qemu-wrapper.c b/qemu-wrapper.c new file mode 100644 index 0000000..2069819 --- /dev/null +++ b/qemu-wrapper.c @@ -0,0 +1,27 @@ +// From https://wiki.gentoo.org/wiki/Embedded_Handbook/General/Compiling_with_qemu_user_chroot +/* + * pass arguments to qemu binary + * QEMU_CPU environment variable can be unset + */ + +#include +#include + +#define XSTR(cpu) STR(cpu) +#define STR(cpu) #cpu + +int main(int argc, char **argv, char **envp) { + int this_len = strlen(argv[0]); + char staticpath[this_len]; + char *newargv[argc + 3]; + + newargv[0] = argv[0]; + newargv[1] = "-cpu"; + newargv[2] = XSTR(QEMU_CPU); + + memcpy(&newargv[3], &argv[1], sizeof(*argv) * (argc -1)); + newargv[argc + 2] = NULL; + memcpy(staticpath, argv[0], this_len - 1); + staticpath[this_len - 1] = 0; + return execve(staticpath, newargv, envp); +} \ No newline at end of file