xref: /aosp_15_r20/external/cronet/build/win/copy_cdb_to_output.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1#!/usr/bin/env python3
2# Copyright 2016 The Chromium Authors
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6
7import glob
8import hashlib
9import os
10import shutil
11import sys
12
13script_dir = os.path.dirname(os.path.realpath(__file__))
14src_build_dir = os.path.abspath(os.path.join(script_dir, os.pardir))
15sys.path.insert(0, src_build_dir)
16
17import vs_toolchain
18
19
20def _HexDigest(file_name):
21  hasher = hashlib.sha256()
22  afile = open(file_name, 'rb')
23  blocksize = 65536
24  buf = afile.read(blocksize)
25  while len(buf) > 0:
26    hasher.update(buf)
27    buf = afile.read(blocksize)
28  afile.close()
29  return hasher.hexdigest()
30
31
32def _CopyImpl(file_name, target_dir, source_dir, verbose=False):
33  """Copy |source| to |target| if it doesn't already exist or if it
34  needs to be updated.
35  """
36  target = os.path.join(target_dir, file_name)
37  source = os.path.join(source_dir, file_name)
38  if (os.path.isdir(os.path.dirname(target)) and
39      ((not os.path.isfile(target)) or
40       _HexDigest(source) != _HexDigest(target))):
41    if verbose:
42      print('Copying %s to %s...' % (source, target))
43    if os.path.exists(target):
44      os.unlink(target)
45    shutil.copy(source, target)
46
47
48def _ConditionalMkdir(output_dir):
49  if not os.path.isdir(output_dir):
50    os.makedirs(output_dir)
51
52
53def _CopyCDBToOutput(output_dir, target_arch):
54  """Copies the Windows debugging executable cdb.exe to the output
55  directory, which is created if it does not exist. The output
56  directory, and target architecture that should be copied, are
57  passed. Supported values for the target architecture are the GYP
58  values "ia32", "x64", "arm64" and the GN values "x86", "x64", "arm64".
59  """
60  _ConditionalMkdir(output_dir)
61  vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
62  # If WINDOWSSDKDIR is not set use the default SDK path. This will be the case
63  # when DEPOT_TOOLS_WIN_TOOLCHAIN=0 and vcvarsall.bat has not been run.
64  win_sdk_dir = os.path.normpath(
65      os.environ.get('WINDOWSSDKDIR',
66                     os.path.expandvars('%ProgramFiles(x86)%'
67                                        '\\Windows Kits\\10')))
68  if target_arch == 'ia32' or target_arch == 'x86':
69    src_arch = 'x86'
70  elif target_arch in ['x64', 'arm64']:
71    src_arch = target_arch
72  else:
73    print('copy_cdb_to_output.py: unknown target_arch %s' % target_arch)
74    sys.exit(1)
75  # We need to copy multiple files, so cache the computed source directory.
76  src_dir = os.path.join(win_sdk_dir, 'Debuggers', src_arch)
77  # We need to copy some helper DLLs to get access to the !uniqstack
78  # command to dump all threads' stacks.
79  src_winext_dir = os.path.join(src_dir, 'winext')
80  dst_winext_dir = os.path.join(output_dir, 'winext')
81  src_winxp_dir = os.path.join(src_dir, 'winxp')
82  dst_winxp_dir = os.path.join(output_dir, 'winxp')
83  # Starting with the 10.0.17763 SDK the ucrt files are in a version-named
84  # directory - this handles both cases.
85  redist_dir = os.path.join(win_sdk_dir, 'Redist')
86  version_dirs = glob.glob(os.path.join(redist_dir, '10.*'))
87  if len(version_dirs) > 0:
88    version_dirs.sort(reverse=True)
89    redist_dir = version_dirs[0]
90  src_crt_dir = os.path.join(redist_dir, 'ucrt', 'DLLs', src_arch)
91  _ConditionalMkdir(dst_winext_dir)
92  _ConditionalMkdir(dst_winxp_dir)
93  # Note that the outputs from the "copy_cdb_to_output" target need to
94  # be kept in sync with this list.
95  _CopyImpl('cdb.exe', output_dir, src_dir)
96  _CopyImpl('dbgeng.dll', output_dir, src_dir)
97  _CopyImpl('dbghelp.dll', output_dir, src_dir)
98  _CopyImpl('dbgmodel.dll', output_dir, src_dir)
99  _CopyImpl('ext.dll', dst_winext_dir, src_winext_dir)
100  _CopyImpl('uext.dll', dst_winext_dir, src_winext_dir)
101  _CopyImpl('exts.dll', dst_winxp_dir, src_winxp_dir)
102  _CopyImpl('ntsdexts.dll', dst_winxp_dir, src_winxp_dir)
103  return 0
104
105
106def main():
107  if len(sys.argv) < 2:
108    print('Usage: copy_cdb_to_output.py <output_dir> ' + \
109        '<target_arch>', file=sys.stderr)
110    return 1
111  return _CopyCDBToOutput(sys.argv[1], sys.argv[2])
112
113
114if __name__ == '__main__':
115  sys.exit(main())
116