• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright 2019 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Build script that builds a binary from a bundle."""
8
9from __future__ import print_function
10
11import argparse
12import os.path
13import re
14import subprocess
15import sys
16
17
18def parse_args():
19  parser = argparse.ArgumentParser()
20  parser.add_argument(
21      '--config',
22      required=True,
23      choices=['cros.hardened', 'cros.nonhardened', 'cros.host', 'android'])
24  parser.add_argument('--use_ccache', required=True, choices=['true', 'false'])
25  parser.add_argument(
26      '--use_llvm_next', required=True, choices=['true', 'false'])
27  parser.add_argument('--output_file', required=True, type=str)
28  parser.add_argument(
29      '--static',
30      choices=['true', 'false'],
31      help='If true, produce a static wrapper. Autodetects a good value if '
32      'unspecified.')
33  args = parser.parse_args()
34
35  if args.static is None:
36    args.static = 'cros' not in args.config
37  else:
38    args.static = args.static == 'true'
39
40  return args
41
42
43def calc_go_args(args, version, build_dir):
44  ldFlags = [
45      '-X',
46      'main.ConfigName=' + args.config,
47      '-X',
48      'main.UseCCache=' + args.use_ccache,
49      '-X',
50      'main.UseLlvmNext=' + args.use_llvm_next,
51      '-X',
52      'main.Version=' + version,
53  ]
54
55  # If the wrapper is intended for Chrome OS, we need to use libc's exec.
56  extra_args = []
57  if not args.static:
58    extra_args += ['-tags', 'libc_exec']
59
60  if args.config == 'android':
61    # If android_llvm_next_flags.go DNE, we'll get an obscure "no
62    # llvmNextFlags" build error; complaining here is clearer.
63    if not os.path.exists(
64        os.path.join(build_dir, 'android_llvm_next_flags.go')):
65      sys.exit('In order to build the Android wrapper, you must have a local '
66               'android_llvm_next_flags.go file; please see '
67               'cros_llvm_next_flags.go.')
68    extra_args += ['-tags', 'android_llvm_next_flags']
69
70  return [
71      'go', 'build', '-o',
72      os.path.abspath(args.output_file), '-ldflags', ' '.join(ldFlags)
73  ] + extra_args
74
75
76def read_version(build_dir):
77  version_path = os.path.join(build_dir, 'VERSION')
78  if os.path.exists(version_path):
79    with open(version_path, 'r') as r:
80      return r.read()
81
82  last_commit_msg = subprocess.check_output(
83      ['git', '-C', build_dir, 'log', '-1', '--pretty=%B'], encoding='utf-8')
84  # Use last found change id to support reverts as well.
85  change_ids = re.findall(r'Change-Id: (\w+)', last_commit_msg)
86  if not change_ids:
87    sys.exit("Couldn't find Change-Id in last commit message.")
88  return change_ids[-1]
89
90
91def main():
92  args = parse_args()
93  build_dir = os.path.dirname(__file__)
94  version = read_version(build_dir)
95  # Note: Go does not support using absolute package names.
96  # So we run go inside the directory of the the build file.
97  sys.exit(
98      subprocess.call(calc_go_args(args, version, build_dir), cwd=build_dir))
99
100
101if __name__ == '__main__':
102  main()
103