From 55f21fa99021d3f4aed7e6472210e220a615bf5c Mon Sep 17 00:00:00 2001 From: inoway46 Date: Sat, 17 Oct 2026 12:50:13 +0900 Subject: [PATCH 1/2] build: use a single producer for shared generated files Cross builds instantiate several shared generation actions in both toolsets, producing duplicate output rules that Ninja rejects. Register these actions once in the target toolset and explicitly share them with host consumers. Keep generator executables in the host toolset for cross builds. Refs: https://github.com/nodejs/node/issues/66803 Assisted-by: Codex Signed-off-by: inoway46 --- deps/crates/crates.gyp | 2 +- src/inspector/node_inspector.gypi | 2 +- tools/v8_gypfiles/d8.gyp | 2 +- tools/v8_gypfiles/v8.gyp | 60 ++++++++++++++------------- tools/v8_gypfiles/v8_debug_helper.gyp | 8 ++-- 5 files changed, 38 insertions(+), 36 deletions(-) diff --git a/deps/crates/crates.gyp b/deps/crates/crates.gyp index 216b0cff5128..702e661f4d3f 100644 --- a/deps/crates/crates.gyp +++ b/deps/crates/crates.gyp @@ -132,7 +132,7 @@ # available to load it at runtime. 'target_name': 'temporal_zoneinfo64_data', 'type': 'none', - 'toolsets': ['host', 'target'], + 'toolsets': ['target'], 'hard_dependency': 1, 'direct_dependent_settings': { 'sources': [ diff --git a/src/inspector/node_inspector.gypi b/src/inspector/node_inspector.gypi index 88e8a2f401ca..fbf9df499b69 100644 --- a/src/inspector/node_inspector.gypi +++ b/src/inspector/node_inspector.gypi @@ -113,7 +113,7 @@ ], 'dependencies': [ '<(protocol_tool_path)/inspector_protocol.gyp:crdtp', - '<(v8_gypfiles_dir)/v8.gyp:v8_inspector_headers', + '<(v8_gypfiles_dir)/v8.gyp:v8_inspector_headers#target', ], 'actions': [ { diff --git a/tools/v8_gypfiles/d8.gyp b/tools/v8_gypfiles/d8.gyp index f59a155b169c..49916168aecb 100644 --- a/tools/v8_gypfiles/d8.gyp +++ b/tools/v8_gypfiles/d8.gyp @@ -19,7 +19,7 @@ 'v8.gyp:v8', 'v8.gyp:v8_libbase', 'v8.gyp:v8_libplatform', - 'v8.gyp:generate_bytecode_builtins_list', + 'v8.gyp:generate_bytecode_builtins_list#target', 'v8.gyp:fp16', ], # Generated source files need this explicitly: diff --git a/tools/v8_gypfiles/v8.gyp b/tools/v8_gypfiles/v8.gyp index 71b6772bc345..e1f8432c6876 100644 --- a/tools/v8_gypfiles/v8.gyp +++ b/tools/v8_gypfiles/v8.gyp @@ -101,9 +101,11 @@ ], }, # v8_pch { + # Shared generated sources have one producer for both toolsets. In cross + # builds, the executable used by this action still belongs to the host. 'target_name': 'run_torque', 'type': 'none', - 'toolsets': ['host', 'target'], + 'toolsets': ['target'], 'conditions': [ ['want_separate_host_toolset', { 'dependencies': ['torque#host'], @@ -191,8 +193,8 @@ 'toolsets': ['host', 'target'], 'hard_dependency': 1, 'dependencies': [ - 'generate_bytecode_builtins_list', - 'run_torque', + 'generate_bytecode_builtins_list#target', + 'run_torque#target', 'v8_base_without_compiler', 'torque_runtime_support', 'v8_maybe_icu', @@ -214,8 +216,8 @@ 'toolsets': ['host', 'target'], 'hard_dependency': 1, 'dependencies': [ - 'generate_bytecode_builtins_list', - 'run_torque', + 'generate_bytecode_builtins_list#target', + 'run_torque#target', 'v8_internal_headers', 'v8_libbase', 'v8_maybe_icu', @@ -236,7 +238,7 @@ 'target_name': 'generate_bytecode_builtins_list', 'type': 'none', 'hard_dependency': 1, - 'toolsets': ['host', 'target'], + 'toolsets': ['target'], 'conditions': [ ['want_separate_host_toolset', { 'dependencies': ['bytecode_builtins_list_generator#host'], @@ -277,8 +279,8 @@ 'type': 'static_library', 'toolsets': ['host', 'target'], 'dependencies': [ - 'generate_bytecode_builtins_list', - 'run_torque', + 'generate_bytecode_builtins_list#target', + 'run_torque#target', 'v8_base_without_compiler', 'v8_initializers', 'v8_maybe_icu', @@ -497,8 +499,8 @@ }], ['want_separate_host_toolset', { 'dependencies': [ - 'generate_bytecode_builtins_list', - 'run_torque', + 'generate_bytecode_builtins_list#target', + 'run_torque#target', 'mksnapshot#host', 'v8_maybe_icu', # [GYP] added explicitly, instead of inheriting from the other deps @@ -509,8 +511,8 @@ ] }, { 'dependencies': [ - 'generate_bytecode_builtins_list', - 'run_torque', + 'generate_bytecode_builtins_list#target', + 'run_torque#target', 'mksnapshot', 'v8_maybe_icu', # [GYP] added explicitly, instead of inheriting from the other deps @@ -631,8 +633,8 @@ 'v8_maybe_icu', 'v8_shared_internal_headers', 'v8_heap_base_headers', - 'generate_bytecode_builtins_list', - 'run_torque', + 'generate_bytecode_builtins_list#target', + 'run_torque#target', 'v8_libbase', 'fp16', ], @@ -961,8 +963,8 @@ 'type': 'static_library', 'toolsets': ['host', 'target'], 'dependencies': [ - 'generate_bytecode_builtins_list', - 'run_torque', + 'generate_bytecode_builtins_list#target', + 'run_torque#target', 'v8_maybe_icu', 'v8_base_without_compiler', 'v8_internal_headers', @@ -983,8 +985,8 @@ 'type': 'static_library', 'toolsets': ['host', 'target'], 'dependencies': [ - 'generate_bytecode_builtins_list', - 'run_torque', + 'generate_bytecode_builtins_list#target', + 'run_torque#target', 'v8_internal_headers', 'v8_maybe_icu', 'v8_base_without_compiler', @@ -1019,8 +1021,8 @@ 'toolsets': ['host', 'target'], 'hard_dependency': 1, 'dependencies': [ - 'generate_bytecode_builtins_list', - 'run_torque', + 'generate_bytecode_builtins_list#target', + 'run_torque#target', 'v8_maybe_icu', ], 'conditions': [ @@ -1044,7 +1046,7 @@ { 'target_name': 'v8_inspector_headers', 'type': 'none', - 'toolsets': ['host', 'target'], + 'toolsets': ['target'], 'hard_dependency': 1, 'includes': ['inspector.gypi'], 'direct_dependent_settings': { @@ -1102,13 +1104,13 @@ 'v8_bigint', 'v8_headers', 'v8_heap_base', - 'v8_inspector_headers', + 'v8_inspector_headers#target', 'v8_libbase', 'v8_shared_internal_headers', 'v8_version', 'cppgc_base', - 'generate_bytecode_builtins_list', - 'run_torque', + 'generate_bytecode_builtins_list#target', + 'run_torque#target', 'v8_internal_headers', 'v8_maybe_icu', 'v8_zlib', @@ -1155,7 +1157,7 @@ }], ['v8_enable_i18n_support==0', { 'dependencies': [ - '../../deps/crates/crates.gyp:temporal_zoneinfo64_data', + '../../deps/crates/crates.gyp:temporal_zoneinfo64_data#target', ], }], ], @@ -1369,7 +1371,7 @@ }], ['v8_enable_i18n_support==1', { 'dependencies': [ - 'run_gen-regexp-special-case', + 'run_gen-regexp-special-case#target', ], 'sources': [ '<(SHARED_INTERMEDIATE_DIR)/src/regexp/special-case.cc', @@ -2080,7 +2082,7 @@ { 'target_name': 'run_gen-regexp-special-case', 'type': 'none', - 'toolsets': ['host', 'target'], + 'toolsets': ['target'], 'conditions': [ ['want_separate_host_toolset', { 'dependencies': ['gen-regexp-special-case#host'], @@ -2320,8 +2322,8 @@ { 'target_name': 'postmortem-metadata', 'type': 'none', - 'toolsets': ['host', 'target'], - 'dependencies': ['run_torque'], + 'toolsets': ['target'], + 'dependencies': ['run_torque#target'], 'variables': { 'heapobject_files': [ '<(SHARED_INTERMEDIATE_DIR)/torque-generated/instance-types.h', diff --git a/tools/v8_gypfiles/v8_debug_helper.gyp b/tools/v8_gypfiles/v8_debug_helper.gyp index e869cb4f9771..2713b9832ca0 100644 --- a/tools/v8_gypfiles/v8_debug_helper.gyp +++ b/tools/v8_gypfiles/v8_debug_helper.gyp @@ -36,8 +36,8 @@ 'dependencies': [ 'gen_heap_constants', - 'v8.gyp:generate_bytecode_builtins_list', - 'v8.gyp:run_torque', + 'v8.gyp:generate_bytecode_builtins_list#target', + 'v8.gyp:run_torque#target', 'v8.gyp:v8_maybe_icu', 'v8.gyp:fp16', 'v8.gyp:v8_libbase', @@ -161,8 +161,8 @@ 'v8.gyp:v8_libplatform', 'v8.gyp:v8_maybe_icu', 'v8.gyp:fp16', - 'v8.gyp:generate_bytecode_builtins_list', - 'v8.gyp:run_torque', + 'v8.gyp:generate_bytecode_builtins_list#target', + 'v8.gyp:run_torque#target', ], 'conditions': [ ['node_shared_abseil=="false"', { From 19c93459614359c7d94ab65b807606e40ffce71b Mon Sep 17 00:00:00 2001 From: inoway46 Date: Sun, 18 Oct 2026 16:02:46 +0900 Subject: [PATCH 2/2] build: separate host and target Rust artifacts in cross builds Capture the Rust target and host triples during configure for bundled Temporal cross builds. Use explicit Cargo targets and separate output directories so host and target archives do not share a build rule. Refs: https://github.com/nodejs/node/issues/66803 Assisted-by: Codex Signed-off-by: inoway46 --- BUILDING.md | 13 +++++++++++++ configure.py | 25 +++++++++++++++++++++++++ deps/crates/crates.gyp | 27 +++++++++++++++++++++++---- 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index 8c7407b96274..b2256169b6a0 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -1067,6 +1067,19 @@ a warning is printed and Temporal support is disabled. Passing both options to `configure.py` is an error. +For non-Windows cross builds with bundled Temporal, set the Rust target when +configuring: + +```bash +CARGO_BUILD_TARGET=riscv64gc-unknown-linux-gnu ./configure \ + --cross-compiling --dest-os=linux --dest-cpu=riscv64 +``` + +Configure saves this target and the host triple reported by `rustc -vV`. +Install the target's Rust standard library and configure the cross linker +separately. Re-run configure when changing targets. Cargo configuration-file +targets and custom JSON targets are not supported by this detection. + ## Building Node.js with external core modules It is possible to specify one or more JavaScript text files to be bundled in diff --git a/configure.py b/configure.py index fb742692f530..390600e6ea42 100755 --- a/configure.py +++ b/configure.py @@ -1957,6 +1957,31 @@ def configure_node(o): os.environ['GYP_CROSSCOMPILE'] = "1" o['variables']['want_separate_host_toolset'] = int(cross_compiling) + o['variables']['cargo_cross_compiling'] = 0 + if (flavor != 'win' and cross_compiling and + not options.v8_disable_temporal_support and not options.shared_temporal_capi): + # Only bundled Temporal cross builds need explicit per-toolset Rust targets. + rust_target = os.environ.get('CARGO_BUILD_TARGET', '') or o['variables']['cargo_rust_target'] + if not rust_target: + error('Cross compilation with bundled Temporal requires CARGO_BUILD_TARGET') + rust_host_target = '' + rustc = os.environ.get('RUSTC', 'rustc') + try: + version = subprocess.check_output(shlex.split(rustc) + ['-vV'], + stderr=subprocess.PIPE, text=True) + except (OSError, subprocess.CalledProcessError): + version = '' + match = re.search(r'^host: (\S+)$', version, re.MULTILINE) + if match: + rust_host_target = match.group(1) + if not rust_host_target: + error('Cannot determine the Rust host triple from rustc -vV') + for triple in (rust_host_target, rust_target): + if not re.fullmatch(r'[A-Za-z0-9_]+(?:-[A-Za-z0-9_]+)+', triple): + error('Rust targets must be target triples, not paths to target JSON files') + o['variables']['cargo_cross_compiling'] = 1 + o['variables']['cargo_rust_target_target'] = rust_target + o['variables']['cargo_rust_target_host'] = rust_host_target if target_arch == 'arm64': o['variables']['arm_fpu'] = options.arm_fpu or 'neon' diff --git a/deps/crates/crates.gyp b/deps/crates/crates.gyp index 702e661f4d3f..53078091c2e8 100644 --- a/deps/crates/crates.gyp +++ b/deps/crates/crates.gyp @@ -6,14 +6,19 @@ 'zoneinfo64_dir': 'zoneinfo64-v0_3', 'temporal_zoneinfo64_data_output': '<(SHARED_INTERMEDIATE_DIR)/src/builtins/builtins-temporal-zoneinfo64-data.cc', 'cargo_rust_target%': '', + 'cargo_cross_compiling%': 0, + 'cargo_rust_target_host%': '', + 'cargo_rust_target_target%': '', + 'node_shared_temporal_capi%': 'false', }, 'conditions': [ ['build_type == "Release"', { 'variables': { 'cargo_build_flags': ['--release'], + 'cargo_profile': 'release', }, 'conditions': [ - ['cargo_rust_target!=""', { + ['cargo_rust_target!="" and cargo_cross_compiling==0', { 'variables': { 'cargo_build_flags': ['--target', '<(cargo_rust_target)'], } @@ -31,6 +36,7 @@ }, { 'variables': { 'cargo_build_flags': [], + 'cargo_profile': 'debug', }, 'conditions': [ ['OS=="win"', { @@ -50,6 +56,17 @@ 'target_name': 'node_crates', 'type': 'none', 'toolsets': ['host', 'target'], + 'variables': { + 'cargo_output_dir': '<(SHARED_INTERMEDIATE_DIR)', + 'cargo_cross_target_flags': [], + 'conditions': [ + ['cargo_cross_compiling==1', { + 'cargo_output_dir': '<(SHARED_INTERMEDIATE_DIR)/cargo/<(_toolset)', + 'cargo_cross_target_flags': ['--target', '<(cargo_rust_target_<(_toolset))'], + 'node_crates_libpath': '<(SHARED_INTERMEDIATE_DIR)/cargo/<(_toolset)/<(cargo_rust_target_<(_toolset))/<(cargo_profile)/<(STATIC_LIB_PREFIX)node_crates<(STATIC_LIB_SUFFIX)', + }], + ], + }, 'hard_dependency': 1, 'sources': [ 'Cargo.toml', @@ -70,7 +87,7 @@ ], }, 'conditions': [ - ['OS=="win"', { + ['OS=="win" and node_shared_temporal_capi=="false"', { 'actions': [ { 'action_name': 'cargo_build', @@ -90,7 +107,8 @@ ], } ], - }, { + }], + ['OS!="win" and node_shared_temporal_capi=="false"', { 'actions': [ { 'action_name': 'cargo_build', @@ -103,10 +121,11 @@ 'action': [ '<(cargo)', 'rustc', + '<@(cargo_cross_target_flags)', '<@(cargo_build_flags)', '--frozen', '--target-dir', - '<(SHARED_INTERMEDIATE_DIR)' + '<(cargo_output_dir)' ], } ],