diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
commit | f215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch) | |
tree | 6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/BaseTools/Plugin | |
parent | Initial commit. (diff) | |
download | virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip |
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/BaseTools/Plugin')
11 files changed, 729 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/BuildToolsReport/BuildToolsReportGenerator.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/BuildToolsReport/BuildToolsReportGenerator.py new file mode 100755 index 00000000..9d94c252 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/BuildToolsReport/BuildToolsReportGenerator.py @@ -0,0 +1,69 @@ +## +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +import os +import logging +import json + +try: + from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin + + class BuildToolsReportGenerator(IUefiBuildPlugin): + def do_report(self, thebuilder): + try: + from edk2toolext.environment import version_aggregator + except ImportError: + logging.critical("Loading BuildToolsReportGenerator failed, please update your Edk2-PyTool-Extensions") + return 0 + + OutputReport = os.path.join(thebuilder.env.GetValue("BUILD_OUTPUT_BASE"), "BUILD_TOOLS_REPORT") + OutputReport = os.path.normpath(OutputReport) + if not os.path.isdir(os.path.dirname(OutputReport)): + os.makedirs(os.path.dirname(OutputReport)) + + Report = BuildToolsReport() + Report.MakeReport(version_aggregator.GetVersionAggregator().GetAggregatedVersionInformation(), OutputReport=OutputReport) + + def do_pre_build(self, thebuilder): + self.do_report(thebuilder) + return 0 + + def do_post_build(self, thebuilder): + self.do_report(thebuilder) + return 0 + +except ImportError: + pass + + +class BuildToolsReport(object): + MY_FOLDER = os.path.dirname(os.path.realpath(__file__)) + VERSION = "1.00" + + def __init__(self): + pass + + def MakeReport(self, BuildTools, OutputReport="BuildToolsReport"): + logging.info("Writing BuildToolsReports to {0}".format(OutputReport)) + versions_list = [] + for key, value in BuildTools.items(): + versions_list.append(value) + versions_list = sorted(versions_list, key=lambda k: k['type']) + json_dict = {"modules": versions_list, + "PluginVersion": BuildToolsReport.VERSION} + + htmlfile = open(OutputReport + ".html", "w") + jsonfile = open(OutputReport + ".json", "w") + template = open(os.path.join(BuildToolsReport.MY_FOLDER, "BuildToolsReport_Template.html"), "r") + + for line in template.readlines(): + if "%TO_BE_FILLED_IN_BY_PYTHON_SCRIPT%" in line: + line = line.replace("%TO_BE_FILLED_IN_BY_PYTHON_SCRIPT%", json.dumps(json_dict)) + htmlfile.write(line) + + jsonfile.write(json.dumps(versions_list, indent=4)) + + jsonfile.close() + template.close() + htmlfile.close() diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/BuildToolsReport/BuildToolsReportGenerator_plug_in.yaml b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/BuildToolsReport/BuildToolsReportGenerator_plug_in.yaml new file mode 100644 index 00000000..8656a497 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/BuildToolsReport/BuildToolsReportGenerator_plug_in.yaml @@ -0,0 +1,12 @@ +## @file +# Build Plugin used to output html report of all versions collected +# during the build +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +{ + "scope": "global", + "name": "Build Tools Report Generator", + "module": "BuildToolsReportGenerator" +} diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/BuildToolsReport/BuildToolsReport_Template.html b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/BuildToolsReport/BuildToolsReport_Template.html new file mode 100644 index 00000000..8273fdee --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/BuildToolsReport/BuildToolsReport_Template.html @@ -0,0 +1,126 @@ +<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible">
+ <title>Build Tools Report</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="stylesheet" type="text/css" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css" />
+ <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.15/css/dataTables.bootstrap.min.css" />
+ <style>
+ div.attribution {
+ border: 1px solid #ddd;
+ background-color: #bbb;
+ padding-left: 20px;
+ }
+ </style>
+</head>
+<body>
+ <div class="container-fluid">
+ <h1>Build Tools Report</h1>
+ <ul class="nav nav-tabs">
+ <li class="active"><a data-toggle="tab" href="#tabs-1">Tools</a></li>
+ <li><a data-toggle="tab" href="#tabs-2">About</a></li>
+ </ul>
+ <div class="tab-content">
+ <div id="tabs-1" class="tab-pane fade in active">
+ <table id="modinfo" class="table table-striped table-bordered table-hover" cellspacing="0">
+ <thead>
+ <tr>
+ <th>Key</th>
+ <th>Value</th>
+ <th>Type</th>
+ </tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ </div>
+ <div id="tabs-2" class="tab-pane">
+ <div class="row">
+ <div class="col-xs-7">
+ <p></p>
+ <p>
+ Build Tools Report Template Version: <span id="ReportTemplateVersion">1.00</span><br />
+ Build Tools Report Plugin Version: <span id='ReportToolVersion'></span><br />
+ </p>
+ <h3>License</h3>
+ <hr />
+ <div id="ToolLicenseContent">
+ <p>
+ <span class="copyright">Copyright (c) Microsoft Corporation.</span><br />
+ <span class="license">
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+ </span>
+ </p>
+ </div>
+ </div>
+ <div id="AttributionListWrapper" class="col-xs-5">
+ <h3>External Licenses</h3>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- Javascript libraries -->
+ <script type="text/javascript" charset="utf8" src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
+ <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>
+ <script type="text/javascript" charset="utf8" src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"></script>
+ <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.15/js/dataTables.bootstrap.min.js"></script>
+
+ <script>
+ var EmbeddedJd = %TO_BE_FILLED_IN_BY_PYTHON_SCRIPT%;
+ </script>
+ <!-- Add javascript here -->
+ <script>
+ var MODULE_TABLE_OFFSET = 350; //Space needed for other stuff besides the Table
+ $(document).ready(function () {
+ $('span#ReportToolVersion').text(EmbeddedJd.PluginVersion);
+ //To support tabs and correct column width we need this change
+ $('a[data-toggle="tab"][href="#tabs-1"]').on('shown.bs.tab', function (e) {
+ $.fn.dataTable.tables({ visible: true, api: true }).columns.adjust();
+ });
+ //table for modules
+ var mTable = $('table#modinfo').dataTable({
+ "aaData": EmbeddedJd.modules,
+ "paginate": false,
+ "autoWidth": false,
+ "scrollY": ($(window).height() - MODULE_TABLE_OFFSET) + "px",
+ "aaSorting": [[2, "asc"]],
+ "aoColumnDefs": [
+ {
+ "mData": "name",
+ "aTargets": [0]
+ },
+
+ {
+ "mData": "version",
+ "aTargets": [1]
+ },
+ {
+ "mData": "type",
+ "aTargets": [2],
+ }
+ ] //end of column def
+ }); //end of modules table
+
+ //
+ // Create Attribution List for all external libraries used
+ //
+ [
+ { Title: "JQuery", Copyright: "Copyright 2017 The jQuery Foundation", Version: $.fn.jquery, LicenseType: "MIT", LicenseLink: "https://jquery.org/license/" },
+ { Title: "DataTables", Copyright: "DataTables designed and created by SpryMedia Ltd Copyright 2007-2017", Version: $.fn.dataTable.version, LicenseType: "MIT", LicenseLink: "https://datatables.net/license/mit" },
+ { Title: "BootStrap", Copyright: "Code and documentation copyright 2011-2017 the Bootstrap Authors and Twitter, Inc.", Version: "3.3.7", LicenseType: "MIT", LicenseLink: "https://github.com/twbs/bootstrap/blob/master/LICENSE" }
+ ].forEach(function (element) {
+ $("<div class='attribution'><h4>" + element.Title + "</h4><p>Version: <span class='version'>" + element.Version + "</span><br /><span class='copyright'>" +
+ element.Copyright + "</span><br />License: <a class='license' href='" + element.LicenseLink + "'>" + element.LicenseType + "</a></p></div>").appendTo("div#AttributionListWrapper");
+ });
+ });
+ $(window).resize(function() {
+ $.fn.dataTable.tables({ visible: true, api: true }).columns.adjust();
+ });
+
+
+ </script>
+</body>
+</html>
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py new file mode 100755 index 00000000..cb7291b9 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py @@ -0,0 +1,115 @@ +# @file HostBasedUnitTestRunner.py +# Plugin to located any host-based unit tests in the output directory and execute them. +## +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +import os +import logging +import glob +import stat +import xml.etree.ElementTree +from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin +from edk2toolext import edk2_logging +import edk2toollib.windows.locate_tools as locate_tools +from edk2toolext.environment import shell_environment +from edk2toollib.utility_functions import RunCmd +from edk2toollib.utility_functions import GetHostInfo + + +class HostBasedUnitTestRunner(IUefiBuildPlugin): + + def do_pre_build(self, thebuilder): + ''' + Run Prebuild + ''' + + return 0 + + def do_post_build(self, thebuilder): + ''' + After a build, will automatically locate and run all host-based unit tests. Logs any + failures with Warning severity and will return a count of the failures as the return code. + + EXPECTS: + - Build Var 'CI_BUILD_TYPE' - If not set to 'host_unit_test', will not do anything. + + UPDATES: + - Shell Var 'CMOCKA_XML_FILE' + ''' + ci_type = thebuilder.env.GetValue('CI_BUILD_TYPE') + if ci_type != 'host_unit_test': + return 0 + + shell_env = shell_environment.GetEnvironment() + logging.log(edk2_logging.get_section_level(), + "Run Host based Unit Tests") + path = thebuilder.env.GetValue("BUILD_OUTPUT_BASE") + + failure_count = 0 + + # Set up the reporting type for Cmocka. + shell_env.set_shell_var('CMOCKA_MESSAGE_OUTPUT', 'xml') + + for arch in thebuilder.env.GetValue("TARGET_ARCH").split(): + logging.log(edk2_logging.get_subsection_level(), + "Testing for architecture: " + arch) + cp = os.path.join(path, arch) + + # If any old results XML files exist, clean them up. + for old_result in glob.iglob(os.path.join(cp, "*.result.xml")): + os.remove(old_result) + + # Find and Run any Host Tests + if GetHostInfo().os.upper() == "LINUX": + testList = glob.glob(os.path.join(cp, "*Test*")) + for a in testList[:]: + p = os.path.join(cp, a) + # It must be a file + if not os.path.isfile(p): + testList.remove(a) + logging.debug(f"Remove directory file: {p}") + continue + # It must be executable + if os.stat(p).st_mode & (stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH) == 0: + testList.remove(a) + logging.debug(f"Remove non-executable file: {p}") + continue + + logging.info(f"Test file found: {p}") + + elif GetHostInfo().os.upper() == "WINDOWS": + testList = glob.glob(os.path.join(cp, "*Test*.exe")) + else: + raise NotImplementedError("Unsupported Operating System") + + for test in testList: + # Configure output name. + shell_env.set_shell_var( + 'CMOCKA_XML_FILE', test + ".%g." + arch + ".result.xml") + + # Run the test. + ret = RunCmd('"' + test + '"', "", workingdir=cp) + if(ret != 0): + logging.error("UnitTest Execution Error: " + + os.path.basename(test)) + else: + logging.info("UnitTest Completed: " + + os.path.basename(test)) + file_match_pattern = test + ".*." + arch + ".result.xml" + xml_results_list = glob.glob(file_match_pattern) + for xml_result_file in xml_results_list: + root = xml.etree.ElementTree.parse( + xml_result_file).getroot() + for suite in root: + for case in suite: + for result in case: + if result.tag == 'failure': + logging.warning( + "%s Test Failed" % os.path.basename(test)) + logging.warning( + " %s - %s" % (case.attrib['name'], result.text)) + failure_count += 1 + + return failure_count diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner_plug_in.yaml b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner_plug_in.yaml new file mode 100644 index 00000000..83ae4b3b --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner_plug_in.yaml @@ -0,0 +1,12 @@ +## +# IUefiBuildPlugin used to run any unittests that +# were built on this build. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +{ + "scope": "host-based-test", + "name": "Host-Based Unit Test Runner", + "module": "HostBasedUnitTestRunner" +} diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain.py new file mode 100755 index 00000000..33508e4f --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain.py @@ -0,0 +1,123 @@ +# @file LinuxGcc5ToolChain.py +# Plugin to configures paths for GCC5 ARM/AARCH64 Toolchain +## +# This plugin works in conjuncture with the tools_def +# +# Copyright (c) Microsoft Corporation +# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +import os +import logging +from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin +from edk2toolext.environment import shell_environment + + +class LinuxGcc5ToolChain(IUefiBuildPlugin): + + def do_post_build(self, thebuilder): + return 0 + + def do_pre_build(self, thebuilder): + self.Logger = logging.getLogger("LinuxGcc5ToolChain") + + # + # GCC5 - The ARM and AARCH64 compilers need their paths set if available + if thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "GCC5": + + # Start with AARACH64 compiler + ret = self._check_aarch64() + if ret != 0: + self.Logger.critical("Failed in check aarch64") + return ret + + # Check arm compiler + ret = self._check_arm() + if ret != 0: + self.Logger.critical("Failed in check arm") + return ret + + # Check RISCV64 compiler + ret = self._check_riscv64() + if ret != 0: + self.Logger.critical("Failed in check riscv64") + return ret + + return 0 + + def _check_arm(self): + # check to see if full path already configured + if shell_environment.GetEnvironment().get_shell_var("GCC5_ARM_PREFIX") is not None: + self.Logger.info("GCC5_ARM_PREFIX is already set.") + + else: + # now check for install dir. If set then set the Prefix + install_path = shell_environment.GetEnvironment().get_shell_var("GCC5_ARM_INSTALL") + if install_path is None: + return 0 + + # make GCC5_ARM_PREFIX to align with tools_def.txt + prefix = os.path.join(install_path, "bin", "arm-linux-gnueabihf-") + shell_environment.GetEnvironment().set_shell_var("GCC5_ARM_PREFIX", prefix) + + # now confirm it exists + if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("GCC5_ARM_PREFIX") + "gcc"): + self.Logger.error("Path for GCC5_ARM_PREFIX toolchain is invalid") + return -2 + + return 0 + + def _check_aarch64(self): + # check to see if full path already configured + if shell_environment.GetEnvironment().get_shell_var("GCC5_AARCH64_PREFIX") is not None: + self.Logger.info("GCC5_AARCH64_PREFIX is already set.") + + else: + # now check for install dir. If set then set the Prefix + install_path = shell_environment.GetEnvironment( + ).get_shell_var("GCC5_AARCH64_INSTALL") + if install_path is None: + return 0 + + # make GCC5_AARCH64_PREFIX to align with tools_def.txt + prefix = os.path.join(install_path, "bin", "aarch64-linux-gnu-") + shell_environment.GetEnvironment().set_shell_var("GCC5_AARCH64_PREFIX", prefix) + + # now confirm it exists + if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("GCC5_AARCH64_PREFIX") + "gcc"): + self.Logger.error( + "Path for GCC5_AARCH64_PREFIX toolchain is invalid") + return -2 + + return 0 + + def _check_riscv64(self): + # now check for install dir. If set then set the Prefix + install_path = shell_environment.GetEnvironment( + ).get_shell_var("GCC5_RISCV64_INSTALL") + if install_path is None: + return 0 + + # check to see if full path already configured + if shell_environment.GetEnvironment().get_shell_var("GCC5_RISCV64_PREFIX") is not None: + self.Logger.info("GCC5_RISCV64_PREFIX is already set.") + + else: + # make GCC5_RISCV64_PREFIX to align with tools_def.txt + prefix = os.path.join(install_path, "bin", "riscv64-unknown-elf-") + shell_environment.GetEnvironment().set_shell_var("GCC5_RISCV64_PREFIX", prefix) + + # now confirm it exists + if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("GCC5_RISCV64_PREFIX") + "gcc"): + self.Logger.error( + "Path for GCC5_RISCV64_PREFIX toolchain is invalid") + return -2 + + # Check if LD_LIBRARY_PATH is set for the libraries of RISC-V GCC toolchain + if shell_environment.GetEnvironment().get_shell_var("LD_LIBRARY_PATH") is not None: + self.Logger.info("LD_LIBRARY_PATH is already set.") + + prefix = os.path.join(install_path, "lib") + shell_environment.GetEnvironment().set_shell_var("LD_LIBRARY_PATH", prefix) + + return 0 diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain_plug_in.yaml b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain_plug_in.yaml new file mode 100644 index 00000000..e07441ae --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain_plug_in.yaml @@ -0,0 +1,12 @@ +## @file +# Build Plugin used to set the path +# for the GCC5 ARM/AARCH64 downloaded compilers +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +{ + "scope": "global-nix", + "name": "Linux GCC5 Tool Chain Support", + "module": "LinuxGcc5ToolChain" +} diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py new file mode 100755 index 00000000..5f1bb5a5 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py @@ -0,0 +1,29 @@ +## @file WinRcPath.py +# Plugin to find Windows SDK Resource Compiler rc.exe +## +# This plugin works in conjuncture with the tools_def to support rc.exe +# +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +import os +from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin +import edk2toollib.windows.locate_tools as locate_tools +from edk2toolext.environment import shell_environment +from edk2toolext.environment import version_aggregator + +class WinRcPath(IUefiBuildPlugin): + + def do_post_build(self, thebuilder): + return 0 + + def do_pre_build(self, thebuilder): + #get the locate tools module + path = locate_tools.FindToolInWinSdk("rc.exe") + if path is None: + thebuilder.logging.warning("Failed to find rc.exe") + else: + p = os.path.abspath(os.path.dirname(path)) + shell_environment.GetEnvironment().set_shell_var("WINSDK_PATH_FOR_RC_EXE", p) + version_aggregator.GetVersionAggregator().ReportVersion("WINSDK_PATH_FOR_RC_EXE", p, version_aggregator.VersionTypes.INFO) + return 0 diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath_plug_in.yaml b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath_plug_in.yaml new file mode 100644 index 00000000..9dc55347 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath_plug_in.yaml @@ -0,0 +1,13 @@ +## @file +# Build Plugin used to set the path to rc.exe on windows. +# The plugin is able to use python to locate the tool as to avoid +# hard-coding the path +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +{ + "scope": "global-win", + "name": "Windows RC Path Support", + "module": "WinRcPath" +} diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain.py new file mode 100755 index 00000000..a2dc7f80 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain.py @@ -0,0 +1,207 @@ +# @file WindowsVsToolChain.py +# Plugin to configures paths for the VS2017 and VS2019 tool chain +## +# This plugin works in conjuncture with the tools_def +# +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +import os +import logging +from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin +import edk2toollib.windows.locate_tools as locate_tools +from edk2toollib.windows.locate_tools import FindWithVsWhere +from edk2toolext.environment import shell_environment +from edk2toolext.environment import version_aggregator +from edk2toollib.utility_functions import GetHostInfo + + +class WindowsVsToolChain(IUefiBuildPlugin): + + def do_post_build(self, thebuilder): + return 0 + + def do_pre_build(self, thebuilder): + self.Logger = logging.getLogger("WindowsVsToolChain") + interesting_keys = ["ExtensionSdkDir", "INCLUDE", "LIB", "LIBPATH", "UniversalCRTSdkDir", + "UCRTVersion", "WindowsLibPath", "WindowsSdkBinPath", "WindowsSdkDir", "WindowsSdkVerBinPath", + "WindowsSDKVersion", "VCToolsInstallDir", "Path"] + + # + # VS2017 - Follow VS2017 where there is potential for many versions of the tools. + # If a specific version is required then the user must set both env variables: + # VS150INSTALLPATH: base install path on system to VC install dir. Here you will find the VC folder, etc + # VS150TOOLVER: version number for the VC compiler tools + # VS2017_PREFIX: path to MSVC compiler folder with trailing slash (can be used instead of two vars above) + # VS2017_HOST: set the host architecture to use for host tools, and host libs, etc + if thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "VS2017": + + # check to see if host is configured + # HostType for VS2017 should be (defined in tools_def): + # x86 == 32bit Intel + # x64 == 64bit Intel + # arm == 32bit Arm + # arm64 == 64bit Arm + # + HostType = shell_environment.GetEnvironment().get_shell_var("VS2017_HOST") + if HostType is not None: + HostType = HostType.lower() + self.Logger.info( + f"HOST TYPE defined by environment. Host Type is {HostType}") + else: + HostInfo = GetHostInfo() + if HostInfo.arch == "x86": + if HostInfo.bit == "32": + HostType = "x86" + elif HostInfo.bit == "64": + HostType = "x64" + else: + raise NotImplementedError() + + # VS2017_HOST options are not exactly the same as QueryVcVariables. This translates. + VC_HOST_ARCH_TRANSLATOR = { + "x86": "x86", "x64": "AMD64", "arm": "not supported", "arm64": "not supported"} + + # check to see if full path already configured + if shell_environment.GetEnvironment().get_shell_var("VS2017_PREFIX") != None: + self.Logger.info("VS2017_PREFIX is already set.") + + else: + install_path = self._get_vs_install_path( + "VS2017".lower(), "VS150INSTALLPATH") + vc_ver = self._get_vc_version(install_path, "VS150TOOLVER") + + if install_path is None or vc_ver is None: + self.Logger.error( + "Failed to configure environment for VS2017") + return -1 + + version_aggregator.GetVersionAggregator().ReportVersion( + "Visual Studio Install Path", install_path, version_aggregator.VersionTypes.INFO) + version_aggregator.GetVersionAggregator().ReportVersion( + "VC Version", vc_ver, version_aggregator.VersionTypes.TOOL) + + # make VS2017_PREFIX to align with tools_def.txt + prefix = os.path.join(install_path, "VC", + "Tools", "MSVC", vc_ver) + prefix = prefix + os.path.sep + shell_environment.GetEnvironment().set_shell_var("VS2017_PREFIX", prefix) + shell_environment.GetEnvironment().set_shell_var("VS2017_HOST", HostType) + + shell_env = shell_environment.GetEnvironment() + # Use the tools lib to determine the correct values for the vars that interest us. + vs_vars = locate_tools.QueryVcVariables( + interesting_keys, VC_HOST_ARCH_TRANSLATOR[HostType], vs_version="vs2017") + for (k, v) in vs_vars.items(): + shell_env.set_shell_var(k, v) + + # now confirm it exists + if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("VS2017_PREFIX")): + self.Logger.error("Path for VS2017 toolchain is invalid") + return -2 + + # + # VS2019 - Follow VS2019 where there is potential for many versions of the tools. + # If a specific version is required then the user must set both env variables: + # VS160INSTALLPATH: base install path on system to VC install dir. Here you will find the VC folder, etc + # VS160TOOLVER: version number for the VC compiler tools + # VS2019_PREFIX: path to MSVC compiler folder with trailing slash (can be used instead of two vars above) + # VS2017_HOST: set the host architecture to use for host tools, and host libs, etc + elif thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "VS2019": + + # check to see if host is configured + # HostType for VS2019 should be (defined in tools_def): + # x86 == 32bit Intel + # x64 == 64bit Intel + # arm == 32bit Arm + # arm64 == 64bit Arm + # + HostType = shell_environment.GetEnvironment().get_shell_var("VS2019_HOST") + if HostType is not None: + HostType = HostType.lower() + self.Logger.info( + f"HOST TYPE defined by environment. Host Type is {HostType}") + else: + HostInfo = GetHostInfo() + if HostInfo.arch == "x86": + if HostInfo.bit == "32": + HostType = "x86" + elif HostInfo.bit == "64": + HostType = "x64" + else: + raise NotImplementedError() + + # VS2019_HOST options are not exactly the same as QueryVcVariables. This translates. + VC_HOST_ARCH_TRANSLATOR = { + "x86": "x86", "x64": "AMD64", "arm": "not supported", "arm64": "not supported"} + + # check to see if full path already configured + if shell_environment.GetEnvironment().get_shell_var("VS2019_PREFIX") != None: + self.Logger.info("VS2019_PREFIX is already set.") + + else: + install_path = self._get_vs_install_path( + "VS2019".lower(), "VS160INSTALLPATH") + vc_ver = self._get_vc_version(install_path, "VS160TOOLVER") + + if install_path is None or vc_ver is None: + self.Logger.error( + "Failed to configure environment for VS2019") + return -1 + + version_aggregator.GetVersionAggregator().ReportVersion( + "Visual Studio Install Path", install_path, version_aggregator.VersionTypes.INFO) + version_aggregator.GetVersionAggregator().ReportVersion( + "VC Version", vc_ver, version_aggregator.VersionTypes.TOOL) + + # make VS2019_PREFIX to align with tools_def.txt + prefix = os.path.join(install_path, "VC", + "Tools", "MSVC", vc_ver) + prefix = prefix + os.path.sep + shell_environment.GetEnvironment().set_shell_var("VS2019_PREFIX", prefix) + shell_environment.GetEnvironment().set_shell_var("VS2019_HOST", HostType) + + shell_env = shell_environment.GetEnvironment() + # Use the tools lib to determine the correct values for the vars that interest us. + vs_vars = locate_tools.QueryVcVariables( + interesting_keys, VC_HOST_ARCH_TRANSLATOR[HostType], vs_version="vs2019") + for (k, v) in vs_vars.items(): + shell_env.set_shell_var(k, v) + + # now confirm it exists + if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("VS2019_PREFIX")): + self.Logger.error("Path for VS2019 toolchain is invalid") + return -2 + + return 0 + + def _get_vs_install_path(self, vs_version, varname): + # check if already specified + path = shell_environment.GetEnvironment().get_shell_var(varname) + if(path is None): + # Not specified...find latest + (rc, path) = FindWithVsWhere(vs_version=vs_version) + if rc == 0 and path is not None and os.path.exists(path): + self.Logger.debug("Found VS instance for %s", vs_version) + else: + self.Logger.error( + "Failed to find VS instance with VsWhere (%d)" % rc) + return path + + def _get_vc_version(self, path, varname): + # check if already specified + vc_ver = shell_environment.GetEnvironment().get_shell_var(varname) + if (path is None): + self.Logger.critical( + "Failed to find Visual Studio tools. Might need to check for VS install") + return vc_ver + if(vc_ver is None): + # Not specified...find latest + p2 = os.path.join(path, "VC", "Tools", "MSVC") + if not os.path.isdir(p2): + self.Logger.critical( + "Failed to find VC tools. Might need to check for VS install") + return vc_ver + vc_ver = os.listdir(p2)[-1].strip() # get last in list + self.Logger.debug("Found VC Tool version is %s" % vc_ver) + return vc_ver diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain_plug_in.yaml b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain_plug_in.yaml new file mode 100644 index 00000000..16a7658a --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain_plug_in.yaml @@ -0,0 +1,11 @@ +## @file +# Build Plugin used to set the path to the visual studio tools chain +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +{ + "scope": "global-win", + "name": "Windows Visual Studio Tool Chain Support", + "module": "WindowsVsToolChain" +} |