mirror of https://github.com/nodejs/node.git
118 lines
4.5 KiB
Markdown
118 lines
4.5 KiB
Markdown
# Maintaining shared library support
|
|
|
|
Node.js unofficially supports a build option where Node.js is built as
|
|
a shared library. The shared library is called libnode with additional postfixes
|
|
as appropriate for the platform (for example libnode.dll on windows).
|
|
The shared library provides a way to embed Node.js into other
|
|
applications and to have multiple applications use a single copy of
|
|
Node.js instead of having to bundle in the full Node.js footprint
|
|
into each application. For workloads that require multiple Node.js
|
|
instances this can result in a significant footprint savings.
|
|
|
|
This document provides an outline of the approach and things to look
|
|
out for when maintaining the shared library support.
|
|
|
|
Currently, shared library support has only been tested on:
|
|
|
|
* Linux
|
|
* macOS
|
|
* Windows
|
|
* AIX
|
|
|
|
## Building with shared library option
|
|
|
|
On non-Windows platforms, Node.js is built with the shared library
|
|
option by adding `--shared` to the configure step. On Windows
|
|
platforms Node.js is built with the shared library option by
|
|
adding `dll` to the vcbuild command line.
|
|
|
|
Once built there are two key components:
|
|
|
|
* executable - node
|
|
* library - libnode
|
|
|
|
The node executable is a thin wrapper around libnode which is
|
|
generated so that we can run the standard Node.js test suite
|
|
against the shared library.
|
|
|
|
The executable and library will have extensions as appropriate
|
|
for the platform on which they are built. For
|
|
example, node.exe on windows and node on other platforms for
|
|
the executable.
|
|
|
|
libnode may have additional naming components, as an example
|
|
in a build on macOS `libnode.105.dylib`. For non-windows platforms
|
|
the additional naming components include the `NODE_MODULE_VERSION` and
|
|
the appropriate postfix used for shared libraries on the platform.
|
|
|
|
In cases where an application links against the shared
|
|
library it is up to the application developer to add options
|
|
so that the shared library can be found by the application or
|
|
to set the LIBPATH (AIX), LD\_LIBRARY\_PATH (Linux/Unix), etc.
|
|
so that it is found at runtime.
|
|
|
|
For the node wrapper, on linux and macOS it is built
|
|
so that it can find the shared library in one of
|
|
the following:
|
|
|
|
* the same directory as the node executable
|
|
* ../lib with the expectation that the executable is
|
|
installed in a `bin` directory at the same level
|
|
as a `lib` directory in which the shared library is
|
|
installed. This is where the default package that
|
|
is build with the shared library option will
|
|
place the executable and library.
|
|
|
|
For the node wrapper on windows it is built expecting
|
|
that both the executable and shared library will
|
|
be in the same directory as it common practice on
|
|
that platform.
|
|
|
|
For the node wrapper on AIX, it is built with
|
|
the path to the shared library hardcoded as that
|
|
is the only option.
|
|
|
|
## Exports
|
|
|
|
On windows, functions that may be linked from native
|
|
addons or additional Node.js executables need to have
|
|
NODE\_EXTERN\_PRIVATE or NODE\_EXTERN otherwise they will
|
|
not be exported by the shared library. In the case of
|
|
functions used by additional Node.js executables
|
|
(ex: `mksnapshot`) a missing NODE\_EXTERN or
|
|
NODE\_EXTERN\_PRIVATE will cause the build to fail.
|
|
NODE\_EXTERN\_PRIVATE should be used in these cases
|
|
unless the intent is to add the function to the
|
|
public embedder API.
|
|
|
|
## Native addons
|
|
|
|
For regular Node.js builds, running native addons relies on symbols
|
|
exported by the node executable. As a result any
|
|
pre-built binaries expect symbols to be exported from the executable
|
|
instead of the shared library itself.
|
|
|
|
The node executable and shared library are built and linked
|
|
so that the required symbols are exported from the node
|
|
executable. This requires some extra work on some platforms
|
|
and the process to build the node executable is a good example
|
|
of how this can be achieved. Applications that use the shared
|
|
library and want to support native addons should employ
|
|
a similar technique.
|
|
|
|
## Testing
|
|
|
|
There is currently no testing in the regular CI run for PRs. There
|
|
are some CI jobs that can be used to test the shared library support and
|
|
some are run as part of daily testing. These include:
|
|
|
|
* [node-test-commit-linux-as-shared-lib](https://ci.nodejs.org/view/Node.js%20Daily/job/node-test-commit-linux-as-shared-lib/)
|
|
* <https://ci.nodejs.org/view/All/job/node-test-commit-osx-as-shared-lib/>
|
|
* [node-test-commit-aix-shared-lib](https://ci.nodejs.org/view/Node.js%20Daily/job/node-test-commit-aix-shared-lib/)
|
|
|
|
TODO: add a Job for windows
|
|
|
|
For code that modifies/affects shared library support these CI jobs should
|
|
run and it should be validated that there are no regressions in
|
|
the test suite.
|