@@ -1620,6 +1620,55 @@ def get_rustc_version(rustc):
16201620 warn (f'Could not recognize `rustc`: { rustc_ret } ' )
16211621 return '0.0'
16221622
1623+ # Prefixes of Rust target triple architectures for each GYP architecture.
1624+ rust_arch_prefixes = {
1625+ 'arm' : ('arm' , 'thumb' ),
1626+ 'arm64' : ('aarch64' ,),
1627+ 'ia32' : ('i386' , 'i586' , 'i686' ),
1628+ 'loong64' : ('loongarch64' ,),
1629+ 'mips64el' : ('mips64el' ,),
1630+ 'mipsel' : ('mipsel' ,),
1631+ 'ppc64' : ('powerpc64' ,),
1632+ 'riscv64' : ('riscv64' ,),
1633+ 's390x' : ('s390x' ,),
1634+ 'x64' : ('x86_64' ,),
1635+ }
1636+
1637+ def get_rust_cross_targets (host_arch , default_target ):
1638+ """Returns (host triple, target triple, problem). problem is non-empty when
1639+ the triples for a bundled Temporal cross build cannot be determined."""
1640+ rust_target = os .environ .get ('CARGO_BUILD_TARGET' , '' ) or default_target
1641+ if not rust_target :
1642+ return '' , '' , 'Cross compilation with bundled Temporal requires CARGO_BUILD_TARGET.'
1643+
1644+ rust_host_target = ''
1645+ rustc = os .environ .get ('RUSTC' , 'rustc' )
1646+ try :
1647+ version = subprocess .check_output (shlex .split (rustc ) + ['-vV' ],
1648+ stderr = subprocess .PIPE , text = True )
1649+ except (OSError , subprocess .CalledProcessError ):
1650+ version = ''
1651+ match = re .search (r'^host: (\S+)$' , version , re .MULTILINE )
1652+ if match :
1653+ rust_host_target = match .group (1 )
1654+ if not rust_host_target :
1655+ return '' , '' , 'Cannot determine the Rust host triple from `rustc -vV`.'
1656+
1657+ # The host toolset follows CC_host, which may build 32-bit host tools for
1658+ # 32-bit targets (e.g. CC_host="gcc -m32") on a 64-bit Rust host.
1659+ rust_host_arch , _ , rust_host_rest = rust_host_target .partition ('-' )
1660+ if not rust_host_arch .startswith (rust_arch_prefixes .get (host_arch , ('' ,))):
1661+ if host_arch == 'ia32' and rust_host_arch == 'x86_64' :
1662+ rust_host_target = f'i686-{ rust_host_rest } '
1663+ else :
1664+ return '' , '' , (f'Rust host triple { rust_host_target } does not match '
1665+ f'the host toolset architecture { host_arch } (CC_host).' )
1666+
1667+ for triple in (rust_host_target , rust_target ):
1668+ if not re .fullmatch (r'[A-Za-z0-9_]+(?:-[A-Za-z0-9_]+)+' , triple ):
1669+ error ('Rust targets must be target triples, not paths to target JSON files' )
1670+ return rust_host_target , rust_target , ''
1671+
16231672# Note: Apple clang self-reports as clang 4.2.0 and gcc 4.2.1. It passes
16241673# the version check more by accident than anything else but a more rigorous
16251674# check involves checking the build number against an allowlist. I'm not
@@ -1957,6 +2006,23 @@ def configure_node(o):
19572006 os .environ ['GYP_CROSSCOMPILE' ] = "1"
19582007
19592008 o ['variables' ]['want_separate_host_toolset' ] = int (cross_compiling )
2009+ o ['variables' ]['cargo_cross_compiling' ] = 0
2010+ if (flavor != 'win' and cross_compiling and
2011+ not options .v8_disable_temporal_support and not options .shared_temporal_capi ):
2012+ # Only bundled Temporal cross builds need explicit per-toolset Rust targets.
2013+ rust_host_target , rust_target , problem = get_rust_cross_targets (
2014+ host_arch , o ['variables' ]['cargo_rust_target' ])
2015+ if problem :
2016+ # Like a missing Rust toolchain, this is only fatal when Temporal support
2017+ # was explicitly requested.
2018+ if options .v8_enable_temporal_support :
2019+ error (problem )
2020+ warn (f'{ problem } Support for Temporal will be disabled.' )
2021+ options .v8_disable_temporal_support = True
2022+ else :
2023+ o ['variables' ]['cargo_cross_compiling' ] = 1
2024+ o ['variables' ]['cargo_rust_target_target' ] = rust_target
2025+ o ['variables' ]['cargo_rust_target_host' ] = rust_host_target
19602026
19612027 if target_arch == 'arm64' :
19622028 o ['variables' ]['arm_fpu' ] = options .arm_fpu or 'neon'
0 commit comments