Updates to VS packaging script for VS 2015

This change updates the packaging script for VS 2015 Update 1. Changes
include:

- Filtering out Windows Performance Toolkit to save space
- Filtering out .msi files to save space
- Adding a 'dryrun' option to quickly print statistics
- Allowing specifying what OS sub-version is desired
- Filtering out unused versions from the include/lib/source directories
- Avoiding the double-include of the ucrt directory
- Adding ucrt directory to include and lib path
- Handling running from 64-bit or 32-bit python

R=scottmg@chromium.org
BUG=chromium:440500

Review URL: https://codereview.chromium.org/1504983002

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@297894 0039d316-1c4b-4281-b951-d872f2087c98
parent 8a6495cb
...@@ -21,7 +21,9 @@ useful as the resulting zip can't be redistributed, and most will presumably ...@@ -21,7 +21,9 @@ useful as the resulting zip can't be redistributed, and most will presumably
have a Pro license anyway). have a Pro license anyway).
""" """
import optparse
import os import os
import platform
import shutil import shutil
import sys import sys
import tempfile import tempfile
...@@ -31,6 +33,7 @@ import get_toolchain_if_necessary ...@@ -31,6 +33,7 @@ import get_toolchain_if_necessary
VS_VERSION = None VS_VERSION = None
WIN_VERSION = None
def BuildFileList(): def BuildFileList():
...@@ -112,24 +115,24 @@ def BuildFileList(): ...@@ -112,24 +115,24 @@ def BuildFileList():
combined = os.path.normpath(os.path.join(root, f)) combined = os.path.normpath(os.path.join(root, f))
# Some of the files in this directory are exceedingly long (and exceed # Some of the files in this directory are exceedingly long (and exceed
#_MAX_PATH for any moderately long root), so exclude them. We don't need #_MAX_PATH for any moderately long root), so exclude them. We don't need
# them anyway. # them anyway. Exclude the Windows Performance Toolkit just to save space.
tail = combined[len(sdk_path) + 1:] tail = combined[len(sdk_path) + 1:]
if tail.startswith('References\\'): if (tail.startswith('References\\') or
tail.startswith('Windows Performance Toolkit\\')):
continue continue
if VS_VERSION == '2015':
# There may be many Include\Lib\Source directories for many different
# versions of Windows and packaging them all wastes ~450 MB
# (uncompressed) per version and wastes time. Only copy the specified
# version.
if (tail.startswith('Include\\') or tail.startswith('Lib\\') or
tail.startswith('Source\\')):
if tail.count(WIN_VERSION) == 0:
continue
to = os.path.join('win_sdk', tail) to = os.path.join('win_sdk', tail)
result.append((combined, to)) result.append((combined, to))
if VS_VERSION == '2015': if VS_VERSION == '2015':
for ucrt_path in (
(r'C:\Program Files (x86)\Windows Kits\10\Include', 'Include'),
(r'C:\Program Files (x86)\Windows Kits\10\Lib', 'Lib'),
(r'C:\Program Files (x86)\Windows Kits\10\Source', 'Source')):
src, target = ucrt_path
for root, _, files in os.walk(src):
for f in files:
combined = os.path.normpath(os.path.join(root, f))
to = os.path.join('ucrt', target, combined[len(src) + 1:])
result.append((combined, to))
system_crt_files = [ system_crt_files = [
'api-ms-win-core-file-l1-2-0.dll', 'api-ms-win-core-file-l1-2-0.dll',
...@@ -158,15 +161,21 @@ def BuildFileList(): ...@@ -158,15 +161,21 @@ def BuildFileList():
'ucrtbase.dll', 'ucrtbase.dll',
'ucrtbased.dll', 'ucrtbased.dll',
] ]
bitness = platform.architecture()[0]
# When running 64-bit python the x64 DLLs will be in System32
x64_path = 'System32' if bitness == '64bit' else 'Sysnative'
x64_path = os.path.join(r'C:\Windows', x64_path)
for system_crt_file in system_crt_files: for system_crt_file in system_crt_files:
result.append((os.path.join(r'C:\Windows\SysWOW64', system_crt_file), result.append((os.path.join(r'C:\Windows\SysWOW64', system_crt_file),
os.path.join('sys32', system_crt_file))) os.path.join('sys32', system_crt_file)))
result.append((os.path.join(r'C:\Windows\Sysnative', system_crt_file), result.append((os.path.join(x64_path, system_crt_file),
os.path.join('sys64', system_crt_file))) os.path.join('sys64', system_crt_file)))
# Generically drop all arm stuff that we don't need. # Generically drop all arm stuff that we don't need, and
# drop .msi files because we don't need installers.
return [(f, t) for f, t in result if 'arm\\' not in f.lower() and return [(f, t) for f, t in result if 'arm\\' not in f.lower() and
'arm64\\' not in f.lower()] 'arm64\\' not in f.lower() and
not f.lower().endswith('.msi')]
def GenerateSetEnvCmd(target_dir): def GenerateSetEnvCmd(target_dir):
...@@ -181,12 +190,13 @@ def GenerateSetEnvCmd(target_dir): ...@@ -181,12 +190,13 @@ def GenerateSetEnvCmd(target_dir):
':: Generated by win_toolchain\\package_from_installed.py.\n' ':: Generated by win_toolchain\\package_from_installed.py.\n'
# Common to x86 and x64 # Common to x86 and x64
'set PATH=%~dp0..\\..\\Common7\\IDE;%PATH%\n' 'set PATH=%~dp0..\\..\\Common7\\IDE;%PATH%\n'
'set INCLUDE=%~dp0..\\..\\win_sdk\\Include\\10.0.10240.0\\um;' 'set INCLUDE=%~dp0..\\..\\win_sdk\\Include\\WINVERSION\\um;'
'%~dp0..\\..\\win_sdk\\Include\\10.0.10240.0\\shared;' '%~dp0..\\..\\win_sdk\\Include\\WINVERSION\\shared;'
'%~dp0..\\..\\win_sdk\\Include\\10.0.10240.0\\winrt;' '%~dp0..\\..\\win_sdk\\Include\\WINVERSION\\winrt;'
'%~dp0..\\..\\win_sdk\\Include\\WINVERSION\\ucrt;' # VS 2015
'%~dp0..\\..\\VC\\include;' '%~dp0..\\..\\VC\\include;'
'%~dp0..\\..\\VC\\atlmfc\\include\n' '%~dp0..\\..\\VC\\atlmfc\\include\n'
'if "%1"=="/x64" goto x64\n') 'if "%1"=="/x64" goto x64\n'.replace('WINVERSION', WIN_VERSION))
# x86. Always use amd64_x86 cross, not x86 on x86. # x86. Always use amd64_x86 cross, not x86 on x86.
f.write('set PATH=%~dp0..\\..\\win_sdk\\bin\\x86;' f.write('set PATH=%~dp0..\\..\\win_sdk\\bin\\x86;'
...@@ -194,9 +204,10 @@ def GenerateSetEnvCmd(target_dir): ...@@ -194,9 +204,10 @@ def GenerateSetEnvCmd(target_dir):
'%~dp0..\\..\\VC\\bin\\amd64;' # Needed for mspdb1x0.dll. '%~dp0..\\..\\VC\\bin\\amd64;' # Needed for mspdb1x0.dll.
'%PATH%\n') '%PATH%\n')
f.write('set LIB=%~dp0..\\..\\VC\\lib;' f.write('set LIB=%~dp0..\\..\\VC\\lib;'
'%~dp0..\\..\\win_sdk\\Lib\\10.0.10240.0\\um\\x86;' '%~dp0..\\..\\win_sdk\\Lib\\WINVERSION\\um\\x86;'
'%~dp0..\\..\\win_sdk\\Lib\\WINVERSION\\ucrt\\x86;' # VS 2015
'%~dp0..\\..\\VC\\atlmfc\\lib\n' '%~dp0..\\..\\VC\\atlmfc\\lib\n'
'goto :EOF\n') 'goto :EOF\n'.replace('WINVERSION', WIN_VERSION))
# x64. # x64.
f.write(':x64\n' f.write(':x64\n'
...@@ -204,8 +215,10 @@ def GenerateSetEnvCmd(target_dir): ...@@ -204,8 +215,10 @@ def GenerateSetEnvCmd(target_dir):
'%~dp0..\\..\\VC\\bin\\amd64;' '%~dp0..\\..\\VC\\bin\\amd64;'
'%PATH%\n') '%PATH%\n')
f.write('set LIB=%~dp0..\\..\\VC\\lib\\amd64;' f.write('set LIB=%~dp0..\\..\\VC\\lib\\amd64;'
'%~dp0..\\..\\win_sdk\\Lib\\10.0.10240.0\\um\\x64;' '%~dp0..\\..\\win_sdk\\Lib\\WINVERSION\\um\\x64;'
'%~dp0..\\..\\VC\\atlmfc\\lib\\amd64\n') '%~dp0..\\..\\win_sdk\\Lib\\WINVERSION\\ucrt\\x64;' # VS 2015
'%~dp0..\\..\\VC\\atlmfc\\lib\\amd64\n'
.replace('WINVERSION', WIN_VERSION))
def AddEnvSetup(files): def AddEnvSetup(files):
...@@ -246,14 +259,27 @@ def RenameToSha1(output): ...@@ -246,14 +259,27 @@ def RenameToSha1(output):
def main(): def main():
if len(sys.argv) != 2 or sys.argv[1] not in ('2013', '2015'): usage = 'usage: %prog [options] 2013|2015'
print 'Usage: package_from_installed.py 2013|2015' parser = optparse.OptionParser(usage)
parser.add_option('-w', '--winver', action='store', type='string',
dest='winver', default='10.0.10586.0',
help='Windows SDK version, such as 10.0.10586.0')
parser.add_option('-d', '--dryrun', action='store_true', dest='dryrun',
default=False,
help='scan for file existence and prints statistics')
(options, args) = parser.parse_args()
if len(args) != 1 or args[0] not in ('2013', '2015'):
print 'Must specify 2013 or 2015'
parser.print_help();
return 1 return 1
global VS_VERSION global VS_VERSION
VS_VERSION = sys.argv[1] VS_VERSION = args[0]
global WIN_VERSION
WIN_VERSION = options.winver
print 'Building file list...' print 'Building file list for VS %s Windows %s...' % (VS_VERSION, WIN_VERSION)
files = BuildFileList() files = BuildFileList()
AddEnvSetup(files) AddEnvSetup(files)
...@@ -267,12 +293,33 @@ def main(): ...@@ -267,12 +293,33 @@ def main():
if os.path.exists(output): if os.path.exists(output):
os.unlink(output) os.unlink(output)
count = 0 count = 0
version_match_count = 0
total_size = 0
missing_files = False
with zipfile.ZipFile(output, 'w', zipfile.ZIP_DEFLATED, True) as zf: with zipfile.ZipFile(output, 'w', zipfile.ZIP_DEFLATED, True) as zf:
for disk_name, archive_name in files: for disk_name, archive_name in files:
sys.stdout.write('\r%d/%d ...%s' % (count, len(files), disk_name[-40:])) sys.stdout.write('\r%d/%d ...%s' % (count, len(files), disk_name[-40:]))
sys.stdout.flush() sys.stdout.flush()
count += 1 count += 1
zf.write(disk_name, archive_name) if disk_name.count(WIN_VERSION) > 0:
version_match_count += 1
if os.path.exists(disk_name):
if options.dryrun:
total_size += os.path.getsize(disk_name)
else:
zf.write(disk_name, archive_name)
else:
missing_files = True
sys.stdout.write('\r%s does not exist.\n\n' % disk_name)
sys.stdout.flush()
if options.dryrun:
sys.stdout.write('\r%1.3f GB of data in %d files, %d files for %s.%s\n' %
(total_size / 1e9, count, version_match_count, WIN_VERSION, ' '*50))
return 0
if missing_files:
raise 'One or more files were missing - aborting'
if version_match_count == 0:
raise 'No files found that match the specified winversion'
sys.stdout.write('\rWrote to %s.%s\n' % (output, ' '*50)) sys.stdout.write('\rWrote to %s.%s\n' % (output, ' '*50))
sys.stdout.flush() sys.stdout.flush()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment