blob: 3cf3888828c071a86e1afb57f5d8f263dd2e8948 [file] [log] [blame]
# @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": "<path to dsc from root of pkg>"
}
"""
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
dp = DscParser()
dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath)
dp.SetPackagePaths(Edk2pathObj.PackagePathList)
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 architecutres 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