From e95b5d6ad52be5b149cecf274905e1aa9ea59a6f Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Mon, 24 Aug 2020 20:00:34 +0000 Subject: [PATCH] Avoid ..\.. in packaged environment variables win_sdk\bin\setenv.cmd is used to configure the build environment for the packaged toolchain. This has always been done by creating paths such as %~dp0..\..\VC, which leads to extra long paths that are less readable than direct paths. These extra long paths make us more vulnerable to MAX_PATH issues. This change generates the paths relative to the grandparent directory. It does that by changing the current directory to the grandparent directory of the script and then generating paths relative to %cd%. The paths are still absolute they are just shorter and simpler. The paths are also stored in SetEnv.*.json and this change alters the relative-root used for these paths. crrev.com/c/2370604 detects the needed relative-root to handle toolchains packaged before and after this change. This change was tested using crrev.com/c/2370604 (temporarily modified to use a toolchain created by this change) to ensure that it works. Bug: 1120785 Change-Id: Icd72e36766d7ec92a491d16dbfd9ad7fc1b2ebc5 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2372727 Reviewed-by: Scott Graham Commit-Queue: Bruce Dawson --- win_toolchain/package_from_installed.py | 81 ++++++++++++++----------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/win_toolchain/package_from_installed.py b/win_toolchain/package_from_installed.py index 24ac233d6..6794f955b 100644 --- a/win_toolchain/package_from_installed.py +++ b/win_toolchain/package_from_installed.py @@ -268,86 +268,90 @@ def GenerateSetEnvCmd(target_dir): do it here manually since we do not do a full install.""" vc_tools_parts = VC_TOOLS.split('/') - # All these paths are relative to the directory containing SetEnv.cmd. + # All these paths are relative to the grandparent of the directory containing + # SetEnv.cmd. include_dirs = [ - ['..', '..', 'win_sdk', 'Include', WIN_VERSION, 'um'], - ['..', '..', 'win_sdk', 'Include', WIN_VERSION, 'shared'], - ['..', '..', 'win_sdk', 'Include', WIN_VERSION, 'winrt'], + ['win_sdk', 'Include', WIN_VERSION, 'um'], + ['win_sdk', 'Include', WIN_VERSION, 'shared'], + ['win_sdk', 'Include', WIN_VERSION, 'winrt'], ] - include_dirs.append(['..', '..', 'win_sdk', 'Include', WIN_VERSION, 'ucrt']) + include_dirs.append(['win_sdk', 'Include', WIN_VERSION, 'ucrt']) include_dirs.extend([ - ['..', '..'] + vc_tools_parts + ['include'], - ['..', '..'] + vc_tools_parts + ['atlmfc', 'include'], + vc_tools_parts + ['include'], + vc_tools_parts + ['atlmfc', 'include'], ]) libpath_dirs = [ - ['..', '..'] + vc_tools_parts + ['lib', 'x86', 'store', 'references'], - ['..', '..', 'win_sdk', 'UnionMetadata', WIN_VERSION], + vc_tools_parts + ['lib', 'x86', 'store', 'references'], + ['win_sdk', 'UnionMetadata', WIN_VERSION], ] # Common to x86, x64, and arm64 env = collections.OrderedDict([ # Yuck: These have a trailing \ character. No good way to represent this in # an OS-independent way. - ('VSINSTALLDIR', [['..', '..\\']]), - ('VCINSTALLDIR', [['..', '..', 'VC\\']]), + ('VSINSTALLDIR', [['.\\']]), + ('VCINSTALLDIR', [['VC\\']]), ('INCLUDE', include_dirs), ('LIBPATH', libpath_dirs), ]) # x86. Always use amd64_x86 cross, not x86 on x86. - env['VCToolsInstallDir'] = [['..', '..'] + vc_tools_parts[:]] + env['VCToolsInstallDir'] = [vc_tools_parts[:]] # Yuck: This one ends in a slash as well. env['VCToolsInstallDir'][0][-1] += '\\' env_x86 = collections.OrderedDict([ ( 'PATH', [ - ['..', '..', 'win_sdk', 'bin', WIN_VERSION, 'x64'], - ['..', '..'] + vc_tools_parts + ['bin', 'HostX64', 'x86'], - ['..', '..'] + vc_tools_parts + ['bin', 'HostX64', 'x64' + ['win_sdk', 'bin', WIN_VERSION, 'x64'], + vc_tools_parts + ['bin', 'HostX64', 'x86'], + vc_tools_parts + ['bin', 'HostX64', 'x64' ], # Needed for mspdb1x0.dll. ]), ('LIB', [ - ['..', '..'] + vc_tools_parts + ['lib', 'x86'], - ['..', '..', 'win_sdk', 'Lib', WIN_VERSION, 'um', 'x86'], - ['..', '..', 'win_sdk', 'Lib', WIN_VERSION, 'ucrt', 'x86'], - ['..', '..'] + vc_tools_parts + ['atlmfc', 'lib', 'x86'], + vc_tools_parts + ['lib', 'x86'], + ['win_sdk', 'Lib', WIN_VERSION, 'um', 'x86'], + ['win_sdk', 'Lib', WIN_VERSION, 'ucrt', 'x86'], + vc_tools_parts + ['atlmfc', 'lib', 'x86'], ]), ]) # x64. env_x64 = collections.OrderedDict([ ('PATH', [ - ['..', '..', 'win_sdk', 'bin', WIN_VERSION, 'x64'], - ['..', '..'] + vc_tools_parts + ['bin', 'HostX64', 'x64'], + ['win_sdk', 'bin', WIN_VERSION, 'x64'], + vc_tools_parts + ['bin', 'HostX64', 'x64'], ]), ('LIB', [ - ['..', '..'] + vc_tools_parts + ['lib', 'x64'], - ['..', '..', 'win_sdk', 'Lib', WIN_VERSION, 'um', 'x64'], - ['..', '..', 'win_sdk', 'Lib', WIN_VERSION, 'ucrt', 'x64'], - ['..', '..'] + vc_tools_parts + ['atlmfc', 'lib', 'x64'], + vc_tools_parts + ['lib', 'x64'], + ['win_sdk', 'Lib', WIN_VERSION, 'um', 'x64'], + ['win_sdk', 'Lib', WIN_VERSION, 'ucrt', 'x64'], + vc_tools_parts + ['atlmfc', 'lib', 'x64'], ]), ]) # arm64. env_arm64 = collections.OrderedDict([ ('PATH', [ - ['..', '..', 'win_sdk', 'bin', WIN_VERSION, 'x64'], - ['..', '..'] + vc_tools_parts + ['bin', 'HostX64', 'arm64'], - ['..', '..'] + vc_tools_parts + ['bin', 'HostX64', 'x64'], + ['win_sdk', 'bin', WIN_VERSION, 'x64'], + vc_tools_parts + ['bin', 'HostX64', 'arm64'], + vc_tools_parts + ['bin', 'HostX64', 'x64'], ]), ('LIB', [ - ['..', '..'] + vc_tools_parts + ['lib', 'arm64'], - ['..', '..', 'win_sdk', 'Lib', WIN_VERSION, 'um', 'arm64'], - ['..', '..', 'win_sdk', 'Lib', WIN_VERSION, 'ucrt', 'arm64'], - ['..', '..'] + vc_tools_parts + ['atlmfc', 'lib', 'arm64'], + vc_tools_parts + ['lib', 'arm64'], + ['win_sdk', 'Lib', WIN_VERSION, 'um', 'arm64'], + ['win_sdk', 'Lib', WIN_VERSION, 'ucrt', 'arm64'], + vc_tools_parts + ['atlmfc', 'lib', 'arm64'], ]), ]) def BatDirs(dirs): - return ';'.join(['%~dp0' + os.path.join(*d) for d in dirs]) + return ';'.join(['%cd%\\' + os.path.join(*d) for d in dirs]) set_env_prefix = os.path.join(target_dir, r'win_sdk\bin\SetEnv') with open(set_env_prefix + '.cmd', 'w') as f: + # The prologue changes the current directory to the grandparent so that the + # path entries can be set up without needing ..\..\ components. f.write('@echo off\n' - ':: Generated by win_toolchain\\package_from_installed.py.\n') + ':: Generated by win_toolchain\\package_from_installed.py.\n' + 'pushd %~dp0..\..\n') for var, dirs in env.items(): f.write('set %s=%s\n' % (var, BatDirs(dirs))) f.write('if "%1"=="/x64" goto x64\n') @@ -356,19 +360,22 @@ def GenerateSetEnvCmd(target_dir): for var, dirs in env_x86.items(): f.write('set %s=%s%s\n' % ( var, BatDirs(dirs), ';%PATH%' if var == 'PATH' else '')) - f.write('goto :EOF\n') + f.write('goto :END\n') f.write(':x64\n') for var, dirs in env_x64.items(): f.write('set %s=%s%s\n' % ( var, BatDirs(dirs), ';%PATH%' if var == 'PATH' else '')) - f.write('goto :EOF\n') + f.write('goto :END\n') f.write(':arm64\n') for var, dirs in env_arm64.items(): f.write('set %s=%s%s\n' % ( var, BatDirs(dirs), ';%PATH%' if var == 'PATH' else '')) - f.write('goto :EOF\n') + f.write('goto :END\n') + f.write(':END\n') + # Restore the original directory. + f.write('popd\n') with open(set_env_prefix + '.x86.json', 'wt', newline='') as f: assert not set(env.keys()) & set(env_x86.keys()), 'dupe keys' json.dump({'env': collections.OrderedDict(list(env.items()) + list(env_x86.items()))},