Flutter Engine
The Flutter Engine
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Functions | Variables
vs_toolchain Namespace Reference

Functions

def SetEnvironmentAndGetRuntimeDllDirs ()
 
def GetVisualStudioVersion ()
 
def DetectVisualStudioPath ()
 
def FindVCComponentRoot (component)
 
def FindVCRedistRoot ()
 
def CopyDlls (target_dir, configuration, target_cpu)
 
def ShouldUpdateToolchain ()
 
def Update (force=False, no_download=False)
 
def NormalizePath (path)
 
def SetEnvironmentAndGetSDKDir ()
 
def GetToolchainDir ()
 
def main ()
 

Variables

string TOOLCHAIN_HASH = '27370823e7'
 
string SDK_VERSION = '10.0.22621.0'
 
 script_dir = os.path.dirname(os.path.realpath(__file__))
 
 json_data_file = os.path.join(script_dir, 'win_toolchain.json')
 
 MSVS_VERSIONS
 
dictionary MSVC_TOOLSET_VERSION
 

Function Documentation

◆ CopyDlls()

def vs_toolchain.CopyDlls (   target_dir,
  configuration,
  target_cpu 
)
Copy the VS runtime DLLs into the requested directory as needed.

configuration is one of 'Debug' or 'Release'.
target_cpu is one of 'x86', 'x64' or 'arm64'.

The debug configuration gets both the debug and release DLLs; the
release config only the latter.

Definition at line 375 of file vs_toolchain.py.

375def CopyDlls(target_dir, configuration, target_cpu):
376 """Copy the VS runtime DLLs into the requested directory as needed.
377
378 configuration is one of 'Debug' or 'Release'.
379 target_cpu is one of 'x86', 'x64' or 'arm64'.
380
381 The debug configuration gets both the debug and release DLLs; the
382 release config only the latter.
383 """
384 vs_runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
385 if not vs_runtime_dll_dirs:
386 return
387
388 x64_runtime, x86_runtime, arm64_runtime = vs_runtime_dll_dirs
389 if target_cpu == 'x64':
390 runtime_dir = x64_runtime
391 elif target_cpu == 'x86':
392 runtime_dir = x86_runtime
393 elif target_cpu == 'arm64':
394 runtime_dir = arm64_runtime
395 else:
396 raise Exception('Unknown target_cpu: ' + target_cpu)
397 _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=False)
398 if configuration == 'Debug':
399 _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=True)
400 _CopyDebugger(target_dir, target_cpu)
401 if target_cpu == 'arm64':
402 target_dir = os.path.join(target_dir, 'win_clang_x64')
403 target_cpu = 'x64'
404 runtime_dir = x64_runtime
405 os.makedirs(target_dir, exist_ok=True)
406 _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=False)
407 if configuration == 'Debug':
408 _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=True)
409 _CopyDebugger(target_dir, target_cpu)
410
411
def SetEnvironmentAndGetRuntimeDllDirs()
Definition: vs_toolchain.py:69
def CopyDlls(target_dir, configuration, target_cpu)

◆ DetectVisualStudioPath()

def vs_toolchain.DetectVisualStudioPath ( )
Return path to the installed Visual Studio.

Definition at line 207 of file vs_toolchain.py.

208 """Return path to the installed Visual Studio.
209 """
210
211 # Note that this code is used from
212 # build/toolchain/win/setup_toolchain.py as well.
213 version_as_year = GetVisualStudioVersion()
214
215 # The VC++ >=2017 install location needs to be located using COM instead of
216 # the registry. For details see:
217 # https://blogs.msdn.microsoft.com/heaths/2016/09/15/changes-to-visual-studio-15-setup/
218 # For now we use a hardcoded default with an environment variable override.
219 if version_as_year >= '2022':
220 program_files_path_variable = '%ProgramFiles%'
221 else:
222 program_files_path_variable = '%ProgramFiles(x86)%'
223 for path in (os.environ.get('vs%s_install' % version_as_year),
224 os.path.expandvars(program_files_path_variable +
225 '/Microsoft Visual Studio/%s/Enterprise' %
226 version_as_year),
227 os.path.expandvars(program_files_path_variable +
228 '/Microsoft Visual Studio/%s/Professional' %
229 version_as_year),
230 os.path.expandvars(program_files_path_variable +
231 '/Microsoft Visual Studio/%s/Community' %
232 version_as_year),
233 os.path.expandvars(program_files_path_variable +
234 '/Microsoft Visual Studio/%s/Preview' %
235 version_as_year),
236 os.path.expandvars(program_files_path_variable +
237 '/Microsoft Visual Studio/%s/BuildTools' %
238 version_as_year)):
239 if path and os.path.exists(path):
240 return path
241
242 raise Exception('Visual Studio Version %s not found.' % version_as_year)
243
244
def DetectVisualStudioPath()
def GetVisualStudioVersion()

