]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Edk2ToolsBuild.py
BaseTools: Add YAML files with path env and tool extdeps
[mirror_edk2.git] / BaseTools / Edk2ToolsBuild.py
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 ##
10 import os
11 import sys
12 import logging
13 import argparse
14 from edk2toolext import edk2_logging
15 from edk2toolext.environment import self_describing_environment
16 from edk2toolext.base_abstract_invocable import BaseAbstractInvocable
17 from edk2toollib.utility_functions import RunCmd
18 from edk2toollib.windows.locate_tools import QueryVcVariables
19
20
21 class Edk2ToolsBuild(BaseAbstractInvocable):
22
23 def ParseCommandLineOptions(self):
24 ''' parse arguments '''
25 ParserObj = argparse.ArgumentParser()
26 ParserObj.add_argument("-t", "--tool_chain_tag", dest="tct", default="VS2017",
27 help="Set the toolchain used to compile the build tools")
28 args = ParserObj.parse_args()
29 self.tool_chain_tag = args.tct
30
31 def GetWorkspaceRoot(self):
32 ''' Return the workspace root for initializing the SDE '''
33
34 # this is the bastools dir...not the traditional EDK2 workspace root
35 return os.path.dirname(os.path.abspath(__file__))
36
37 def GetActiveScopes(self):
38 ''' return tuple containing scopes that should be active for this process '''
39
40 # for now don't use scopes
41 return ('global',)
42
43 def GetLoggingLevel(self, loggerType):
44 ''' Get the logging level for a given type (return Logging.Level)
45 base == lowest logging level supported
46 con == Screen logging
47 txt == plain text file logging
48 md == markdown file logging
49 '''
50 if(loggerType == "con"):
51 return logging.ERROR
52 else:
53 return logging.DEBUG
54
55 def GetLoggingFolderRelativeToRoot(self):
56 ''' Return a path to folder for log files '''
57 return "BaseToolsBuild"
58
59 def GetVerifyCheckRequired(self):
60 ''' Will call self_describing_environment.VerifyEnvironment if this returns True '''
61 return True
62
63 def GetLoggingFileName(self, loggerType):
64 ''' Get the logging file name for the type.
65 Return None if the logger shouldn't be created
66
67 base == lowest logging level supported
68 con == Screen logging
69 txt == plain text file logging
70 md == markdown file logging
71 '''
72 return "BASETOOLS_BUILD"
73
74 def WritePathEnvFile(self, OutputDir):
75 ''' Write a PyTool path env file for future PyTool based edk2 builds'''
76 content = '''##
77 # Set shell variable EDK_TOOLS_BIN to this folder
78 #
79 # Autogenerated by Edk2ToolsBuild.py
80 #
81 # Copyright (c), Microsoft Corporation
82 # SPDX-License-Identifier: BSD-2-Clause-Patent
83 ##
84 {
85 "id": "You-Built-BaseTools",
86 "scope": "edk2-build",
87 "flags": ["set_shell_var", "set_path"],
88 "var_name": "EDK_TOOLS_BIN"
89 }
90 '''
91 with open(os.path.join(OutputDir, "basetoolsbin_path_env.yaml"), "w") as f:
92 f.write(content)
93
94 def Go(self):
95 logging.info("Running Python version: " + str(sys.version_info))
96
97 (build_env, shell_env) = self_describing_environment.BootstrapEnvironment(
98 self.GetWorkspaceRoot(), self.GetActiveScopes())
99
100 # # Bind our current execution environment into the shell vars.
101 ph = os.path.dirname(sys.executable)
102 if " " in ph:
103 ph = '"' + ph + '"'
104 shell_env.set_shell_var("PYTHON_HOME", ph)
105 # PYTHON_COMMAND is required to be set for using edk2 python builds.
106 pc = sys.executable
107 if " " in pc:
108 pc = '"' + pc + '"'
109 shell_env.set_shell_var("PYTHON_COMMAND", pc)
110
111 if self.tool_chain_tag.lower().startswith("vs"):
112
113 # # Update environment with required VC vars.
114 interesting_keys = ["ExtensionSdkDir", "INCLUDE", "LIB"]
115 interesting_keys.extend(
116 ["LIBPATH", "Path", "UniversalCRTSdkDir", "UCRTVersion", "WindowsLibPath", "WindowsSdkBinPath"])
117 interesting_keys.extend(
118 ["WindowsSdkDir", "WindowsSdkVerBinPath", "WindowsSDKVersion", "VCToolsInstallDir"])
119 vc_vars = QueryVcVariables(
120 interesting_keys, 'x86', vs_version=self.tool_chain_tag.lower())
121 for key in vc_vars.keys():
122 logging.debug(f"Var - {key} = {vc_vars[key]}")
123 if key.lower() == 'path':
124 shell_env.insert_path(vc_vars[key])
125 else:
126 shell_env.set_shell_var(key, vc_vars[key])
127
128 self.OutputDir = os.path.join(
129 shell_env.get_shell_var("EDK_TOOLS_PATH"), "Bin", "Win32")
130
131 # compiled tools need to be added to path because antlr is referenced
132 shell_env.insert_path(self.OutputDir)
133
134 # Actually build the tools.
135 ret = RunCmd('nmake.exe', None,
136 workingdir=shell_env.get_shell_var("EDK_TOOLS_PATH"))
137 if ret != 0:
138 raise Exception("Failed to build.")
139
140 self.WritePathEnvFile(self.OutputDir)
141 return ret
142
143 elif self.tool_chain_tag.lower().startswith("gcc"):
144 ret = RunCmd("make", "-C .", workingdir=shell_env.get_shell_var("EDK_TOOLS_PATH"))
145 if ret != 0:
146 raise Exception("Failed to build.")
147
148 self.OutputDir = os.path.join(
149 shell_env.get_shell_var("EDK_TOOLS_PATH"), "Source", "C", "bin")
150
151 self.WritePathEnvFile(self.OutputDir)
152 return ret
153
154 logging.critical("Tool Chain not supported")
155 return -1
156
157
158 def main():
159 Edk2ToolsBuild().Invoke()
160
161
162 if __name__ == "__main__":
163 main()