Skip to content

Commit 8671a3f

Browse files
authored
Merge pull request #7 from TEN-framework/feat/win
feat: add Windows platform support (x64 and ARM64) to build workflow
2 parents 2f244e0 + 714fb7d commit 8671a3f

1 file changed

Lines changed: 243 additions & 6 deletions

File tree

.github/workflows/build_node_shared.yml

Lines changed: 243 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
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 }}
@@ -73,6 +81,65 @@ jobs:
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

Comments
 (0)