diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/libwebrtc/build/util/generate_wrapper.py | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/build/util/generate_wrapper.py')
-rwxr-xr-x | third_party/libwebrtc/build/util/generate_wrapper.py | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/third_party/libwebrtc/build/util/generate_wrapper.py b/third_party/libwebrtc/build/util/generate_wrapper.py new file mode 100755 index 0000000000..07167e8655 --- /dev/null +++ b/third_party/libwebrtc/build/util/generate_wrapper.py @@ -0,0 +1,217 @@ +#!/usr/bin/env vpython +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Wraps an executable and any provided arguments into an executable script.""" + +import argparse +import os +import sys +import textwrap + + +# The bash template passes the python script into vpython via stdin. +# The interpreter doesn't know about the script, so we have bash +# inject the script location. +BASH_TEMPLATE = textwrap.dedent("""\ + #!/usr/bin/env {vpython} + _SCRIPT_LOCATION = __file__ + {script} + """) + + +# The batch template reruns the batch script with vpython, with the -x +# flag instructing the interpreter to ignore the first line. The interpreter +# knows about the (batch) script in this case, so it can get the file location +# directly. +BATCH_TEMPLATE = textwrap.dedent("""\ + @SETLOCAL ENABLEDELAYEDEXPANSION \ + & {vpython}.bat -x "%~f0" %* \ + & EXIT /B !ERRORLEVEL! + _SCRIPT_LOCATION = __file__ + {script} + """) + + +SCRIPT_TEMPLATES = { + 'bash': BASH_TEMPLATE, + 'batch': BATCH_TEMPLATE, +} + + +PY_TEMPLATE = textwrap.dedent("""\ + import os + import re + import subprocess + import sys + + _WRAPPED_PATH_RE = re.compile(r'@WrappedPath\(([^)]+)\)') + _PATH_TO_OUTPUT_DIR = '{path_to_output_dir}' + _SCRIPT_DIR = os.path.dirname(os.path.realpath(_SCRIPT_LOCATION)) + + + def ExpandWrappedPath(arg): + m = _WRAPPED_PATH_RE.match(arg) + if m: + relpath = os.path.join( + os.path.relpath(_SCRIPT_DIR), _PATH_TO_OUTPUT_DIR, m.group(1)) + npath = os.path.normpath(relpath) + if os.path.sep not in npath: + # If the original path points to something in the current directory, + # returning the normalized version of it can be a problem. + # normpath() strips off the './' part of the path + # ('./foo' becomes 'foo'), which can be a problem if the result + # is passed to something like os.execvp(); in that case + # osexecvp() will search $PATH for the executable, rather than + # just execing the arg directly, and if '.' isn't in $PATH, this + # results in an error. + # + # So, we need to explicitly return './foo' (or '.\\foo' on windows) + # instead of 'foo'. + # + # Hopefully there are no cases where this causes a problem; if + # there are, we will either need to change the interface to + # WrappedPath() somehow to distinguish between the two, or + # somehow ensure that the wrapped executable doesn't hit cases + # like this. + return '.' + os.path.sep + npath + return npath + return arg + + + def ExpandWrappedPaths(args): + for i, arg in enumerate(args): + args[i] = ExpandWrappedPath(arg) + return args + + + def FindIsolatedOutdir(raw_args): + outdir = None + i = 0 + remaining_args = [] + while i < len(raw_args): + if raw_args[i] == '--isolated-outdir' and i < len(raw_args)-1: + outdir = raw_args[i+1] + i += 2 + elif raw_args[i].startswith('--isolated-outdir='): + outdir = raw_args[i][len('--isolated-outdir='):] + i += 1 + else: + remaining_args.append(raw_args[i]) + i += 1 + if not outdir and 'ISOLATED_OUTDIR' in os.environ: + outdir = os.environ['ISOLATED_OUTDIR'] + return outdir, remaining_args + + + def FilterIsolatedOutdirBasedArgs(outdir, args): + rargs = [] + i = 0 + while i < len(args): + if 'ISOLATED_OUTDIR' in args[i]: + if outdir: + # Rewrite the arg. + rargs.append(args[i].replace('${{ISOLATED_OUTDIR}}', + outdir).replace( + '$ISOLATED_OUTDIR', outdir)) + i += 1 + else: + # Simply drop the arg. + i += 1 + elif (not outdir and + args[i].startswith('-') and + '=' not in args[i] and + i < len(args) - 1 and + 'ISOLATED_OUTDIR' in args[i+1]): + # Parsing this case is ambiguous; if we're given + # `--foo $ISOLATED_OUTDIR` we can't tell if $ISOLATED_OUTDIR + # is meant to be the value of foo, or if foo takes no argument + # and $ISOLATED_OUTDIR is the first positional arg. + # + # We assume the former will be much more common, and so we + # need to drop --foo and $ISOLATED_OUTDIR. + i += 2 + else: + rargs.append(args[i]) + i += 1 + return rargs + + + def main(raw_args): + executable_path = ExpandWrappedPath('{executable_path}') + outdir, remaining_args = FindIsolatedOutdir(raw_args) + args = {executable_args} + args = FilterIsolatedOutdirBasedArgs(outdir, args) + executable_args = ExpandWrappedPaths(args) + cmd = [executable_path] + args + remaining_args + if executable_path.endswith('.py'): + cmd = [sys.executable] + cmd + return subprocess.call(cmd) + + + if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) + """) + + +def Wrap(args): + """Writes a wrapped script according to the provided arguments. + + Arguments: + args: an argparse.Namespace object containing command-line arguments + as parsed by a parser returned by CreateArgumentParser. + """ + path_to_output_dir = os.path.relpath( + args.output_directory, + os.path.dirname(args.wrapper_script)) + + with open(args.wrapper_script, 'w') as wrapper_script: + py_contents = PY_TEMPLATE.format( + path_to_output_dir=path_to_output_dir, + executable_path=str(args.executable), + executable_args=str(args.executable_args)) + template = SCRIPT_TEMPLATES[args.script_language] + wrapper_script.write( + template.format(script=py_contents, vpython=args.vpython)) + os.chmod(args.wrapper_script, 0o750) + + return 0 + + +def CreateArgumentParser(): + """Creates an argparse.ArgumentParser instance.""" + parser = argparse.ArgumentParser() + parser.add_argument( + '--executable', + help='Executable to wrap.') + parser.add_argument( + '--wrapper-script', + help='Path to which the wrapper script will be written.') + parser.add_argument( + '--output-directory', + help='Path to the output directory.') + parser.add_argument( + '--script-language', + choices=SCRIPT_TEMPLATES.keys(), + help='Language in which the wrapper script will be written.') + parser.add_argument('--use-vpython3', + dest='vpython', + action='store_const', + const='vpython3', + default='vpython', + help='Use vpython3 instead of vpython') + parser.add_argument( + 'executable_args', nargs='*', + help='Arguments to wrap into the executable.') + return parser + + +def main(raw_args): + parser = CreateArgumentParser() + args = parser.parse_args(raw_args) + return Wrap(args) + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) |