CISettings.py 9.9 KB

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