blob: c701c5401886f7ab60e267933955b86ea508c300 [file] [log] [blame]
Alex Kleinda35fcf2019-03-07 16:01:15 -07001# -*- coding: utf-8 -*-
2# Copyright 2019 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Build target class and related functionality."""
7
8from __future__ import print_function
9
10import os
Alex Klein1a55dde2020-03-06 15:53:29 -070011import re
Alex Kleinda35fcf2019-03-07 16:01:15 -070012
13
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
25 def __init__(self, name, profile=None, build_root=None):
26 """Build Target init.
27
28 Args:
29 name (str): The full name of the target.
30 profile (str): The profile name.
31 build_root (str): The path to the buildroot.
32 """
33 if not name:
34 raise InvalidNameError('Name is required.')
35
Alex Klein171da612019-08-06 14:00:42 -060036 self._name = name
Alex Kleinda35fcf2019-03-07 16:01:15 -070037 self.board, _, self.variant = name.partition('_')
38 self.profile = profile
39
40 if build_root:
41 self.root = os.path.normpath(build_root)
42 else:
Alex Klein1a55dde2020-03-06 15:53:29 -070043 self.root = get_default_sysroot_path(self.name)
Alex Kleinda35fcf2019-03-07 16:01:15 -070044
Alex Klein171da612019-08-06 14:00:42 -060045 def __eq__(self, other):
46 if self.__class__ is other.__class__:
47 return (self.name == other.name and self.profile == other.profile and
48 self.root == other.root)
49
50 return NotImplemented
51
52 def __hash__(self):
53 return hash(self.name)
54
Alex Kleinaf0e0452019-06-03 18:10:01 -060055 def __str__(self):
56 return self.name
57
Alex Klein171da612019-08-06 14:00:42 -060058 @property
59 def name(self):
60 return self._name
Alex Kleinda35fcf2019-03-07 16:01:15 -070061
Alex Klein309c7572020-01-27 10:55:01 -070062 def get_command(self, base_command):
63 """Get the build target's variant of the given base command.
64
65 We create wrappers for many scripts that handle the build target's
66 arguments. Build the target-specific variant for such a command.
67 e.g. emerge -> emerge-eve.
68
69 TODO: Add optional validation the command exists.
70
71 Args:
72 base_command (str): The wrapped command.
73
74 Returns:
75 str: The build target's command wrapper.
76 """
77 return '%s-%s' % (base_command, self.name)
Alex Kleine1abe2c2019-08-14 10:29:46 -060078
Alex Klein1a55dde2020-03-06 15:53:29 -070079
80def get_default_sysroot_path(build_target_name):
81 """Get the default sysroot path for a build target."""
82 if build_target_name:
83 return os.path.join('/build', build_target_name)
Alex Kleinda35fcf2019-03-07 16:01:15 -070084 else:
85 raise InvalidNameError('Target name is required.')
Alex Klein1a55dde2020-03-06 15:53:29 -070086
87
88def is_valid_name(build_target_name):
89 """Validate |build_target_name| is a valid name."""
90 return bool(re.match(r'^[a-zA-Z0-9-_]+$', build_target_name))