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

build: do not hard code module and napi versions #49277

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ The Node.js ecosystem is reliant on ABI compatibility within a major release.
To maintain ABI compatibility it is required that distributed builds of Node.js
be built against the same version of dependencies, or similar versions that do
not break their ABI compatibility, as those released by Node.js for any given
`NODE_MODULE_VERSION` (located in `src/node_version.h`).
`NODE_MODULE_VERSION` (located in `node_api_versions.json`).

When Node.js is built (with an intention to distribute) with an ABI
incompatible with the official Node.js builds (e.g. using a ABI incompatible
Expand Down
14 changes: 7 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,9 @@ out/Makefile: config.gypi common.gypi node.gyp \
tools/v8_gypfiles/inspector.gypi tools/v8_gypfiles/v8.gyp
$(PYTHON) tools/gyp_node.py -f make

# node_version.h is listed because the N-API version is taken from there
# node_api_versions.json is listed because the N-API version is taken from there
# and included in config.gypi
config.gypi: configure configure.py src/node_version.h
config.gypi: configure configure.py node_api_versions.json
@if [ -x config.status ]; then \
export PATH="$(NO_BIN_OVERRIDE_PATH)" && ./config.status; \
else \
Expand Down Expand Up @@ -390,7 +390,7 @@ ADDONS_BINDING_SOURCES := \
ADDONS_PREREQS := config.gypi \
deps/npm/node_modules/node-gyp/package.json tools/build-addons.mjs \
deps/uv/include/*.h deps/v8/include/*.h \
src/node.h src/node_buffer.h src/node_object_wrap.h src/node_version.h
src/node.h src/node_buffer.h src/node_object_wrap.h src/node_version.h.in

define run_build_addons
env npm_config_loglevel=$(LOGLEVEL) npm_config_nodedir="$$PWD" \
Expand Down Expand Up @@ -776,7 +776,7 @@ $(LINK_DATA): $(wildcard lib/*.js) tools/doc/apilinks.mjs | out/doc
$(call available-node, $(gen-apilink))

# Regenerate previous versions data if the current version changes
$(VERSIONS_DATA): CHANGELOG.md src/node_version.h tools/doc/versions.mjs
$(VERSIONS_DATA): CHANGELOG.md src/node_version.h.in tools/doc/versions.mjs
$(call available-node, tools/doc/versions.mjs $@)

node_use_icu = $(call available-node,"-p" "typeof Intl === 'object'")
Expand Down Expand Up @@ -865,7 +865,7 @@ FULLVERSION=$(VERSION)-$(TAG)
endif # ifeq ($(DISTTYPE),release)

DISTTYPEDIR ?= $(DISTTYPE)
RELEASE=$(shell sed -ne 's/\#define NODE_VERSION_IS_RELEASE \([01]\)/\1/p' src/node_version.h)
RELEASE=$(shell sed -ne 's/\#define NODE_VERSION_IS_RELEASE \([01]\)/\1/p' src/node_version.h.in)
PLATFORM=$(shell uname | tr '[:upper:]' '[:lower:]')
ifeq ($(findstring os/390,$PLATFORM),os/390)
PLATFORM ?= os390
Expand Down Expand Up @@ -1033,7 +1033,7 @@ release-only: check-xz
else \
echo "" >&2 ; \
echo "#NODE_VERSION_IS_RELEASE is set to $(RELEASE)." >&2 ; \
echo "Did you remember to update src/node_version.h?" >&2 ; \
echo "Did you remember to update src/node_version.h.in?" >&2 ; \
echo "" >&2 ; \
exit 1 ; \
fi
Expand Down Expand Up @@ -1270,7 +1270,7 @@ endif
$(RM) $(BINARYNAME).tar

.PHONY: binary
# This requires NODE_VERSION_IS_RELEASE defined as 1 in src/node_version.h.
# This requires NODE_VERSION_IS_RELEASE defined as 1 in src/node_version.h.in.
binary: $(BINARYTAR) ## Build release binary tarballs.

.PHONY: binary-upload
Expand Down
32 changes: 24 additions & 8 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@

# imports in tools/
sys.path.insert(0, 'tools')
import getmoduleversion
import getnapibuildversion
import getsharedopensslhasquic
from gyp_node import run_gyp
from utils import SearchFiles
Expand All @@ -58,6 +56,8 @@
valid_intl_modes = ('none', 'small-icu', 'full-icu', 'system-icu')
icu_versions = json.loads((tools_path / 'icu' / 'icu_versions.json').read_text(encoding='utf-8'))

node_api_versions = json.loads(Path('node_api_versions.json').read_text(encoding='utf-8'))

shareable_builtins = {'cjs_module_lexer/lexer': 'deps/cjs-module-lexer/lexer.js',
'cjs_module_lexer/dist/lexer': 'deps/cjs-module-lexer/dist/lexer.js',
'undici/undici': 'deps/undici/undici.js'
Expand Down Expand Up @@ -818,12 +818,24 @@
default=None,
help='Enable the built-in snapshot compression in V8.')

parser.add_argument('--napi-build-version',
action='store',
dest='napi_build_version',
default=None,
help='Override the value of napi_build_version')

parser.add_argument('--node-builtin-modules-path',
action='store',
dest='node_builtin_modules_path',
default=False,
help='node will load builtin modules from disk instead of from binary')

parser.add_argument('--node-module-version',
action='store',
dest='node_module_version',
default=None,
help='Override the value of node_module_version')

parser.add_argument('--node-snapshot-main',
action='store',
dest='node_snapshot_main',
Expand Down Expand Up @@ -1390,7 +1402,15 @@ def configure_node(o):

o['variables']['node_shared'] = b(options.shared)
o['variables']['libdir'] = options.libdir
node_module_version = getmoduleversion.get_version()

if options.node_module_version:
node_module_version = options.node_module_version
else:
node_module_version = str(node_api_versions['node_module_version'])
if options.napi_build_version:
napi_build_version = options.napi_build_version
else:
napi_build_version = str(node_api_versions['napi_build_version'])

if options.dest_os == 'android':
shlib_suffix = 'so'
Expand All @@ -1408,6 +1428,7 @@ def configure_node(o):
shlib_suffix %= node_module_version

o['variables']['node_module_version'] = int(node_module_version)
o['variables']['napi_build_version'] = napi_build_version
o['variables']['shlib_suffix'] = shlib_suffix

if options.linked_module:
Expand All @@ -1431,10 +1452,6 @@ def configure_node(o):
print('Warning! Loading builtin modules from disk is for development')
o['variables']['node_builtin_modules_path'] = options.node_builtin_modules_path

def configure_napi(output):
version = getnapibuildversion.get_napi_version()
output['variables']['napi_build_version'] = version

def configure_library(lib, output, pkgname=None):
shared_lib = 'shared_' + lib
output['variables']['node_' + shared_lib] = b(getattr(options, shared_lib))
Expand Down Expand Up @@ -2013,7 +2030,6 @@ def make_bin_override():

configure_node(output)
configure_node_lib_files(output)
configure_napi(output)
configure_library('zlib', output)
configure_library('http_parser', output)
configure_library('libuv', output)
Expand Down
14 changes: 3 additions & 11 deletions doc/contributing/releases-node-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ release process.
* [0. Pre-release steps](#0-pre-release-steps)
* [1. Update the main branch](#1-update-the-main-branch)
* [2. Create a new branch for the release](#2-create-a-new-branch-for-the-release)
* [3. Update `NAPI_VERSION`](#3-update-napi_version)
* [3. Update `napi_build_version`](#3-update-napi_build_version)
* [4. Define `addon_context_register_func`](#4-define-addon_context_register_func)
* [5. Update version guards](#5-update-version-guards)
* [6. Create release commit](#6-create-release-commit)
Expand Down Expand Up @@ -55,17 +55,9 @@ Create a new branch named `node-api-x-proposal`, off the main branch.
git checkout -b node-api-10-proposal upstream/main
```

### 3. Update `NAPI_VERSION`
### 3. Update `napi_build_version`

Set the version for the proposed release using the following macros, which are
already defined in `src/node_version.h`:

```c
#define NAPI_VERSION x
```

> Note: Do not update the `NAPI_VERSION` defined in `src/js_native_api.h`. It
> is a fixed constant baseline version of Node-API.
Set the version for the proposed release using in `node_api_versions.json`.

### 4. Define `addon_context_register_func`

Expand Down
28 changes: 14 additions & 14 deletions doc/contributing/releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ official release builds for Node.js, hosted on <https://nodejs.org/>.
* [0. Pre-release steps](#0-pre-release-steps)
* [1. Update the staging branch](#1-update-the-staging-branch)
* [2. Create a new branch for the release](#2-create-a-new-branch-for-the-release)
* [3. Update `src/node_version.h`](#3-update-srcnode_versionh)
* [3. Update `src/node_version.h.in`](#3-update-srcnode_versionhin)
* [4. Update the changelog](#4-update-the-changelog)
* [5. Create release commit](#5-create-release-commit)
* [6. Propose release on GitHub](#6-propose-release-on-github)
Expand Down Expand Up @@ -297,7 +297,7 @@ git cherry-pick ... # cherry-pick nodejs-private PR commits directly into the

</details>

### 3. Update `src/node_version.h`
### 3. Update `src/node_version.h.in`

Set the version for the proposed release using the following macros, which are
already defined in `src/node_version.h`:
Expand Down Expand Up @@ -468,8 +468,8 @@ run.

### 5. Create release commit

The `CHANGELOG.md`, `doc/changelogs/CHANGELOG_Vx.md`, `src/node_version.h`, and
`REPLACEME` changes should be the final commit that will be tagged for the
The `CHANGELOG.md`, `doc/changelogs/CHANGELOG_Vx.md`, `src/node_version.h.in`,
and `REPLACEME` changes should be the final commit that will be tagged for the
release. When committing these to git, use the following message format:

```text
Expand Down Expand Up @@ -732,7 +732,7 @@ project README.

### 12. Set up for the next release

On release proposal branch, edit `src/node_version.h` again and:
On release proposal branch, edit `src/node_version.h.in` again and:

* Increment `NODE_PATCH_VERSION` by one
* Change `NODE_VERSION_IS_RELEASE` back to `0`
Expand Down Expand Up @@ -790,16 +790,16 @@ git cherry-pick --strategy-option=diff-algorithm=patience v1.x^

Git should stop to let you fix conflicts.

Revert all changes that were made to `src/node_version.h`:
Revert all changes that were made to `src/node_version.h.in`:

```bash
git checkout --ours HEAD -- src/node_version.h
git checkout --ours HEAD -- src/node_version.h.in
```

<details>
<summary>Major version release</summary>

On the main branch, instead of reverting changes made to `src/node_version.h`
On the main branch, instead of reverting changes made to `src/node_version.h.in`
edit it instead and:

* Increment `NODE_MAJOR_VERSION` by one
Expand All @@ -815,9 +815,9 @@ git commit --amend
</details>

Even if there are no conflicts, ensure that you revert all the changes that were
made to `src/node_version.h`. `NODE_VERSION_IS_RELEASE` must be `0`.
made to `src/node_version.h.in`. `NODE_VERSION_IS_RELEASE` must be `0`.

<sup>Edit `src/node_version.h`, revert `NODE_VERSION_IS_RELEASE` back to `0`, and `git commit --amend`</sup>
<sup>Edit `src/node_version.h.in`, revert `NODE_VERSION_IS_RELEASE` back to `0`, and `git commit --amend`</sup>

If there are conflicts in `doc` due to updated `REPLACEME`
placeholders (that happens when a change previously landed on another release
Expand All @@ -832,7 +832,7 @@ the cherry-pick step.
Then finish cherry-picking and push the commit upstream:

```bash
git add src/node_version.h doc
git add src/node_version.h.in doc
git diff --staged src doc # read output to validate that changes shows up as expected
git cherry-pick --continue
make lint-md && make lint-cpp
Expand Down Expand Up @@ -1073,7 +1073,7 @@ git node release --prepare --startLTS
<summary>Manual steps for reference.</summary>

To mark a release line as LTS, the following changes must be made to
`src/node_version.h`:
`src/node_version.h.in`:

* The `NODE_MINOR_VERSION` macro must be incremented by one
* The `NODE_PATCH_VERSION` macro must be set to `0`
Expand Down Expand Up @@ -1205,8 +1205,8 @@ that will need updating to include the new major release.

### Update `NODE_MODULE_VERSION`

This macro in `src/node_version.h` is used to signal an ABI version for native
addons. It currently has two common uses in the community:
This macro in `src/node_version.h.in` is used to signal an ABI version for
native addons. It currently has two common uses in the community:

* Determining what API to work against for compiling native addons, e.g.
[NAN](https://github.com/nodejs/nan) uses it to form a compatibility-layer for
Expand Down
27 changes: 26 additions & 1 deletion node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@
'src/node_stat_watcher.h',
'src/node_union_bytes.h',
'src/node_url.h',
'src/node_version.h',
'src/node_version.h.in',
'src/node_v8.h',
'src/node_v8_platform-inl.h',
'src/node_wasi.h',
Expand Down Expand Up @@ -773,6 +773,12 @@
'node.gypi',
],

'direct_dependent_settings': {
'include_dirs': [
'<(SHARED_INTERMEDIATE_DIR)' # for node_version.h
],
},

'include_dirs': [
'src',
'deps/postject',
Expand All @@ -790,6 +796,8 @@

'sources': [
'<@(node_sources)',
# Generated headers
'<(SHARED_INTERMEDIATE_DIR)/node_version.h',
# Dependency headers
'deps/v8/include/v8.h',
'deps/postject/postject-api.h',
Expand Down Expand Up @@ -958,6 +966,23 @@
'<@(linked_module_files)',
],
},
{
'action_name': 'generate_node_version_h',
'process_outputs_as_sources': 1,
'inputs': [
'src/node_version.h.in',
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/node_version.h',
],
'action': [
'tools/generate_node_version.py',
'<@(_inputs)',
'<@(_outputs)',
'<(node_module_version)',
'<(napi_build_version)',
],
},
],
}, # node_lib_target_name
{ # fuzz_env
Expand Down
4 changes: 4 additions & 0 deletions node_api_versions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"node_module_version": 115,
"napi_build_version": 9
}
4 changes: 2 additions & 2 deletions src/node_version.h → src/node_version.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@
* version matching should open a pull request to reserve a number in this
* registry.
*/
#define NODE_MODULE_VERSION 115
#define NODE_MODULE_VERSION /*NODE_MODULE_VERSION_PLACEHOLDER*/

// The NAPI_VERSION supported by the runtime. This is the inclusive range of
// versions which the Node.js binary being built supports.
#define NODE_API_SUPPORTED_VERSION_MAX 9
#define NODE_API_SUPPORTED_VERSION_MAX /*NAPI_BUILD_VERSION_PLACEHOLDER*/
#define NODE_API_SUPPORTED_VERSION_MIN 1

// Node API modules use NAPI_VERSION 8 by default if it is not explicitly
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-release-changelog.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const getDefine = (text, name) => {

const srcRoot = path.join(__dirname, '..', '..');
const mainChangelogFile = path.join(srcRoot, 'CHANGELOG.md');
const versionFile = path.join(srcRoot, 'src', 'node_version.h');
const versionFile = path.join(srcRoot, 'src', 'node_version.h.in');
const versionText = fs.readFileSync(versionFile, { encoding: 'utf8' });
const release = getDefine(versionText, 'NODE_VERSION_IS_RELEASE') !== '0';

Expand Down
2 changes: 1 addition & 1 deletion tools/doc/versions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const srcRoot = new URL('../../', import.meta.url);

const isRelease = () => {
const re = /#define NODE_VERSION_IS_RELEASE 0/;
const file = new URL('./src/node_version.h', srcRoot);
const file = new URL('./src/node_version.h.in', srcRoot);
return !re.test(readFileSync(file, { encoding: 'utf8' }));
};

Expand Down
25 changes: 25 additions & 0 deletions tools/generate_node_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env python3

import sys


def main(input_file, output_file, node_module_version, napi_build_version):
with open(input_file, 'r') as i:
content = i.read() \
.replace("/*NODE_MODULE_VERSION_PLACEHOLDER*/", \
node_module_version) \
.replace("/*NAPI_BUILD_VERSION_PLACEHOLDER*/", \
napi_build_version)

with open(output_file, 'w') as o:
o.write(content)


if __name__ == '__main__':
if len(sys.argv) != 5:
print("Usage: generate_node_version.py "
"<node_version.h.in> <node_version.h> "
"<node_module_version> <napi_build_version>")
sys.exit(1)

main(*sys.argv[1:])
Loading
Loading