blob: 7c49573b0b7b84a80e07e45a63c58697c0e053c5 [file] [log] [blame]
David James4a697fd2012-02-11 15:27:53 -08001# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""
6Generate a file that sets the specified board's binhosts to include all of the
7other compatible boards in this buildroot.
8"""
9
10import collections
11import glob
12import optparse
13import os
14import sys
15
16from chromite.buildbot import cbuildbot_config
17from chromite.lib import cros_build_lib as cros_lib
18
19def FindCandidateBoards(board):
20 """Find candidate local boards to grab prebuilts from."""
21 board_no_variant = board.partition("_")[0]
22 portageq_prefix = "/usr/local/bin/portageq-"
23 for path in sorted(glob.glob("%s*" % portageq_prefix)):
24 # Strip off the portageq prefix, leaving only the board.
25 other_board = path.replace(portageq_prefix, "")
26
27 # It is only safe to inherit prebuilts from generic boards, or from the
28 # same board without the variant. This rule helps keep inheritance trees
29 # sane.
30 if (other_board in cbuildbot_config.generic_boards or
31 other_board == board_no_variant or other_board == board):
32 yield other_board
33
34
35def SummarizeCompatibility(board):
36 """Returns a string that will be the same for compatible boards."""
37 cmd = ["portageq-%s" % board, "envvar", "ARCH", "CFLAGS"]
38 return cros_lib.RunCommand(cmd, redirect_stdout=True,
39 print_cmd=False).output.rstrip()
40
41
42def GenerateBinhostLine(build_root, compatible_boards):
43 """Generate a binhost line pulling binaries from the specified boards."""
44 local_binhosts = " ".join([
45 "file://localhost" + os.path.join(build_root, x, "packages")
46 for x in sorted(compatible_boards)])
47 return "LOCAL_BINHOST='%s'" % local_binhosts
48
49
50def main(argv):
51 parser = optparse.OptionParser(usage="USAGE: ./%prog --board=board [options]")
52
53 parser.add_option("--build_root", default="/build",
54 dest="build_root",
55 help="Location of boards (normally /build)")
56 parser.add_option("--board", default=None,
57 dest="board",
58 help="Board name (required).")
59
60 flags, remaining_arguments = parser.parse_args(argv)
61
62 if remaining_arguments or not flags.board:
63 parser.print_help()
64 sys.exit(1)
65
66 by_compatibility = collections.defaultdict(set)
67 compatible_boards = None
68 for other_board in FindCandidateBoards(flags.board):
69 compat_id = SummarizeCompatibility(other_board)
70 if other_board == flags.board:
71 compatible_boards = by_compatibility[compat_id]
72 else:
73 by_compatibility[compat_id].add(other_board)
74
75 if compatible_boards is None:
76 print >>sys.stderr, "Missing portageq wrapper for %s" % flags.board
77 sys.exit(1)
78
79 # If a non-generic prebuilt is available, ignore the generic ones,
80 # since the non-generic ones will be better matches.
81 compatible_specific_boards = \
82 compatible_boards - set(cbuildbot_config.generic_boards)
83 if compatible_specific_boards:
84 compatible_boards = compatible_specific_boards
85
86 print "# Generated by cros_generate_local_binhosts."
87 print GenerateBinhostLine(flags.build_root, compatible_boards)