Skip to content

Commit 60102da

Browse files
feat: output a slim node.exe(without V8 engine)
1 parent 08448cc commit 60102da

1 file changed

Lines changed: 91 additions & 2 deletions

File tree

.github/workflows/build_node_shared.yml

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,14 +354,103 @@ jobs:
354354
python --version
355355
vcbuild.bat dll x64
356356
357+
- name: Build node.exe that links to libnode.dll (Windows)
358+
if: matrix.platform == 'win'
359+
shell: powershell
360+
run: |
361+
Write-Host "========== Building node.exe that uses libnode.dll =========="
362+
Write-Host ""
363+
Write-Host "The vcbuild.bat dll option creates libnode.dll but the default node.exe"
364+
Write-Host "is statically linked. We need to build a thin node.exe that dynamically"
365+
Write-Host "links to libnode.dll (which contains V8 and Node.js core)."
366+
Write-Host ""
367+
368+
# Create a minimal C++ launcher that calls node::Start() from libnode.dll
369+
# This is based on src/node_main.cc but simplified for external linking
370+
$launcherCode = @'
371+
// Minimal Node.js launcher that links to libnode.dll
372+
// This executable does NOT contain V8 - it uses V8 from libnode.dll
373+
374+
#include <windows.h>
375+
376+
namespace node {
377+
int Start(int argc, char** argv);
378+
}
379+
380+
#ifdef _UNICODE
381+
int wmain(int argc, wchar_t* wargv[]) {
382+
// Convert wide args to UTF-8
383+
char** argv = new char*[argc + 1];
384+
for (int i = 0; i < argc; i++) {
385+
int size = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, nullptr, 0, nullptr, nullptr);
386+
argv[i] = new char[size];
387+
WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i], size, nullptr, nullptr);
388+
}
389+
argv[argc] = nullptr;
390+
391+
int result = node::Start(argc, argv);
392+
393+
for (int i = 0; i < argc; i++) {
394+
delete[] argv[i];
395+
}
396+
delete[] argv;
397+
398+
return result;
399+
}
400+
#else
401+
int main(int argc, char** argv) {
402+
return node::Start(argc, argv);
403+
}
404+
#endif
405+
'@
406+
407+
Set-Location Release
408+
409+
# Write the launcher source file
410+
$launcherCode | Out-File -FilePath "node_launcher.cc" -Encoding UTF8
411+
Write-Host "Created node_launcher.cc"
412+
413+
# Compile the launcher and link against libnode.lib
414+
Write-Host ""
415+
Write-Host "Compiling node.exe (thin launcher linked to libnode.dll)..."
416+
417+
# Use cl.exe to compile
418+
$compileResult = & cl.exe /nologo /O2 /MD /EHsc /DUNICODE /D_UNICODE `
419+
node_launcher.cc `
420+
/link /OUT:node.exe `
421+
libnode.lib `
422+
/SUBSYSTEM:CONSOLE 2>&1
423+
424+
Write-Host $compileResult
425+
426+
if (Test-Path "node.exe") {
427+
Write-Host ""
428+
Write-Host "[OK] node.exe built successfully!"
429+
Write-Host ""
430+
Write-Host "Verifying node.exe dependencies:"
431+
& dumpbin /dependents node.exe | Select-String -Pattern "libnode|KERNEL32|VCRUNTIME|api-ms"
432+
433+
Write-Host ""
434+
Write-Host "File sizes comparison:"
435+
$nodeSize = (Get-Item "node.exe").Length / 1KB
436+
$libSize = (Get-Item "libnode.dll").Length / 1MB
437+
Write-Host " node.exe: $([math]::Round($nodeSize, 2)) KB (thin launcher, no V8)"
438+
Write-Host " libnode.dll: $([math]::Round($libSize, 2)) MB (contains V8 and Node.js core)"
439+
} else {
440+
Write-Host ""
441+
Write-Host "[ERROR] Failed to build node.exe"
442+
exit 1
443+
}
444+
357445
- name: Package assets
358446
if: startsWith(github.ref, 'refs/tags/')
359447
run: |
360448
if [ "${{ matrix.platform }}" = "win" ]; then
361449
cd Release
362450
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
451+
# Package shared libraries and node.exe into zip archive
452+
# node.exe is now dynamically linked to libnode.dll (does not contain V8)
453+
7z a node-shared-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.compiler }}.zip ${{ matrix.lib_name }} libnode.lib node.lib node.exe
365454
else
366455
cd out/Release
367456

0 commit comments

Comments
 (0)