1*8975f5c5SAndroid Build Coastguard Worker# Copyright 2013 The Chromium Authors 2*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 3*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file. 4*8975f5c5SAndroid Build Coastguard Worker# 5*8975f5c5SAndroid Build Coastguard Worker# Copies the given "win tool" (which the toolchain uses to wrap compiler 6*8975f5c5SAndroid Build Coastguard Worker# invocations) and the environment blocks for the 32-bit and 64-bit builds on 7*8975f5c5SAndroid Build Coastguard Worker# Windows to the build directory. 8*8975f5c5SAndroid Build Coastguard Worker# 9*8975f5c5SAndroid Build Coastguard Worker# The arguments are the visual studio install location and the location of the 10*8975f5c5SAndroid Build Coastguard Worker# win tool. The script assumes that the root build directory is the current dir 11*8975f5c5SAndroid Build Coastguard Worker# and the files will be written to the current directory. 12*8975f5c5SAndroid Build Coastguard Worker 13*8975f5c5SAndroid Build Coastguard Worker 14*8975f5c5SAndroid Build Coastguard Workerimport errno 15*8975f5c5SAndroid Build Coastguard Workerimport json 16*8975f5c5SAndroid Build Coastguard Workerimport os 17*8975f5c5SAndroid Build Coastguard Workerimport re 18*8975f5c5SAndroid Build Coastguard Workerimport subprocess 19*8975f5c5SAndroid Build Coastguard Workerimport sys 20*8975f5c5SAndroid Build Coastguard Worker 21*8975f5c5SAndroid Build Coastguard Workersys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) 22*8975f5c5SAndroid Build Coastguard Workerimport gn_helpers 23*8975f5c5SAndroid Build Coastguard Worker 24*8975f5c5SAndroid Build Coastguard WorkerSCRIPT_DIR = os.path.dirname(__file__) 25*8975f5c5SAndroid Build Coastguard WorkerSDK_VERSION = '10.0.22621.0' 26*8975f5c5SAndroid Build Coastguard Worker 27*8975f5c5SAndroid Build Coastguard Worker 28*8975f5c5SAndroid Build Coastguard Workerdef _ExtractImportantEnvironment(output_of_set): 29*8975f5c5SAndroid Build Coastguard Worker """Extracts environment variables required for the toolchain to run from 30*8975f5c5SAndroid Build Coastguard Worker a textual dump output by the cmd.exe 'set' command.""" 31*8975f5c5SAndroid Build Coastguard Worker envvars_to_save = ( 32*8975f5c5SAndroid Build Coastguard Worker 'cipd_cache_dir', # needed by vpython 33*8975f5c5SAndroid Build Coastguard Worker 'homedrive', # needed by vpython 34*8975f5c5SAndroid Build Coastguard Worker 'homepath', # needed by vpython 35*8975f5c5SAndroid Build Coastguard Worker 'include', 36*8975f5c5SAndroid Build Coastguard Worker 'lib', 37*8975f5c5SAndroid Build Coastguard Worker 'libpath', 38*8975f5c5SAndroid Build Coastguard Worker 'luci_context', # needed by vpython 39*8975f5c5SAndroid Build Coastguard Worker 'path', 40*8975f5c5SAndroid Build Coastguard Worker 'pathext', 41*8975f5c5SAndroid Build Coastguard Worker 'systemroot', 42*8975f5c5SAndroid Build Coastguard Worker 'temp', 43*8975f5c5SAndroid Build Coastguard Worker 'tmp', 44*8975f5c5SAndroid Build Coastguard Worker 'userprofile', # needed by vpython 45*8975f5c5SAndroid Build Coastguard Worker 'vpython_virtualenv_root' # needed by vpython 46*8975f5c5SAndroid Build Coastguard Worker ) 47*8975f5c5SAndroid Build Coastguard Worker env = {} 48*8975f5c5SAndroid Build Coastguard Worker # This occasionally happens and leads to misleading SYSTEMROOT error messages 49*8975f5c5SAndroid Build Coastguard Worker # if not caught here. 50*8975f5c5SAndroid Build Coastguard Worker if output_of_set.count('=') == 0: 51*8975f5c5SAndroid Build Coastguard Worker raise Exception('Invalid output_of_set. Value is:\n%s' % output_of_set) 52*8975f5c5SAndroid Build Coastguard Worker for line in output_of_set.splitlines(): 53*8975f5c5SAndroid Build Coastguard Worker for envvar in envvars_to_save: 54*8975f5c5SAndroid Build Coastguard Worker if re.match(envvar + '=', line.lower()): 55*8975f5c5SAndroid Build Coastguard Worker var, setting = line.split('=', 1) 56*8975f5c5SAndroid Build Coastguard Worker if envvar == 'path': 57*8975f5c5SAndroid Build Coastguard Worker # Our own rules and actions in Chromium rely on python being in the 58*8975f5c5SAndroid Build Coastguard Worker # path. Add the path to this python here so that if it's not in the 59*8975f5c5SAndroid Build Coastguard Worker # path when ninja is run later, python will still be found. 60*8975f5c5SAndroid Build Coastguard Worker setting = os.path.dirname(sys.executable) + os.pathsep + setting 61*8975f5c5SAndroid Build Coastguard Worker if envvar in ['include', 'lib']: 62*8975f5c5SAndroid Build Coastguard Worker # Make sure that the include and lib paths point to directories that 63*8975f5c5SAndroid Build Coastguard Worker # exist. This ensures a (relatively) clear error message if the 64*8975f5c5SAndroid Build Coastguard Worker # required SDK is not installed. 65*8975f5c5SAndroid Build Coastguard Worker for part in setting.split(';'): 66*8975f5c5SAndroid Build Coastguard Worker if not os.path.exists(part) and len(part) != 0: 67*8975f5c5SAndroid Build Coastguard Worker raise Exception( 68*8975f5c5SAndroid Build Coastguard Worker 'Path "%s" from environment variable "%s" does not exist. ' 69*8975f5c5SAndroid Build Coastguard Worker 'Make sure the necessary SDK is installed.' % (part, envvar)) 70*8975f5c5SAndroid Build Coastguard Worker env[var.upper()] = setting 71*8975f5c5SAndroid Build Coastguard Worker break 72*8975f5c5SAndroid Build Coastguard Worker if sys.platform in ('win32', 'cygwin'): 73*8975f5c5SAndroid Build Coastguard Worker for required in ('SYSTEMROOT', 'TEMP', 'TMP'): 74*8975f5c5SAndroid Build Coastguard Worker if required not in env: 75*8975f5c5SAndroid Build Coastguard Worker raise Exception('Environment variable "%s" ' 76*8975f5c5SAndroid Build Coastguard Worker 'required to be set to valid path' % required) 77*8975f5c5SAndroid Build Coastguard Worker return env 78*8975f5c5SAndroid Build Coastguard Worker 79*8975f5c5SAndroid Build Coastguard Worker 80*8975f5c5SAndroid Build Coastguard Workerdef _DetectVisualStudioPath(): 81*8975f5c5SAndroid Build Coastguard Worker """Return path to the installed Visual Studio. 82*8975f5c5SAndroid Build Coastguard Worker """ 83*8975f5c5SAndroid Build Coastguard Worker 84*8975f5c5SAndroid Build Coastguard Worker # Use the code in build/vs_toolchain.py to avoid duplicating code. 85*8975f5c5SAndroid Build Coastguard Worker chromium_dir = os.path.abspath(os.path.join(SCRIPT_DIR, '..', '..', '..')) 86*8975f5c5SAndroid Build Coastguard Worker sys.path.append(os.path.join(chromium_dir, 'build')) 87*8975f5c5SAndroid Build Coastguard Worker import vs_toolchain 88*8975f5c5SAndroid Build Coastguard Worker return vs_toolchain.DetectVisualStudioPath() 89*8975f5c5SAndroid Build Coastguard Worker 90*8975f5c5SAndroid Build Coastguard Worker 91*8975f5c5SAndroid Build Coastguard Workerdef _LoadEnvFromBat(args): 92*8975f5c5SAndroid Build Coastguard Worker """Given a bat command, runs it and returns env vars set by it.""" 93*8975f5c5SAndroid Build Coastguard Worker args = args[:] 94*8975f5c5SAndroid Build Coastguard Worker args.extend(('&&', 'set')) 95*8975f5c5SAndroid Build Coastguard Worker popen = subprocess.Popen( 96*8975f5c5SAndroid Build Coastguard Worker args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 97*8975f5c5SAndroid Build Coastguard Worker variables, _ = popen.communicate() 98*8975f5c5SAndroid Build Coastguard Worker if popen.returncode != 0: 99*8975f5c5SAndroid Build Coastguard Worker raise Exception('"%s" failed with error %d' % (args, popen.returncode)) 100*8975f5c5SAndroid Build Coastguard Worker return variables.decode(errors='ignore') 101*8975f5c5SAndroid Build Coastguard Worker 102*8975f5c5SAndroid Build Coastguard Worker 103*8975f5c5SAndroid Build Coastguard Workerdef _LoadToolchainEnv(cpu, toolchain_root, sdk_dir, target_store): 104*8975f5c5SAndroid Build Coastguard Worker """Returns a dictionary with environment variables that must be set while 105*8975f5c5SAndroid Build Coastguard Worker running binaries from the toolchain (e.g. INCLUDE and PATH for cl.exe).""" 106*8975f5c5SAndroid Build Coastguard Worker # Check if we are running in the SDK command line environment and use 107*8975f5c5SAndroid Build Coastguard Worker # the setup script from the SDK if so. |cpu| should be either 108*8975f5c5SAndroid Build Coastguard Worker # 'x86' or 'x64' or 'arm' or 'arm64'. 109*8975f5c5SAndroid Build Coastguard Worker assert cpu in ('x86', 'x64', 'arm', 'arm64') 110*8975f5c5SAndroid Build Coastguard Worker if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', 1))) and sdk_dir: 111*8975f5c5SAndroid Build Coastguard Worker # Load environment from json file. 112*8975f5c5SAndroid Build Coastguard Worker env = os.path.normpath(os.path.join(sdk_dir, 'bin/SetEnv.%s.json' % cpu)) 113*8975f5c5SAndroid Build Coastguard Worker env = json.load(open(env))['env'] 114*8975f5c5SAndroid Build Coastguard Worker if env['VSINSTALLDIR'] == [["..", "..\\"]]: 115*8975f5c5SAndroid Build Coastguard Worker # Old-style paths were relative to the win_sdk\bin directory. 116*8975f5c5SAndroid Build Coastguard Worker json_relative_dir = os.path.join(sdk_dir, 'bin') 117*8975f5c5SAndroid Build Coastguard Worker else: 118*8975f5c5SAndroid Build Coastguard Worker # New-style paths are relative to the toolchain directory. 119*8975f5c5SAndroid Build Coastguard Worker json_relative_dir = toolchain_root 120*8975f5c5SAndroid Build Coastguard Worker for k in env: 121*8975f5c5SAndroid Build Coastguard Worker entries = [os.path.join(*([json_relative_dir] + e)) for e in env[k]] 122*8975f5c5SAndroid Build Coastguard Worker # clang-cl wants INCLUDE to be ;-separated even on non-Windows, 123*8975f5c5SAndroid Build Coastguard Worker # lld-link wants LIB to be ;-separated even on non-Windows. Path gets :. 124*8975f5c5SAndroid Build Coastguard Worker # The separator for INCLUDE here must match the one used in main() below. 125*8975f5c5SAndroid Build Coastguard Worker sep = os.pathsep if k == 'PATH' else ';' 126*8975f5c5SAndroid Build Coastguard Worker env[k] = sep.join(entries) 127*8975f5c5SAndroid Build Coastguard Worker # PATH is a bit of a special case, it's in addition to the current PATH. 128*8975f5c5SAndroid Build Coastguard Worker env['PATH'] = env['PATH'] + os.pathsep + os.environ['PATH'] 129*8975f5c5SAndroid Build Coastguard Worker # Augment with the current env to pick up TEMP and friends. 130*8975f5c5SAndroid Build Coastguard Worker for k in os.environ: 131*8975f5c5SAndroid Build Coastguard Worker if k not in env: 132*8975f5c5SAndroid Build Coastguard Worker env[k] = os.environ[k] 133*8975f5c5SAndroid Build Coastguard Worker 134*8975f5c5SAndroid Build Coastguard Worker varlines = [] 135*8975f5c5SAndroid Build Coastguard Worker for k in sorted(env.keys()): 136*8975f5c5SAndroid Build Coastguard Worker varlines.append('%s=%s' % (str(k), str(env[k]))) 137*8975f5c5SAndroid Build Coastguard Worker variables = '\n'.join(varlines) 138*8975f5c5SAndroid Build Coastguard Worker 139*8975f5c5SAndroid Build Coastguard Worker # Check that the json file contained the same environment as the .cmd file. 140*8975f5c5SAndroid Build Coastguard Worker if sys.platform in ('win32', 'cygwin'): 141*8975f5c5SAndroid Build Coastguard Worker script = os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.cmd')) 142*8975f5c5SAndroid Build Coastguard Worker arg = '/' + cpu 143*8975f5c5SAndroid Build Coastguard Worker json_env = _ExtractImportantEnvironment(variables) 144*8975f5c5SAndroid Build Coastguard Worker cmd_env = _ExtractImportantEnvironment(_LoadEnvFromBat([script, arg])) 145*8975f5c5SAndroid Build Coastguard Worker assert _LowercaseDict(json_env) == _LowercaseDict(cmd_env) 146*8975f5c5SAndroid Build Coastguard Worker else: 147*8975f5c5SAndroid Build Coastguard Worker if 'GYP_MSVS_OVERRIDE_PATH' not in os.environ: 148*8975f5c5SAndroid Build Coastguard Worker os.environ['GYP_MSVS_OVERRIDE_PATH'] = _DetectVisualStudioPath() 149*8975f5c5SAndroid Build Coastguard Worker # We only support x64-hosted tools. 150*8975f5c5SAndroid Build Coastguard Worker script_path = os.path.normpath(os.path.join( 151*8975f5c5SAndroid Build Coastguard Worker os.environ['GYP_MSVS_OVERRIDE_PATH'], 152*8975f5c5SAndroid Build Coastguard Worker 'VC/vcvarsall.bat')) 153*8975f5c5SAndroid Build Coastguard Worker if not os.path.exists(script_path): 154*8975f5c5SAndroid Build Coastguard Worker # vcvarsall.bat for VS 2017 fails if run after running vcvarsall.bat from 155*8975f5c5SAndroid Build Coastguard Worker # VS 2013 or VS 2015. Fix this by clearing the vsinstalldir environment 156*8975f5c5SAndroid Build Coastguard Worker # variable. Since vcvarsall.bat appends to the INCLUDE, LIB, and LIBPATH 157*8975f5c5SAndroid Build Coastguard Worker # environment variables we need to clear those to avoid getting double 158*8975f5c5SAndroid Build Coastguard Worker # entries when vcvarsall.bat has been run before gn gen. vcvarsall.bat 159*8975f5c5SAndroid Build Coastguard Worker # also adds to PATH, but there is no clean way of clearing that and it 160*8975f5c5SAndroid Build Coastguard Worker # doesn't seem to cause problems. 161*8975f5c5SAndroid Build Coastguard Worker if 'VSINSTALLDIR' in os.environ: 162*8975f5c5SAndroid Build Coastguard Worker del os.environ['VSINSTALLDIR'] 163*8975f5c5SAndroid Build Coastguard Worker if 'INCLUDE' in os.environ: 164*8975f5c5SAndroid Build Coastguard Worker del os.environ['INCLUDE'] 165*8975f5c5SAndroid Build Coastguard Worker if 'LIB' in os.environ: 166*8975f5c5SAndroid Build Coastguard Worker del os.environ['LIB'] 167*8975f5c5SAndroid Build Coastguard Worker if 'LIBPATH' in os.environ: 168*8975f5c5SAndroid Build Coastguard Worker del os.environ['LIBPATH'] 169*8975f5c5SAndroid Build Coastguard Worker other_path = os.path.normpath(os.path.join( 170*8975f5c5SAndroid Build Coastguard Worker os.environ['GYP_MSVS_OVERRIDE_PATH'], 171*8975f5c5SAndroid Build Coastguard Worker 'VC/Auxiliary/Build/vcvarsall.bat')) 172*8975f5c5SAndroid Build Coastguard Worker if not os.path.exists(other_path): 173*8975f5c5SAndroid Build Coastguard Worker raise Exception('%s is missing - make sure VC++ tools are installed.' % 174*8975f5c5SAndroid Build Coastguard Worker script_path) 175*8975f5c5SAndroid Build Coastguard Worker script_path = other_path 176*8975f5c5SAndroid Build Coastguard Worker cpu_arg = "amd64" 177*8975f5c5SAndroid Build Coastguard Worker if (cpu != 'x64'): 178*8975f5c5SAndroid Build Coastguard Worker # x64 is default target CPU thus any other CPU requires a target set 179*8975f5c5SAndroid Build Coastguard Worker cpu_arg += '_' + cpu 180*8975f5c5SAndroid Build Coastguard Worker args = [script_path, cpu_arg, ] 181*8975f5c5SAndroid Build Coastguard Worker # Store target must come before any SDK version declaration 182*8975f5c5SAndroid Build Coastguard Worker if (target_store): 183*8975f5c5SAndroid Build Coastguard Worker args.append('store') 184*8975f5c5SAndroid Build Coastguard Worker # Explicitly specifying the SDK version to build with to avoid accidentally 185*8975f5c5SAndroid Build Coastguard Worker # building with a new and untested SDK. This should stay in sync with the 186*8975f5c5SAndroid Build Coastguard Worker # packaged toolchain in build/vs_toolchain.py. 187*8975f5c5SAndroid Build Coastguard Worker args.append(SDK_VERSION) 188*8975f5c5SAndroid Build Coastguard Worker variables = _LoadEnvFromBat(args) 189*8975f5c5SAndroid Build Coastguard Worker return _ExtractImportantEnvironment(variables) 190*8975f5c5SAndroid Build Coastguard Worker 191*8975f5c5SAndroid Build Coastguard Worker 192*8975f5c5SAndroid Build Coastguard Workerdef _FormatAsEnvironmentBlock(envvar_dict): 193*8975f5c5SAndroid Build Coastguard Worker """Format as an 'environment block' directly suitable for CreateProcess. 194*8975f5c5SAndroid Build Coastguard Worker Briefly this is a list of key=value\0, terminated by an additional \0. See 195*8975f5c5SAndroid Build Coastguard Worker CreateProcess documentation for more details.""" 196*8975f5c5SAndroid Build Coastguard Worker block = '' 197*8975f5c5SAndroid Build Coastguard Worker nul = '\0' 198*8975f5c5SAndroid Build Coastguard Worker for key, value in envvar_dict.items(): 199*8975f5c5SAndroid Build Coastguard Worker block += key + '=' + value + nul 200*8975f5c5SAndroid Build Coastguard Worker block += nul 201*8975f5c5SAndroid Build Coastguard Worker return block 202*8975f5c5SAndroid Build Coastguard Worker 203*8975f5c5SAndroid Build Coastguard Worker 204*8975f5c5SAndroid Build Coastguard Workerdef _LowercaseDict(d): 205*8975f5c5SAndroid Build Coastguard Worker """Returns a copy of `d` with both key and values lowercased. 206*8975f5c5SAndroid Build Coastguard Worker 207*8975f5c5SAndroid Build Coastguard Worker Args: 208*8975f5c5SAndroid Build Coastguard Worker d: dict to lowercase (e.g. {'A': 'BcD'}). 209*8975f5c5SAndroid Build Coastguard Worker 210*8975f5c5SAndroid Build Coastguard Worker Returns: 211*8975f5c5SAndroid Build Coastguard Worker A dict with both keys and values lowercased (e.g.: {'a': 'bcd'}). 212*8975f5c5SAndroid Build Coastguard Worker """ 213*8975f5c5SAndroid Build Coastguard Worker return {k.lower(): d[k].lower() for k in d} 214*8975f5c5SAndroid Build Coastguard Worker 215*8975f5c5SAndroid Build Coastguard Worker 216*8975f5c5SAndroid Build Coastguard Workerdef FindFileInEnvList(env, env_name, separator, file_name, optional=False): 217*8975f5c5SAndroid Build Coastguard Worker parts = env[env_name].split(separator) 218*8975f5c5SAndroid Build Coastguard Worker for path in parts: 219*8975f5c5SAndroid Build Coastguard Worker if os.path.exists(os.path.join(path, file_name)): 220*8975f5c5SAndroid Build Coastguard Worker return os.path.realpath(path) 221*8975f5c5SAndroid Build Coastguard Worker assert optional, "%s is not found in %s:\n%s\nCheck if it is installed." % ( 222*8975f5c5SAndroid Build Coastguard Worker file_name, env_name, '\n'.join(parts)) 223*8975f5c5SAndroid Build Coastguard Worker return '' 224*8975f5c5SAndroid Build Coastguard Worker 225*8975f5c5SAndroid Build Coastguard Worker 226*8975f5c5SAndroid Build Coastguard Workerdef main(): 227*8975f5c5SAndroid Build Coastguard Worker if len(sys.argv) != 7: 228*8975f5c5SAndroid Build Coastguard Worker print('Usage setup_toolchain.py ' 229*8975f5c5SAndroid Build Coastguard Worker '<visual studio path> <win sdk path> ' 230*8975f5c5SAndroid Build Coastguard Worker '<runtime dirs> <target_os> <target_cpu> ' 231*8975f5c5SAndroid Build Coastguard Worker '<environment block name|none>') 232*8975f5c5SAndroid Build Coastguard Worker sys.exit(2) 233*8975f5c5SAndroid Build Coastguard Worker # toolchain_root and win_sdk_path are only read if the hermetic Windows 234*8975f5c5SAndroid Build Coastguard Worker # toolchain is set, that is if DEPOT_TOOLS_WIN_TOOLCHAIN is not set to 0. 235*8975f5c5SAndroid Build Coastguard Worker # With the hermetic Windows toolchain, the visual studio path in argv[1] 236*8975f5c5SAndroid Build Coastguard Worker # is the root of the Windows toolchain directory. 237*8975f5c5SAndroid Build Coastguard Worker toolchain_root = sys.argv[1] 238*8975f5c5SAndroid Build Coastguard Worker win_sdk_path = sys.argv[2] 239*8975f5c5SAndroid Build Coastguard Worker 240*8975f5c5SAndroid Build Coastguard Worker runtime_dirs = sys.argv[3] 241*8975f5c5SAndroid Build Coastguard Worker target_os = sys.argv[4] 242*8975f5c5SAndroid Build Coastguard Worker target_cpu = sys.argv[5] 243*8975f5c5SAndroid Build Coastguard Worker environment_block_name = sys.argv[6] 244*8975f5c5SAndroid Build Coastguard Worker if (environment_block_name == 'none'): 245*8975f5c5SAndroid Build Coastguard Worker environment_block_name = '' 246*8975f5c5SAndroid Build Coastguard Worker 247*8975f5c5SAndroid Build Coastguard Worker if (target_os == 'winuwp'): 248*8975f5c5SAndroid Build Coastguard Worker target_store = True 249*8975f5c5SAndroid Build Coastguard Worker else: 250*8975f5c5SAndroid Build Coastguard Worker target_store = False 251*8975f5c5SAndroid Build Coastguard Worker 252*8975f5c5SAndroid Build Coastguard Worker cpus = ('x86', 'x64', 'arm', 'arm64') 253*8975f5c5SAndroid Build Coastguard Worker assert target_cpu in cpus 254*8975f5c5SAndroid Build Coastguard Worker vc_bin_dir = '' 255*8975f5c5SAndroid Build Coastguard Worker include = '' 256*8975f5c5SAndroid Build Coastguard Worker lib = '' 257*8975f5c5SAndroid Build Coastguard Worker 258*8975f5c5SAndroid Build Coastguard Worker def relflag(s): # Make s relative to builddir when cwd and sdk on same drive. 259*8975f5c5SAndroid Build Coastguard Worker try: 260*8975f5c5SAndroid Build Coastguard Worker return os.path.relpath(s).replace('\\', '/') 261*8975f5c5SAndroid Build Coastguard Worker except ValueError: 262*8975f5c5SAndroid Build Coastguard Worker return s 263*8975f5c5SAndroid Build Coastguard Worker 264*8975f5c5SAndroid Build Coastguard Worker def q(s): # Quote s if it contains spaces or other weird characters. 265*8975f5c5SAndroid Build Coastguard Worker return s if re.match(r'^[a-zA-Z0-9._/\\:-]*$', s) else '"' + s + '"' 266*8975f5c5SAndroid Build Coastguard Worker 267*8975f5c5SAndroid Build Coastguard Worker for cpu in cpus: 268*8975f5c5SAndroid Build Coastguard Worker if cpu == target_cpu: 269*8975f5c5SAndroid Build Coastguard Worker # Extract environment variables for subprocesses. 270*8975f5c5SAndroid Build Coastguard Worker env = _LoadToolchainEnv(cpu, toolchain_root, win_sdk_path, target_store) 271*8975f5c5SAndroid Build Coastguard Worker env['PATH'] = runtime_dirs + os.pathsep + env['PATH'] 272*8975f5c5SAndroid Build Coastguard Worker 273*8975f5c5SAndroid Build Coastguard Worker vc_bin_dir = FindFileInEnvList(env, 'PATH', os.pathsep, 'cl.exe') 274*8975f5c5SAndroid Build Coastguard Worker 275*8975f5c5SAndroid Build Coastguard Worker # The separator for INCLUDE here must match the one used in 276*8975f5c5SAndroid Build Coastguard Worker # _LoadToolchainEnv() above. 277*8975f5c5SAndroid Build Coastguard Worker include = [p.replace('"', r'\"') for p in env['INCLUDE'].split(';') if p] 278*8975f5c5SAndroid Build Coastguard Worker include = list(map(relflag, include)) 279*8975f5c5SAndroid Build Coastguard Worker 280*8975f5c5SAndroid Build Coastguard Worker lib = [p.replace('"', r'\"') for p in env['LIB'].split(';') if p] 281*8975f5c5SAndroid Build Coastguard Worker lib = list(map(relflag, lib)) 282*8975f5c5SAndroid Build Coastguard Worker 283*8975f5c5SAndroid Build Coastguard Worker include_I = ['/I' + i for i in include] 284*8975f5c5SAndroid Build Coastguard Worker include_imsvc = ['-imsvc' + i for i in include] 285*8975f5c5SAndroid Build Coastguard Worker libpath_flags = ['-libpath:' + i for i in lib] 286*8975f5c5SAndroid Build Coastguard Worker 287*8975f5c5SAndroid Build Coastguard Worker if (environment_block_name != ''): 288*8975f5c5SAndroid Build Coastguard Worker env_block = _FormatAsEnvironmentBlock(env) 289*8975f5c5SAndroid Build Coastguard Worker with open(environment_block_name, 'w', encoding='utf8') as f: 290*8975f5c5SAndroid Build Coastguard Worker f.write(env_block) 291*8975f5c5SAndroid Build Coastguard Worker 292*8975f5c5SAndroid Build Coastguard Worker def ListToArgString(x): 293*8975f5c5SAndroid Build Coastguard Worker return gn_helpers.ToGNString(' '.join(q(i) for i in x)) 294*8975f5c5SAndroid Build Coastguard Worker 295*8975f5c5SAndroid Build Coastguard Worker def ListToArgList(x): 296*8975f5c5SAndroid Build Coastguard Worker return f'[{", ".join(gn_helpers.ToGNString(i) for i in x)}]' 297*8975f5c5SAndroid Build Coastguard Worker 298*8975f5c5SAndroid Build Coastguard Worker print('vc_bin_dir = ' + gn_helpers.ToGNString(vc_bin_dir)) 299*8975f5c5SAndroid Build Coastguard Worker assert include_I 300*8975f5c5SAndroid Build Coastguard Worker print(f'include_flags_I = {ListToArgString(include_I)}') 301*8975f5c5SAndroid Build Coastguard Worker print(f'include_flags_I_list = {ListToArgList(include_I)}') 302*8975f5c5SAndroid Build Coastguard Worker assert include_imsvc 303*8975f5c5SAndroid Build Coastguard Worker if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', 1))) and win_sdk_path: 304*8975f5c5SAndroid Build Coastguard Worker flags = ['/winsysroot' + relflag(toolchain_root)] 305*8975f5c5SAndroid Build Coastguard Worker print(f'include_flags_imsvc = {ListToArgString(flags)}') 306*8975f5c5SAndroid Build Coastguard Worker print(f'include_flags_imsvc_list = {ListToArgList(flags)}') 307*8975f5c5SAndroid Build Coastguard Worker else: 308*8975f5c5SAndroid Build Coastguard Worker print(f'include_flags_imsvc = {ListToArgString(include_imsvc)}') 309*8975f5c5SAndroid Build Coastguard Worker print(f'include_flags_imsvc_list = {ListToArgList(include_imsvc)}') 310*8975f5c5SAndroid Build Coastguard Worker print('paths = ' + gn_helpers.ToGNString(env['PATH'])) 311*8975f5c5SAndroid Build Coastguard Worker assert libpath_flags 312*8975f5c5SAndroid Build Coastguard Worker print(f'libpath_flags = {ListToArgString(libpath_flags)}') 313*8975f5c5SAndroid Build Coastguard Worker print(f'libpath_flags_list = {ListToArgList(libpath_flags)}') 314*8975f5c5SAndroid Build Coastguard Worker if bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', 1))) and win_sdk_path: 315*8975f5c5SAndroid Build Coastguard Worker flags = ['/winsysroot:' + relflag(toolchain_root)] 316*8975f5c5SAndroid Build Coastguard Worker print(f'libpath_lldlink_flags = {ListToArgString(flags)}') 317*8975f5c5SAndroid Build Coastguard Worker print(f'libpath_lldlink_flags_list = {ListToArgList(flags)}') 318*8975f5c5SAndroid Build Coastguard Worker else: 319*8975f5c5SAndroid Build Coastguard Worker print(f'libpath_lldlink_flags = {ListToArgString(libpath_flags)}') 320*8975f5c5SAndroid Build Coastguard Worker print(f'libpath_lldlink_flags_list = {ListToArgList(libpath_flags)}') 321*8975f5c5SAndroid Build Coastguard Worker 322*8975f5c5SAndroid Build Coastguard Worker 323*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__': 324*8975f5c5SAndroid Build Coastguard Worker main() 325