From c6684fda9877962580c021aab7c8bc0e9f1c2647 Mon Sep 17 00:00:00 2001 From: Fumitoshi Ukai Date: Tue, 1 Apr 2025 17:45:14 -0700 Subject: [PATCH] win_toolchain: setup junction for toolchain dir Some builders use env:DEPOT_TOOLS_WIN_TOOLCHAIN_ROOT to specify shared builder cache on bot, which is out side of builder's workspace, so we needed to set RBE_exec_root to common ancestor dir above for reclient. This CL sets up a directory junction in win_toolchain (default location) to toolchain dir if specified by `--toolchain-dir` or env:DEPOT_TOOLS_WIN_TOOLCHAIN_ROOT, download win toolchain in the toolchain dir, and use default location path for win toolchain, so win toolchain can be available under normal exec root. Bug: 397786479, 313567009 Change-Id: Ia39ce9e40f477f71e70036ed47c4b61c29626718 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/6288233 Reviewed-by: Junji Watanabe Commit-Queue: Fumitoshi Ukai Reviewed-by: Andy Perelson Reviewed-by: Dirk Pranke Reviewed-by: Philipp Wollermann --- win_toolchain/get_toolchain_if_necessary.py | 44 ++++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/win_toolchain/get_toolchain_if_necessary.py b/win_toolchain/get_toolchain_if_necessary.py index ce6bd54289..18b747a3f3 100755 --- a/win_toolchain/get_toolchain_if_necessary.py +++ b/win_toolchain/get_toolchain_if_necessary.py @@ -474,6 +474,30 @@ def EnableCrashDumpCollection(): pass +def SetupJunction(target_dir): + """Sets up junction for toolchain dir.""" + junction_dir = os.path.join(BASEDIR, 'vs_files') + if junction_dir == target_dir: + return target_dir + if not sys.platform.startswith('win32'): + # build/vs_toolchain.py sets up ciopfs on vs_files, + # so using different target_dir won't work on Linux? + return target_dir + if os.path.exists(junction_dir): + try: + if os.path.samefile(os.readlink(junction_dir), target_dir): + return junction_dir + except: + # os.readlink may fail if junction_dir is not junction or symlink + pass + RmDir(junction_dir) + print('Setup a directory junction %s to %s' % (junction_dir, target_dir)) + subprocess.run(['mklink', '/J', junction_dir, target_dir], + shell=True, + check=True) + return junction_dir + + def main(): parser = argparse.ArgumentParser( description=__doc__, @@ -494,6 +518,10 @@ def main(): parser.add_argument('desired_hash', metavar='desired-hash', help='toolchain hash to download') + parser.add_argument( + '--no-junction', + action='store_true', + help='don\'t setup junction for toolchain dir on Windows') args = parser.parse_args() if not (sys.platform.startswith(('cygwin', 'win32')) or args.force): @@ -517,16 +545,20 @@ def main(): toolchain_dir = os.path.abspath(args.toolchain_dir) if not os.path.isdir(toolchain_dir): os.makedirs(toolchain_dir) - os.chdir(toolchain_dir) + abs_target_dir = os.path.join(toolchain_dir, 'vs_files') + if not os.path.isdir(abs_target_dir): + os.mkdir(abs_target_dir) + if not args.no_junction: + # Set up a directory junction in BASEDIR to toolchain_dir + # so toolchain files can be accessible under exec root. + abs_target_dir = SetupJunction(abs_target_dir) # Move to depot_tools\win_toolchain where we'll store our files, and where # the downloader script is. + os.chdir(os.path.dirname(abs_target_dir)) target_dir = 'vs_files' - if not os.path.isdir(target_dir): - os.mkdir(target_dir) - toolchain_target_dir = os.path.join(target_dir, args.desired_hash) - - abs_toolchain_target_dir = os.path.abspath(toolchain_target_dir) + toolchain_target_dir = os.path.join('vs_files', args.desired_hash) + abs_toolchain_target_dir = os.path.join(abs_target_dir, args.desired_hash) got_new_toolchain = False