@@ -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'
0 commit comments