xref: /llvm-project/libcxx/utils/run.py (revision d2b71c7a1aef52a500909283aab5c968f71c9ff4)
1f998e0d6SLouis Dionne#!/usr/bin/env python
21261f1b9SVedant Kumar# ===----------------------------------------------------------------------===##
31261f1b9SVedant Kumar#
41261f1b9SVedant Kumar# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
51261f1b9SVedant Kumar# See https://llvm.org/LICENSE.txt for license information.
61261f1b9SVedant Kumar# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
71261f1b9SVedant Kumar#
81261f1b9SVedant Kumar# ===----------------------------------------------------------------------===##
91261f1b9SVedant Kumar
101261f1b9SVedant Kumar"""run.py is a utility for running a program.
111261f1b9SVedant Kumar
121261f1b9SVedant KumarIt can perform code signing, forward arguments to the program, and return the
131261f1b9SVedant Kumarprogram's error code.
141261f1b9SVedant Kumar"""
151261f1b9SVedant Kumar
160feaf22cSLouis Dionneimport argparse
1734ee3d91SMartin Storsjöimport os
1834ee3d91SMartin Storsjöimport platform
191261f1b9SVedant Kumarimport subprocess
201261f1b9SVedant Kumar
211261f1b9SVedant Kumar
221261f1b9SVedant Kumardef main():
23e22fe98dSLouis Dionne    parser = argparse.ArgumentParser()
247bfaa0f0STobias Hieta    parser.add_argument("--execdir", type=str, required=True)
257bfaa0f0STobias Hieta    parser.add_argument("--codesign_identity", type=str, required=False, default=None)
267bfaa0f0STobias Hieta    parser.add_argument("--env", type=str, nargs="*", required=False, default=[])
277bfaa0f0STobias Hieta    parser.add_argument(
287bfaa0f0STobias Hieta        "--prepend_env", type=str, nargs="*", required=False, default=[]
297bfaa0f0STobias Hieta    )
303980e895SAlex Richardson    parser.add_argument("command", nargs=argparse.ONE_OR_MORE)
313980e895SAlex Richardson    args = parser.parse_args()
323980e895SAlex Richardson    commandLine = args.command
331261f1b9SVedant Kumar
34232d3a3eSLouis Dionne    # HACK:
35232d3a3eSLouis Dionne    # If an argument is a file that ends in `.tmp.exe`, assume it is the name
36232d3a3eSLouis Dionne    # of an executable generated by a test file. We call these test-executables
37232d3a3eSLouis Dionne    # below. This allows us to do custom processing like codesigning test-executables.
38232d3a3eSLouis Dionne    # It's also possible for there to be no such executable, for example in the case
39232d3a3eSLouis Dionne    # of a .sh.cpp test.
407bfaa0f0STobias Hieta    isTestExe = lambda exe: exe.endswith(".tmp.exe") and os.path.exists(exe)
41232d3a3eSLouis Dionne
42232d3a3eSLouis Dionne    # Do any necessary codesigning of test-executables found in the command line.
43e22fe98dSLouis Dionne    if args.codesign_identity:
44232d3a3eSLouis Dionne        for exe in filter(isTestExe, commandLine):
45*d2b71c7aSLouis Dionne            codesign = ["codesign", "-f", "-s", args.codesign_identity, exe]
46*d2b71c7aSLouis Dionne            subprocess.check_call(codesign, env={})
471261f1b9SVedant Kumar
48e22fe98dSLouis Dionne    # Extract environment variables into a dictionary
497bfaa0f0STobias Hieta    env = {k: v for (k, v) in map(lambda s: s.split("=", 1), args.env)}
50ba3bddb6SMartin Storsjö
51ba3bddb6SMartin Storsjö    # Set environment variables where we prepend the given value to the
52ba3bddb6SMartin Storsjö    # existing environment variable.
537bfaa0f0STobias Hieta    for (k, v) in map(lambda s: s.split("=", 1), args.prepend_env):
54ba3bddb6SMartin Storsjö        if k in os.environ:
55ba3bddb6SMartin Storsjö            v = v + os.pathsep + os.environ[k]
56ba3bddb6SMartin Storsjö        env[k] = v
57ba3bddb6SMartin Storsjö
587bfaa0f0STobias Hieta    if platform.system() == "Windows":
5934ee3d91SMartin Storsjö        # Pass some extra variables through on Windows:
6034ee3d91SMartin Storsjö        # COMSPEC is needed for running subprocesses via std::system().
617bfaa0f0STobias Hieta        if "COMSPEC" in os.environ:
627bfaa0f0STobias Hieta            env["COMSPEC"] = os.environ.get("COMSPEC")
6334ee3d91SMartin Storsjö        # TEMP is needed for placing temp files in a sensible directory.
647bfaa0f0STobias Hieta        if "TEMP" in os.environ:
657bfaa0f0STobias Hieta            env["TEMP"] = os.environ.get("TEMP")
66e22fe98dSLouis Dionne
675eb8d45aSLouis Dionne    # Run the command line with the given environment in the execution directory.
68f1a96de1SLouis Dionne    return subprocess.call(commandLine, cwd=args.execdir, env=env, shell=False)
693fefda6eSLouis Dionne
701261f1b9SVedant Kumar
717bfaa0f0STobias Hietaif __name__ == "__main__":
721261f1b9SVedant Kumar    exit(main())
73