From 42eeab482d70bc2a17fcd87cc7efe3df7622cbc3 Mon Sep 17 00:00:00 2001 From: "brucedawson@chromium.org" Date: Tue, 10 May 2016 19:33:08 +0000 Subject: [PATCH] Update toolchain packaging to support VC++ preview toolsets This change adds a --override option to the VC++ packaging script so that an arbitrary bin/include/lib containing directory can be used to package up those components of VC++. See this post for details: https://blogs.msdn.microsoft.com/vcblog/2016/02/16/try-out-the-latest-c-compiler-toolset-without-waiting-for-the-next-update-of-visual-studio/ Typical usage is like this: package_from_installed.py 2015 --override \packages\VisualCppTools.14.0.24109-Pre\lib\native In order to make this work the path tuple support was fixed so that the local relative path was propagated to the destination path, instead of just the file name. At the same time, the code to package up the UCRT installers was deleted because it isn't needed, and windows.winmd is filtered out because it makes consistent package creation impossible (it is different on every machine). While removing the UCRT installers I discovered nested if VS_VERSION checks. Oops. Fixed. BUG=440500 Review-Url: https://codereview.chromium.org/1967653002 git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@300527 0039d316-1c4b-4281-b951-d872f2087c98 --- win_toolchain/package_from_installed.py | 121 +++++++++++++----------- 1 file changed, 64 insertions(+), 57 deletions(-) diff --git a/win_toolchain/package_from_installed.py b/win_toolchain/package_from_installed.py index c1f5e809b..7c8d71348 100644 --- a/win_toolchain/package_from_installed.py +++ b/win_toolchain/package_from_installed.py @@ -39,7 +39,7 @@ VS_VERSION = None WIN_VERSION = None -def BuildFileList(): +def BuildFileList(override_dir): result = [] # Subset of VS corresponding roughly to VC. @@ -49,13 +49,23 @@ def BuildFileList(): 'DIA SDK/include', 'DIA SDK/lib', 'VC/atlmfc', - 'VC/bin', 'VC/crt', - 'VC/include', - 'VC/lib', 'VC/redist', ] + if override_dir: + paths += [ + (os.path.join(override_dir, 'bin'), 'VC/bin'), + (os.path.join(override_dir, 'include'), 'VC/include'), + (os.path.join(override_dir, 'lib'), 'VC/lib'), + ] + else: + paths += [ + 'VC/bin', + 'VC/include', + 'VC/lib', + ] + if VS_VERSION == '2013': paths += [ ('VC/redist/x86/Microsoft.VC120.CRT', 'sys32'), @@ -92,14 +102,18 @@ def BuildFileList(): for path in paths: src = path[0] if isinstance(path, tuple) else path - combined = os.path.join(vs_path, src) + # Note that vs_path is ignored if src is an absolute path. + # normpath is needed to change '/' to '\\' characters. + combined = os.path.normpath(os.path.join(vs_path, src)) assert os.path.exists(combined) and os.path.isdir(combined) for root, _, files in os.walk(combined): for f in files: final_from = os.path.normpath(os.path.join(root, f)) if isinstance(path, tuple): + assert final_from.startswith(combined) + dest = final_from[len(combined) + 1:] result.append( - (final_from, os.path.normpath(os.path.join(path[1], f)))) + (final_from, os.path.normpath(os.path.join(path[1], dest)))) else: assert final_from.startswith(vs_path) dest = final_from[len(vs_path) + 1:] @@ -140,61 +154,44 @@ def BuildFileList(): result.append((combined, to)) if VS_VERSION == '2015': - # The Windows 10 Universal C Runtime installers are needed when packaging - # VS 2015. They can be download from here: - # https://support.microsoft.com/en-us/kb/2999226 - # and they must be downloaded to the current user's downloads directory. - # The versions needed are those for 64-bit Windows 7, Windows 8, and - # Windows 8.1. The 64-bit Server 2008 R2, Server 2012, and Server 2012 R2 - # versions are identical (same name and contents). - universal_runtime_installers = [ - 'Windows6.1-KB2999226-x64.msu', - 'Windows8-RT-KB2999226-x64.msu', - 'Windows8.1-KB2999226-x64.msu', + # Copy the x86 ucrt DLLs to all directories with 32-bit binaries that are + # added to the path by SetEnv.cmd, and to sys32. + ucrt_paths = glob.glob(os.path.join(sdk_path, r'redist\ucrt\dlls\x86\*')) + for ucrt_path in ucrt_paths: + ucrt_file = os.path.split(ucrt_path)[1] + for dest_dir in [ r'win_sdk\bin\x86', 'sys32' ]: + result.append((ucrt_path, os.path.join(dest_dir, ucrt_file))) + + # Copy the x64 ucrt DLLs to all directories with 64-bit binaries that are + # added to the path by SetEnv.cmd, and to sys64. + ucrt_paths = glob.glob(os.path.join(sdk_path, r'redist\ucrt\dlls\x64\*')) + for ucrt_path in ucrt_paths: + ucrt_file = os.path.split(ucrt_path)[1] + for dest_dir in [ r'VC\bin\amd64_x86', r'VC\bin\amd64', + r'win_sdk\bin\x64', 'sys64']: + result.append((ucrt_path, os.path.join(dest_dir, ucrt_file))) + + system_crt_files = [ + # Needed to let debug binaries run. + 'ucrtbased.dll', ] - - for installer in universal_runtime_installers: - result.append((os.path.join(os.environ['userprofile'], 'downloads', - installer), - os.path.join('installers', installer))) - - if VS_VERSION == '2015': - # Copy the x86 ucrt DLLs to all directories with 32-bit binaries that are - # added to the path by SetEnv.cmd, and to sys32. - ucrt_paths = glob.glob(os.path.join(sdk_path, r'redist\ucrt\dlls\x86\*')) - for ucrt_path in ucrt_paths: - ucrt_file = os.path.split(ucrt_path)[1] - for dest_dir in [ r'win_sdk\bin\x86', 'sys32' ]: - result.append((ucrt_path, os.path.join(dest_dir, ucrt_file))) - - # Copy the x64 ucrt DLLs to all directories with 64-bit binaries that are - # added to the path by SetEnv.cmd, and to sys64. - ucrt_paths = glob.glob(os.path.join(sdk_path, r'redist\ucrt\dlls\x64\*')) - for ucrt_path in ucrt_paths: - ucrt_file = os.path.split(ucrt_path)[1] - for dest_dir in [ r'VC\bin\amd64_x86', r'VC\bin\amd64', - r'win_sdk\bin\x64', 'sys64']: - result.append((ucrt_path, os.path.join(dest_dir, ucrt_file))) - - system_crt_files = [ - # Needed to let debug binaries run. - '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(x64_path, system_crt_file), - os.path.join('sys64', system_crt_file))) + 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(x64_path, system_crt_file), + os.path.join('sys64', system_crt_file))) # Generically drop all arm stuff that we don't need, and - # drop .msi files because we don't need installers. + # drop .msi files because we don't need installers, and drop windows.winmd + # because it is unneeded and is different on every machine. return [(f, t) for f, t in result if 'arm\\' not in f.lower() and 'arm64\\' not in f.lower() and - not f.lower().endswith('.msi')] + not f.lower().endswith('.msi') and + not f.lower().endswith('windows.winmd')] def GenerateSetEnvCmd(target_dir): @@ -329,6 +326,9 @@ def main(): parser.add_option('-d', '--dryrun', action='store_true', dest='dryrun', default=False, help='scan for file existence and prints statistics') + parser.add_option('--override', action='store', type='string', + dest='override_dir', default=None, + help='Specify alternate bin/include/lib directory') (options, args) = parser.parse_args() if len(args) != 1 or args[0] not in ('2013', '2015'): @@ -336,13 +336,20 @@ def main(): parser.print_help(); return 1 + if options.override_dir: + if (not os.path.exists(os.path.join(options.override_dir, 'bin')) or + not os.path.exists(os.path.join(options.override_dir, 'include')) or + not os.path.exists(os.path.join(options.override_dir, 'lib'))): + print 'Invalid override directory - must contain bin/include/lib dirs' + return 1 + global VS_VERSION VS_VERSION = args[0] global WIN_VERSION WIN_VERSION = options.winver print 'Building file list for VS %s Windows %s...' % (VS_VERSION, WIN_VERSION) - files = BuildFileList() + files = BuildFileList(options.override_dir) AddEnvSetup(files)