From 0744896c86ed622b3ef3371ed0247a4e148b69f8 Mon Sep 17 00:00:00 2001 From: Adam Kallai Date: Wed, 13 Mar 2019 15:11:17 +0100 Subject: [PATCH] msvs: Support ARM64 configuration platform * This change is intent to support top-level ARM64 configuration, so a project can be built as ARM64 project. * Unit test also included --- pylib/gyp/MSVS/MSVSSettings.py | 1 + pylib/gyp/generator/msvs.py | 2 ++ pylib/gyp/msvs_emulation.py | 24 +++++++++++++----- test/configurations/arm64/configurations.c | 6 +++++ test/configurations/arm64/configurations.gyp | 22 +++++++++++++++++ test/configurations/arm64/gyptest-arm64.py | 26 ++++++++++++++++++++ 6 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 test/configurations/arm64/configurations.c create mode 100644 test/configurations/arm64/configurations.gyp create mode 100644 test/configurations/arm64/gyptest-arm64.py diff --git a/pylib/gyp/MSVS/MSVSSettings.py b/pylib/gyp/MSVS/MSVSSettings.py index 36d03878..d7e9ac91 100644 --- a/pylib/gyp/MSVS/MSVSSettings.py +++ b/pylib/gyp/MSVS/MSVSSettings.py @@ -978,6 +978,7 @@ def _ValidateSettings(validators, settings, stderr): _Same(_midl, 'TargetEnvironment', _Enumeration(['NotSet', 'Win32', # /env win32 + 'ARM64', # /env arm64 'Itanium', # /env ia64 'X64'])) # /env x64 _Same(_midl, 'EnableErrorChecks', diff --git a/pylib/gyp/generator/msvs.py b/pylib/gyp/generator/msvs.py index 32f6e01b..3291c375 100644 --- a/pylib/gyp/generator/msvs.py +++ b/pylib/gyp/generator/msvs.py @@ -1825,6 +1825,8 @@ def _InitNinjaFlavor(params, target_list, target_dicts): configuration = '$(Configuration)' if params.get('target_arch') == 'x64': configuration += '_x64' + if params.get('target_arch') == 'arm64': + configuration += '_arm64' spec['msvs_external_builder_out_dir'] = os.path.join( gyp.common.RelativePath(params['options'].toplevel_dir, gyp_dir), ninja_generator.ComputeOutputDir(params), diff --git a/pylib/gyp/msvs_emulation.py b/pylib/gyp/msvs_emulation.py index 11918174..20aa5d3b 100644 --- a/pylib/gyp/msvs_emulation.py +++ b/pylib/gyp/msvs_emulation.py @@ -200,7 +200,11 @@ def GetExtension(self): def GetVSMacroEnv(self, base_to_build=None, config=None): """Get a dict of variables mapping internal VS macro names to their gyp equivalents.""" - target_platform = 'Win32' if self.GetArch(config) == 'x86' else 'x64' + target_arch = self.GetArch(config) + if target_arch == 'x86': + target_platform = 'Win32' + else: + target_platform = target_arch target_name = self.spec.get('product_prefix', '') + self.spec.get('product_name', self.spec['target_name']) target_dir = base_to_build + '\\' if base_to_build else '' target_ext = '.' + self.GetExtension() @@ -276,7 +280,7 @@ def GetArch(self, config): if not platform: # If no specific override, use the configuration's. platform = configuration_platform # Map from platform to architecture. - return {'Win32': 'x86', 'x64': 'x64'}.get(platform, 'x86') + return {'Win32': 'x86', 'x64': 'x64', 'ARM64': 'arm64'}.get(platform, 'x86') def _TargetConfig(self, config): """Returns the target-specific configuration.""" @@ -475,7 +479,10 @@ def GetLibFlags(self, config, gyp_to_build_path): lib = self._GetWrapper(self, self.msvs_settings[config], 'VCLibrarianTool', append=libflags) libflags.extend(self._GetAdditionalLibraryDirectories('VCLibrarianTool', config, gyp_to_build_path)) lib('LinkTimeCodeGeneration', map={'true': '/LTCG'}) - lib('TargetMachine', map={'1': 'X86', '17': 'X64', '3': 'ARM'}, prefix='/MACHINE:') + # TODO: These 'map' values come from machineTypeOption enum, + # and does not have an official value for ARM64 in VS2017 (yet). + # It needs to verify the ARM64 value when machineTypeOption is updated. + lib('TargetMachine', map={'1': 'X86', '17': 'X64', '3': 'ARM', '18': 'ARM64'}, prefix='/MACHINE:') lib('AdditionalOptions') return libflags @@ -514,7 +521,10 @@ def GetLdflags(self, config, gyp_to_build_path, expand_special, manifest_base_na ld = self._GetWrapper(self, self.msvs_settings[config], 'VCLinkerTool', append=ldflags) self._GetDefFileAsLdflags(ldflags, gyp_to_build_path) ld('GenerateDebugInformation', map={'true': '/DEBUG'}) - ld('TargetMachine', map={'1': 'X86', '17': 'X64', '3': 'ARM'}, prefix='/MACHINE:') + # TODO: These 'map' values come from machineTypeOption enum, + # and does not have an official value for ARM64 in VS2017 (yet). + # It needs to verify the ARM64 value when machineTypeOption is updated. + ld('TargetMachine', map={'1': 'X86', '17': 'X64', '3': 'ARM', '18': 'ARM64'}, prefix='/MACHINE:') ldflags.extend(self._GetAdditionalLibraryDirectories('VCLinkerTool', config, gyp_to_build_path)) ld('DelayLoadDLLs', prefix='/DELAYLOAD:') ld('TreatLinkerWarningAsErrors', prefix='/WX', map={'true': '', 'false': ':NO'}) @@ -764,7 +774,9 @@ def midl(name, default=None): output = [header, dlldata, iid, proxy] variables = [('tlb', tlb), ('h', header), ('dlldata', dlldata), ('iid', iid), ('proxy', proxy)] # TODO(scottmg): Are there configuration settings to set these flags? - target_platform = 'win32' if self.GetArch(config) == 'x86' else 'x64' + target_platform = self.GetArch(config) + if target_platform == 'x86': + target_platform = 'win32' flags = ['/char', 'signed', '/env', target_platform, '/Oicf'] return outdir, output, variables, flags @@ -921,7 +933,7 @@ def GenerateEnvironmentFiles(toplevel_build_dir, generator_flags): if generator_flags.get('ninja_use_custom_environment_files', False) or not vs.path: return - archs = ('x86', 'x64') + archs = ('x86', 'x64', 'arm64') for arch in archs: env = _GetEnvironment(arch, vs) env_block = NUL.join(encode(k) + '=' + encode(v) for k, v in env.items()) + NUL + NUL diff --git a/test/configurations/arm64/configurations.c b/test/configurations/arm64/configurations.c new file mode 100644 index 00000000..e1afaf18 --- /dev/null +++ b/test/configurations/arm64/configurations.c @@ -0,0 +1,6 @@ +#include + +int main(void) { + printf("Hello ARM64\n"); + return 0; +} diff --git a/test/configurations/arm64/configurations.gyp b/test/configurations/arm64/configurations.gyp new file mode 100644 index 00000000..aaf830dc --- /dev/null +++ b/test/configurations/arm64/configurations.gyp @@ -0,0 +1,22 @@ +# Copyright (c) 2009 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'target_defaults': { + 'configurations': { + 'Debug': { + 'msvs_configuration_platform': 'ARM64', + }, + }, + }, + 'targets': [ + { + 'target_name': 'configurationsARM64', + 'type': 'executable', + 'sources': [ + 'configurations.c', + ], + }, + ], +} diff --git a/test/configurations/arm64/gyptest-arm64.py b/test/configurations/arm64/gyptest-arm64.py new file mode 100644 index 00000000..93c963a9 --- /dev/null +++ b/test/configurations/arm64/gyptest-arm64.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python + +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +Verifies build of an executable for ARM64 configurations. +""" + +import TestGyp + +import sys + +if sys.platform == 'win32': + formats = ['msvs', 'ninja'] +test = TestGyp.TestGyp(formats=formats) + +test.run_gyp('configurations.gyp') +test.set_configuration('Debug|ARM64') +test.build('configurations.gyp', test.ALL) + +output = test.run_dumpbin('/headers', test.built_file_path('configurations%s.exe' % 'ARM64')) +if 'AA64 machine (ARM64)' not in output: + test.fail_test() +test.pass_test()