VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/BaseTools/Edk2ToolsBuild.py

最後變更 在這個檔案是 101291,由 vboxsync 提交於 14 月 前

EFI/FirmwareNew: Make edk2-stable202308 build on all supported platforms (using gcc at least, msvc not tested yet), bugref:4643

  • 屬性 svn:eol-style 設為 native
檔案大小: 6.6 KB
 
1# @file Edk2ToolsBuild.py
2# Invocable class that builds the basetool c files.
3#
4# Supports VS2017, VS2019, and GCC5
5##
6# Copyright (c) Microsoft Corporation
7#
8# SPDX-License-Identifier: BSD-2-Clause-Patent
9##
10import os
11import sys
12import logging
13import argparse
14import multiprocessing
15from edk2toolext import edk2_logging
16from edk2toolext.environment import self_describing_environment
17from edk2toolext.base_abstract_invocable import BaseAbstractInvocable
18from edk2toollib.utility_functions import RunCmd
19from edk2toollib.windows.locate_tools import QueryVcVariables
20
21
22class Edk2ToolsBuild(BaseAbstractInvocable):
23
24 def ParseCommandLineOptions(self):
25 ''' parse arguments '''
26 ParserObj = argparse.ArgumentParser()
27 ParserObj.add_argument("-t", "--tool_chain_tag", dest="tct", default="VS2017",
28 help="Set the toolchain used to compile the build tools")
29 args = ParserObj.parse_args()
30 self.tool_chain_tag = args.tct
31
32 def GetWorkspaceRoot(self):
33 ''' Return the workspace root for initializing the SDE '''
34
35 # this is the bastools dir...not the traditional EDK2 workspace root
36 return os.path.dirname(os.path.abspath(__file__))
37
38 def GetActiveScopes(self):
39 ''' return tuple containing scopes that should be active for this process '''
40
41 # for now don't use scopes
42 return ('global',)
43
44 def GetLoggingLevel(self, loggerType):
45 ''' Get the logging level for a given type (return Logging.Level)
46 base == lowest logging level supported
47 con == Screen logging
48 txt == plain text file logging
49 md == markdown file logging
50 '''
51 if(loggerType == "con"):
52 return logging.ERROR
53 else:
54 return logging.DEBUG
55
56 def GetLoggingFolderRelativeToRoot(self):
57 ''' Return a path to folder for log files '''
58 return "BaseToolsBuild"
59
60 def GetVerifyCheckRequired(self):
61 ''' Will call self_describing_environment.VerifyEnvironment if this returns True '''
62 return True
63
64 def GetLoggingFileName(self, loggerType):
65 ''' Get the logging file name for the type.
66 Return None if the logger shouldn't be created
67
68 base == lowest logging level supported
69 con == Screen logging
70 txt == plain text file logging
71 md == markdown file logging
72 '''
73 return "BASETOOLS_BUILD"
74
75 def WritePathEnvFile(self, OutputDir):
76 ''' Write a PyTool path env file for future PyTool based edk2 builds'''
77 content = '''##
78# Set shell variable EDK_TOOLS_BIN to this folder
79#
80# Autogenerated by Edk2ToolsBuild.py
81#
82# Copyright (c), Microsoft Corporation
83# SPDX-License-Identifier: BSD-2-Clause-Patent
84##
85{
86 "id": "You-Built-BaseTools",
87 "scope": "edk2-build",
88 "flags": ["set_shell_var", "set_path"],
89 "var_name": "EDK_TOOLS_BIN"
90}
91'''
92 with open(os.path.join(OutputDir, "basetoolsbin_path_env.yaml"), "w") as f:
93 f.write(content)
94
95 def Go(self):
96 logging.info("Running Python version: " + str(sys.version_info))
97
98 (build_env, shell_env) = self_describing_environment.BootstrapEnvironment(
99 self.GetWorkspaceRoot(), self.GetActiveScopes())
100
101 # # Bind our current execution environment into the shell vars.
102 ph = os.path.dirname(sys.executable)
103 if " " in ph:
104 ph = '"' + ph + '"'
105 shell_env.set_shell_var("PYTHON_HOME", ph)
106 # PYTHON_COMMAND is required to be set for using edk2 python builds.
107 pc = sys.executable
108 if " " in pc:
109 pc = '"' + pc + '"'
110 shell_env.set_shell_var("PYTHON_COMMAND", pc)
111
112 if self.tool_chain_tag.lower().startswith("vs"):
113
114 # # Update environment with required VC vars.
115 interesting_keys = ["ExtensionSdkDir", "INCLUDE", "LIB"]
116 interesting_keys.extend(
117 ["LIBPATH", "Path", "UniversalCRTSdkDir", "UCRTVersion", "WindowsLibPath", "WindowsSdkBinPath"])
118 interesting_keys.extend(
119 ["WindowsSdkDir", "WindowsSdkVerBinPath", "WindowsSDKVersion", "VCToolsInstallDir"])
120 vc_vars = QueryVcVariables(
121 interesting_keys, 'x86', vs_version=self.tool_chain_tag.lower())
122 for key in vc_vars.keys():
123 logging.debug(f"Var - {key} = {vc_vars[key]}")
124 if key.lower() == 'path':
125 shell_env.set_path(vc_vars[key])
126 else:
127 shell_env.set_shell_var(key, vc_vars[key])
128
129 self.OutputDir = os.path.join(
130 shell_env.get_shell_var("EDK_TOOLS_PATH"), "Bin", "Win32")
131
132 # compiled tools need to be added to path because antlr is referenced
133 shell_env.insert_path(self.OutputDir)
134
135 # Actually build the tools.
136 output_stream = edk2_logging.create_output_stream()
137 ret = RunCmd('nmake.exe', None,
138 workingdir=shell_env.get_shell_var("EDK_TOOLS_PATH"))
139 edk2_logging.remove_output_stream(output_stream)
140 problems = edk2_logging.scan_compiler_output(output_stream)
141 for level, problem in problems:
142 logging.log(level, problem)
143 if ret != 0:
144 raise Exception("Failed to build.")
145
146 self.WritePathEnvFile(self.OutputDir)
147 return ret
148
149 elif self.tool_chain_tag.lower().startswith("gcc"):
150 cpu_count = self.GetCpuThreads()
151
152 output_stream = edk2_logging.create_output_stream()
153 ret = RunCmd("make", f"-C . -j {cpu_count}", workingdir=shell_env.get_shell_var("EDK_TOOLS_PATH"))
154 edk2_logging.remove_output_stream(output_stream)
155 problems = edk2_logging.scan_compiler_output(output_stream)
156 for level, problem in problems:
157 logging.log(level, problem)
158 if ret != 0:
159 raise Exception("Failed to build.")
160
161 self.OutputDir = os.path.join(
162 shell_env.get_shell_var("EDK_TOOLS_PATH"), "Source", "C", "bin")
163
164 self.WritePathEnvFile(self.OutputDir)
165 return ret
166
167 logging.critical("Tool Chain not supported")
168 return -1
169
170 def GetCpuThreads(self) -> int:
171 ''' Function to return number of cpus. If error return 1'''
172 cpus = 1
173 try:
174 cpus = multiprocessing.cpu_count()
175 except:
176 # from the internet there are cases where cpu_count is not implemented.
177 # will handle error by just doing single proc build
178 pass
179 return cpus
180
181
182
183def main():
184 Edk2ToolsBuild().Invoke()
185
186
187if __name__ == "__main__":
188 main()
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette