# @file CompilerPlugin.py ## # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: BSD-2-Clause-Patent ## import logging import os import re from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin from edk2toolext.environment.uefi_build import UefiBuilder from edk2toolext import edk2_logging from edk2toolext.environment.var_dict import VarDict class CompilerPlugin(ICiBuildPlugin): """ A CiBuildPlugin that compiles the package dsc from the package being tested. Configuration options: "CompilerPlugin": { "DscPath": "" } """ def GetTestName(self, packagename: str, environment: VarDict) -> tuple: """ Provide the testcase name and classname for use in reporting Args: packagename: string containing name of package to build environment: The VarDict for the test to run in Returns: a tuple containing the testcase name and the classname (testcasename, classname) """ target = environment.GetValue("TARGET") return ("Compile " + packagename + " " + target, packagename + ".Compiler." + target) def RunsOnTargetList(self): return ["DEBUG", "RELEASE"] ## # External function of plugin. This function is used to perform the task of the ICiBuildPlugin Plugin # # - package is the edk2 path to package. This means workspace/packagepath relative. # - edk2path object configured with workspace and packages path # - PkgConfig Object (dict) for the pkg # - EnvConfig Object # - Plugin Manager Instance # - Plugin Helper Obj Instance # - Junit Logger # - output_stream the StringIO output stream from this plugin via logging def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None): self._env = environment # Parse the config for required DscPath element if "DscPath" not in pkgconfig: tc.SetSkipped() tc.LogStdError("DscPath not found in config file. Nothing to compile.") return -1 AP = Edk2pathObj.GetAbsolutePathOnThisSystemFromEdk2RelativePath(packagename) APDSC = os.path.join(AP, pkgconfig["DscPath"].strip()) AP_Path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(APDSC) if AP is None or AP_Path is None or not os.path.isfile(APDSC): tc.SetSkipped() tc.LogStdError("Package Dsc not found.") return -1 logging.info("Building {0}".format(AP_Path)) self._env.SetValue("ACTIVE_PLATFORM", AP_Path, "Set in Compiler Plugin") # Parse DSC to check for SUPPORTED_ARCHITECTURES build_target = self._env.GetValue("TARGET") input_vars = self._env.GetAllBuildKeyValues(build_target) dp = DscParser() dp.SetEdk2Path(Edk2pathObj).SetInputVars(input_vars) dp.ParseFile(AP_Path) if "SUPPORTED_ARCHITECTURES" in dp.LocalVars: SUPPORTED_ARCHITECTURES = dp.LocalVars["SUPPORTED_ARCHITECTURES"].split('|') TARGET_ARCHITECTURES = environment.GetValue("TARGET_ARCH").split(' ') # Skip if there is no intersection between SUPPORTED_ARCHITECTURES and TARGET_ARCHITECTURES if len(set(SUPPORTED_ARCHITECTURES) & set(TARGET_ARCHITECTURES)) == 0: tc.SetSkipped() tc.LogStdError("No supported architectures to build") return -1 uefiBuilder = UefiBuilder() # do all the steps # WorkSpace, PackagesPath, PInHelper, PInManager ret = uefiBuilder.Go(Edk2pathObj.WorkspacePath, os.pathsep.join(Edk2pathObj.PackagePathList), PLMHelper, PLM) if ret != 0: # failure: tc.SetFailed("Compile failed for {0}".format(packagename), "Compile_FAILED") tc.LogStdError("{0} Compile failed with error code {1} ".format(AP_Path, ret)) return 1 else: tc.SetSuccess() return 0