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
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
18 class Settings(CiBuildSettingsManager
, UpdateSettingsManager
, SetupSettingsManager
, PrEvalSettingsManager
):
21 self
.ActualPackages
= []
22 self
.ActualTargets
= []
23 self
.ActualArchitectures
= []
24 self
.ActualToolChainTag
= ""
25 self
.UseBuiltInBaseTools
= None
26 self
.ActualScopes
= None
28 # ####################################################################################### #
29 # Extra CmdLine configuration #
30 # ####################################################################################### #
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")
37 def RetrieveCommandLineOptions(self
, args
):
38 super().RetrieveCommandLineOptions(args
)
39 if args
.force_piptools
:
40 self
.UseBuiltInBaseTools
= True
42 self
.UseBuiltInBaseTools
= False
44 # ####################################################################################### #
45 # Default Support for this Ci Build #
46 # ####################################################################################### #
48 def GetPackagesSupported(self
):
49 ''' return iterable of edk2 packages supported by this build.
50 These should be edk2 workspace relative paths '''
59 "IntelFsp2WrapperPkg",
73 "UnitTestFrameworkPkg",
76 "SourceLevelDebugPkg",
80 def GetArchitecturesSupported(self
):
81 ''' return iterable of edk2 architectures supported by this build '''
90 def GetTargetsSupported(self
):
91 ''' return iterable of edk2 target tags supported by this build '''
92 return ("DEBUG", "RELEASE", "NO-TARGET", "NOOPT")
94 # ####################################################################################### #
95 # Verify and Save requested Ci Build Config #
96 # ####################################################################################### #
98 def SetPackages(self
, list_of_requested_packages
):
99 ''' Confirm the requested package list is valid and configure SettingsManager
100 to build the requested packages.
102 Raise UnsupportedException if a requested_package is not supported
104 unsupported
= set(list_of_requested_packages
) - \
105 set(self
.GetPackagesSupported())
106 if(len(unsupported
) > 0):
108 "Unsupported Package Requested: " + " ".join(unsupported
))
109 raise Exception("Unsupported Package Requested: " +
110 " ".join(unsupported
))
111 self
.ActualPackages
= list_of_requested_packages
113 def SetArchitectures(self
, list_of_requested_architectures
):
114 ''' Confirm the requests architecture list is valid and configure SettingsManager
115 to run only the requested architectures.
117 Raise Exception if a list_of_requested_architectures is not supported
119 unsupported
= set(list_of_requested_architectures
) - \
120 set(self
.GetArchitecturesSupported())
121 if(len(unsupported
) > 0):
123 "Unsupported Architecture Requested: " + " ".join(unsupported
))
125 "Unsupported Architecture Requested: " + " ".join(unsupported
))
126 self
.ActualArchitectures
= list_of_requested_architectures
128 def SetTargets(self
, list_of_requested_target
):
129 ''' Confirm the request target list is valid and configure SettingsManager
130 to run only the requested targets.
132 Raise UnsupportedException if a requested_target is not supported
134 unsupported
= set(list_of_requested_target
) - \
135 set(self
.GetTargetsSupported())
136 if(len(unsupported
) > 0):
138 "Unsupported Targets Requested: " + " ".join(unsupported
))
139 raise Exception("Unsupported Targets Requested: " +
140 " ".join(unsupported
))
141 self
.ActualTargets
= list_of_requested_target
143 # ####################################################################################### #
144 # Actual Configuration for Ci Build #
145 # ####################################################################################### #
147 def GetActiveScopes(self
):
148 ''' return tuple containing scopes that should be active for this process '''
149 if self
.ActualScopes
is None:
150 scopes
= ("cibuild", "edk2-build", "host-based-test")
152 self
.ActualToolChainTag
= shell_environment
.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
154 is_linux
= GetHostInfo().os
.upper() == "LINUX"
156 if self
.UseBuiltInBaseTools
is None:
157 is_linux
= GetHostInfo().os
.upper() == "LINUX"
158 # try and import the pip module for basetools
161 self
.UseBuiltInBaseTools
= True
163 self
.UseBuiltInBaseTools
= False
166 if self
.UseBuiltInBaseTools
== True:
167 scopes
+= ('pipbuild-unix',) if is_linux
else ('pipbuild-win',)
168 logging
.warning("Using Pip Tools based BaseTools")
170 logging
.warning("Falling back to using in-tree BaseTools")
172 if is_linux
and self
.ActualToolChainTag
.upper().startswith("GCC"):
173 if "AARCH64" in self
.ActualArchitectures
:
174 scopes
+= ("gcc_aarch64_linux",)
175 if "ARM" in self
.ActualArchitectures
:
176 scopes
+= ("gcc_arm_linux",)
177 if "RISCV64" in self
.ActualArchitectures
:
178 scopes
+= ("gcc_riscv64_unknown",)
179 if "LOONGARCH64" in self
.ActualArchitectures
:
180 scopes
+= ("gcc_loongarch64_unknown_linux",)
181 self
.ActualScopes
= scopes
182 return self
.ActualScopes
184 def GetRequiredSubmodules(self
):
185 ''' return iterable containing RequiredSubmodule objects.
186 If no RequiredSubmodules return an empty iterable
189 rs
.append(RequiredSubmodule(
190 "ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3", False))
191 rs
.append(RequiredSubmodule(
192 "CryptoPkg/Library/OpensslLib/openssl", False))
193 rs
.append(RequiredSubmodule(
194 "UnitTestFrameworkPkg/Library/CmockaLib/cmocka", False))
195 rs
.append(RequiredSubmodule(
196 "UnitTestFrameworkPkg/Library/GoogleTestLib/googletest", False))
197 rs
.append(RequiredSubmodule(
198 "MdeModulePkg/Universal/RegularExpressionDxe/oniguruma", False))
199 rs
.append(RequiredSubmodule(
200 "MdeModulePkg/Library/BrotliCustomDecompressLib/brotli", False))
201 rs
.append(RequiredSubmodule(
202 "BaseTools/Source/C/BrotliCompress/brotli", False))
203 rs
.append(RequiredSubmodule(
204 "RedfishPkg/Library/JsonLib/jansson", False))
210 def GetDependencies(self
):
214 def GetPackagesPath(self
):
217 def GetWorkspaceRoot(self
):
218 ''' get WorkspacePath '''
219 return os
.path
.dirname(os
.path
.dirname(os
.path
.abspath(__file__
)))
221 def FilterPackagesToTest(self
, changedFilesList
: list, potentialPackagesList
: list) -> list:
222 ''' Filter potential packages to test based on changed files. '''
223 build_these_packages
= []
224 possible_packages
= potentialPackagesList
.copy()
225 for f
in changedFilesList
:
226 # split each part of path for comparison later
229 # python file change in .pytool folder causes building all
230 if f
.endswith(".py") and ".pytool" in nodes
:
231 build_these_packages
= possible_packages
234 # BaseTools files that might change the build
235 if "BaseTools" in nodes
:
236 if os
.path
.splitext(f
) not in [".txt", ".md"]:
237 build_these_packages
= possible_packages
239 return build_these_packages