1 | # @file CompilerPlugin.py
|
---|
2 | ##
|
---|
3 | # Copyright (c) Microsoft Corporation.
|
---|
4 | # SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
5 | ##
|
---|
6 |
|
---|
7 | import logging
|
---|
8 | import os
|
---|
9 | import re
|
---|
10 | from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser
|
---|
11 | from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
|
---|
12 | from edk2toolext.environment.uefi_build import UefiBuilder
|
---|
13 | from edk2toolext import edk2_logging
|
---|
14 | from edk2toolext.environment.var_dict import VarDict
|
---|
15 |
|
---|
16 |
|
---|
17 | class 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
|
---|