◆ FindVCComponentRoot()

def vs_toolchain.FindVCComponentRoot (   component)
Find the most recent Tools or Redist or other directory in an MSVC install.
Typical results are {toolchain_root}/VC/{component}/MSVC/{x.y.z}. The {x.y.z}
version number part changes frequently so the highest version number found is
used.

Definition at line 337 of file vs_toolchain.py.

337def FindVCComponentRoot(component):
338 """Find the most recent Tools or Redist or other directory in an MSVC install.
339 Typical results are {toolchain_root}/VC/{component}/MSVC/{x.y.z}. The {x.y.z}
340 version number part changes frequently so the highest version number found is
341 used.
342 """
343
345 assert ('GYP_MSVS_OVERRIDE_PATH' in os.environ)
346 vc_component_msvc_root = os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'],
347 'VC', component, 'MSVC')
348 vc_component_msvc_contents = glob.glob(
349 os.path.join(vc_component_msvc_root, '14.*'))
350 # Select the most recent toolchain if there are several.
351 _SortByHighestVersionNumberFirst(vc_component_msvc_contents)
352 for directory in vc_component_msvc_contents:
353 if os.path.isdir(directory):
354 return directory
355 raise Exception('Unable to find the VC %s directory.' % component)
356
357
def FindVCComponentRoot(component)

◆ FindVCRedistRoot()

def vs_toolchain.FindVCRedistRoot ( )
In >=VS2017, Redist binaries are located in
{toolchain_root}/VC/Redist/MSVC/{x.y.z}/{target_cpu}/.

This returns the '{toolchain_root}/VC/Redist/MSVC/{x.y.z}/' path.

Definition at line 358 of file vs_toolchain.py.

358def FindVCRedistRoot():
359 """In >=VS2017, Redist binaries are located in
360 {toolchain_root}/VC/Redist/MSVC/{x.y.z}/{target_cpu}/.
361
362 This returns the '{toolchain_root}/VC/Redist/MSVC/{x.y.z}/' path.
363 """
364 return FindVCComponentRoot('Redist')
365
366
def FindVCRedistRoot()

◆ GetToolchainDir()

def vs_toolchain.GetToolchainDir ( )
Gets location information about the current toolchain (must have been
previously updated by 'update'). This is used for the GN build.

Definition at line 562 of file vs_toolchain.py.

