1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70

build / config / ios / strip_arm64e.py [blame]

# Copyright 2020 The Chromium Authors
# 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.decode('UTF-8', errors='ignore'))
    sys.exit(process.returncode)
  return outs.decode('UTF-8')


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')
  parser.add_argument('--xcode-version', required=True, help='Version of Xcode')
  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:])