1 | # @file
|
---|
2 | #
|
---|
3 | # Copyright (c) Microsoft Corporation.
|
---|
4 | # Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
---|
5 | # Copyright (c) 2020 - 2021, ARM Limited. All rights reserved.<BR>
|
---|
6 | # SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
7 | ##
|
---|
8 | import os
|
---|
9 | import logging
|
---|
10 | from edk2toolext.environment import shell_environment
|
---|
11 | from edk2toolext.invocables.edk2_ci_build import CiBuildSettingsManager
|
---|
12 | from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
|
---|
13 | from edk2toolext.invocables.edk2_update import UpdateSettingsManager
|
---|
14 | from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
|
---|
15 | from edk2toollib.utility_functions import GetHostInfo
|
---|
16 |
|
---|
17 |
|
---|
18 | class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
|
---|
19 |
|
---|
20 | def __init__(self):
|
---|
21 | self.ActualPackages = []
|
---|
22 | self.ActualTargets = []
|
---|
23 | self.ActualArchitectures = []
|
---|
24 | self.ActualToolChainTag = ""
|
---|
25 | self.UseBuiltInBaseTools = None
|
---|
26 | self.ActualScopes = None
|
---|
27 |
|
---|
28 | # ####################################################################################### #
|
---|
29 | # Extra CmdLine configuration #
|
---|
30 | # ####################################################################################### #
|
---|
31 |
|
---|
32 | def AddCommandLineOptions(self, parserObj):
|
---|
33 | group = parserObj.add_mutually_exclusive_group()
|
---|
34 | group.add_argument("-force_piptools", "--fpt", dest="force_piptools", action="store_true", default=False, help="Force the system to use pip tools")
|
---|
35 | group.add_argument("-no_piptools", "--npt", dest="no_piptools", action="store_true", default=False, help="Force the system to not use pip tools")
|
---|
36 |
|
---|
37 | def RetrieveCommandLineOptions(self, args):
|
---|
38 | super().RetrieveCommandLineOptions(args)
|
---|
39 | if args.force_piptools:
|
---|
40 | self.UseBuiltInBaseTools = True
|
---|
41 | if args.no_piptools:
|
---|
42 | self.UseBuiltInBaseTools = False
|
---|
43 |
|
---|
44 | # ####################################################################################### #
|
---|
45 | # Default Support for this Ci Build #
|
---|
46 | # ####################################################################################### #
|
---|
47 |
|
---|
48 | def GetPackagesSupported(self):
|
---|
49 | ''' return iterable of edk2 packages supported by this build.
|
---|
50 | These should be edk2 workspace relative paths '''
|
---|
51 |
|
---|
52 | return ("ArmPkg",
|
---|
53 | "ArmPlatformPkg",
|
---|
54 | "ArmVirtPkg",
|
---|
55 | "DynamicTablesPkg",
|
---|
56 | "EmulatorPkg",
|
---|
57 | "MdePkg",
|
---|
58 | "MdeModulePkg",
|
---|
59 | "NetworkPkg",
|
---|
60 | "PcAtChipsetPkg",
|
---|
61 | "SecurityPkg",
|
---|
62 | "UefiCpuPkg",
|
---|
63 | "FmpDevicePkg",
|
---|
64 | "ShellPkg",
|
---|
65 | "StandaloneMmPkg",
|
---|
66 | "FatPkg",
|
---|
67 | "CryptoPkg",
|
---|
68 | "UnitTestFrameworkPkg",
|
---|
69 | "OvmfPkg",
|
---|
70 | "RedfishPkg"
|
---|
71 | )
|
---|
72 |
|
---|
73 | def GetArchitecturesSupported(self):
|
---|
74 | ''' return iterable of edk2 architectures supported by this build '''
|
---|
75 | return (
|
---|
76 | "IA32",
|
---|
77 | "X64",
|
---|
78 | "ARM",
|
---|
79 | "AARCH64",
|
---|
80 | "RISCV64")
|
---|
81 |
|
---|
82 | def GetTargetsSupported(self):
|
---|
83 | ''' return iterable of edk2 target tags supported by this build '''
|
---|
84 | return ("DEBUG", "RELEASE", "NO-TARGET", "NOOPT")
|
---|
85 |
|
---|
86 | # ####################################################################################### #
|
---|
87 | # Verify and Save requested Ci Build Config #
|
---|
88 | # ####################################################################################### #
|
---|
89 |
|
---|
90 | def SetPackages(self, list_of_requested_packages):
|
---|
91 | ''' Confirm the requested package list is valid and configure SettingsManager
|
---|
92 | to build the requested packages.
|
---|
93 |
|
---|
94 | Raise UnsupportedException if a requested_package is not supported
|
---|
95 | '''
|
---|
96 | unsupported = set(list_of_requested_packages) - \
|
---|
97 | set(self.GetPackagesSupported())
|
---|
98 | if(len(unsupported) > 0):
|
---|
99 | logging.critical(
|
---|
100 | "Unsupported Package Requested: " + " ".join(unsupported))
|
---|
101 | raise Exception("Unsupported Package Requested: " +
|
---|
102 | " ".join(unsupported))
|
---|
103 | self.ActualPackages = list_of_requested_packages
|
---|
104 |
|
---|
105 | def SetArchitectures(self, list_of_requested_architectures):
|
---|
106 | ''' Confirm the requests architecture list is valid and configure SettingsManager
|
---|
107 | to run only the requested architectures.
|
---|
108 |
|
---|
109 | Raise Exception if a list_of_requested_architectures is not supported
|
---|
110 | '''
|
---|
111 | unsupported = set(list_of_requested_architectures) - \
|
---|
112 | set(self.GetArchitecturesSupported())
|
---|
113 | if(len(unsupported) > 0):
|
---|
114 | logging.critical(
|
---|
115 | "Unsupported Architecture Requested: " + " ".join(unsupported))
|
---|
116 | raise Exception(
|
---|
117 | "Unsupported Architecture Requested: " + " ".join(unsupported))
|
---|
118 | self.ActualArchitectures = list_of_requested_architectures
|
---|
119 |
|
---|
120 | def SetTargets(self, list_of_requested_target):
|
---|
121 | ''' Confirm the request target list is valid and configure SettingsManager
|
---|
122 | to run only the requested targets.
|
---|
123 |
|
---|
124 | Raise UnsupportedException if a requested_target is not supported
|
---|
125 | '''
|
---|
126 | unsupported = set(list_of_requested_target) - \
|
---|
127 | set(self.GetTargetsSupported())
|
---|
128 | if(len(unsupported) > 0):
|
---|
129 | logging.critical(
|
---|
130 | "Unsupported Targets Requested: " + " ".join(unsupported))
|
---|
131 | raise Exception("Unsupported Targets Requested: " +
|
---|
132 | " ".join(unsupported))
|
---|
133 | self.ActualTargets = list_of_requested_target
|
---|
134 |
|
---|
135 | # ####################################################################################### #
|
---|
136 | # Actual Configuration for Ci Build #
|
---|
137 | # ####################################################################################### #
|
---|
138 |
|
---|
139 | def GetActiveScopes(self):
|
---|
140 | ''' return tuple containing scopes that should be active for this process '''
|
---|
141 | if self.ActualScopes is None:
|
---|
142 | scopes = ("cibuild", "edk2-build", "host-based-test")
|
---|
143 |
|
---|
144 | self.ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
|
---|
145 |
|
---|
146 | is_linux = GetHostInfo().os.upper() == "LINUX"
|
---|
147 |
|
---|
148 | if self.UseBuiltInBaseTools is None:
|
---|
149 | is_linux = GetHostInfo().os.upper() == "LINUX"
|
---|
150 | # try and import the pip module for basetools
|
---|
151 | try:
|
---|
152 | import edk2basetools
|
---|
153 | self.UseBuiltInBaseTools = True
|
---|
154 | except ImportError:
|
---|
155 | self.UseBuiltInBaseTools = False
|
---|
156 | pass
|
---|
157 |
|
---|
158 | if self.UseBuiltInBaseTools == True:
|
---|
159 | scopes += ('pipbuild-unix',) if is_linux else ('pipbuild-win',)
|
---|
160 | logging.warning("Using Pip Tools based BaseTools")
|
---|
161 | else:
|
---|
162 | logging.warning("Falling back to using in-tree BaseTools")
|
---|
163 |
|
---|
164 | if is_linux and self.ActualToolChainTag.upper().startswith("GCC"):
|
---|
165 | if "AARCH64" in self.ActualArchitectures:
|
---|
166 | scopes += ("gcc_aarch64_linux",)
|
---|
167 | if "ARM" in self.ActualArchitectures:
|
---|
168 | scopes += ("gcc_arm_linux",)
|
---|
169 | if "RISCV64" in self.ActualArchitectures:
|
---|
170 | scopes += ("gcc_riscv64_unknown",)
|
---|
171 | self.ActualScopes = scopes
|
---|
172 | return self.ActualScopes
|
---|
173 |
|
---|
174 | def GetRequiredSubmodules(self):
|
---|
175 | ''' return iterable containing RequiredSubmodule objects.
|
---|
176 | If no RequiredSubmodules return an empty iterable
|
---|
177 | '''
|
---|
178 | rs = []
|
---|
179 | rs.append(RequiredSubmodule(
|
---|
180 | "ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3", False))
|
---|
181 | rs.append(RequiredSubmodule(
|
---|
182 | "CryptoPkg/Library/OpensslLib/openssl", False))
|
---|
183 | rs.append(RequiredSubmodule(
|
---|
184 | "UnitTestFrameworkPkg/Library/CmockaLib/cmocka", False))
|
---|
185 | rs.append(RequiredSubmodule(
|
---|
186 | "MdeModulePkg/Universal/RegularExpressionDxe/oniguruma", False))
|
---|
187 | rs.append(RequiredSubmodule(
|
---|
188 | "MdeModulePkg/Library/BrotliCustomDecompressLib/brotli", False))
|
---|
189 | rs.append(RequiredSubmodule(
|
---|
190 | "BaseTools/Source/C/BrotliCompress/brotli", False))
|
---|
191 | rs.append(RequiredSubmodule(
|
---|
192 | "RedfishPkg/Library/JsonLib/jansson", False))
|
---|
193 | return rs
|
---|
194 |
|
---|
195 | def GetName(self):
|
---|
196 | return "Edk2"
|
---|
197 |
|
---|
198 | def GetDependencies(self):
|
---|
199 | return [
|
---|
200 | ]
|
---|
201 |
|
---|
202 | def GetPackagesPath(self):
|
---|
203 | return ()
|
---|
204 |
|
---|
205 | def GetWorkspaceRoot(self):
|
---|
206 | ''' get WorkspacePath '''
|
---|
207 | return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
---|
208 |
|
---|
209 | def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
|
---|
210 | ''' Filter potential packages to test based on changed files. '''
|
---|
211 | build_these_packages = []
|
---|
212 | possible_packages = potentialPackagesList.copy()
|
---|
213 | for f in changedFilesList:
|
---|
214 | # split each part of path for comparison later
|
---|
215 | nodes = f.split("/")
|
---|
216 |
|
---|
217 | # python file change in .pytool folder causes building all
|
---|
218 | if f.endswith(".py") and ".pytool" in nodes:
|
---|
219 | build_these_packages = possible_packages
|
---|
220 | break
|
---|
221 |
|
---|
222 | # BaseTools files that might change the build
|
---|
223 | if "BaseTools" in nodes:
|
---|
224 | if os.path.splitext(f) not in [".txt", ".md"]:
|
---|
225 | build_these_packages = possible_packages
|
---|
226 | break
|
---|
227 | return build_these_packages
|
---|