Skip to content

Commit d6286d2

Browse files
committed
Initial commit
0 parents  commit d6286d2

9 files changed

Lines changed: 730 additions & 0 deletions

File tree

.dockerignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Keep the Docker build context small: only the Dockerfile and build-libnode.ps1
2+
# are needed inside the image.
3+
.git
4+
.github
5+
examples
6+
artifacts
7+
*.zip
8+
SHA256SUMS.txt
9+
build-*.log
10+
README.md
11+
.gitignore

.gitattributes

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# This repository targets Windows. Keep CRLF line endings on checkout.
2+
* text=auto eol=crlf
3+
4+
# Anything binary that might land here stays untouched.
5+
*.zip binary
6+
*.dll binary
7+
*.lib binary
8+
*.pdb binary
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
name: Build libnode (Windows)
2+
3+
# Builds Node.js as a shared library (libnode.dll) on a Windows runner and
4+
# uploads the V8 headers + libnode binaries as zip artifacts -- the same zips
5+
# the Docker image produces, ready to publish to a CDN for mod_v8 to consume.
6+
#
7+
# Trigger manually (Actions tab -> "Build libnode (Windows)" -> Run workflow)
8+
# choosing the Node tag, or push a tag like `libnode-v20.19.2` to build it.
9+
10+
on:
11+
workflow_dispatch:
12+
inputs:
13+
node_version:
14+
description: 'Node.js git tag to build (e.g. v20.19.2)'
15+
required: true
16+
default: 'v20.19.2'
17+
configs:
18+
description: 'Configurations to build (space-separated)'
19+
required: true
20+
default: 'Release Debug'
21+
arch:
22+
description: 'Target architecture'
23+
required: true
24+
default: 'x64'
25+
type: choice
26+
options: [x64, arm64]
27+
push:
28+
tags:
29+
- 'libnode-v*' # e.g. push tag `libnode-v20.19.2`
30+
31+
jobs:
32+
build:
33+
runs-on: windows-2022
34+
timeout-minutes: 300
35+
permissions:
36+
contents: write # needed to attach zips to a Release on tag push
37+
steps:
38+
- name: Checkout builder
39+
uses: actions/checkout@v4
40+
41+
- name: Resolve build parameters
42+
id: p
43+
shell: pwsh
44+
run: |
45+
if ($env:GITHUB_EVENT_NAME -eq 'push') {
46+
# tag form: libnode-v20.19.2 -> node tag v20.19.2
47+
$nv = "$env:GITHUB_REF_NAME" -replace '^libnode-', ''
48+
$cfg = 'Release Debug'
49+
$arch = 'x64'
50+
} else {
51+
$nv = '${{ inputs.node_version }}'
52+
$cfg = '${{ inputs.configs }}'
53+
$arch = '${{ inputs.arch }}'
54+
}
55+
"node_version=$nv" >> $env:GITHUB_OUTPUT
56+
"configs=$cfg" >> $env:GITHUB_OUTPUT
57+
"arch=$arch" >> $env:GITHUB_OUTPUT
58+
Write-Host "Building Node $nv [$cfg] for $arch"
59+
60+
# Node 20.x's configure rejects Python 3.14; 3.13 is accepted by Node 20..26.
61+
- name: Set up Python 3.13
62+
uses: actions/setup-python@v5
63+
with:
64+
python-version: '3.13'
65+
66+
# NASM is required for OpenSSL's x64 assembler modules and is not preinstalled.
67+
- name: Install NASM
68+
shell: pwsh
69+
run: choco install -y --no-progress nasm
70+
71+
# Rust (cargo/rustc) is only needed for Node >= 26 (Temporal builds the
72+
# deps/crates). The windows-2022 image ships Rust preinstalled; this just
73+
# confirms it's on PATH and is a no-op for Node 20/22.
74+
- name: Verify toolchain
75+
shell: pwsh
76+
run: |
77+
Write-Host "Python : $(python --version 2>&1)"
78+
Write-Host "NASM : $((Get-Command nasm -ErrorAction SilentlyContinue)?.Source)"
79+
Write-Host "cargo : $((Get-Command cargo -ErrorAction SilentlyContinue)?.Source)"
80+
Write-Host "git : $(git --version)"
81+
82+
- name: Build libnode + package zips
83+
shell: pwsh
84+
env:
85+
NODE_VERSION: ${{ steps.p.outputs.node_version }}
86+
CONFIGS: ${{ steps.p.outputs.configs }}
87+
ARCH: ${{ steps.p.outputs.arch }}
88+
OUT_DIR: ${{ github.workspace }}\artifacts
89+
run: .\build-libnode.ps1
90+
91+
- name: List artifacts
92+
shell: pwsh
93+
run: Get-ChildItem '${{ github.workspace }}\artifacts' | Format-Table Name, Length
94+
95+
- name: Upload zips
96+
uses: actions/upload-artifact@v4
97+
with:
98+
name: libnode-${{ steps.p.outputs.node_version }}-${{ steps.p.outputs.arch }}
99+
path: |
100+
artifacts/*.zip
101+
artifacts/SHA256SUMS.txt
102+
if-no-files-found: error
103+
retention-days: 30
104+
105+
# On a tag push, also attach the zips to a GitHub Release for easy download.
106+
- name: Publish to Release
107+
if: github.event_name == 'push'
108+
uses: softprops/action-gh-release@v2
109+
with:
110+
files: |
111+
artifacts/*.zip
112+
artifacts/SHA256SUMS.txt

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Build outputs
2+
/artifacts/
3+
*.zip
4+
SHA256SUMS.txt
5+
build-*.log
6+
7+
# Node.js source checkout (when building natively in-tree)
8+
/node/
9+
10+
# OS / editor cruft
11+
Thumbs.db
12+
.DS_Store

Dockerfile

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# escape=`
2+
#
3+
# Builds Node.js on Windows as a SHARED library (libnode.dll) and packages
4+
# the V8 headers + libnode import library/DLL into zip files that the FreeSWITCH
5+
# mod_v8 JavaScript module can consume in place of the old standalone libv8 zips.
6+
#
7+
# This image only contains the TOOLCHAIN. The actual Node version is built at
8+
# `docker run` time from an env var, so you can produce a new release without
9+
# rebuilding the (slow, multi-GB) toolchain layer.
10+
#
11+
# Build the toolchain image once:
12+
# docker build -t libnode-packaging .
13+
#
14+
# Produce zips for a Node tag (writes to .\artifacts on the host):
15+
# docker run --rm --cpus 8 --memory 16g `
16+
# -e NODE_VERSION=v20.19.2 `
17+
# -v ${PWD}\artifacts:C:\artifacts `
18+
# libnode-packaging
19+
#
20+
# Requires Windows containers. The host must be able to run a Windows base
21+
# image of an equal-or-older build than the host (process isolation), otherwise
22+
# run with `--isolation=hyperv`.
23+
24+
ARG WINDOWS_BASE=mcr.microsoft.com/windows/servercore:ltsc2025
25+
FROM ${WINDOWS_BASE}
26+
27+
# The Visual Studio bootstrapper. aka.ms/vs/17/release installs the latest VS 2022 Build Tools,
28+
# new enough for the ClangCL components that Node >= 24 requires.
29+
ARG VS_BOOTSTRAPPER_URL=https://aka.ms/vs/17/release/vs_buildtools.exe
30+
31+
SHELL ["powershell", "-NoLogo", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", "$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue';"]
32+
33+
# ---------------------------------------------------------------------------
34+
# 1. Chocolatey + Node's non-VS prerequisites:
35+
# - python3 : a Python 3.x on PATH for Node's configure (PEP 514). The build
36+
# actually uses the 3.13 installed in step 2c (Node 20.x rejects 3.14).
37+
# - nasm : OpenSSL assembler modules on x64 (find_nasm.cmd looks in %ProgramFiles%\NASM)
38+
# - git : to clone the Node source at the requested tag
39+
# ---------------------------------------------------------------------------
40+
RUN [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; `
41+
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
42+
43+
RUN choco install -y --no-progress python3 nasm git; `
44+
if ($LASTEXITCODE -ne 0) { throw "choco install failed ($LASTEXITCODE)" }
45+
46+
# ---------------------------------------------------------------------------
47+
# 2. Visual Studio 2022 Build Tools: C++ workload + ClangCL.
48+
# Node.js >= 24 forces ClangCL (vcbuild sets clang_cl=1), so the two LLVM
49+
# components below are mandatory. --includeRecommended pulls in MSVC v143
50+
# and the Windows SDK.
51+
# Exit code 3010 == success-but-reboot-required, which is fine in an image.
52+
# ---------------------------------------------------------------------------
53+
RUN Invoke-WebRequest -Uri $env:VS_BOOTSTRAPPER_URL -OutFile C:\vs_buildtools.exe; `
54+
Write-Host 'Installing Visual Studio Build Tools (this takes a while)...'; `
55+
$p = Start-Process -FilePath C:\vs_buildtools.exe -Wait -PassThru -ArgumentList `
56+
'--quiet','--wait','--norestart','--nocache', `
57+
'--installPath','C:\BuildTools', `
58+
'--add','Microsoft.VisualStudio.Workload.VCTools', `
59+
'--add','Microsoft.VisualStudio.Component.VC.Llvm.Clang', `
60+
'--add','Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset', `
61+
'--includeRecommended'; `
62+
if ($p.ExitCode -ne 0 -and $p.ExitCode -ne 3010) { throw "VS Build Tools install failed ($($p.ExitCode))" }; `
63+
Remove-Item C:\vs_buildtools.exe -Force
64+
65+
# ---------------------------------------------------------------------------
66+
# 2b. Rust toolchain (MSVC ABI). Installed AFTER VS so this small layer can be
67+
# added without invalidating the cached (slow) VS Build Tools layer above.
68+
# Node >= 26 builds the deps/crates Rust crates because Temporal support is
69+
# ON by default; cargo/rustc (>= 1.82) are required unless the build is
70+
# configured with --v8-disable-temporal-support.
71+
# ---------------------------------------------------------------------------
72+
RUN choco install -y --no-progress rust-ms; `
73+
if ($LASTEXITCODE -ne 0) { throw "rust install failed ($LASTEXITCODE)" }
74+
75+
# ---------------------------------------------------------------------------
76+
# 2c. Python 3.13. Node 20.x's configure rejects Python 3.14 ("Please use
77+
# python3.13 or ..."), while newer Node (>= 24) accepts 3.13 too. Installing
78+
# 3.13 alongside the default python3 covers every Node line we build;
79+
# build-libnode.ps1 puts C:\Python313 first on PATH so find_python picks it.
80+
# Installed after VS so this small layer doesn't invalidate the VS cache.
81+
# ---------------------------------------------------------------------------
82+
RUN choco install -y --no-progress python313; `
83+
if ($LASTEXITCODE -ne 0) { throw "python313 install failed ($LASTEXITCODE)" }
84+
85+
# NOTE: do NOT set `ENV PATH` here. The Windows base image exports the variable
86+
# as `Path` (mixed case), but Docker's ${...} substitution is case-sensitive, so
87+
# `${PATH}` expands to empty and wipes C:\Windows\System32 from the path. The
88+
# choco/VS installers already register their dirs in the machine PATH (which
89+
# container processes inherit), and build-libnode.ps1 prepends the tool dirs
90+
# defensively at runtime. vcbuild locates VS itself via vswhere.
91+
92+
# ---------------------------------------------------------------------------
93+
# 3. Build driver.
94+
# ---------------------------------------------------------------------------
95+
COPY build-libnode.ps1 C:\build-libnode.ps1
96+
97+
# Defaults; override any of these with `docker run -e ...`.
98+
# Default matches the Linux libnode-dev on Debian trixie (Node 20 -> V8 11.3) so
99+
# the same mod_v8 source compiles on both platforms. Bump for newer toolchains.
100+
ENV NODE_VERSION=v20.19.2 `
101+
CONFIGS="Release Debug" `
102+
ARCH=x64 `
103+
PKG_PREFIX=libnode `
104+
OUT_DIR=C:\artifacts `
105+
NODE_REPO=https://github.com/nodejs/node.git
106+
107+
ENTRYPOINT ["C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", "-NoLogo", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "C:\\build-libnode.ps1"]

0 commit comments

Comments
 (0)