4646 nproc_cmd : nproc
4747 # macOS x64 builds
4848 # Note: macOS should use Clang (Apple's official toolchain), GCC has compatibility issues
49- - os : macos-13
49+ - os : macos-15-intel
5050 platform : mac
5151 arch : x64
5252 compiler : clang
@@ -55,13 +55,21 @@ jobs:
5555 nproc_cmd : sysctl -n hw.ncpu
5656 # macOS ARM64 builds
5757 # Note: Apple Silicon only supports Clang
58- - os : macos-14
58+ - os : macos-latest
5959 platform : mac
6060 arch : arm64
6161 compiler : clang
6262 container : " "
6363 lib_name : libnode.127.dylib
6464 nproc_cmd : sysctl -n hw.ncpu
65+ # Windows x64 builds
66+ - os : windows-latest
67+ platform : win
68+ arch : x64
69+ compiler : msvc
70+ container : " "
71+ lib_name : libnode.dll
72+ nproc_cmd : $env:NUMBER_OF_PROCESSORS
6573
6674 runs-on : ${{ matrix.os }}
6775 container : ${{ matrix.container != '' && matrix.container || null }}
7381 repository : nodejs/node
7482 ref : v22.12.0
7583
84+ # Ref: https://github.com/nodejs/help/issues/5070
85+ # https://forum.qt.io/topic/162305/possible-marking-state.h-chromium-bug-when-compiling-qtwebengine-from-source/2
86+ - name : Patch V8 for MSVC compatibility (Windows)
87+ if : matrix.platform == 'win'
88+ shell : powershell
89+ run : |
90+ Write-Host "========== Applying V8 MSVC Compatibility Patch =========="
91+ Write-Host "Issue: MSVC C2352 error - non-static member function requires an object"
92+ Write-Host "Affected file: deps\v8\src\heap\cppgc\marking-state.h"
93+ Write-Host "Reference: https://forum.qt.io/topic/162305"
94+ Write-Host ""
95+
96+ $file = "deps\v8\src\heap\cppgc\marking-state.h"
97+
98+ if (!(Test-Path $file)) {
99+ Write-Host "ERROR: $file not found!"
100+ exit 1
101+ }
102+
103+ Write-Host "Reading file..."
104+ $lines = Get-Content $file
105+ $modified = $false
106+ $lineNumber = 0
107+
108+ $newLines = foreach ($line in $lines) {
109+ $lineNumber++
110+ $originalLine = $line
111+
112+ # Fix: MutatorMarkingState::BasicMarkingState::MarkNoPush(header)
113+ # -> BasicMarkingState::MarkNoPush(header)
114+ if ($line -match 'MutatorMarkingState::BasicMarkingState::MarkNoPush\(') {
115+ $line = $line -replace 'MutatorMarkingState::BasicMarkingState::MarkNoPush\(', 'BasicMarkingState::MarkNoPush('
116+ Write-Host " Line $lineNumber : Fixed qualified scope call"
117+ $modified = $true
118+ }
119+
120+ # Fix: return MarkingStateBase::MarkNoPush(
121+ # -> return this->MarkNoPush(
122+ if ($line -match '\s+return\s+MarkingStateBase::MarkNoPush\(') {
123+ $line = $line -replace 'return\s+MarkingStateBase::MarkNoPush\(', 'return this->MarkNoPush('
124+ Write-Host " Line $lineNumber : Fixed base class call"
125+ $modified = $true
126+ }
127+
128+ $line
129+ }
130+
131+ if ($modified) {
132+ Set-Content $file -Value $newLines
133+ Write-Host ""
134+ Write-Host "Successfully patched $file"
135+ } else {
136+ Write-Host ""
137+ Write-Host "No matching patterns found (file may already be patched or have different code)"
138+ Write-Host "Build will continue, but may still fail with C2352 error"
139+ }
140+
141+ Write-Host "========== Patch Complete =========="
142+
76143 - name : Setup cross-compilation toolchain (Linux ARM64)
77144 if : matrix.platform == 'linux' && matrix.arch == 'arm64'
78145 run : |
@@ -88,6 +155,148 @@ jobs:
88155 with :
89156 python-version : ' 3.11'
90157
158+ # Reference: https://github.com/nodejs/node/blob/v22.12.0/BUILDING.md#option-2-automated-install-with-winget
159+ # https://github.com/nodejs/node/blob/v22.12.0/.configurations/configuration.vsEnterprise.dsc.yaml
160+ # Using direct winget install commands instead of DSC configuration due to compatibility issues in CI environment
161+ - name : Setup Node.js prerequisites with WinGet (Windows)
162+ if : matrix.platform == 'win'
163+ shell : powershell
164+ run : |
165+ Write-Host "Installing Node.js build prerequisites with WinGet..."
166+
167+ # Install Python 3.12
168+ Write-Host "`n[1/3] Installing Python 3.12..."
169+ winget install --id Python.Python.3.12 --source winget --silent --accept-package-agreements --accept-source-agreements
170+
171+ # Install Git
172+ Write-Host "`n[2/3] Installing Git..."
173+ winget install --id Git.Git --source winget --silent --accept-package-agreements --accept-source-agreements
174+
175+ # Install NASM (NetWide Assembler) for OpenSSL
176+ Write-Host "`n[3/3] Installing NASM..."
177+ winget install --id Nasm.Nasm --source winget --silent --accept-package-agreements --accept-source-agreements
178+
179+ Write-Host "`nAll WinGet packages installed!"
180+
181+ - name : Install Visual Studio Components (Windows)
182+ if : matrix.platform == 'win'
183+ shell : powershell
184+ run : |
185+ Write-Host "Installing required Visual Studio components..."
186+ Write-Host "Components: C++ Desktop Development, Clang, ClangToolset"
187+
188+ # Find existing VS installation (GitHub Actions has VS 2022 Enterprise pre-installed)
189+ $vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
190+ $vsPath = & $vsWhere -latest -products Microsoft.VisualStudio.Product.Enterprise -property installationPath
191+
192+ Write-Host "Visual Studio installation found at: $vsPath"
193+
194+ # Get VS product ID
195+ $productId = & $vsWhere -path "$vsPath" -property productId
196+ Write-Host "Product ID: $productId"
197+
198+ # Use VS Installer to add required components
199+ # Note: Using --passive instead of --quiet to see progress, and allow warnings
200+ $installerPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vs_installer.exe"
201+
202+ Write-Host "`nAdding required components (this may take 10-20 minutes)..."
203+ & $installerPath modify `
204+ --installPath "$vsPath" `
205+ --add Microsoft.VisualStudio.Workload.NativeDesktop `
206+ --add Microsoft.VisualStudio.Component.VC.Llvm.Clang `
207+ --add Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset `
208+ --includeRecommended `
209+ --quiet `
210+ --norestart `
211+ --wait
212+
213+ $exitCode = $LASTEXITCODE
214+
215+ if ($exitCode -eq 0) {
216+ Write-Host ""
217+ Write-Host "[OK] Visual Studio components installed successfully!"
218+ } elseif ($exitCode -eq 3010) {
219+ Write-Host ""
220+ Write-Host "[OK] Visual Studio components installed successfully! (Reboot requested but skipped)"
221+ } elseif ($exitCode -eq 1641) {
222+ Write-Host ""
223+ Write-Host "[OK] Visual Studio components installed successfully! (Restart initiated)"
224+ } else {
225+ Write-Host ""
226+ Write-Host "[WARN] VS Installer returned exit code: $exitCode"
227+ if ($exitCode -eq 87) {
228+ Write-Host "Exit code 87 usually means components are already installed or parameters are incorrect."
229+ Write-Host "Continuing with build process..."
230+ } else {
231+ Write-Host "Warning: Unexpected exit code. Continuing anyway..."
232+ }
233+ }
234+
235+ - name : Verify installations (Windows)
236+ if : matrix.platform == 'win'
237+ shell : powershell
238+ run : |
239+ Write-Host "Verifying installed tools:"
240+ Write-Host "=========================="
241+
242+ # Refresh PATH
243+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
244+
245+ Write-Host "`nPython:"
246+ python --version
247+
248+ Write-Host "`nGit:"
249+ git --version
250+
251+ Write-Host "`nNASM:"
252+ nasm -v
253+
254+ Write-Host "`n--- Visual Studio Information ---"
255+ $vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
256+
257+ Write-Host "`nVisual Studio 2022 Enterprise:"
258+ $vsPath = & $vsWhere -latest -products Microsoft.VisualStudio.Product.Enterprise -property installationPath
259+
260+ if ([string]::IsNullOrEmpty($vsPath)) {
261+ Write-Host "WARNING: VS 2022 Enterprise not found! Looking for any VS installation..."
262+ $vsPath = & $vsWhere -latest -products * -property installationPath
263+ }
264+
265+ Write-Host "Installation path: $vsPath"
266+
267+ $displayName = & $vsWhere -path "$vsPath" -property displayName
268+ $version = & $vsWhere -path "$vsPath" -property installationVersion
269+ $productId = & $vsWhere -path "$vsPath" -property productId
270+
271+ Write-Host "Product: $displayName"
272+ Write-Host "Version: $version"
273+ Write-Host "Product ID: $productId"
274+
275+ Write-Host "`nSearching for MSVC and Clang compilers:"
276+ $clPath = & $vsWhere -path "$vsPath" -find "**/Hostx64/x64/cl.exe" | Select-Object -First 1
277+ $clangPath = & $vsWhere -path "$vsPath" -find "**/bin/Hostx64/clang.exe" | Select-Object -First 1
278+
279+ if ($clPath) {
280+ Write-Host " [OK] MSVC cl.exe: $clPath"
281+ } else {
282+ Write-Host " [NOT FOUND] MSVC cl.exe"
283+ }
284+
285+ if ($clangPath) {
286+ Write-Host " [OK] Clang: $clangPath"
287+ } else {
288+ Write-Host " [NOT FOUND] Clang (May need to install C++ workload)"
289+ }
290+
291+ Write-Host "`n=========================================="
292+ Write-Host "Prerequisites verification completed!"
293+
294+ - name : Setup MSVC (Windows)
295+ if : matrix.platform == 'win'
296+ uses : ilammy/msvc-dev-cmd@v1
297+ with :
298+ arch : ${{ matrix.arch }}
299+
91300 - name : Configure and Build (Linux ARM64 with cross-compilation)
92301 if : matrix.platform == 'linux' && matrix.arch == 'arm64'
93302 run : |
@@ -112,7 +321,7 @@ jobs:
112321 make -j$(nproc)
113322
114323 - name : Configure and Build (Linux x64 and macOS)
115- if : matrix.platform != 'linux' || matrix.arch != 'arm64'
324+ if : matrix.platform != 'win' && (matrix.platform != ' linux' || matrix.arch != 'arm64')
116325 run : |
117326 if [ "${{ matrix.compiler }}" = "gcc" ]; then
118327 export CC=gcc
@@ -126,17 +335,45 @@ jobs:
126335
127336 make -j$(${{ matrix.nproc_cmd }})
128337
338+ - name : Add Python to PATH (Windows)
339+ if : matrix.platform == 'win'
340+ shell : powershell
341+ run : |
342+ # Add winget-installed Python to GitHub Actions PATH
343+ $pythonPath = "$env:LOCALAPPDATA\Programs\Python\Python312"
344+ if (Test-Path $pythonPath) {
345+ echo "$pythonPath" >> $env:GITHUB_PATH
346+ echo "$pythonPath\Scripts" >> $env:GITHUB_PATH
347+ Write-Host "Added Python path: $pythonPath"
348+ }
349+
350+ - name : Configure and Build (Windows)
351+ if : matrix.platform == 'win'
352+ shell : cmd
353+ run : |
354+ python --version
355+ vcbuild.bat dll x64
356+
129357 - name : Package assets
130358 if : startsWith(github.ref, 'refs/tags/')
131359 run : |
132- cd out/Release
360+ if [ "${{ matrix.platform }}" = "win" ]; then
361+ cd Release
133362
134- # Package shared libraries into zip archive
135- zip node-shared-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.compiler }}.zip ${{ matrix.lib_name }}
363+ # Package shared libraries into zip archive
364+ 7z a node-shared-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.compiler }}.zip ${{ matrix.lib_name }} libnode.lib node.lib
365+ else
366+ cd out/Release
367+
368+ # Package shared libraries into zip archive
369+ zip node-shared-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.compiler }}.zip ${{ matrix.lib_name }}
370+ fi
371+ shell : bash
136372
137373 - name : Publish to release assets
138374 uses : softprops/action-gh-release@v2
139375 if : startsWith(github.ref, 'refs/tags/')
140376 with :
141377 files : |
142378 out/Release/node-shared-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.compiler }}.zip
379+ Release/node-shared-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.compiler }}.zip
0 commit comments