feat: add Windows platform support (x64 and ARM64) to build workflow #38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build Node.js Shared Library | |
| on: | |
| release: | |
| types: [created] | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| paths: | |
| - '.github/workflows/build_node_shared.yml' | |
| jobs: | |
| build: | |
| timeout-minutes: 720 # 12 hours (QEMU ARM64 builds are slow) | |
| strategy: | |
| matrix: | |
| include: | |
| # Linux x64 builds | |
| - os: ubuntu-latest | |
| platform: linux | |
| arch: x64 | |
| compiler: gcc | |
| container: ghcr.io/ten-framework/ten_building_ubuntu2204 | |
| lib_name: libnode.so.127 | |
| nproc_cmd: nproc | |
| - os: ubuntu-latest | |
| platform: linux | |
| arch: x64 | |
| compiler: clang | |
| container: ghcr.io/ten-framework/ten_building_ubuntu2204 | |
| lib_name: libnode.so.127 | |
| nproc_cmd: nproc | |
| # Linux ARM64 builds (using cross-compilation) | |
| - os: ubuntu-latest | |
| platform: linux | |
| arch: arm64 | |
| compiler: gcc | |
| container: ghcr.io/ten-framework/ten_building_ubuntu2204 | |
| lib_name: libnode.so.127 | |
| nproc_cmd: nproc | |
| - os: ubuntu-latest | |
| platform: linux | |
| arch: arm64 | |
| compiler: clang | |
| container: ghcr.io/ten-framework/ten_building_ubuntu2204 | |
| lib_name: libnode.so.127 | |
| nproc_cmd: nproc | |
| # macOS x64 builds | |
| # Note: macOS should use Clang (Apple's official toolchain), GCC has compatibility issues | |
| - os: macos-15-intel | |
| platform: mac | |
| arch: x64 | |
| compiler: clang | |
| container: "" | |
| lib_name: libnode.127.dylib | |
| nproc_cmd: sysctl -n hw.ncpu | |
| # macOS ARM64 builds | |
| # Note: Apple Silicon only supports Clang | |
| - os: macos-latest | |
| platform: mac | |
| arch: arm64 | |
| compiler: clang | |
| container: "" | |
| lib_name: libnode.127.dylib | |
| nproc_cmd: sysctl -n hw.ncpu | |
| # Windows x64 builds | |
| - os: windows-latest | |
| platform: win | |
| arch: x64 | |
| compiler: msvc | |
| container: "" | |
| lib_name: libnode.dll | |
| nproc_cmd: $env:NUMBER_OF_PROCESSORS | |
| # Windows ARM64 builds (cross-compilation) | |
| - os: windows-latest | |
| platform: win | |
| arch: arm64 | |
| compiler: msvc | |
| container: "" | |
| lib_name: libnode.dll | |
| nproc_cmd: $env:NUMBER_OF_PROCESSORS | |
| runs-on: ${{ matrix.os }} | |
| container: ${{ matrix.container != '' && matrix.container || null }} | |
| steps: | |
| - name: Checkout Node.js | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: nodejs/node | |
| ref: v22.12.0 | |
| - name: Setup cross-compilation toolchain (Linux ARM64) | |
| if: matrix.platform == 'linux' && matrix.arch == 'arm64' | |
| run: | | |
| apt-get update | |
| apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu | |
| if [ "${{ matrix.compiler }}" = "clang" ]; then | |
| apt-get install -y clang llvm | |
| fi | |
| - name: Setup Python (macOS) | |
| if: matrix.platform == 'mac' | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| # Reference: https://github.com/nodejs/node/blob/v22.12.0/BUILDING.md#option-2-automated-install-with-winget | |
| # https://raw.githubusercontent.com/nodejs/node/main/.configurations/configuration.dsc.yaml | |
| # Using direct winget install commands instead of DSC configuration due to compatibility issues in CI environment | |
| - name: Setup Node.js prerequisites with WinGet (Windows) | |
| if: matrix.platform == 'win' | |
| shell: powershell | |
| run: | | |
| Write-Host "Installing Node.js build prerequisites with WinGet..." | |
| # Install Python 3.12 | |
| Write-Host "`n[1/3] Installing Python 3.12..." | |
| winget install --id Python.Python.3.12 --source winget --silent --accept-package-agreements --accept-source-agreements | |
| # Install Git | |
| Write-Host "`n[2/3] Installing Git..." | |
| winget install --id Git.Git --source winget --silent --accept-package-agreements --accept-source-agreements | |
| # Install NASM (NetWide Assembler) for OpenSSL | |
| Write-Host "`n[3/3] Installing NASM..." | |
| winget install --id Nasm.Nasm --source winget --silent --accept-package-agreements --accept-source-agreements | |
| Write-Host "`nAll WinGet packages installed!" | |
| - name: Install Visual Studio Components (Windows) | |
| if: matrix.platform == 'win' | |
| shell: powershell | |
| run: | | |
| Write-Host "Installing required Visual Studio components..." | |
| Write-Host "Components: C++ Desktop Development, Clang, ClangToolset" | |
| # Find existing VS installation (GitHub Actions has VS 2022 Enterprise pre-installed) | |
| $vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" | |
| $vsPath = & $vsWhere -latest -products * -requires Microsoft.Component.MSBuild -property installationPath | |
| Write-Host "Visual Studio installation found at: $vsPath" | |
| # Get VS product ID (Enterprise, Professional, or Community) | |
| $productId = & $vsWhere -latest -products * -property productId | |
| Write-Host "Product ID: $productId" | |
| # Use VS Installer to modify existing installation and add required components | |
| $installerPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vs_installer.exe" | |
| Write-Host "Adding C++ workload and Clang components..." | |
| $processArgs = @( | |
| "modify", | |
| "--installPath", "`"$vsPath`"", | |
| "--add", "Microsoft.VisualStudio.Workload.NativeDesktop", | |
| "--add", "Microsoft.VisualStudio.Component.VC.Llvm.Clang", | |
| "--add", "Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset", | |
| "--includeRecommended", | |
| "--quiet", | |
| "--norestart" | |
| ) | |
| $process = Start-Process -FilePath $installerPath -ArgumentList $processArgs -Wait -PassThru -NoNewWindow | |
| if ($process.ExitCode -eq 0) { | |
| Write-Host "Visual Studio components installed successfully!" | |
| } elseif ($process.ExitCode -eq 3010) { | |
| Write-Host "Visual Studio components installed successfully! (Reboot required but skipped)" | |
| } else { | |
| Write-Host "Warning: VS Installer returned exit code $($process.ExitCode)" | |
| Write-Host "This may indicate the components are already installed or partially installed." | |
| Write-Host "Continuing with build process..." | |
| } | |
| - name: Verify installations (Windows) | |
| if: matrix.platform == 'win' | |
| shell: powershell | |
| run: | | |
| Write-Host "Verifying installed tools:" | |
| Write-Host "==========================" | |
| # Refresh PATH | |
| $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") | |
| Write-Host "`nPython:" | |
| python --version | |
| Write-Host "`nGit:" | |
| git --version | |
| Write-Host "`nNASM:" | |
| nasm -v | |
| Write-Host "`nVisual Studio:" | |
| vswhere -latest -property displayName | |
| vswhere -latest -property installationVersion | |
| Write-Host "`n==========================" | |
| Write-Host "All prerequisites verified!" | |
| - name: Setup MSVC (Windows) | |
| if: matrix.platform == 'win' | |
| uses: ilammy/msvc-dev-cmd@v1 | |
| with: | |
| arch: ${{ matrix.arch }} | |
| - name: Configure and Build (Linux ARM64 with cross-compilation) | |
| if: matrix.platform == 'linux' && matrix.arch == 'arm64' | |
| run: | | |
| if [ "${{ matrix.compiler }}" = "gcc" ]; then | |
| export CC=aarch64-linux-gnu-gcc | |
| export CXX=aarch64-linux-gnu-g++ | |
| export CC_host=gcc | |
| export CXX_host=g++ | |
| else | |
| export CC="clang --target=aarch64-linux-gnu" | |
| export CXX="clang++ --target=aarch64-linux-gnu" | |
| export CC_host=clang | |
| export CXX_host=clang++ | |
| fi | |
| ./configure --shared \ | |
| --dest-cpu=arm64 \ | |
| --cross-compiling \ | |
| --without-npm \ | |
| --without-corepack | |
| make -j$(nproc) | |
| - name: Configure and Build (Linux x64 and macOS) | |
| if: matrix.platform != 'win' && (matrix.platform != 'linux' || matrix.arch != 'arm64') | |
| run: | | |
| if [ "${{ matrix.compiler }}" = "gcc" ]; then | |
| export CC=gcc | |
| export CXX=g++ | |
| else | |
| export CC=clang | |
| export CXX=clang++ | |
| fi | |
| ./configure --shared | |
| make -j$(${{ matrix.nproc_cmd }}) | |
| - name: Configure and Build (Windows) | |
| if: matrix.platform == 'win' | |
| shell: cmd | |
| run: | | |
| if "${{ matrix.arch }}" == "arm64" ( | |
| vcbuild.bat dll arm64 | |
| ) else ( | |
| vcbuild.bat dll x64 | |
| ) | |
| - name: Package assets | |
| if: startsWith(github.ref, 'refs/tags/') | |
| run: | | |
| if [ "${{ matrix.platform }}" = "win" ]; then | |
| cd Release | |
| # Package shared libraries into zip archive | |
| 7z a node-shared-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.compiler }}.zip ${{ matrix.lib_name }} libnode.lib node.lib | |
| else | |
| cd out/Release | |
| # Package shared libraries into zip archive | |
| zip node-shared-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.compiler }}.zip ${{ matrix.lib_name }} | |
| fi | |
| shell: bash | |
| - name: Publish to release assets | |
| uses: softprops/action-gh-release@v2 | |
| if: startsWith(github.ref, 'refs/tags/') | |
| with: | |
| files: | | |
| out/Release/node-shared-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.compiler }}.zip | |
| Release/node-shared-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.compiler }}.zip |