Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Marlow <william.marlow@ibm.com>2022-02-04 13:12:57 +0300
committerRafaelGSS <rafael.nunu@hotmail.com>2022-05-10 15:13:19 +0300
commit0eb32ed976296b5082c7c5e1e13f32e91cb23400 (patch)
tree90d2389881106e04696c40dce513feab6b7b15b3 /node.gyp
parent840e61e745e37448c9b23a0d44892b0bc50e1f24 (diff)
build: fix various shared library build issues
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>
Diffstat (limited to 'node.gyp')
-rw-r--r--node.gyp55
1 files changed, 54 insertions, 1 deletions
diff --git a/node.gyp b/node.gyp
index 4e06d00c823..e2a7cd5d69d 100644
--- a/node.gyp
+++ b/node.gyp
@@ -196,6 +196,16 @@
'dependencies': [ 'node_aix_shared' ],
}, {
'dependencies': [ '<(node_lib_target_name)' ],
+ 'conditions': [
+ ['OS=="win" and node_shared=="true"', {
+ 'dependencies': ['generate_node_def'],
+ 'msvs_settings': {
+ 'VCLinkerTool': {
+ 'ModuleDefinitionFile': '<(PRODUCT_DIR)/<(node_core_target_name).def',
+ },
+ },
+ }],
+ ],
}],
[ 'node_intermediate_lib_type=="static_library" and node_shared=="false"', {
'xcode_settings': {
@@ -235,8 +245,15 @@
}],
[ 'node_shared=="true"', {
'xcode_settings': {
- 'OTHER_LDFLAGS': [ '-Wl,-rpath,@loader_path', ],
+ 'OTHER_LDFLAGS': [ '-Wl,-rpath,@loader_path', '-Wl,-rpath,@loader_path/../lib'],
},
+ 'conditions': [
+ ['OS=="linux"', {
+ 'ldflags': [
+ '-Wl,-rpath,\\$$ORIGIN/../lib'
+ ],
+ }],
+ ],
}],
[ 'enable_lto=="true"', {
'xcode_settings': {
@@ -749,6 +766,7 @@
'libraries': [
'Dbghelp',
'Psapi',
+ 'Winmm',
'Ws2_32',
],
}],
@@ -1502,5 +1520,40 @@
},
]
}], # end aix section
+ ['OS=="win" and node_shared=="true"', {
+ 'targets': [
+ {
+ 'target_name': 'gen_node_def',
+ 'type': 'executable',
+ 'sources': [
+ 'tools/gen_node_def.cc'
+ ],
+ },
+ {
+ 'target_name': 'generate_node_def',
+ 'dependencies': [
+ 'gen_node_def',
+ '<(node_lib_target_name)',
+ ],
+ 'type': 'none',
+ 'actions': [
+ {
+ 'action_name': 'generate_node_def_action',
+ 'inputs': [
+ '<(PRODUCT_DIR)/<(node_lib_target_name).dll'
+ ],
+ 'outputs': [
+ '<(PRODUCT_DIR)/<(node_core_target_name).def',
+ ],
+ 'action': [
+ '<(PRODUCT_DIR)/gen_node_def.exe',
+ '<@(_inputs)',
+ '<@(_outputs)',
+ ],
+ },
+ ],
+ },
+ ],
+ }], # end win section
], # end conditions block
}