Skip to content

Commit eb3ae47

Browse files
authored
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. If the triples cannot be determined, disable Temporal with a warning unless it was explicitly enabled. Fixes: #66897 Refs: #66803 Assisted-by: Codex Signed-off-by: inoway46 <inoueyuya416@gmail.com> PR-URL: #66823 Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent f39899d commit eb3ae47

3 files changed

Lines changed: 92 additions & 2 deletions

File tree

‎BUILDING.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,12 @@ a warning is printed and Temporal support is disabled.
10711071

10721072
Passing both options to `configure.py` is an error.
10731073

1074+
For non-Windows cross builds with bundled Temporal, set `CARGO_BUILD_TARGET`
1075+
to the Rust target triple when running `configure.py` (for example,
1076+
`aarch64-unknown-linux-gnu`). Otherwise, Temporal support is disabled with a
1077+
warning, or `configure.py` stops with an error when
1078+
`--v8-enable-temporal-support` is passed.
1079+
10741080
## Building Node.js with external core modules
10751081

10761082
It is possible to specify one or more JavaScript text files to be bundled in

‎configure.py‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,6 +1597,55 @@ def get_rustc_version(rustc):
15971597
warn(f'Could not recognize `rustc`: {rustc_ret}')
15981598
return '0.0'
15991599

1600+
# Prefixes of Rust target triple architectures for each GYP architecture.
1601+
rust_arch_prefixes = {
1602+
'arm': ('arm', 'thumb'),
1603+
'arm64': ('aarch64',),
1604+
'ia32': ('i386', 'i586', 'i686'),
1605+
'loong64': ('loongarch64',),
1606+
'mips64el': ('mips64el',),
1607+
'mipsel': ('mipsel',),
1608+
'ppc64': ('powerpc64',),
1609+
'riscv64': ('riscv64',),
1610+
's390x': ('s390x',),
1611+
'x64': ('x86_64',),
1612+
}
1613+
1614+
def get_rust_cross_targets(host_arch, default_target):
1615+
"""Returns (host triple, target triple, problem). problem is non-empty when
1616+
the triples for a bundled Temporal cross build cannot be determined."""
1617+
rust_target = os.environ.get('CARGO_BUILD_TARGET', '') or default_target
1618+
if not rust_target:
1619+
return '', '', 'Cross compilation with bundled Temporal requires CARGO_BUILD_TARGET.'
1620+
1621+
rust_host_target = ''
1622+
rustc = os.environ.get('RUSTC', 'rustc')
1623+
try:
1624+
version = subprocess.check_output(shlex.split(rustc) + ['-vV'],
1625+
stderr=subprocess.PIPE, text=True)
1626+
except (OSError, subprocess.CalledProcessError):
1627+
version = ''
1628+
match = re.search(r'^host: (\S+)$', version, re.MULTILINE)
1629+
if match:
1630+
rust_host_target = match.group(1)
1631+
if not rust_host_target:
1632+
return '', '', 'Cannot determine the Rust host triple from `rustc -vV`.'
1633+
1634+
# The host toolset follows CC_host, which may build 32-bit host tools for
1635+
# 32-bit targets (e.g. CC_host="gcc -m32") on a 64-bit Rust host.
1636+
rust_host_arch, _, rust_host_rest = rust_host_target.partition('-')
1637+
if not rust_host_arch.startswith(rust_arch_prefixes.get(host_arch, ('',))):
1638+
if host_arch == 'ia32' and rust_host_arch == 'x86_64':
1639+
rust_host_target = f'i686-{rust_host_rest}'
1640+
else:
1641+
return '', '', (f'Rust host triple {rust_host_target} does not match '
1642+
f'the host toolset architecture {host_arch} (CC_host).')
1643+
1644+
for triple in (rust_host_target, rust_target):
1645+
if not re.fullmatch(r'[A-Za-z0-9_]+(?:-[A-Za-z0-9_]+)+', triple):
1646+
error('Rust targets must be target triples, not paths to target JSON files')
1647+
return rust_host_target, rust_target, ''
1648+
16001649
# Note: Apple clang self-reports as clang 4.2.0 and gcc 4.2.1. It passes
16011650
# the version check more by accident than anything else but a more rigorous
16021651
# check involves checking the build number against an allowlist. I'm not
@@ -1934,6 +1983,23 @@ def configure_node(o):
19341983
os.environ['GYP_CROSSCOMPILE'] = "1"
19351984

