blob: 4220b54a69cbf19222d6554ebaf57243dcbce877 [file] [log] [blame]
Alex Kleinda35fcf2019-03-07 16:01:15 -07001# Copyright 2019 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"""Build target class and related functionality."""
6
Alex Kleinda35fcf2019-03-07 16:01:15 -07007import os
Alex Klein1a55dde2020-03-06 15:53:29 -07008import re
nohe@chromium.orgc78b38f2021-08-23 09:48:13 -07009from typing import Optional
Alex Kleinda35fcf2019-03-07 16:01:15 -070010
LaMont Jonesfeffd1b2020-08-05 18:24:59 -060011from chromite.api.gen.chromiumos import common_pb2
12
Alex Kleinda35fcf2019-03-07 16:01:15 -070013
14class Error(Exception):
15 """Base module error class."""
16
17
Alex Kleindf4a4482019-09-04 15:31:17 -060018class InvalidNameError(Error):
Alex Kleinda35fcf2019-03-07 16:01:15 -070019 """Error for invalid target name argument."""
20
21
22class BuildTarget(object):
23 """Class to handle the build target information."""
24
nohe@chromium.orgc78b38f2021-08-23 09:48:13 -070025 def __init__(self,
26 name: str,
27 profile: Optional[str] = None,
28 build_root: Optional[str] = None):
Alex Kleinda35fcf2019-03-07 16:01:15 -070029 """Build Target init.
30
31 Args:
nohe@chromium.orgc78b38f2021-08-23 09:48:13 -070032 name: The full name of the target.
33 profile: The profile name.
34 build_root: The path to the buildroot.
Alex Kleinda35fcf2019-03-07 16:01:15 -070035 """
36 if not name:
37 raise InvalidNameError('Name is required.')
38
Alex Klein171da612019-08-06 14:00:42 -060039 self._name = name
Alex Kleinda35fcf2019-03-07 16:01:15 -070040 self.board, _, self.variant = name.partition('_')
41 self.profile = profile
42
43 if build_root:
44 self.root = os.path.normpath(build_root)
45 else:
Alex Klein1a55dde2020-03-06 15:53:29 -070046 self.root = get_default_sysroot_path(self.name)
Alex Kleinda35fcf2019-03-07 16:01:15 -070047
Alex Klein171da612019-08-06 14:00:42 -060048 def __eq__(self, other):
49 if self.__class__ is other.__class__:
50 return (self.name == other.name and self.profile == other.profile and
51 self.root == other.root)
52
53 return NotImplemented
54
55 def __hash__(self):
56 return hash(self.name)
57
Alex Kleinaf0e0452019-06-03 18:10:01 -060058 def __str__(self):
59 return self.name
60
Alex Klein171da612019-08-06 14:00:42 -060061 @property
62 def name(self):
63 return self._name
Alex Kleinda35fcf2019-03-07 16:01:15 -070064
LaMont Jonesfeffd1b2020-08-05 18:24:59 -060065 @property
66 def as_protobuf(self):
67 return common_pb2.BuildTarget(name=self.name)
68
69 @classmethod
70 def from_protobuf(cls, message):
71 return cls(name=message.name)
72
73 @property
74 def profile_protobuf(self):
75 return common_pb2.Profile(name=self.profile)
76
Michael Mortensen125bb012020-05-21 14:02:10 -060077 def full_path(self, *args):
78 """Turn a sysroot-relative path into an absolute path."""
79 return os.path.join(self.root, *[part.lstrip(os.sep) for part in args])
80
nohe@chromium.orgc78b38f2021-08-23 09:48:13 -070081 def get_command(self, base_command: str) -> str:
Alex Klein309c7572020-01-27 10:55:01 -070082 """Get the build target's variant of the given base command.
83
84 We create wrappers for many scripts that handle the build target's
85 arguments. Build the target-specific variant for such a command.
86 e.g. emerge -> emerge-eve.
87
88 TODO: Add optional validation the command exists.
89
90 Args:
nohe@chromium.orgc78b38f2021-08-23 09:48:13 -070091 base_command: The wrapped command.
Alex Klein309c7572020-01-27 10:55:01 -070092
93 Returns:
nohe@chromium.orgc78b38f2021-08-23 09:48:13 -070094 The build target's command wrapper.
Alex Klein309c7572020-01-27 10:55:01 -070095 """
96 return '%s-%s' % (base_command, self.name)
Alex Kleine1abe2c2019-08-14 10:29:46 -060097
Alex Klein1a55dde2020-03-06 15:53:29 -070098
Alex Klein62b7e1e2020-03-09 13:36:50 -060099def get_default_sysroot_path(build_target_name=None):
100 """Get the default sysroot location or '/' if |build_target_name| is None."""
101 if build_target_name is None:
102 return '/'
103 return os.path.join('/build', build_target_name)
Alex Klein1a55dde2020-03-06 15:53:29 -0700104
105
Alex Klein5417f3d2021-07-09 15:23:02 -0600106def get_sdk_sysroot_path() -> str:
107 """Get the SDK's sysroot path.
108
109 Convenience/clarification wrapper for get_default_sysroot_path for use when
110 explicitly fetching the SDK's sysroot path.
111 """
112 return get_default_sysroot_path()
113
114
Alex Klein1a55dde2020-03-06 15:53:29 -0700115def is_valid_name(build_target_name):
116 """Validate |build_target_name| is a valid name."""
117 return bool(re.match(r'^[a-zA-Z0-9-_]+$', build_target_name))