blob: fb9b115be0151037493adb9e1cf85a8ff92cf18f [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2019 The ChromiumOS Authors
Alex Kleinda35fcf2019-03-07 16:01:15 -07002# 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
11
12class Error(Exception):
Alex Klein1699fab2022-09-08 08:46:06 -060013 """Base module error class."""
Alex Kleinda35fcf2019-03-07 16:01:15 -070014
15
Alex Klein074f94f2023-06-22 10:32:06 -060016class BuildTarget:
Alex Klein1699fab2022-09-08 08:46:06 -060017 """Class to handle the build target information."""
Alex Kleinda35fcf2019-03-07 16:01:15 -070018
Alex Klein1699fab2022-09-08 08:46:06 -060019 def __init__(
20 self,
21 name: Optional[str],
22 profile: Optional[str] = None,
23 build_root: Optional[str] = None,
24 ):
25 """Build Target init.
Alex Kleinda35fcf2019-03-07 16:01:15 -070026
Alex Klein1699fab2022-09-08 08:46:06 -060027 Args:
Alex Kleind52f46c2022-10-17 17:06:57 -060028 name: The full name of the target.
29 profile: The profile name.
30 build_root: The path to the buildroot.
Alex Klein1699fab2022-09-08 08:46:06 -060031 """
32 self._name = name or None
33 self.profile = profile
Alex Kleinda35fcf2019-03-07 16:01:15 -070034
Alex Klein1699fab2022-09-08 08:46:06 -060035 if build_root:
36 self.root = os.path.normpath(build_root)
37 else:
38 self.root = get_default_sysroot_path(self.name)
Alex Kleinda35fcf2019-03-07 16:01:15 -070039
Alex Klein1699fab2022-09-08 08:46:06 -060040 def __eq__(self, other):
41 if self.__class__ is other.__class__:
42 return (
43 self.name == other.name
44 and self.profile == other.profile
45 and self.root == other.root
46 )
Alex Klein171da612019-08-06 14:00:42 -060047
Alex Klein1699fab2022-09-08 08:46:06 -060048 return NotImplemented
Alex Klein171da612019-08-06 14:00:42 -060049
Alex Klein1699fab2022-09-08 08:46:06 -060050 def __hash__(self):
51 return hash(self.name)
Alex Klein171da612019-08-06 14:00:42 -060052
Alex Klein1699fab2022-09-08 08:46:06 -060053 def __str__(self):
54 return self.name
Alex Kleinaf0e0452019-06-03 18:10:01 -060055
Alex Klein1699fab2022-09-08 08:46:06 -060056 @property
57 def name(self):
58 return self._name
Alex Kleinda35fcf2019-03-07 16:01:15 -070059
Alex Klein1699fab2022-09-08 08:46:06 -060060 def full_path(self, *args):
61 """Turn a sysroot-relative path into an absolute path."""
62 return os.path.join(self.root, *[part.lstrip(os.sep) for part in args])
Michael Mortensen125bb012020-05-21 14:02:10 -060063
Alex Klein1699fab2022-09-08 08:46:06 -060064 def get_command(self, base_command: str) -> str:
65 """Get the build target's variant of the given base command.
Alex Klein309c7572020-01-27 10:55:01 -070066
Alex Klein1699fab2022-09-08 08:46:06 -060067 We create wrappers for many scripts that handle the build target's
68 arguments. Build the target-specific variant for such a command.
69 e.g. emerge -> emerge-eve.
Alex Klein309c7572020-01-27 10:55:01 -070070
Alex Klein1699fab2022-09-08 08:46:06 -060071 TODO: Add optional validation the command exists.
Alex Klein309c7572020-01-27 10:55:01 -070072
Alex Klein1699fab2022-09-08 08:46:06 -060073 Args:
Alex Kleind52f46c2022-10-17 17:06:57 -060074 base_command: The wrapped command.
Alex Klein309c7572020-01-27 10:55:01 -070075
Alex Klein1699fab2022-09-08 08:46:06 -060076 Returns:
Alex Kleind52f46c2022-10-17 17:06:57 -060077 The build target's command wrapper.
Alex Klein1699fab2022-09-08 08:46:06 -060078 """
79 if self.is_host():
80 return base_command
Sloan Johnson48138052021-12-28 21:08:32 +000081
Alex Klein1699fab2022-09-08 08:46:06 -060082 return "%s-%s" % (base_command, self.name)
Alex Kleine1abe2c2019-08-14 10:29:46 -060083
Alex Klein1699fab2022-09-08 08:46:06 -060084 def is_host(self) -> bool:
85 """Check if the build target refers to the host."""
86 return not self.name
Sloan Johnson48138052021-12-28 21:08:32 +000087
Alex Klein1a55dde2020-03-06 15:53:29 -070088
Alex Klein62b7e1e2020-03-09 13:36:50 -060089def get_default_sysroot_path(build_target_name=None):
Alex Klein79a68fa2023-03-21 17:11:07 -060090 """Get the default sysroot location or / if |build_target_name| is None."""
Alex Klein1699fab2022-09-08 08:46:06 -060091 if build_target_name is None:
92 return "/"
93 return os.path.join("/build", build_target_name)
Alex Klein1a55dde2020-03-06 15:53:29 -070094
95
Alex Klein5417f3d2021-07-09 15:23:02 -060096def get_sdk_sysroot_path() -> str:
Alex Klein1699fab2022-09-08 08:46:06 -060097 """Get the SDK's sysroot path.
Alex Klein5417f3d2021-07-09 15:23:02 -060098
Alex Klein1699fab2022-09-08 08:46:06 -060099 Convenience/clarification wrapper for get_default_sysroot_path for use when
100 explicitly fetching the SDK's sysroot path.
101 """
102 return get_default_sysroot_path()
Alex Klein5417f3d2021-07-09 15:23:02 -0600103
104
Alex Klein1a55dde2020-03-06 15:53:29 -0700105def is_valid_name(build_target_name):
Alex Klein1699fab2022-09-08 08:46:06 -0600106 """Validate |build_target_name| is a valid name."""
107 return bool(re.match(r"^[a-zA-Z0-9-_]+$", build_target_name))