Skip to content

Commit a9db717

Browse files
committed
Add single-toolchain ARM64 build support on Windows
Adds ARM64 targets to generated .sln/.vcxproj files for cross-compiling node modules to Windows on Arm, 64-bit. To use, run `set npm_config_arch=arm64` on the command prompt before `npm install`. Change-Id: Idbe401437e58d13c815c02f7b5b45247daabbe65
1 parent bb8b294 commit a9db717

File tree

5 files changed

+25
-7
lines changed

5 files changed

+25
-7
lines changed

gyp/pylib/gyp/MSVSSettings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,7 @@ def _ValidateSettings(validators, settings, stderr):
972972
_Same(_midl, 'TargetEnvironment',
973973
_Enumeration(['NotSet',
974974
'Win32', # /env win32
975+
'ARM64', # /env ARM64
975976
'Itanium', # /env ia64
976977
'X64'])) # /env x64
977978
_Same(_midl, 'EnableErrorChecks',

gyp/pylib/gyp/generator/msvs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1887,6 +1887,8 @@ def _InitNinjaFlavor(params, target_list, target_dicts):
18871887
configuration = '$(Configuration)'
18881888
if params.get('target_arch') == 'x64':
18891889
configuration += '_x64'
1890+
if params.get('target_arch') == 'arm64':
1891+
configuration += '_arm64'
18901892
spec['msvs_external_builder_out_dir'] = os.path.join(
18911893
gyp.common.RelativePath(params['options'].toplevel_dir, gyp_dir),
18921894
ninja_generator.ComputeOutputDir(params),

gyp/pylib/gyp/generator/ninja.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ def __init__(self, hash_for_rules, target_outputs, base_dir, build_dir,
234234
if flavor == 'win':
235235
# See docstring of msvs_emulation.GenerateEnvironmentFiles().
236236
self.win_env = {}
237-
for arch in ('x86', 'x64'):
237+
for arch in ('x86', 'x64', 'arm64'):
238238
self.win_env[arch] = 'environment.' + arch
239239

240240
# Relative path from build output dir to base dir.

gyp/pylib/gyp/msvs_emulation.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,11 @@ def GetExtension(self):
237237
def GetVSMacroEnv(self, base_to_build=None, config=None):
238238
"""Get a dict of variables mapping internal VS macro names to their gyp
239239
equivalents."""
240-
target_platform = 'Win32' if self.GetArch(config) == 'x86' else 'x64'
240+
target_arch = self.GetArch(config)
241+
if target_arch == 'x86':
242+
target_platform = 'Win32'
243+
else:
244+
target_platform = target_arch
241245
target_name = self.spec.get('product_prefix', '') + \
242246
self.spec.get('product_name', self.spec['target_name'])
243247
target_dir = base_to_build + '\\' if base_to_build else ''
@@ -299,7 +303,7 @@ def GetArch(self, config):
299303
if not platform: # If no specific override, use the configuration's.
300304
platform = configuration_platform
301305
# Map from platform to architecture.
302-
return {'Win32': 'x86', 'x64': 'x64'}.get(platform, 'x86')
306+
return {'Win32': 'x86', 'x64': 'x64', 'ARM64': 'arm64'}.get(platform, 'x86')
303307

304308
def _TargetConfig(self, config):
305309
"""Returns the target-specific configuration."""
@@ -519,7 +523,10 @@ def GetLibFlags(self, config, gyp_to_build_path):
519523
libflags.extend(self._GetAdditionalLibraryDirectories(
520524
'VCLibrarianTool', config, gyp_to_build_path))
521525
lib('LinkTimeCodeGeneration', map={'true': '/LTCG'})
522-
lib('TargetMachine', map={'1': 'X86', '17': 'X64', '3': 'ARM'},
526+
# TODO: These 'map' values come from machineTypeOption enum,
527+
# and does not have an official value for ARM64 in VS2017 (yet).
528+
# It needs to verify the ARM64 value when machineTypeOption is updated.
529+
lib('TargetMachine', map={'1': 'X86', '17': 'X64', '3': 'ARM', '18': 'ARM64'},
523530
prefix='/MACHINE:')
524531
lib('AdditionalOptions')
525532
return libflags
@@ -563,7 +570,10 @@ def GetLdflags(self, config, gyp_to_build_path, expand_special,
563570
'VCLinkerTool', append=ldflags)
564571
self._GetDefFileAsLdflags(ldflags, gyp_to_build_path)
565572
ld('GenerateDebugInformation', map={'true': '/DEBUG'})
566-
ld('TargetMachine', map={'1': 'X86', '17': 'X64', '3': 'ARM'},
573+
# TODO: These 'map' values come from machineTypeOption enum,
574+
# and does not have an official value for ARM64 in VS2017 (yet).
575+
# It needs to verify the ARM64 value when machineTypeOption is updated.
576+
ld('TargetMachine', map={'1': 'X86', '17': 'X64', '3': 'ARM', '18': 'ARM64'},
567577
prefix='/MACHINE:')
568578
ldflags.extend(self._GetAdditionalLibraryDirectories(
569579
'VCLinkerTool', config, gyp_to_build_path))
@@ -860,7 +870,9 @@ def midl(name, default=None):
860870
('iid', iid),
861871
('proxy', proxy)]
862872
# TODO(scottmg): Are there configuration settings to set these flags?
863-
target_platform = 'win32' if self.GetArch(config) == 'x86' else 'x64'
873+
target_platform = self.GetArch(config)
874+
if target_platform == 'x86':
875+
target_platform = 'win32'
864876
flags = ['/char', 'signed', '/env', target_platform, '/Oicf']
865877
return outdir, output, variables, flags
866878

@@ -1014,7 +1026,7 @@ def GenerateEnvironmentFiles(toplevel_build_dir, generator_flags,
10141026
meet your requirement (e.g. for custom toolchains), you can pass
10151027
"-G ninja_use_custom_environment_files" to the gyp to suppress file
10161028
generation and use custom environment files prepared by yourself."""
1017-
archs = ('x86', 'x64')
1029+
archs = ('x86', 'x64', 'arm64')
10181030
if generator_flags.get('ninja_use_custom_environment_files', 0):
10191031
cl_paths = {}
10201032
for arch in archs:

lib/configure.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ function configure (gyp, argv, callback) {
134134

135135
// set the target_arch variable
136136
variables.target_arch = gyp.opts.arch || process.arch || 'ia32'
137+
if (variables.target_arch == 'arm64') {
138+
defaults['msvs_configuration_platform'] = 'ARM64'
139+
}
137140

138141
// set the node development directory
139142
variables.nodedir = nodeDir

0 commit comments

Comments
 (0)