--- /dev/null
+##\r
+# Copyright (c) Microsoft Corporation.\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+import os\r
+import logging\r
+import json\r
+\r
+try:\r
+ from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin\r
+\r
+ class BuildToolsReportGenerator(IUefiBuildPlugin):\r
+ def do_report(self, thebuilder):\r
+ try:\r
+ from edk2toolext.environment import version_aggregator\r
+ except ImportError:\r
+ logging.critical("Loading BuildToolsReportGenerator failed, please update your Edk2-PyTool-Extensions")\r
+ return 0\r
+\r
+ OutputReport = os.path.join(thebuilder.env.GetValue("BUILD_OUTPUT_BASE"), "BUILD_TOOLS_REPORT")\r
+ OutputReport = os.path.normpath(OutputReport)\r
+ if not os.path.isdir(os.path.dirname(OutputReport)):\r
+ os.makedirs(os.path.dirname(OutputReport))\r
+\r
+ Report = BuildToolsReport()\r
+ Report.MakeReport(version_aggregator.GetVersionAggregator().GetAggregatedVersionInformation(), OutputReport=OutputReport)\r
+\r
+ def do_pre_build(self, thebuilder):\r
+ self.do_report(thebuilder)\r
+ return 0\r
+\r
+ def do_post_build(self, thebuilder):\r
+ self.do_report(thebuilder)\r
+ return 0\r
+\r
+except ImportError:\r
+ pass\r
+\r
+\r
+class BuildToolsReport(object):\r
+ MY_FOLDER = os.path.dirname(os.path.realpath(__file__))\r
+ VERSION = "1.00"\r
+\r
+ def __init__(self):\r
+ pass\r
+\r
+ def MakeReport(self, BuildTools, OutputReport="BuildToolsReport"):\r
+ logging.info("Writing BuildToolsReports to {0}".format(OutputReport))\r
+ versions_list = []\r
+ for key, value in BuildTools.items():\r
+ versions_list.append(value)\r
+ versions_list = sorted(versions_list, key=lambda k: k['type'])\r
+ json_dict = {"modules": versions_list,\r
+ "PluginVersion": BuildToolsReport.VERSION}\r
+\r
+ htmlfile = open(OutputReport + ".html", "w")\r
+ jsonfile = open(OutputReport + ".json", "w")\r
+ template = open(os.path.join(BuildToolsReport.MY_FOLDER, "BuildToolsReport_Template.html"), "r")\r
+\r
+ for line in template.readlines():\r
+ if "%TO_BE_FILLED_IN_BY_PYTHON_SCRIPT%" in line:\r
+ line = line.replace("%TO_BE_FILLED_IN_BY_PYTHON_SCRIPT%", json.dumps(json_dict))\r
+ htmlfile.write(line)\r
+\r
+ jsonfile.write(json.dumps(versions_list, indent=4))\r
+\r
+ jsonfile.close()\r
+ template.close()\r
+ htmlfile.close()\r
--- /dev/null
+## @file\r
+# Build Plugin used to output html report of all versions collected\r
+# during the build\r
+#\r
+# Copyright (c) Microsoft Corporation.\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+{\r
+ "scope": "global",\r
+ "name": "Build Tools Report Generator",\r
+ "module": "BuildToolsReportGenerator"\r
+}\r
--- /dev/null
+<!doctype html>\r
+<html lang="en">\r
+<head>\r
+ <meta charset="utf-8">\r
+ <meta http-equiv="X-UA-Compatible">\r
+ <title>Build Tools Report</title>\r
+ <meta name="viewport" content="width=device-width, initial-scale=1">\r
+ <link rel="stylesheet" type="text/css" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css" />\r
+ <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.15/css/dataTables.bootstrap.min.css" />\r
+ <style>\r
+ div.attribution {\r
+ border: 1px solid #ddd;\r
+ background-color: #bbb;\r
+ padding-left: 20px;\r
+ }\r
+ </style>\r
+</head>\r
+<body>\r
+ <div class="container-fluid">\r
+ <h1>Build Tools Report</h1>\r
+ <ul class="nav nav-tabs">\r
+ <li class="active"><a data-toggle="tab" href="#tabs-1">Tools</a></li>\r
+ <li><a data-toggle="tab" href="#tabs-2">About</a></li>\r
+ </ul>\r
+ <div class="tab-content">\r
+ <div id="tabs-1" class="tab-pane fade in active">\r
+ <table id="modinfo" class="table table-striped table-bordered table-hover" cellspacing="0">\r
+ <thead>\r
+ <tr>\r
+ <th>Key</th>\r
+ <th>Value</th>\r
+ <th>Type</th>\r
+ </tr>\r
+ </thead>\r
+ <tbody></tbody>\r
+ </table>\r
+ </div>\r
+ <div id="tabs-2" class="tab-pane">\r
+ <div class="row">\r
+ <div class="col-xs-7">\r
+ <p></p>\r
+ <p>\r
+ Build Tools Report Template Version: <span id="ReportTemplateVersion">1.00</span><br />\r
+ Build Tools Report Plugin Version: <span id='ReportToolVersion'></span><br />\r
+ </p>\r
+ <h3>License</h3>\r
+ <hr />\r
+ <div id="ToolLicenseContent">\r
+ <p>\r
+ <span class="copyright">Copyright (c) Microsoft Corporation.</span><br />\r
+ <span class="license">\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ </span>\r
+ </p>\r
+ </div>\r
+ </div>\r
+ <div id="AttributionListWrapper" class="col-xs-5">\r
+ <h3>External Licenses</h3>\r
+ </div>\r
+ </div>\r
+ </div>\r
+ </div>\r
+ </div>\r
+\r
+ <!-- Javascript libraries -->\r
+ <script type="text/javascript" charset="utf8" src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>\r
+ <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>\r
+ <script type="text/javascript" charset="utf8" src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"></script>\r
+ <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.15/js/dataTables.bootstrap.min.js"></script>\r
+\r
+ <script>\r
+ var EmbeddedJd = %TO_BE_FILLED_IN_BY_PYTHON_SCRIPT%;\r
+ </script>\r
+ <!-- Add javascript here -->\r
+ <script>\r
+ var MODULE_TABLE_OFFSET = 350; //Space needed for other stuff besides the Table\r
+ $(document).ready(function () {\r
+ $('span#ReportToolVersion').text(EmbeddedJd.PluginVersion);\r
+ //To support tabs and correct column width we need this change\r
+ $('a[data-toggle="tab"][href="#tabs-1"]').on('shown.bs.tab', function (e) {\r
+ $.fn.dataTable.tables({ visible: true, api: true }).columns.adjust();\r
+ });\r
+ //table for modules\r
+ var mTable = $('table#modinfo').dataTable({\r
+ "aaData": EmbeddedJd.modules,\r
+ "paginate": false,\r
+ "autoWidth": false,\r
+ "scrollY": ($(window).height() - MODULE_TABLE_OFFSET) + "px",\r
+ "aaSorting": [[2, "asc"]],\r
+ "aoColumnDefs": [\r
+ {\r
+ "mData": "name",\r
+ "aTargets": [0]\r
+ },\r
+\r
+ {\r
+ "mData": "version",\r
+ "aTargets": [1]\r
+ },\r
+ {\r
+ "mData": "type",\r
+ "aTargets": [2],\r
+ }\r
+ ] //end of column def\r
+ }); //end of modules table\r
+\r
+ //\r
+ // Create Attribution List for all external libraries used\r
+ //\r
+ [\r
+ { Title: "JQuery", Copyright: "Copyright 2017 The jQuery Foundation", Version: $.fn.jquery, LicenseType: "MIT", LicenseLink: "https://jquery.org/license/" },\r
+ { 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" },\r
+ { 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" }\r
+ ].forEach(function (element) {\r
+ $("<div class='attribution'><h4>" + element.Title + "</h4><p>Version: <span class='version'>" + element.Version + "</span><br /><span class='copyright'>" +\r
+ element.Copyright + "</span><br />License: <a class='license' href='" + element.LicenseLink + "'>" + element.LicenseType + "</a></p></div>").appendTo("div#AttributionListWrapper");\r
+ });\r
+ });\r
+ $(window).resize(function() {\r
+ $.fn.dataTable.tables({ visible: true, api: true }).columns.adjust();\r
+ });\r
+\r
+\r
+ </script>\r
+</body>\r
+</html>\r
--- /dev/null
+# @file LinuxGcc5ToolChain.py\r
+# Plugin to configures paths for GCC5 ARM/AARCH64 Toolchain\r
+##\r
+# This plugin works in conjuncture with the tools_def\r
+#\r
+# Copyright (c) Microsoft Corporation\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+import os\r
+import logging\r
+from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin\r
+from edk2toolext.environment import shell_environment\r
+\r
+\r
+class LinuxGcc5ToolChain(IUefiBuildPlugin):\r
+\r
+ def do_post_build(self, thebuilder):\r
+ return 0\r
+\r
+ def do_pre_build(self, thebuilder):\r
+ self.Logger = logging.getLogger("LinuxGcc5ToolChain")\r
+\r
+ #\r
+ # GCC5 - The ARM and AARCH64 compilers need their paths set if available\r
+ if thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "GCC5":\r
+\r
+ # Start with AARACH64 compiler\r
+ ret = self._check_aarch64()\r
+ if ret != 0:\r
+ self.Logger.critical("Failed in check aarch64")\r
+ return ret\r
+\r
+ # Check arm compiler\r
+ ret = self._check_arm()\r
+ if ret != 0:\r
+ self.Logger.critical("Failed in check arm")\r
+ return ret\r
+\r
+ return 0\r
+\r
+ def _check_arm(self):\r
+ # check to see if full path already configured\r
+ if shell_environment.GetEnvironment().get_shell_var("GCC5_ARM_PREFIX") is not None:\r
+ self.Logger.info("GCC5_ARM_PREFIX is already set.")\r
+\r
+ else:\r
+ # now check for install dir. If set then set the Prefix\r
+ install_path = shell_environment.GetEnvironment().get_shell_var("GCC5_ARM_INSTALL")\r
+ if install_path is None:\r
+ return 0\r
+\r
+ # make GCC5_ARM_PREFIX to align with tools_def.txt\r
+ prefix = os.path.join(install_path, "bin", "arm-linux-gnueabihf-")\r
+ shell_environment.GetEnvironment().set_shell_var("GCC5_ARM_PREFIX", prefix)\r
+\r
+ # now confirm it exists\r
+ if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("GCC5_ARM_PREFIX") + "gcc"):\r
+ self.Logger.error("Path for GCC5_ARM_PREFIX toolchain is invalid")\r
+ return -2\r
+\r
+ return 0\r
+\r
+ def _check_aarch64(self):\r
+ # check to see if full path already configured\r
+ if shell_environment.GetEnvironment().get_shell_var("GCC5_AARCH64_PREFIX") is not None:\r
+ self.Logger.info("GCC5_AARCH64_PREFIX is already set.")\r
+\r
+ else:\r
+ # now check for install dir. If set then set the Prefix\r
+ install_path = shell_environment.GetEnvironment(\r
+ ).get_shell_var("GCC5_AARCH64_INSTALL")\r
+ if install_path is None:\r
+ return 0\r
+\r
+ # make GCC5_AARCH64_PREFIX to align with tools_def.txt\r
+ prefix = os.path.join(install_path, "bin", "aarch64-linux-gnu-")\r
+ shell_environment.GetEnvironment().set_shell_var("GCC5_AARCH64_PREFIX", prefix)\r
+\r
+ # now confirm it exists\r
+ if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("GCC5_AARCH64_PREFIX") + "gcc"):\r
+ self.Logger.error(\r
+ "Path for GCC5_AARCH64_PREFIX toolchain is invalid")\r
+ return -2\r
+\r
+ return 0\r
--- /dev/null
+## @file\r
+# Build Plugin used to set the path\r
+# for the GCC5 ARM/AARCH64 downloaded compilers\r
+#\r
+# Copyright (c) Microsoft Corporation.\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+{\r
+ "scope": "global-nix",\r
+ "name": "Linux GCC5 Tool Chain Support",\r
+ "module": "LinuxGcc5ToolChain"\r
+}\r
--- /dev/null
+## @file WinRcPath.py\r
+# Plugin to find Windows SDK Resource Compiler rc.exe\r
+##\r
+# This plugin works in conjuncture with the tools_def to support rc.exe\r
+#\r
+# Copyright (c) Microsoft Corporation\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+import os\r
+from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin\r
+import edk2toollib.windows.locate_tools as locate_tools\r
+from edk2toolext.environment import shell_environment\r
+from edk2toolext.environment import version_aggregator\r
+\r
+class WinRcPath(IUefiBuildPlugin):\r
+\r
+ def do_post_build(self, thebuilder):\r
+ return 0\r
+\r
+ def do_pre_build(self, thebuilder):\r
+ #get the locate tools module\r
+ path = locate_tools.FindToolInWinSdk("rc.exe")\r
+ if path is None:\r
+ thebuilder.logging.warning("Failed to find rc.exe")\r
+ else:\r
+ p = os.path.abspath(os.path.dirname(path))\r
+ shell_environment.GetEnvironment().set_shell_var("WINSDK_PATH_FOR_RC_EXE", p)\r
+ version_aggregator.GetVersionAggregator().ReportVersion("WINSDK_PATH_FOR_RC_EXE", p, version_aggregator.VersionTypes.INFO)\r
+ return 0\r
--- /dev/null
+## @file\r
+# Build Plugin used to set the path to rc.exe on windows.\r
+# The plugin is able to use python to locate the tool as to avoid\r
+# hard-coding the path\r
+#\r
+# Copyright (c) Microsoft Corporation.\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+{\r
+ "scope": "global-win",\r
+ "name": "Windows RC Path Support",\r
+ "module": "WinRcPath"\r
+}\r
--- /dev/null
+## @file WindowsVsToolChain.py\r
+# Plugin to configures paths for the VS2017 and VS2019 tool chain\r
+##\r
+# This plugin works in conjuncture with the tools_def\r
+#\r
+# Copyright (c) Microsoft Corporation\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+import os\r
+import logging\r
+from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin\r
+import edk2toollib.windows.locate_tools as locate_tools\r
+from edk2toollib.windows.locate_tools import FindWithVsWhere\r
+from edk2toolext.environment import shell_environment\r
+from edk2toolext.environment import version_aggregator\r
+\r
+class WindowsVsToolChain(IUefiBuildPlugin):\r
+\r
+ def do_post_build(self, thebuilder):\r
+ return 0\r
+\r
+ def do_pre_build(self, thebuilder):\r
+ self.Logger = logging.getLogger("WindowsVsToolChain")\r
+\r
+#\r
+ # VS2017 - Follow VS2017 where there is potential for many versions of the tools.\r
+ # If a specific version is required then the user must set both env variables:\r
+ ## VS150INSTALLPATH: base install path on system to VC install dir. Here you will find the VC folder, etc\r
+ ## VS150TOOLVER: version number for the VC compiler tools\r
+ ## VS2017_PREFIX: path to MSVC compiler folder with trailing slash (can be used instead of two vars above)\r
+ if thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "VS2017":\r
+\r
+ # check to see if full path already configured\r
+ if shell_environment.GetEnvironment().get_shell_var("VS2017_PREFIX") != None:\r
+ self.Logger.info("VS2017_PREFIX is already set.")\r
+\r
+ else:\r
+ install_path = self._get_vs_install_path("VS2017".lower(), "VS150INSTALLPATH")\r
+ vc_ver = self._get_vc_version(install_path, "VS150TOOLVER")\r
+\r
+ if install_path is None or vc_ver is None:\r
+ self.Logger.error("Failed to configure environment for VS2017")\r
+ return -1\r
+\r
+ version_aggregator.GetVersionAggregator().ReportVersion(\r
+ "Visual Studio Install Path", install_path, version_aggregator.VersionTypes.INFO)\r
+ version_aggregator.GetVersionAggregator().ReportVersion(\r
+ "VC Version", vc_ver, version_aggregator.VersionTypes.TOOL)\r
+\r
+ #make VS2017_PREFIX to align with tools_def.txt\r
+ prefix = os.path.join(install_path, "VC", "Tools", "MSVC", vc_ver)\r
+ prefix = prefix + os.path.sep\r
+ shell_environment.GetEnvironment().set_shell_var("VS2017_PREFIX", prefix)\r
+\r
+ # now confirm it exists\r
+ if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("VS2017_PREFIX")):\r
+ self.Logger.error("Path for VS2017 toolchain is invalid")\r
+ return -2\r
+\r
+ #\r
+ # VS2019 - Follow VS2019 where there is potential for many versions of the tools.\r
+ # If a specific version is required then the user must set both env variables:\r
+ ## VS160INSTALLPATH: base install path on system to VC install dir. Here you will find the VC folder, etc\r
+ ## VS160TOOLVER: version number for the VC compiler tools\r
+ ## VS2019_PREFIX: path to MSVC compiler folder with trailing slash (can be used instead of two vars above)\r
+ elif thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "VS2019":\r
+\r
+ # check to see if full path already configured\r
+ if shell_environment.GetEnvironment().get_shell_var("VS2019_PREFIX") != None:\r
+ self.Logger.info("VS2019_PREFIX is already set.")\r
+\r
+ else:\r
+ install_path = self._get_vs_install_path("VS2019".lower(), "VS160INSTALLPATH")\r
+ vc_ver = self._get_vc_version(install_path, "VS160TOOLVER")\r
+\r
+ if install_path is None or vc_ver is None:\r
+ self.Logger.error("Failed to configure environment for VS2019")\r
+ return -1\r
+\r
+ version_aggregator.GetVersionAggregator().ReportVersion(\r
+ "Visual Studio Install Path", install_path, version_aggregator.VersionTypes.INFO)\r
+ version_aggregator.GetVersionAggregator().ReportVersion(\r
+ "VC Version", vc_ver, version_aggregator.VersionTypes.TOOL)\r
+\r
+ #make VS2019_PREFIX to align with tools_def.txt\r
+ prefix = os.path.join(install_path, "VC", "Tools", "MSVC", vc_ver)\r
+ prefix = prefix + os.path.sep\r
+ shell_environment.GetEnvironment().set_shell_var("VS2019_PREFIX", prefix)\r
+\r
+ # now confirm it exists\r
+ if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("VS2019_PREFIX")):\r
+ self.Logger.error("Path for VS2019 toolchain is invalid")\r
+ return -2\r
+\r
+ return 0\r
+\r
+ def _get_vs_install_path(self, vs_version, varname):\r
+ # check if already specified\r
+ path = shell_environment.GetEnvironment().get_shell_var(varname)\r
+ if(path is None):\r
+ # Not specified...find latest\r
+ (rc, path) = FindWithVsWhere(vs_version=vs_version)\r
+ if rc == 0 and path is not None and os.path.exists(path):\r
+ self.Logger.debug("Found VS instance for %s", vs_version)\r
+ else:\r
+ self.Logger.error("Failed to find VS instance with VsWhere (%d)" % rc)\r
+ return path\r
+\r
+ def _get_vc_version(self, path, varname):\r
+ # check if already specified\r
+ vc_ver = shell_environment.GetEnvironment().get_shell_var(varname)\r
+ if (path is None):\r
+ self.Logger.critical("Failed to find Visual Studio tools. Might need to check for VS install")\r
+ return vc_ver\r
+ if(vc_ver is None):\r
+ # Not specified...find latest\r
+ p2 = os.path.join(path, "VC", "Tools", "MSVC")\r
+ if not os.path.isdir(p2):\r
+ self.Logger.critical(\r
+ "Failed to find VC tools. Might need to check for VS install")\r
+ return vc_ver\r
+ vc_ver = os.listdir(p2)[-1].strip() # get last in list\r
+ self.Logger.debug("Found VC Tool version is %s" % vc_ver)\r
+ return vc_ver\r
+\r
+\r
--- /dev/null
+## @file\r
+# Build Plugin used to set the path to the visual studio tools chain\r
+#\r
+# Copyright (c) Microsoft Corporation.\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+{\r
+ "scope": "global-win",\r
+ "name": "Windows Visual Studio Tool Chain Support",\r
+ "module": "WindowsVsToolChain"\r
+}\r