xref: /openbsd-src/gnu/llvm/libcxx/utils/run.py (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
1037e7968Spatrick#!/usr/bin/env python
246035553Spatrick#===----------------------------------------------------------------------===##
346035553Spatrick#
446035553Spatrick# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick# See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick#
846035553Spatrick#===----------------------------------------------------------------------===##
946035553Spatrick
1046035553Spatrick"""run.py is a utility for running a program.
1146035553Spatrick
1246035553SpatrickIt can perform code signing, forward arguments to the program, and return the
1346035553Spatrickprogram's error code.
1446035553Spatrick"""
1546035553Spatrick
16037e7968Spatrickimport argparse
17*76d0caaeSpatrickimport os
18*76d0caaeSpatrickimport platform
1946035553Spatrickimport subprocess
2046035553Spatrick
2146035553Spatrick
2246035553Spatrickdef main():
23037e7968Spatrick    parser = argparse.ArgumentParser()
24037e7968Spatrick    parser.add_argument('--execdir', type=str, required=True)
25037e7968Spatrick    parser.add_argument('--codesign_identity', type=str, required=False, default=None)
26037e7968Spatrick    parser.add_argument('--env', type=str, nargs='*', required=False, default=dict())
27*76d0caaeSpatrick    parser.add_argument("command", nargs=argparse.ONE_OR_MORE)
28*76d0caaeSpatrick    args = parser.parse_args()
29*76d0caaeSpatrick    commandLine = args.command
3046035553Spatrick
31*76d0caaeSpatrick    # HACK:
32*76d0caaeSpatrick    # If an argument is a file that ends in `.tmp.exe`, assume it is the name
33*76d0caaeSpatrick    # of an executable generated by a test file. We call these test-executables
34*76d0caaeSpatrick    # below. This allows us to do custom processing like codesigning test-executables.
35*76d0caaeSpatrick    # It's also possible for there to be no such executable, for example in the case
36*76d0caaeSpatrick    # of a .sh.cpp test.
37*76d0caaeSpatrick    isTestExe = lambda exe: exe.endswith('.tmp.exe') and os.path.exists(exe)
3846035553Spatrick
39*76d0caaeSpatrick    # Do any necessary codesigning of test-executables found in the command line.
40037e7968Spatrick    if args.codesign_identity:
41*76d0caaeSpatrick        for exe in filter(isTestExe, commandLine):
42*76d0caaeSpatrick            subprocess.check_call(['xcrun', 'codesign', '-f', '-s', args.codesign_identity, exe], env={})
4346035553Spatrick
44037e7968Spatrick    # Extract environment variables into a dictionary
45037e7968Spatrick    env = {k : v  for (k, v) in map(lambda s: s.split('=', 1), args.env)}
46*76d0caaeSpatrick    if platform.system() == 'Windows':
47*76d0caaeSpatrick        # Pass some extra variables through on Windows:
48*76d0caaeSpatrick        # COMSPEC is needed for running subprocesses via std::system().
49*76d0caaeSpatrick        if 'COMSPEC' in os.environ:
50*76d0caaeSpatrick            env['COMSPEC'] = os.environ.get('COMSPEC')
51*76d0caaeSpatrick        # TEMP is needed for placing temp files in a sensible directory.
52*76d0caaeSpatrick        if 'TEMP' in os.environ:
53*76d0caaeSpatrick            env['TEMP'] = os.environ.get('TEMP')
54037e7968Spatrick
55037e7968Spatrick    # Run the command line with the given environment in the execution directory.
56*76d0caaeSpatrick    return subprocess.call(commandLine, cwd=args.execdir, env=env, shell=False)
57037e7968Spatrick
5846035553Spatrick
5946035553Spatrickif __name__ == '__main__':
6046035553Spatrick    exit(main())
61