19361985
o['variables']['want_separate_host_toolset'] = int(cross_compiling)
1986+
o['variables']['cargo_cross_compiling'] = 0
1987+
if (flavor != 'win' and cross_compiling and
1988+
not options.v8_disable_temporal_support and not options.shared_temporal_capi):
1989+
# Only bundled Temporal cross builds need explicit per-toolset Rust targets.
1990+
rust_host_target, rust_target, problem = get_rust_cross_targets(
1991+
host_arch, o['variables']['cargo_rust_target'])
1992+
if problem:
1993+
# Like a missing Rust toolchain, this is only fatal when Temporal support
1994+
# was explicitly requested.
1995+
if options.v8_enable_temporal_support:
1996+
error(problem)
1997+
warn(f'{problem} Support for Temporal will be disabled.')
1998+
options.v8_disable_temporal_support = True
1999+
else:
2000+
o['variables']['cargo_cross_compiling'] = 1
2001+
o['variables']['cargo_rust_target_target'] = rust_target
2002+
o['variables']['cargo_rust_target_host'] = rust_host_target
19372003

19382004
if target_arch == 'arm64':
19392005
o['variables']['arm_fpu'] = options.arm_fpu or 'neon'

‎deps/crates/crates.gyp‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,18 @@
66
'zoneinfo64_dir': 'zoneinfo64-v0_3',
77
'temporal_zoneinfo64_data_output': '<(SHARED_INTERMEDIATE_DIR)/src/builtins/builtins-temporal-zoneinfo64-data.cc',
88
'cargo_rust_target%': '',
9+
'cargo_cross_compiling%': 0,
10+
'cargo_rust_target_host%': '',
11+
'cargo_rust_target_target%': '',
912
},
1013
'conditions': [
1114
['build_type == "Release"', {
1215
'variables': {
1316
'cargo_build_flags': ['--release'],
17+
'cargo_profile': 'release',
1418
},
1519
'conditions': [
16-
['cargo_rust_target!=""', {
20+
['cargo_rust_target!="" and cargo_cross_compiling==0', {
1721
'variables': {
1822
'cargo_build_flags': ['--target', '<(cargo_rust_target)'],
1923
}
@@ -31,6 +35,7 @@
3135
}, {
3236
'variables': {
3337
'cargo_build_flags': [],
38+
'cargo_profile': 'debug',
3439
},
3540
'conditions': [
3641
['OS=="win"', {
@@ -50,6 +55,18 @@
5055
'target_name': 'node_crates',
5156
'type': 'none',
5257
'toolsets': ['host', 'target'],
58+
'variables': {
59+
'cargo_output_dir': '<(SHARED_INTERMEDIATE_DIR)',
60+
'cargo_cross_target_flags': [],
61+
'conditions': [
62+
['cargo_cross_compiling==1', {
63+
'cargo_output_dir': '<(SHARED_INTERMEDIATE_DIR)/cargo/<(_toolset)',
64+
'cargo_cross_target_flags': ['--target', '<(cargo_rust_target_<(_toolset))'],
65+
# Referencing cargo_output_dir here would use its pre-condition value.
66+
'node_crates_libpath': '<(SHARED_INTERMEDIATE_DIR)/cargo/<(_toolset)/<(cargo_rust_target_<(_toolset))/<(cargo_profile)/<(STATIC_LIB_PREFIX)node_crates<(STATIC_LIB_SUFFIX)',
67+
}],
68+
],
69+
},
5370
'hard_dependency': 1,
5471
'sources': [
5572
'Cargo.toml',
@@ -103,10 +120,11 @@
103120
'action': [
104121
'<(cargo)',
105122
'rustc',
123+
'<@(cargo_cross_target_flags)',
106124
'<@(cargo_build_flags)',
107125
'--frozen',
108126
'--target-dir',
109-
'<(SHARED_INTERMEDIATE_DIR)'
127+
'<(cargo_output_dir)'
110128
],
111129
}
112130
],

0 commit comments

Comments
 (0)