blob: ff5faf58e2285a275188cf60567bb1942001abc1 [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 Kleinda35fcf2019-03-07 16:01:15 -070018class BuildTarget(object):
19 """Class to handle the build target information."""
20
nohe@chromium.orgc78b38f2021-08-23 09:48:13 -070021 def __init__(self,
Sloan Johnson48138052021-12-28 21:08:32 +000022 name: Optional[str],
nohe@chromium.orgc78b38f2021-08-23 09:48:13 -070023 profile: Optional[str] = None,
24 build_root: Optional[str] = None):
Alex Kleinda35fcf2019-03-07 16:01:15 -070025 """Build Target init.
26
27 Args:
nohe@chromium.orgc78b38f2021-08-23 09:48:13 -070028 name: The full name of the target.
29 profile: The profile name.
30 build_root: The path to the buildroot.
Alex Kleinda35fcf2019-03-07 16:01:15 -070031 """
Sloan Johnson48138052021-12-28 21:08:32 +000032 self._name = name or None
Alex Kleinda35fcf2019-03-07 16:01:15 -070033 self.profile = profile
34
35 if build_root:
36 self.root = os.path.normpath(build_root)
37 else:
Alex Klein1a55dde2020-03-06 15:53:29 -070038 self.root = get_default_sysroot_path(self.name)
Alex Kleinda35fcf2019-03-07 16:01:15 -070039
Alex Klein171da612019-08-06 14:00:42 -060040 def __eq__(self, other):
41 if self.__class__ is other.__class__:
42 return (self.name == other.name and self.profile == other.profile and
43 self.root == other.root)
44
45 return NotImplemented
46
47 def __hash__(self):
48 return hash(self.name)
49
Alex Kleinaf0e0452019-06-03 18:10:01 -060050 def __str__(self):
51 return self.name
52
Alex Klein171da612019-08-06 14:00:42 -060053 @property
54 def name(self):
55 return self._name
Alex Kleinda35fcf2019-03-07 16:01:15 -070056
LaMont Jonesfeffd1b2020-08-05 18:24:59 -060057 @property
58 def as_protobuf(self):
Sloan Johnson48138052021-12-28 21:08:32 +000059 return common_pb2.BuildTarget(name=self.name or '')
LaMont Jonesfeffd1b2020-08-05 18:24:59 -060060
61 @classmethod
62 def from_protobuf(cls, message):
63 return cls(name=message.name)
64
65 @property
66 def profile_protobuf(self):
67 return common_pb2.Profile(name=self.profile)
68
Michael Mortensen125bb012020-05-21 14:02:10 -060069 def full_path(self, *args):
70 """Turn a sysroot-relative path into an absolute path."""
71 return os.path.join(self.root, *[part.lstrip(os.sep) for part in args])
72
nohe@chromium.orgc78b38f2021-08-23 09:48:13 -070073 def get_command(self, base_command: str) -> str:
Alex Klein309c7572020-01-27 10:55:01 -070074 """Get the build target's variant of the given base command.
75
76 We create wrappers for many scripts that handle the build target's
77 arguments. Build the target-specific variant for such a command.
78 e.g. emerge -> emerge-eve.
79
80 TODO: Add optional validation the command exists.
81
82 Args:
nohe@chromium.orgc78b38f2021-08-23 09:48:13 -070083 base_command: The wrapped command.
Alex Klein309c7572020-01-27 10:55:01 -070084
85 Returns:
nohe@chromium.orgc78b38f2021-08-23 09:48:13 -070086 The build target's command wrapper.
Alex Klein309c7572020-01-27 10:55:01 -070087 """
Sloan Johnson48138052021-12-28 21:08:32 +000088 if self.is_host():
89 return base_command
90
Alex Klein309c7572020-01-27 10:55:01 -070091 return '%s-%s' % (base_command, self.name)
Alex Kleine1abe2c2019-08-14 10:29:46 -060092
Sloan Johnson48138052021-12-28 21:08:32 +000093 def is_host(self) -> bool:
94 """Check if the build target refers to the host."""
95 return not self.name
96
Alex Klein1a55dde2020-03-06 15:53:29 -070097
Alex Klein62b7e1e2020-03-09 13:36:50 -060098def get_default_sysroot_path(build_target_name=None):
99 """Get the default sysroot location or '/' if |build_target_name| is None."""
100 if build_target_name is None:
101 return '/'
102 return os.path.join('/build', build_target_name)
Alex Klein1a55dde2020-03-06 15:53:29 -0700103
104
Alex Klein5417f3d2021-07-09 15:23:02 -0600105def get_sdk_sysroot_path() -> str:
106 """Get the SDK's sysroot path.
107
108 Convenience/clarification wrapper for get_default_sysroot_path for use when
109 explicitly fetching the SDK's sysroot path.
110 """
111 return get_default_sysroot_path()
112
113
Alex Klein1a55dde2020-03-06 15:53:29 -0700114def is_valid_name(build_target_name):
115 """Validate |build_target_name| is a valid name."""
116 return bool(re.match(r'^[a-zA-Z0-9-_]+$', build_target_name))