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
have a Pro license anyway).
"""
import optparse
import os
import platform
import shutil
import sys
import tempfile
......@@ -31,6 +33,7 @@ import get_toolchain_if_necessary
VS_VERSION = None
WIN_VERSION = None
def BuildFileList():
......@@ -112,24 +115,24 @@ def BuildFileList():
combined = os.path.normpath(os.path.join(root, f))
# 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
# them anyway.
# them anyway. Exclude the Windows Performance Toolkit just to save space.
tail = combined[len(sdk_path) + 1:]
if tail.startswith('References\\'):
if (tail.startswith('References\\') or
tail.startswith('Windows Performance Toolkit\\')):
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)
result.append((combined, to))
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 = [
'api-ms-win-core-file-l1-2-0.dll',
......@@ -158,15 +161,21 @@ def BuildFileList():
'ucrtbase.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:
result.append((os.path.join(r'C:\Windows\SysWOW64', 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)))
# 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
'arm64\\' not in f.lower()]
'arm64\\' not in f.lower() and
not f.lower().endswith('.msi')]
def GenerateSetEnvCmd(target_dir):
......@@ -181,12 +190,13 @@ def GenerateSetEnvCmd(target_dir):
':: Generated by win_toolchain\\package_from_installed.py.\n'
# Common to x86 and x64
'set PATH=%~dp0..\\..\\Common7\\IDE;%PATH%\n'
'set INCLUDE=%~dp0..\\..\\win_sdk\\Include\\10.0.10240.0\\um;'
'%~dp0..\\..\\win_sdk\\Include\\10.0.10240.0\\shared;'
'%~dp0..\\..\\win_sdk\\Include\\10.0.10240.0\\winrt;'
'set INCLUDE=%~dp0..\\..\\win_sdk\\Include\\WINVERSION\\um;'
'%~dp0..\\..\\win_sdk\\Include\\WINVERSION\\shared;'
'%~dp0..\\..\\win_sdk\\Include\\WINVERSION\\winrt;'
'%~dp0..\\..\\win_sdk\\Include\\WINVERSION\\ucrt;' # VS 2015
'%~dp0..\\..\\VC\\include;'
'%~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.
f.write('set PATH=%~dp0..\\..\\win_sdk\\bin\\x86;'
......@@ -194,9 +204,10 @@ def GenerateSetEnvCmd(target_dir):
'%~dp0..\\..\\VC\\bin\\amd64;' # Needed for mspdb1x0.dll.
'%PATH%\n')
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'
'goto :EOF\n')
'goto :EOF\n'.replace('WINVERSION', WIN_VERSION))
# x64.
f.write(':x64\n'
......@@ -204,8 +215,10 @@ def GenerateSetEnvCmd(target_dir):
'%~dp0..\\..\\VC\\bin\\amd64;'
'%PATH%\n')
f.write('set LIB=%~dp0..\\..\\VC\\lib\\amd64;'
'%~dp0..\\..\\win_sdk\\Lib\\10.0.10240.0\\um\\x64;'
'%~dp0..\\..\\VC\\atlmfc\\lib\\amd64\n')
'%~dp0..\\..\\win_sdk\\Lib\\WINVERSION\\um\\x64;'
'%~dp0..\\..\\win_sdk\\Lib\\WINVERSION\\ucrt\\x64;' # VS 2015
'%~dp0..\\..\\VC\\atlmfc\\lib\\amd64\n'
.replace('WINVERSION', WIN_VERSION))
def AddEnvSetup(files):
......@@ -246,14 +259,27 @@ def RenameToSha1(output):
def main():
if len(sys.argv) != 2 or sys.argv[1] not in ('2013', '2015'):
print 'Usage: package_from_installed.py 2013|2015'
usage = 'usage: %prog [options] 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
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()
AddEnvSetup(files)
......@@ -267,12 +293,33 @@ def main():
if os.path.exists(output):
os.unlink(output)
count = 0
version_match_count = 0
total_size = 0
missing_files = False
with zipfile.ZipFile(output, 'w', zipfile.ZIP_DEFLATED, True) as zf:
for disk_name, archive_name in files:
sys.stdout.write('\r%d/%d ...%s' % (count, len(files), disk_name[-40:]))
sys.stdout.flush()
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.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