1# @file CompilerPlugin.py 2## 3# Copyright (c) Microsoft Corporation. 4# SPDX-License-Identifier: BSD-2-Clause-Patent 5## 6 7import logging 8import os 9import re 10from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser 11from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin 12from edk2toolext.environment.uefi_build import UefiBuilder 13from edk2toolext import edk2_logging 14from edk2toolext.environment.var_dict import VarDict 15 16 17class CompilerPlugin(ICiBuildPlugin): 18 """ 19 A CiBuildPlugin that compiles the package dsc 20 from the package being tested. 21 22 Configuration options: 23 "CompilerPlugin": { 24 "DscPath": "<path to dsc from root of pkg>" 25 } 26 """ 27 28 def GetTestName(self, packagename: str, environment: VarDict) -> tuple: 29 """ Provide the testcase name and classname for use in reporting 30 31 Args: 32 packagename: string containing name of package to build 33 environment: The VarDict for the test to run in 34 Returns: 35 a tuple containing the testcase name and the classname 36 (testcasename, classname) 37 """ 38 target = environment.GetValue("TARGET") 39 return ("Compile " + packagename + " " + target, packagename + ".Compiler." + target) 40 41 def RunsOnTargetList(self): 42 return ["DEBUG", "RELEASE"] 43 44 ## 45 # External function of plugin. This function is used to perform the task of the ICiBuildPlugin Plugin 46 # 47 # - package is the edk2 path to package. This means workspace/packagepath relative. 48 # - edk2path object configured with workspace and packages path 49 # - PkgConfig Object (dict) for the pkg 50 # - EnvConfig Object 51 # - Plugin Manager Instance 52 # - Plugin Helper Obj Instance 53 # - Junit Logger 54 # - output_stream the StringIO output stream from this plugin via logging 55 def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None): 56 self._env = environment 57 58 # Parse the config for required DscPath element 59 if "DscPath" not in pkgconfig: 60 tc.SetSkipped() 61 tc.LogStdError("DscPath not found in config file. Nothing to compile.") 62 return -1 63 64 AP = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename) 65 66 APDSC = os.path.join(AP, pkgconfig["DscPath"].strip()) 67 AP_Path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(APDSC) 68 if AP is None or AP_Path is None or not os.path.isfile(APDSC): 69 tc.SetSkipped() 70 tc.LogStdError("Package Dsc not found.") 71 return -1 72 73 logging.info("Building {0}".format(AP_Path)) 74 self._env.SetValue("ACTIVE_PLATFORM", AP_Path, "Set in Compiler Plugin") 75 76 # Parse DSC to check for SUPPORTED_ARCHITECTURES 77 dp = DscParser() 78 dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath) 79 dp.SetPackagePaths(Edk2pathObj.PackagePathList) 80 dp.ParseFile(AP_Path) 81 if "SUPPORTED_ARCHITECTURES" in dp.LocalVars: 82 SUPPORTED_ARCHITECTURES = dp.LocalVars["SUPPORTED_ARCHITECTURES"].split('|') 83 TARGET_ARCHITECTURES = environment.GetValue("TARGET_ARCH").split(' ') 84 85 # Skip if there is no intersection between SUPPORTED_ARCHITECTURES and TARGET_ARCHITECTURES 86 if len(set(SUPPORTED_ARCHITECTURES) & set(TARGET_ARCHITECTURES)) == 0: 87 tc.SetSkipped() 88 tc.LogStdError("No supported architecutres to build") 89 return -1 90 91 uefiBuilder = UefiBuilder() 92 # do all the steps 93 # WorkSpace, PackagesPath, PInHelper, PInManager 94 ret = uefiBuilder.Go(Edk2pathObj.WorkspacePath, os.pathsep.join(Edk2pathObj.PackagePathList), PLMHelper, PLM) 95 if ret != 0: # failure: 96 tc.SetFailed("Compile failed for {0}".format(packagename), "Compile_FAILED") 97 tc.LogStdError("{0} Compile failed with error code {1} ".format(AP_Path, ret)) 98 return 1 99 100 else: 101 tc.SetSuccess() 102 return 0 103