1#!/usr/bin/env python 2#===----------------------------------------------------------------------===## 3# 4# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5# See https://llvm.org/LICENSE.txt for license information. 6# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7# 8#===----------------------------------------------------------------------===## 9 10"""run.py is a utility for running a program. 11 12It can perform code signing, forward arguments to the program, and return the 13program's error code. 14""" 15 16import argparse 17import os 18import platform 19import subprocess 20import sys 21 22 23def main(): 24 parser = argparse.ArgumentParser() 25 parser.add_argument('--execdir', type=str, required=True) 26 parser.add_argument('--codesign_identity', type=str, required=False, default=None) 27 parser.add_argument('--env', type=str, nargs='*', required=False, default=dict()) 28 parser.add_argument("command", nargs=argparse.ONE_OR_MORE) 29 args = parser.parse_args() 30 commandLine = args.command 31 32 # HACK: 33 # If an argument is a file that ends in `.tmp.exe`, assume it is the name 34 # of an executable generated by a test file. We call these test-executables 35 # below. This allows us to do custom processing like codesigning test-executables. 36 # It's also possible for there to be no such executable, for example in the case 37 # of a .sh.cpp test. 38 isTestExe = lambda exe: exe.endswith('.tmp.exe') and os.path.exists(exe) 39 40 # Do any necessary codesigning of test-executables found in the command line. 41 if args.codesign_identity: 42 for exe in filter(isTestExe, commandLine): 43 subprocess.check_call(['xcrun', 'codesign', '-f', '-s', args.codesign_identity, exe], env={}) 44 45 # Extract environment variables into a dictionary 46 env = {k : v for (k, v) in map(lambda s: s.split('=', 1), args.env)} 47 if platform.system() == 'Windows': 48 # Pass some extra variables through on Windows: 49 # COMSPEC is needed for running subprocesses via std::system(). 50 if 'COMSPEC' in os.environ: 51 env['COMSPEC'] = os.environ.get('COMSPEC') 52 # TEMP is needed for placing temp files in a sensible directory. 53 if 'TEMP' in os.environ: 54 env['TEMP'] = os.environ.get('TEMP') 55 56 # Run the command line with the given environment in the execution directory. 57 return subprocess.call(commandLine, cwd=args.execdir, env=env, shell=False) 58 59 60if __name__ == '__main__': 61 exit(main()) 62