1 # @file Edk2ToolsBuild.py
2 # Invocable class that builds the basetool c files.
4 # Supports VS2017, VS2019, and GCC5
6 # Copyright (c) Microsoft Corporation
8 # SPDX-License-Identifier: BSD-2-Clause-Patent
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
21 class Edk2ToolsBuild(BaseAbstractInvocable
):
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
31 def GetWorkspaceRoot(self
):
32 ''' Return the workspace root for initializing the SDE '''
34 # this is the bastools dir...not the traditional EDK2 workspace root
35 return os
.path
.dirname(os
.path
.abspath(__file__
))
37 def GetActiveScopes(self
):
38 ''' return tuple containing scopes that should be active for this process '''
40 # for now don't use scopes
43 def GetLoggingLevel(self
, loggerType
):
44 ''' Get the logging level for a given type (return Logging.Level)
45 base == lowest logging level supported
47 txt == plain text file logging
48 md == markdown file logging
50 if(loggerType
== "con"):
55 def GetLoggingFolderRelativeToRoot(self
):
56 ''' Return a path to folder for log files '''
57 return "BaseToolsBuild"
59 def GetVerifyCheckRequired(self
):
60 ''' Will call self_describing_environment.VerifyEnvironment if this returns True '''
63 def GetLoggingFileName(self
, loggerType
):
64 ''' Get the logging file name for the type.
65 Return None if the logger shouldn't be created
67 base == lowest logging level supported
69 txt == plain text file logging
70 md == markdown file logging
72 return "BASETOOLS_BUILD"
74 def WritePathEnvFile(self
, OutputDir
):
75 ''' Write a PyTool path env file for future PyTool based edk2 builds'''
77 # Set shell variable EDK_TOOLS_BIN to this folder
79 # Autogenerated by Edk2ToolsBuild.py
81 # Copyright (c), Microsoft Corporation
82 # SPDX-License-Identifier: BSD-2-Clause-Patent
85 "id": "You-Built-BaseTools",
86 "scope": "edk2-build",
87 "flags": ["set_shell_var", "set_path"],
88 "var_name": "EDK_TOOLS_BIN"
91 with
open(os
.path
.join(OutputDir
, "basetoolsbin_path_env.yaml"), "w") as f
:
95 logging
.info("Running Python version: " + str(sys
.version_info
))
97 (build_env
, shell_env
) = self_describing_environment
.BootstrapEnvironment(
98 self
.GetWorkspaceRoot(), self
.GetActiveScopes())
100 # # Bind our current execution environment into the shell vars.
101 ph
= os
.path
.dirname(sys
.executable
)
104 shell_env
.set_shell_var("PYTHON_HOME", ph
)
105 # PYTHON_COMMAND is required to be set for using edk2 python builds.
109 shell_env
.set_shell_var("PYTHON_COMMAND", pc
)
111 if self
.tool_chain_tag
.lower().startswith("vs"):
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
])
126 shell_env
.set_shell_var(key
, vc_vars
[key
])
128 self
.OutputDir
= os
.path
.join(
129 shell_env
.get_shell_var("EDK_TOOLS_PATH"), "Bin", "Win32")
131 # compiled tools need to be added to path because antlr is referenced
132 shell_env
.insert_path(self
.OutputDir
)
134 # Actually build the tools.
135 ret
= RunCmd('nmake.exe', None,
136 workingdir
=shell_env
.get_shell_var("EDK_TOOLS_PATH"))
138 raise Exception("Failed to build.")
140 self
.WritePathEnvFile(self
.OutputDir
)
143 elif self
.tool_chain_tag
.lower().startswith("gcc"):
144 ret
= RunCmd("make", "-C .", workingdir
=shell_env
.get_shell_var("EDK_TOOLS_PATH"))
146 raise Exception("Failed to build.")
148 self
.OutputDir
= os
.path
.join(
149 shell_env
.get_shell_var("EDK_TOOLS_PATH"), "Source", "C", "bin")
151 self
.WritePathEnvFile(self
.OutputDir
)
154 logging
.critical("Tool Chain not supported")
159 Edk2ToolsBuild().Invoke()
162 if __name__
== "__main__":