meson/mesonbuild/scripts/cmake_run_ctgt.py

103 lines
3.2 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
import argparse
import subprocess
import shutil
import sys
from pathlib import Path
2020-08-30 03:23:43 +08:00
import typing as T
2020-08-30 03:23:43 +08:00
def run(argsv: T.List[str]) -> int:
commands = [[]] # type: T.List[T.List[str]]
SEPARATOR = ';;;'
# Generate CMD parameters
parser = argparse.ArgumentParser(description='Wrapper for add_custom_command')
parser.add_argument('-d', '--directory', type=str, metavar='D', required=True, help='Working directory to cwd to')
parser.add_argument('-o', '--outputs', nargs='+', metavar='O', required=True, help='Expected output files')
parser.add_argument('-O', '--original-outputs', nargs='*', metavar='O', default=[], help='Output files expected by CMake')
parser.add_argument('commands', nargs=argparse.REMAINDER, help='A "{}" seperated list of commands'.format(SEPARATOR))
# Parse
args = parser.parse_args(argsv)
2020-08-30 03:23:43 +08:00
directory = Path(args.directory)
dummy_target = None
if len(args.outputs) == 1 and len(args.original_outputs) == 0:
2020-08-30 03:23:43 +08:00
dummy_target = Path(args.outputs[0])
elif len(args.outputs) != len(args.original_outputs):
print('Length of output list and original output list differ')
2020-08-30 03:23:43 +08:00
return 1
for i in args.commands:
if i == SEPARATOR:
commands += [[]]
continue
i = i.replace('"', '') # Remove lefover quotes
commands[-1] += [i]
# Execute
for i in commands:
# Skip empty lists
if not i:
continue
cmd = []
stdout = None
stderr = None
capture_file = ''
for j in i:
if j in ['>', '>>']:
stdout = subprocess.PIPE
continue
elif j in ['&>', '&>>']:
stdout = subprocess.PIPE
stderr = subprocess.STDOUT
continue
if stdout is not None or stderr is not None:
capture_file += j
else:
cmd += [j]
try:
2020-08-30 03:23:43 +08:00
directory.mkdir(parents=True, exist_ok=True)
2020-08-30 03:23:43 +08:00
res = subprocess.run(cmd, stdout=stdout, stderr=stderr, cwd=str(directory), check=True)
if capture_file:
2020-08-30 03:23:43 +08:00
out_file = directory / capture_file
out_file.write_bytes(res.stdout)
except subprocess.CalledProcessError:
2020-08-30 03:23:43 +08:00
return 1
if dummy_target:
2020-08-30 03:23:43 +08:00
dummy_target.touch()
return 0
# Copy outputs
2020-08-30 03:23:43 +08:00
zipped_outputs = zip([Path(x) for x in args.outputs], [Path(x) for x in args.original_outputs])
for expected, generated in zipped_outputs:
do_copy = False
2020-08-30 03:23:43 +08:00
if not expected.exists():
if not generated.exists():
print('Unable to find generated file. This can cause the build to fail:')
print(generated)
do_copy = False
else:
do_copy = True
2020-08-30 03:23:43 +08:00
elif generated.exists():
if generated.stat().st_mtime > expected.stat().st_mtime:
do_copy = True
if do_copy:
2020-08-30 03:23:43 +08:00
if expected.exists():
expected.unlink()
shutil.copyfile(str(generated), str(expected))
return 0
if __name__ == '__main__':
2020-08-30 03:23:43 +08:00
sys.exit(run(sys.argv[1:]))