1# Maintaining shared library support 2 3Node.js unofficially supports a build option where Node.js is built as 4a shared library. The shared library is called libnode with additional postfixes 5as appropriate for the platform (for example libnode.dll on windows). 6The shared library provides a way to embed Node.js into other 7applications and to have multiple applications use a single copy of 8Node.js instead of having to bundle in the full Node.js footprint 9into each application. For workloads that require multiple Node.js 10instances this can result in a significant footprint savings. 11 12This document provides an outline of the approach and things to look 13out for when maintaining the shared library support. 14 15Currently, shared library support has only been tested on: 16 17* Linux 18* macOS 19* Windows 20* AIX 21 22## Building with shared library option 23 24On non-Windows platforms, Node.js is built with the shared library 25option by adding `--shared` to the configure step. On Windows 26platforms Node.js is built with the shared library option by 27adding `dll` to the vcbuild command line. 28 29Once built there are two key components: 30 31* executable - node 32* library - libnode 33 34The node executable is a thin wrapper around libnode which is 35generated so that we can run the standard Node.js test suite 36against the shared library. 37 38The executable and library will have extensions as appropriate 39for the platform on which they are built. For 40example, node.exe on windows and node on other platforms for 41the executable. 42 43libnode may have additional naming components, as an example 44in a build on macOS `libnode.105.dylib`. For non-windows platforms 45the additional naming components include the `NODE_MODULE_VERSION` and 46the appropriate postfix used for shared libraries on the platform. 47 48In cases where an application links against the shared 49library it is up to the application developer to add options 50so that the shared library can be found by the application or 51to set the LIBPATH (AIX), LD\_LIBRARY\_PATH (Linux/Unix), etc. 52so that it is found at runtime. 53 54For the node wrapper, on linux and macOS it is built 55so that it can find the shared library in one of 56the following: 57 58* the same directory as the node executable 59* ../lib with the expectation that the executable is 60 installed in a `bin` directory at the same level 61 as a `lib` directory in which the shared library is 62 installed. This is where the default package that 63 is build with the shared library option will 64 place the executable and library. 65 66For the node wrapper on windows it is built expecting 67that both the executable and shared library will 68be in the same directory as it common practice on 69that platform. 70 71For the node wrapper on AIX, it is built with 72the path to the shared library hardcoded as that 73is the only option. 74 75## Exports 76 77On windows, functions that may be linked from native 78addons or additional Node.js executables need to have 79NODE\_EXTERN\_PRIVATE or NODE\_EXTERN otherwise they will 80not be exported by the shared library. In the case of 81functions used by additional Node.js executables 82(ex: `mksnapshot`) a missing NODE\_EXTERN or 83NODE\_EXTERN\_PRIVATE will cause the build to fail. 84NODE\_EXTERN\_PRIVATE should be used in these cases 85unless the intent is to add the function to the 86public embedder API. 87 88## Native addons 89 90For regular Node.js builds, running native addons relies on symbols 91exported by the node executable. As a result any 92pre-built binaries expect symbols to be exported from the executable 93instead of the shared library itself. 94 95The node executable and shared library are built and linked 96so that the required symbols are exported from the node 97executable. This requires some extra work on some platforms 98and the process to build the node executable is a good example 99of how this can be achieved. Applications that use the shared 100library and want to support native addons should employ 101a similar technique. 102 103## Testing 104 105There is currently no testing in the regular CI run for PRs. There 106are some CI jobs that can be used to test the shared library support and 107some are run as part of daily testing. These include: 108 109* [node-test-commit-linux-as-shared-lib](https://ci.nodejs.org/view/Node.js%20Daily/job/node-test-commit-linux-as-shared-lib/) 110* <https://ci.nodejs.org/view/All/job/node-test-commit-osx-as-shared-lib/> 111* [node-test-commit-aix-shared-lib](https://ci.nodejs.org/view/Node.js%20Daily/job/node-test-commit-aix-shared-lib/) 112 113TODO: add a Job for windows 114 115For code that modifies/affects shared library support these CI jobs should 116run and it should be validated that there are no regressions in 117the test suite. 118