| #!/usr/bin/env python3 |
| # -*- coding: utf-8 -*- |
| # Copyright 2019 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Build script that builds a binary from a bundle.""" |
| |
| from __future__ import print_function |
| |
| import argparse |
| import os.path |
| import re |
| import subprocess |
| import sys |
| |
| |
| def parse_args(): |
| parser = argparse.ArgumentParser() |
| parser.add_argument( |
| '--config', |
| required=True, |
| choices=['cros.hardened', 'cros.nonhardened', 'cros.host', 'android']) |
| parser.add_argument('--use_ccache', required=True, choices=['true', 'false']) |
| parser.add_argument( |
| '--use_llvm_next', required=True, choices=['true', 'false']) |
| parser.add_argument('--output_file', required=True, type=str) |
| parser.add_argument( |
| '--static', |
| choices=['true', 'false'], |
| help='If true, produce a static wrapper. Autodetects a good value if ' |
| 'unspecified.') |
| args = parser.parse_args() |
| |
| if args.static is None: |
| args.static = 'cros' not in args.config |
| else: |
| args.static = args.static == 'true' |
| |
| return args |
| |
| |
| def calc_go_args(args, version, build_dir): |
| ldFlags = [ |
| '-X', |
| 'main.ConfigName=' + args.config, |
| '-X', |
| 'main.UseCCache=' + args.use_ccache, |
| '-X', |
| 'main.UseLlvmNext=' + args.use_llvm_next, |
| '-X', |
| 'main.Version=' + version, |
| ] |
| |
| # If the wrapper is intended for Chrome OS, we need to use libc's exec. |
| extra_args = [] |
| if not args.static: |
| extra_args += ['-tags', 'libc_exec'] |
| |
| if args.config == 'android': |
| # If android_llvm_next_flags.go DNE, we'll get an obscure "no |
| # llvmNextFlags" build error; complaining here is clearer. |
| if not os.path.exists( |
| os.path.join(build_dir, 'android_llvm_next_flags.go')): |
| sys.exit('In order to build the Android wrapper, you must have a local ' |
| 'android_llvm_next_flags.go file; please see ' |
| 'cros_llvm_next_flags.go.') |
| extra_args += ['-tags', 'android_llvm_next_flags'] |
| |
| return [ |
| 'go', 'build', '-o', |
| os.path.abspath(args.output_file), '-ldflags', ' '.join(ldFlags) |
| ] + extra_args |
| |
| |
| def read_version(build_dir): |
| version_path = os.path.join(build_dir, 'VERSION') |
| if os.path.exists(version_path): |
| with open(version_path, 'r') as r: |
| return r.read() |
| |
| last_commit_msg = subprocess.check_output( |
| ['git', '-C', build_dir, 'log', '-1', '--pretty=%B'], encoding='utf-8') |
| # Use last found change id to support reverts as well. |
| change_ids = re.findall(r'Change-Id: (\w+)', last_commit_msg) |
| if not change_ids: |
| sys.exit("Couldn't find Change-Id in last commit message.") |
| return change_ids[-1] |
| |
| |
| def main(): |
| args = parse_args() |
| build_dir = os.path.dirname(__file__) |
| version = read_version(build_dir) |
| # Note: Go does not support using absolute package names. |
| # So we run go inside the directory of the the build file. |
| sys.exit( |
| subprocess.call(calc_go_args(args, version, build_dir), cwd=build_dir)) |
| |
| |
| if __name__ == '__main__': |
| main() |