| #!/usr/bin/env python |
| |
| # Copyright 2020 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. |
| |
| """Strip arm64e architecture from a binary if present.""" |
| |
| import argparse |
| import os |
| import shutil |
| import subprocess |
| import sys |
| |
| |
| def check_output(command): |
| """Returns the output from |command| or propagates error, quitting script.""" |
| process = subprocess.Popen( |
| command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| outs, errs = process.communicate() |
| if process.returncode: |
| sys.stderr.write('error: command failed with retcode %d: %s\n\n' % |
| (process.returncode, ' '.join(map(repr, command)))) |
| sys.stderr.write(errs) |
| sys.exit(process.returncode) |
| return outs |
| |
| |
| def check_call(command): |
| """Invokes |command| or propagates error.""" |
| check_output(command) |
| |
| |
| def parse_args(args): |
| """Parses the command-line.""" |
| parser = argparse.ArgumentParser() |
| parser.add_argument('--input', required=True, help='Path to input binary') |
| parser.add_argument('--output', required=True, help='Path to output binary') |
| return parser.parse_args(args) |
| |
| |
| def get_archs(path): |
| """Extracts the architectures present in binary at |path|.""" |
| outputs = check_output(["xcrun", "lipo", "-info", os.path.abspath(path)]) |
| return outputs.split(': ')[-1].split() |
| |
| |
| def main(args): |
| parsed = parse_args(args) |
| |
| outdir = os.path.dirname(parsed.output) |
| if not os.path.isdir(outdir): |
| os.makedirs(outdir) |
| |
| if os.path.exists(parsed.output): |
| os.unlink(parsed.output) |
| |
| # As "lipo" fails with an error if asked to remove an architecture that is |
| # not included, only use it if "arm64e" is present in the binary. Otherwise |
| # simply copy the file. |
| if 'arm64e' in get_archs(parsed.input): |
| check_output([ |
| "xcrun", "lipo", "-remove", "arm64e", "-output", |
| os.path.abspath(parsed.output), |
| os.path.abspath(parsed.input) |
| ]) |
| else: |
| shutil.copy(parsed.input, parsed.output) |
| |
| |
| if __name__ == '__main__': |
| main(sys.argv[1:]) |