Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: add maintaining info for shared library option #42517

Closed
wants to merge 26 commits into from
Closed
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
04fc7e6
doc: add maintaining info for shared libary option
mhdawson Mar 29, 2022
d868979
fix typo
mhdawson Mar 29, 2022
31a712d
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Mar 30, 2022
00f1f2b
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Mar 30, 2022
e3d1085
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Mar 30, 2022
e066018
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Mar 30, 2022
2dea68b
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Mar 30, 2022
b81291c
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Mar 30, 2022
8f5935e
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Mar 30, 2022
a5b3e46
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Mar 30, 2022
c721355
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Mar 30, 2022
b3c5a0a
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Mar 30, 2022
4ce8d4a
squash: address comments
mhdawson Mar 30, 2022
6b136cd
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Mar 31, 2022
487a5c2
squash: address comments
mhdawson Mar 31, 2022
3f0212b
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Apr 7, 2022
5ca69c2
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Apr 7, 2022
1646f22
squash: address comments
mhdawson Apr 7, 2022
2136f11
squash: satisfy the linter
mhdawson Apr 7, 2022
b165ebd
Update doc/contributing/maintaining-shared-library-support.md
mhdawson Apr 21, 2022
86b1571
squash: address comments
mhdawson Apr 21, 2022
1912c7c
squash: address comments
mhdawson Apr 21, 2022
fa78950
Update doc/contributing/maintaining-shared-library-support.md
mhdawson May 10, 2022
7703b6e
squash: update to reflect current approach
mhdawson May 10, 2022
0a42b27
squash: address linter issues
mhdawson May 10, 2022
a89bafa
squash: stand on head to make linter happy
mhdawson May 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions doc/contributing/maintaining-shared-library-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# 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 platoforms, Node.js is built with the shared library
option by adding `--shared` to the configure step. On Windows
platofrms 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.