mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
1af70548bd
Node.js unofficially supports a shared library variant where the main node executable is a thin wrapper around node.dll/libnode.so. The key benefit of this is to support embedding Node.js in other applications. Since Node.js 12 there have been a number of issues preventing the shared library build from working correctly, primarily on Windows: * A number of functions used executables such as `mksnapshot` are not exported from `libnode.dll` using a `NODE_EXTERN` attribute * A dependency on the `Winmm` system library is missing * Incorrect defines on executable targets leads to `node.exe` claiming to export a number of functions that are actually in `libnode.dll` * Because `node.exe` attempts to export symbols, `node.lib` gets generated causing native extensions to try to link against `node.exe` not `libnode.dll`. * Similarly, because `node.dll` was renamed to `libnode.dll`, native extensions don't know to look for `libnode.lib` rather than `node.lib`. * On macOS an RPATH is added to find `libnode.dylib` relative to `node` in the same folder. This works fine from the `out/Release` folder but not from an installed prefix, where `node` will be in `bin/` and `libnode.dylib` will be in `lib/`. * Similarly on Linux, no RPATH is added so LD_LIBRARY_PATH needs setting correctly for `bin/node` to find `lib/libnode.so`. For the `libnode.lib` vs `node.lib` issue there are two possible options: 1. Ensure `node.lib` from `node.exe` does not get generated, and instead copy `libnode.lib` to `node.lib`. This means addons compiled when referencing the correct `node.lib` file will correctly depend on `libnode.dll`. The down side is that native addons compiled with stock Node.js will still try to resolve symbols against node.exe rather than libnode.dll. 2. After building `libnode.dll`, dump the exports using `dumpbin`, and process this to generate a `node.def` file to be linked into `node.exe` with the `/DEF:node.def` flag. The export entries in `node.def` will all read ``` my_symbol=libnode.my_symbol ``` so that `node.exe` will redirect all exported symbols back to `libnode.dll`. This has the benefit that addons compiled with stock Node.js will load correctly into `node.exe` from a shared library build, but means that every embedding executable also needs to perform this same trick. I went with the first option as it is the cleaner of the two solutions in my opinion. Projects wishing to generate a shared library variant of Node.js can now, for example, ``` .\vcbuild dll package vs ``` to generate a full node installation including `libnode.dll`, `Release\node.lib`, and all the necessary headers. Native addons can then be built against the shared library build easily by specifying the correct `nodedir` option. For example ``` >npx node-gyp configure --nodedir C:\Users\User\node\Release\node-v18.0.0-win-x64 ... >npx node-gyp build ... >dumpbin /dependents build\Release\binding.node Microsoft (R) COFF/PE Dumper Version 14.29.30136.0 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file build\Release\binding.node File Type: DLL Image has the following dependencies: KERNEL32.dll libnode.dll VCRUNTIME140.dll api-ms-win-crt-string-l1-1-0.dll api-ms-win-crt-stdio-l1-1-0.dll api-ms-win-crt-runtime-l1-1-0.dll ... ``` PR-URL: https://github.com/nodejs/node/pull/41850 Reviewed-By: Michael Dawson <midawson@redhat.com> Reviewed-By: Beth Griggs <bgriggs@redhat.com> Reviewed-By: Richard Lau <rlau@redhat.com> |
||
---|---|---|
.. | ||
actions | ||
bootstrap | ||
clang-format | ||
code_cache | ||
configure.d | ||
doc | ||
eslint-rules | ||
gyp | ||
icu | ||
inspector_protocol | ||
lint-md | ||
macos-installer | ||
msvs | ||
node_modules | ||
pip | ||
rpm | ||
snapshot | ||
v8 | ||
v8_gypfiles | ||
.eslintrc.yaml | ||
build-addons.js | ||
certdata.txt | ||
checkimports.py | ||
compress_json.py | ||
copyfile.py | ||
cpplint.py | ||
create_android_makefiles | ||
create_expfile.sh | ||
enable_fips_include.py | ||
find-inactive-collaborators.mjs | ||
find-inactive-tsc.mjs | ||
gen_node_def.cc | ||
genv8constants.py | ||
getarch.py | ||
getendian.py | ||
getmachine.py | ||
getmoduleversion.py | ||
getnapibuildversion.py | ||
getnodeversion.py | ||
getsharedopensslhasquic.py | ||
gyp_node.py | ||
install.py | ||
js2c.py | ||
license2rtf.js | ||
license-builder.sh | ||
lint-pr-url.mjs | ||
lint-sh.js | ||
lsan_suppressions.txt | ||
macos-firewall.sh | ||
make-v8.sh | ||
mk-ca-bundle.pl | ||
mkssldef.py | ||
osx-codesign.sh | ||
osx-entitlements.plist | ||
osx-gon-config.json.tmpl | ||
osx-notarize.sh | ||
osx-pkg-postinstall.sh | ||
osx-productsign.sh | ||
release.sh | ||
run-valgrind.py | ||
run-worker.js | ||
sign.bat | ||
specialize_node_d.py | ||
test-npm-package.js | ||
test-v8.bat | ||
test.py | ||
update-authors.js | ||
update-cares.sh | ||
update-eslint.sh | ||
update-nghttp2.sh | ||
update-npm.sh | ||
update-undici.sh | ||
utils.py | ||
valgrind.supp |