From c49d00ea5f95de8f26bd40fbcbc60ae655dc66ba Mon Sep 17 00:00:00 2001 From: Joey Vagedes Date: Mon, 14 Aug 2023 11:43:37 -0700 Subject: [PATCH] WinRcPath: improve performance (#512) ## Description WinRcPath generally takes about 2 seconds to run, due to calling multiple .bat files behind the scenes. This change reduces this time to ~0 seconds due to the following changes: 1. It will attempt to load the path from the cache, which is located a $(WORKSPACE)/Conf/.rc_path. If the loading is a success and the rc_path still exists, it will use it. 2. If the cache did not exist, or the path provided by the cache does not exist, it will find the rc path via the .bat files. If that succeeds, it will write the path to the cache. - [ ] Impacts functionality? - **Functionality** - Does the change ultimately impact how firmware functions? - Examples: Add a new library, publish a new PPI, update an algorithm, ... - [ ] Impacts security? - **Security** - Does the change have a direct security impact on an application, flow, or firmware? - Examples: Crypto algorithm change, buffer overflow fix, parameter validation improvement, ... - [ ] Breaking change? - **Breaking change** - Will anyone consuming this change experience a break in build or boot behavior? - Examples: Add a new library class, move a module to a different repo, call a function in a new library class in a pre-existing module, ... - [ ] Includes tests? - **Tests** - Does the change include any explicit test code? - Examples: Unit tests, integration tests, robot tests, ... - [ ] Includes documentation? - **Documentation** - Does the change contain explicit documentation additions outside direct code modifications (and comments)? - Examples: Update readme file, add feature readme file, link to documentation on an a separate Web page, ... ## How This Was Tested 1. Confirmed the plugin will create a cache file on first run and use it in later runs 2. Confirmed updating the path in the cache to a wrong value will invoke the typical means to find the cache and save the correct path into the cache ## Integration Instructions N/A --- .../WindowsResourceCompiler/WinRcPath.py | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py b/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py index 3d7f3daa3e..243d6ba6d7 100644 --- a/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py +++ b/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py @@ -6,27 +6,42 @@ # 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 edk2toolext.environment import shell_environment from edk2toolext.environment import version_aggregator +from pathlib import Path +# MU_CHANGE Entire File - Perf improvements class WinRcPath(IUefiBuildPlugin): - def do_post_build(self, thebuilder): - return 0 - def do_pre_build(self, thebuilder): #get the locate tools module + + # Check if the rc.exe path is already cached and still exists + cache_path = Path(thebuilder.ws, "Conf", ".rc_path") + if cache_path.exists(): + with open(cache_path, "r") as f: + rc_path = Path(f.readline().strip()).absolute() + if (rc_path / "rc.exe").exists(): + logging.debug(f"Found rc.exe folder in cache: {rc_path}") + self._set_path(rc_path) + return 0 + + # If it does not exist, try to find it with FindToolInWinSdk path = locate_tools.FindToolInWinSdk("rc.exe") if path is None: logging.critical("Failed to find rc.exe") return 1 - 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 + + path = Path(path).absolute().parent + self._set_path(path) + cache_path.unlink(missing_ok=True) + with cache_path.open("w") as f: + f.write(str(path)) return 0 + + def _set_path(self, path: Path): + shell_environment.GetEnvironment().set_shell_var("WINSDK_PATH_FOR_RC_EXE", str(path)) + version_aggregator.GetVersionAggregator().ReportVersion("WINSDK_PATH_FOR_RC_EXE", str(path), version_aggregator.VersionTypes.INFO)