562def GetToolchainDir():
563 """Gets location information about the current toolchain (must have been
564 previously updated by 'update'). This is used for the GN build."""
565 runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
566 win_sdk_dir = SetEnvironmentAndGetSDKDir()
567
568 print('''vs_path = %s
569sdk_version = %s
570sdk_path = %s
571vs_version = %s
572wdk_dir = %s
573runtime_dirs = %s
575 os.environ['GYP_MSVS_OVERRIDE_PATH'])), ToGNString(SDK_VERSION),
577 ToGNString(NormalizePath(os.environ.get('WDK_DIR', ''))),
578 ToGNString(os.path.pathsep.join(runtime_dll_dirs or ['None']))))
579
580
def ToGNString(value, allow_dicts=True)
Definition: gn_helpers.py:30
def print(*args, **kwargs)
Definition: run_tests.py:49
def NormalizePath(path)
def SetEnvironmentAndGetSDKDir()
def GetToolchainDir()

◆ GetVisualStudioVersion()

def vs_toolchain.GetVisualStudioVersion ( )
Return best available version of Visual Studio.

Definition at line 165 of file vs_toolchain.py.

166 """Return best available version of Visual Studio.
167 """
168 supported_versions = list(MSVS_VERSIONS.keys())
169
170 # VS installed in depot_tools for Googlers
171 if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1'))):
172 return supported_versions[0]
173
174 # VS installed in system for external developers
175 supported_versions_str = ', '.join('{} ({})'.format(v,k)
176 for k,v in MSVS_VERSIONS.items())
177 available_versions = []
178 for version in supported_versions:
179 # Checking vs%s_install environment variables.
180 # For example, vs2019_install could have the value
181 # "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community".
182 # Only vs2017_install, vs2019_install and vs2022_install are supported.
183 path = os.environ.get('vs%s_install' % version)
184 if path and os.path.exists(path):
185 available_versions.append(version)
186 break
187 # Detecting VS under possible paths.
188 if version >= '2022':
189 program_files_path_variable = '%ProgramFiles%'
190 else:
191 program_files_path_variable = '%ProgramFiles(x86)%'
192 path = os.path.expandvars(program_files_path_variable +
193 '/Microsoft Visual Studio/%s' % version)
194 if path and any(
195 os.path.exists(os.path.join(path, edition))
196 for edition in ('Enterprise', 'Professional', 'Community', 'Preview',
197 'BuildTools')):
198 available_versions.append(version)
199 break
200
201 if not available_versions:
202 raise Exception('No supported Visual Studio can be found.'
203 ' Supported versions are: %s.' % supported_versions_str)
204 return available_versions[0]
205
206
uint32_t uint32_t * format
SIT bool any(const Vec< 1, T > &x)
Definition: SkVx.h:530
static SkString join(const CommandLineFlags::StringArray &)
Definition: skpbench.cpp:741

◆ main()

def vs_toolchain.main ( )

Definition at line 581 of file vs_toolchain.py.

581def main():
582 commands = {
583 'update': Update,
584 'get_toolchain_dir': GetToolchainDir,
585 'copy_dlls': CopyDlls,
586 }
587 if len(sys.argv) < 2 or sys.argv[1] not in commands:
588 print('Expected one of: %s' % ', '.join(commands), file=sys.stderr)
589 return 1
590 return commands[sys.argv[1]](*sys.argv[2:])
591
592

◆ NormalizePath()

def vs_toolchain.NormalizePath (   path)

Definition at line 541 of file vs_toolchain.py.

541def NormalizePath(path):
542 while path.endswith('\\'):
543 path = path[:-1]
544 return path
545
546

◆ SetEnvironmentAndGetRuntimeDllDirs()

def vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs ( )
Sets up os.environ to use the depot_tools VS toolchain with gyp, and
returns the location of the VC runtime DLLs so they can be copied into
the output directory after gyp generation.

Return value is [x64path, x86path, 'Arm64Unused'] or None. arm64path is
generated separately because there are multiple folders for the arm64 VC
runtime.

Definition at line 69 of file vs_toolchain.py.

70 """Sets up os.environ to use the depot_tools VS toolchain with gyp, and
71 returns the location of the VC runtime DLLs so they can be copied into
72 the output directory after gyp generation.
73
74 Return value is [x64path, x86path, 'Arm64Unused'] or None. arm64path is
75 generated separately because there are multiple folders for the arm64 VC
76 runtime.
77 """
78 vs_runtime_dll_dirs = None
79 depot_tools_win_toolchain = \
80 bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
81 # When running on a non-Windows host, only do this if the SDK has explicitly
82 # been downloaded before (in which case json_data_file will exist).
83 if ((_HostIsWindows() or os.path.exists(json_data_file))
84 and depot_tools_win_toolchain):
86 if len(sys.argv) > 1 and sys.argv[1] == 'update':
87 update_result = Update()
88 else:
89 update_result = Update(no_download=True)
90 if update_result != 0:
91 raise Exception('Failed to update, error code %d.' % update_result)
92 with open(json_data_file, 'r') as tempf:
93 toolchain_data = json.load(tempf)
94
95 toolchain = toolchain_data['path']
96 version = toolchain_data['version']
97 win_sdk = toolchain_data.get('win_sdk')
98 wdk = toolchain_data['wdk']
99 # TODO(scottmg): The order unfortunately matters in these. They should be
100 # split into separate keys for x64/x86/arm64. (See CopyDlls call below).
101 # http://crbug.com/345992
102 vs_runtime_dll_dirs = toolchain_data['runtime_dirs']
103 # The number of runtime_dirs in the toolchain_data was two (x64/x86) but
104 # changed to three (x64/x86/arm64) and this code needs to handle both
105 # possibilities, which can change independently from this code.
106 if len(vs_runtime_dll_dirs) == 2:
107 vs_runtime_dll_dirs.append('Arm64Unused')
108
109 os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain
110
111 os.environ['WINDOWSSDKDIR'] = win_sdk
112 os.environ['WDK_DIR'] = wdk
113 # Include the VS runtime in the PATH in case it's not machine-installed.
114 runtime_path = os.path.pathsep.join(vs_runtime_dll_dirs)
115 os.environ['PATH'] = runtime_path + os.path.pathsep + os.environ['PATH']
116 elif sys.platform == 'win32' and not depot_tools_win_toolchain:
117 if not 'GYP_MSVS_OVERRIDE_PATH' in os.environ:
118 os.environ['GYP_MSVS_OVERRIDE_PATH'] = DetectVisualStudioPath()
119
120 # When using an installed toolchain these files aren't needed in the output
121 # directory in order to run binaries locally, but they are needed in order
122 # to create isolates or the mini_installer. Copying them to the output
123 # directory ensures that they are available when needed.
124 bitness = platform.architecture()[0]
125 # When running 64-bit python the x64 DLLs will be in System32
126 # ARM64 binaries will not be available in the system directories because we
127 # don't build on ARM64 machines.
128 x64_path = 'System32' if bitness == '64bit' else 'Sysnative'
129 x64_path = os.path.join(os.path.expandvars('%windir%'), x64_path)
130 vs_runtime_dll_dirs = [x64_path,
131 os.path.join(os.path.expandvars('%windir%'),
132 'SysWOW64'),
133 'Arm64Unused']
134
135 return vs_runtime_dll_dirs
136
137
def Update(force=False, no_download=False)
def ShouldUpdateToolchain()

◆ SetEnvironmentAndGetSDKDir()

def vs_toolchain.SetEnvironmentAndGetSDKDir ( )
Gets location information about the current sdk (must have been
previously updated by 'update'). This is used for the GN build.

Definition at line 547 of file vs_toolchain.py.

548 """Gets location information about the current sdk (must have been
549 previously updated by 'update'). This is used for the GN build."""
551
552 # If WINDOWSSDKDIR is not set, search the default SDK path and set it.
553 if not 'WINDOWSSDKDIR' in os.environ:
554 default_sdk_path = os.path.expandvars('%ProgramFiles(x86)%'
555 '\\Windows Kits\\10')
556 if os.path.isdir(default_sdk_path):
557 os.environ['WINDOWSSDKDIR'] = default_sdk_path
558
559 return NormalizePath(os.environ['WINDOWSSDKDIR'])
560
561

◆ ShouldUpdateToolchain()

def vs_toolchain.ShouldUpdateToolchain ( )
Check if the toolchain should be upgraded.

Definition at line 465 of file vs_toolchain.py.

466 """Check if the toolchain should be upgraded."""
467 if not os.path.exists(json_data_file):
468 return True
469 with open(json_data_file, 'r') as tempf:
470 toolchain_data = json.load(tempf)
471 version = toolchain_data['version']
472 env_version = GetVisualStudioVersion()
473 # If there's a mismatch between the version set in the environment and the one
474 # in the json file then the toolchain should be updated.
475 return version != env_version
476
477

◆ Update()

def vs_toolchain.Update (   force = False,
  no_download = False 
)
Requests an update of the toolchain to the specific hashes we have at
this revision. The update outputs a .json of the various configuration
information required to pass to gyp which we use in |GetToolchainDir()|.
If no_download is true then the toolchain will be configured if present but
will not be downloaded.

Definition at line 478 of file vs_toolchain.py.

478def Update(force=False, no_download=False):
479 """Requests an update of the toolchain to the specific hashes we have at
480 this revision. The update outputs a .json of the various configuration
481 information required to pass to gyp which we use in |GetToolchainDir()|.
482 If no_download is true then the toolchain will be configured if present but
483 will not be downloaded.
484 """
485 if force != False and force != '--force':
486 print('Unknown parameter "%s"' % force, file=sys.stderr)
487 return 1
488 if force == '--force' or os.path.exists(json_data_file):
489 force = True
490
491 depot_tools_win_toolchain = \
492 bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
493 if (_HostIsWindows() or force) and depot_tools_win_toolchain:
494 import find_depot_tools
496
497 # On Linux, the file system is usually case-sensitive while the Windows
498 # SDK only works on case-insensitive file systems. If it doesn't already
499 # exist, set up a ciopfs fuse mount to put the SDK in a case-insensitive
500 # part of the file system.
501 toolchain_dir = os.path.join(depot_tools_path, 'win_toolchain', 'vs_files')
502 # For testing this block, unmount existing mounts with
503 # fusermount -u third_party/depot_tools/win_toolchain/vs_files
504 if sys.platform.startswith('linux') and not os.path.ismount(toolchain_dir):
505 ciopfs = shutil.which('ciopfs')
506 if not ciopfs:
507 # ciopfs not found in PATH; try the one downloaded from the DEPS hook.
508 ciopfs = os.path.join(script_dir, 'ciopfs')
509 if not os.path.isdir(toolchain_dir):
510 os.mkdir(toolchain_dir)
511 if not os.path.isdir(toolchain_dir + '.ciopfs'):
512 os.mkdir(toolchain_dir + '.ciopfs')
513 # Without use_ino, clang's #pragma once and Wnonportable-include-path
514 # both don't work right, see https://llvm.org/PR34931
515 # use_ino doesn't slow down builds, so it seems there's no drawback to
516 # just using it always.
517 subprocess.check_call([
518 ciopfs, '-o', 'use_ino', toolchain_dir + '.ciopfs', toolchain_dir])
519
520 # Dart specific patch: Store the visual studio toolchain inside the exec
521 # root directory such that it can be sent to RBE and invoked with a
522 # relative path identical on all checkouts.
523 toolchain_dir = os.path.join(os.getcwd(), 'sdk', 'win_toolchain')
524 get_toolchain_args = [
525 sys.executable,
526 os.path.join(depot_tools_path,
527 'win_toolchain',
528 'get_toolchain_if_necessary.py'),
529 '--output-json', json_data_file,
530 '--toolchain-dir', toolchain_dir,
531 ] + _GetDesiredVsToolchainHashes()
532 if force:
533 get_toolchain_args.append('--force')
534 if no_download:
535 get_toolchain_args.append('--no-download')
536 subprocess.check_call(get_toolchain_args)
537
538 return 0
539
540

Variable Documentation

◆ json_data_file

vs_toolchain.json_data_file = os.path.join(script_dir, 'win_toolchain.json')

Definition at line 46 of file vs_toolchain.py.

◆ MSVC_TOOLSET_VERSION

dictionary vs_toolchain.MSVC_TOOLSET_VERSION
Initial value:
1= {
2 '2022': 'VC143',
3 '2019': 'VC142',
4 '2017': 'VC141',
5}

Definition at line 59 of file vs_toolchain.py.

◆ MSVS_VERSIONS

vs_toolchain.MSVS_VERSIONS
Initial value:
1= collections.OrderedDict([
2 ('2022', '17.0'), # Default and packaged version of Visual Studio.
3 ('2019', '16.0'),
4 ('2017', '15.0'),
5])

Definition at line 51 of file vs_toolchain.py.

◆ script_dir

vs_toolchain.script_dir = os.path.dirname(os.path.realpath(__file__))

Definition at line 45 of file vs_toolchain.py.

◆ SDK_VERSION

string vs_toolchain.SDK_VERSION = '10.0.22621.0'

Definition at line 43 of file vs_toolchain.py.

◆ TOOLCHAIN_HASH

string vs_toolchain.TOOLCHAIN_HASH = '27370823e7'

Definition at line 42 of file vs_toolchain.py.