-
Notifications
You must be signed in to change notification settings - Fork 37
/
uefi_build.py
672 lines (561 loc) · 26.3 KB
/
uefi_build.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
# @file uefi_build.py
# This module contains code that supports the Tianocore Edk2 build system
# This class is designed to be subclassed by a platform to allow
# more extensive and custom behavior.
##
# Copyright (c) Microsoft Corporation
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
"""Code that supports the Tianocore Edk2 build system.
This class is designed to be subclassed by a platform to allow more extensive
and custom behavior.
"""
import os
import logging
from edk2toolext.environment.multiple_workspace import MultipleWorkspace
from edk2toolext.environment import conf_mgmt
import traceback
import time
from edk2toolext.environment import shell_environment
from edk2toollib.uefi.edk2.parsers.targettxt_parser import TargetTxtParser
from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser
from edk2toollib.uefi.edk2.parsers.fdf_parser import FdfParser
from edk2toollib.utility_functions import RunCmd, RemoveTree
from edk2toolext import edk2_logging
from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin
import datetime
class UefiBuilder(object):
"""Object responsible for the full build process.
The following steps are completed by the `UefiBuilder` and is overridable
by the platform:
1. `PlatformPreBuild()`
2. `UefiBuildPlugins` that implement `do_pre_build()`
3. `Build()` (should not be overridden)
4. `UefiBuildPlugins` that implement `do_post_build()`
5. `PlatformFlashImage()`
Attributes:
SkipPreBuild (bool): Skip Pre Build or not
SkipPostBuild (bool): Skip Post Build or not
SkipBuild (bool): Skip Build or not
FlashImage (bool): Flash the image not
Clean (bool): Clean the build directory or not
Update Conf (bool): Update the conf or not
env (VarDict): Special dictionary containing build and env vars
mws (MultipleWorkspace): multiple workspace manager
ws (str): Workspace root dir
pp (str): packagespath separated by os.pathsep
Helper (HelperFunctions): object containing registered helper functions
pm (PluginManager): The plugin manager
"""
def __init__(self):
"""Inits an empty UefiBuilder."""
self.SkipBuild = False
self.SkipPreBuild = False
self.SkipPostBuild = False
self.FlashImage = False
self.ShowHelpOnly = False
self.OutputBuildEnvBeforeBuildToFile = None
self.Clean = False
self.UpdateConf = False
self.OutputConfig = None
def AddPlatformCommandLineOptions(self, parserObj):
"""Adds command line options to the argparser.
Args:
parserObj(argparser): argparser object
"""
parserObj.add_argument("--SKIPBUILD", "--skipbuild", "--SkipBuild", dest="SKIPBUILD",
action='store_true', default=False, help="Skip the build process")
parserObj.add_argument("--SKIPPREBUILD", "--skipprebuild", "--SkipPrebuild", dest="SKIPPREBUILD",
action='store_true', default=False, help="Skip prebuild process")
parserObj.add_argument("--SKIPPOSTBUILD", "--skippostbuild", "--SkipPostBuild", dest="SKIPPOSTBUILD",
action='store_true', default=False, help="Skip postbuild process")
parserObj.add_argument("--FLASHONLY", "--flashonly", "--FlashOnly", dest="FLASHONLY",
action='store_true', default=False, help="Flash rom after build.")
parserObj.add_argument("--FLASHROM", "--flashrom", "--FlashRom", dest="FLASHROM",
action='store_true', default=False, help="Flash rom. Rom must be built previously.")
parserObj.add_argument("--UPDATECONF", "--updateconf", "--UpdateConf",
dest="UPDATECONF", action='store_true', default=False,
help="Update Conf. Builders Conf files will be replaced with latest template files")
parserObj.add_argument("--CLEAN", "--clean", "--CLEAN", dest="CLEAN",
action='store_true', default=False,
help="Clean. Remove all old build artifacts and intermediate files")
parserObj.add_argument("--CLEANONLY", "--cleanonly", "--CleanOnly", dest="CLEANONLY",
action='store_true', default=False,
help="Clean Only. Do clean operation and don't build just exit.")
parserObj.add_argument("--OUTPUTCONFIG", "--outputconfig", "--OutputConfig",
dest='OutputConfig', required=False, type=str,
help='Provide shell variables in a file')
def RetrievePlatformCommandLineOptions(self, args):
"""Retrieve command line options from the argparser.
Args:
args (Namespace): namespace containing gathered args from argparser
"""
self.OutputConfig = os.path.abspath(args.OutputConfig) if args.OutputConfig else None
self.SkipBuild = args.SKIPBUILD
self.SkipPreBuild = args.SKIPPREBUILD
self.SkipPostBuild = args.SKIPPOSTBUILD
self.Clean = args.CLEAN
self.FlashImage = args.FLASHROM
self.UpdateConf = args.UPDATECONF
if (args.FLASHONLY):
self.SkipPostBuild = True
self.SkipBuild = True
self.SkipPreBuild = True
self.FlashImage = True
elif (args.CLEANONLY):
self.Clean = True
self.SkipBuild = True
self.SkipPreBuild = True
self.SkipPostBuild = True
self.FlashImage = False
def Go(self, WorkSpace, PackagesPath, PInHelper, PInManager):
"""Core executable that performs all build steps."""
self.env = shell_environment.GetBuildVars()
self.mws = MultipleWorkspace()
self.mws.setWs(WorkSpace, PackagesPath)
self.ws = WorkSpace
self.pp = PackagesPath # string using os.pathsep
self.Helper = PInHelper
self.pm = PInManager
try:
edk2_logging.log_progress("Start time: {0}".format(datetime.datetime.now()))
start_time = time.perf_counter()
self.Helper.DebugLogRegisteredFunctions()
ret = self.SetEnv()
if (ret != 0):
logging.critical("SetEnv failed")
return ret
# clean
if (self.Clean):
edk2_logging.log_progress("Cleaning")
ret = self.CleanTree()
if (ret != 0):
logging.critical("Clean failed")
return ret
# prebuild
if (self.SkipPreBuild):
edk2_logging.log_progress("Skipping Pre Build")
else:
ret = self.PreBuild()
if (ret != 0):
logging.critical("Pre Build failed")
return ret
# Output Build Environment to File - this is mostly for debug of build
# issues or adding other build features using existing variables
if (self.OutputConfig is not None):
edk2_logging.log_progress("Writing Build Env Info out to File")
logging.debug("Found an Output Build Env File: " + self.OutputConfig)
self.env.PrintAll(self.OutputConfig)
if (self.env.GetValue("GATEDBUILD") is not None) and (self.env.GetValue("GATEDBUILD").upper() == "TRUE"):
ShouldGatedBuildRun = self.PlatformGatedBuildShouldHappen()
logging.debug("Platform Gated Build Should Run returned: %s" % str(
ShouldGatedBuildRun))
if (not self.SkipBuild):
self.SkipBuild = not ShouldGatedBuildRun
if (not self.SkipPostBuild):
self.SkipPostBuild = not ShouldGatedBuildRun
# build
if (self.SkipBuild):
edk2_logging.log_progress("Skipping Build")
else:
ret = self.Build()
if (ret != 0):
logging.critical("Build failed")
return ret
# postbuild
if (self.SkipPostBuild):
edk2_logging.log_progress("Skipping Post Build")
else:
ret = self.PostBuild()
if (ret != 0):
logging.critical("Post Build failed")
return ret
# flash
if (self.FlashImage):
edk2_logging.log_progress("Flashing Image")
ret = self.FlashRomImage()
if (ret != 0):
logging.critical("Flash Image failed")
return ret
except Exception:
logging.critical("Build Process Exception")
logging.error(traceback.format_exc())
return -1
except SystemExit:
logging.critical("Build Process Exit")
logging.error(traceback.format_exc())
return -1
except KeyboardInterrupt:
logging.critical("Build Cancelled by user")
return -2
finally:
end_time = time.perf_counter()
elapsed_time_s = int((end_time - start_time))
edk2_logging.log_progress("End time: {0}\t Total time Elapsed: {1}".format(
datetime.datetime.now(), datetime.timedelta(seconds=elapsed_time_s)))
return 0
def CleanTree(self, RemoveConfTemplateFilesToo=False):
"""Cleans the build directory.
Args:
RemoveConfTemplateFilesToo (bool): deletes conf files used for building makefiles
"""
ret = 0
# loop thru each build target set.
edk2_logging.log_progress("Cleaning All Output for Build")
d = self.env.GetValue("BUILD_OUTPUT_BASE")
if (os.path.isdir(d)):
logging.debug("Removing [%s]", d)
# if the folder is opened in Explorer do not fail the entire Rebuild
try:
RemoveTree(d)
except WindowsError as wex:
logging.debug(wex)
else:
logging.debug("Directory [%s] already clean" % d)
# delete the conf .dbcache
# this needs to be removed in case build flags changed
d = os.path.join(self.ws, "Conf", ".cache")
if (os.path.isdir(d)):
logging.debug("Removing [%s]" % d)
RemoveTree(d)
if (RemoveConfTemplateFilesToo):
for a in ["target.txt", "build_rule.txt", "tools_def.txt"]:
d = os.path.join(self.ws, "Conf", a)
if (os.path.isfile(d)):
logging.debug("Removing [%s]" % d)
os.remove(d)
return ret
def Build(self):
"""Adds all arguments to the build command and runs it."""
BuildType = self.env.GetValue("TARGET")
edk2_logging.log_progress("Running Build %s" % BuildType)
# set target, arch, toolchain, threads, and platform
params = "-p " + self.env.GetValue("ACTIVE_PLATFORM")
params += " -b " + BuildType
params += " -t " + self.env.GetValue("TOOL_CHAIN_TAG")
# Thread number is now optional and not set in default tianocore target.txt
if self.env.GetValue("MAX_CONCURRENT_THREAD_NUMBER") is not None:
params += " -n " + self.env.GetValue("MAX_CONCURRENT_THREAD_NUMBER")
# Set the arch flags. Multiple are split by space
rt = self.env.GetValue("TARGET_ARCH").split(" ")
for t in rt:
params += " -a " + t
# get the report options and setup the build command
if (self.env.GetValue("BUILDREPORTING") == "TRUE"):
params += " -y " + self.env.GetValue("BUILDREPORT_FILE")
rt = self.env.GetValue("BUILDREPORT_TYPES").split(" ")
for t in rt:
params += " -Y " + t
# add special processing to handle building a single module
mod = self.env.GetValue("BUILDMODULE")
if (mod is not None and len(mod.strip()) > 0):
params += " -m " + mod
edk2_logging.log_progress("Single Module Build: " + mod)
self.SkipPostBuild = True
self.FlashImage = False
# attach the generic build vars
buildvars = self.env.GetAllBuildKeyValues(BuildType)
for key, value in buildvars.items():
params += " -D " + key + "=" + value
output_stream = edk2_logging.create_output_stream()
env = shell_environment.ShellEnvironment()
# WORKAROUND - Pin the PYTHONHASHSEED so that TianoCore build tools
# have consistent ordering. Addresses incremental builds.
pre_build_env_chk = env.checkpoint()
env.set_shell_var('PYTHONHASHSEED', '0')
env.log_environment()
edk2_build_cmd = self.env.GetValue("EDK_BUILD_CMD")
if edk2_build_cmd is None:
edk2_build_cmd = "build"
logging.debug(f"The edk2 build command is {edk2_build_cmd}")
edk2_build_params = self.env.GetValue("EDK_BUILD_PARAMS")
if edk2_build_params is None:
edk2_build_params = params
logging.debug(f"Edk2 build parameters are {edk2_build_params}")
ret = RunCmd(edk2_build_cmd, edk2_build_params)
# WORKAROUND - Undo the workaround.
env.restore_checkpoint(pre_build_env_chk)
problems = edk2_logging.scan_compiler_output(output_stream)
edk2_logging.remove_output_stream(output_stream)
for level, problem in problems:
logging.log(level, problem)
if (ret != 0):
return ret
return 0
def PreBuild(self):
"""Performs internal PreBuild steps.
This including calling the platform overridable `PlatformPreBuild()`
"""
edk2_logging.log_progress("Running Pre Build")
#
# Run the platform pre-build steps.
#
ret = self.PlatformPreBuild()
if (ret != 0):
logging.critical("PlatformPreBuild failed %d" % ret)
return ret
#
# run all loaded UefiBuild Plugins
#
for Descriptor in self.pm.GetPluginsOfClass(IUefiBuildPlugin):
rc = Descriptor.Obj.do_pre_build(self)
if (rc != 0):
if (rc is None):
logging.error(
"Plugin Failed: %s returned NoneType" % Descriptor.Name)
ret = -1
else:
logging.error("Plugin Failed: %s returned %d" %
(Descriptor.Name, rc))
ret = rc
break # fail on plugin error
else:
logging.debug("Plugin Success: %s" % Descriptor.Name)
return ret
def PostBuild(self):
"""Performs internal PostBuild steps.
This includes calling the platform overridable `PlatformPostBuild()`.
"""
edk2_logging.log_progress("Running Post Build")
#
# Run the platform post-build steps.
#
ret = self.PlatformPostBuild()
if (ret != 0):
logging.critical("PlatformPostBuild failed %d" % ret)
return ret
#
# run all loaded UefiBuild Plugins
#
for Descriptor in self.pm.GetPluginsOfClass(IUefiBuildPlugin):
rc = Descriptor.Obj.do_post_build(self)
if (rc != 0):
if (rc is None):
logging.error(
"Plugin Failed: %s returned NoneType" % Descriptor.Name)
ret = -1
else:
logging.error("Plugin Failed: %s returned %d" %
(Descriptor.Name, rc))
ret = rc
break # fail on plugin error
else:
logging.debug("Plugin Success: %s" % Descriptor.Name)
return ret
def SetEnv(self):
"""Performs internal SetEnv steps.
This includes platform overridable `SetPlatformEnv()` and `SetPlatformEnvAfterTarget().
"""
edk2_logging.log_progress("Setting up the Environment")
shell_environment.GetEnvironment().set_shell_var("WORKSPACE", self.ws)
shell_environment.GetBuildVars().SetValue("WORKSPACE", self.ws, "Set in SetEnv")
if (self.pp is not None):
shell_environment.GetEnvironment().set_shell_var("PACKAGES_PATH", self.pp)
shell_environment.GetBuildVars().SetValue(
"PACKAGES_PATH", self.pp, "Set in SetEnv")
# process platform parameters defined in platform build file
ret = self.SetPlatformEnv()
if (ret != 0):
logging.critical("Set Platform Env failed")
return ret
# set some basic defaults
self.SetBasicDefaults()
# Handle all the template files for workspace/conf/ Allow override
TemplateDirList = [self.env.GetValue("EDK_TOOLS_PATH")] # set to edk2 BaseTools
PlatTemplatesForConf = self.env.GetValue("CONF_TEMPLATE_DIR") # get platform defined additional path
if (PlatTemplatesForConf is not None):
PlatTemplatesForConf = self.mws.join(self.ws, PlatTemplatesForConf)
TemplateDirList.insert(0, PlatTemplatesForConf)
logging.debug(f"Platform defined override for Template Conf Files: {PlatTemplatesForConf}")
conf_dir = os.path.join(self.ws, "Conf")
conf_mgmt.ConfMgmt().populate_conf_dir(conf_dir, self.UpdateConf, TemplateDirList)
# parse target file
ret = self.ParseTargetFile()
if (ret != 0):
logging.critical("ParseTargetFile failed")
return ret
# parse tools_def file
ret = self.ParseToolsDefFile()
if (ret != 0):
logging.critical("ParseToolsDefFile failed")
return ret
# parse DSC file
ret = self.ParseDscFile()
if (ret != 0):
logging.critical("ParseDscFile failed")
return ret
# parse FDF file
ret = self.ParseFdfFile()
if (ret != 0):
logging.critical("ParseFdfFile failed")
return ret
# set build output base envs for all builds
if self.env.GetValue("OUTPUT_DIRECTORY") is None:
logging.warn("OUTPUT_DIRECTORY was not found, defaulting to Build")
self.env.SetValue("OUTPUT_DIRECTORY", "Build", "default from uefi_build", True)
# BUILD_OUT_TEMP is a path so the value should use native directory separators
self.env.SetValue("BUILD_OUT_TEMP",
os.path.normpath(os.path.join(self.ws, self.env.GetValue("OUTPUT_DIRECTORY"))),
"Computed in SetEnv")
target = self.env.GetValue("TARGET")
self.env.SetValue("BUILD_OUTPUT_BASE", os.path.join(self.env.GetValue(
"BUILD_OUT_TEMP"), target + "_" + self.env.GetValue("TOOL_CHAIN_TAG")), "Computed in SetEnv")
# We have our build target now. Give platform build one more chance for target specific settings.
ret = self.SetPlatformEnvAfterTarget()
if (ret != 0):
logging.critical("SetPlatformEnvAfterTarget failed")
return ret
# set the build report file
self.env.SetValue("BUILDREPORT_FILE", os.path.join(
self.env.GetValue("BUILD_OUTPUT_BASE"), "BUILD_REPORT.TXT"), True)
# set environment variables for the build process
os.environ["EFI_SOURCE"] = self.ws
return 0
def FlashRomImage(self):
"""Executes platform overridable `PlatformFlashImage()`."""
return self.PlatformFlashImage()
# -----------------------------------------------------------------------
# Methods that will be overridden by child class
# -----------------------------------------------------------------------
@classmethod
def PlatformPreBuild(self):
"""Perform Platform PreBuild Steps."""
return 0
@classmethod
def PlatformPostBuild(self):
"""Perform Platform PostBuild Steps."""
return 0
@classmethod
def SetPlatformEnv(self):
"""Set and read Platform Env variables.
This is performed before platform files like the DSC and FDF have been parsed.
TIP: If a platform file (DSC, FDF, etc) relies on a variable set in
the `UefiBuilder`, it must be set here, before the platform files
have been parsed and values have been set.
"""
return 0
@classmethod
def SetPlatformEnvAfterTarget(self):
"""Set and read Platform Env variables after platform files have been parsed."""
return 0
@classmethod
def PlatformBuildRom(self):
"""Build the platform Rom.
TIP: Typically called by the platform in PlatformFlashImage. Not called
automatically by the `UefiBuilder`.
"""
return 0
@classmethod
def PlatformFlashImage(self):
"""Flashes the image to the system."""
return 0
@classmethod
def PlatformGatedBuildShouldHappen(self):
"""Specifies if a gated build should happen."""
return True
# ------------------------------------------------------------------------
# HELPER FUNCTIONS
# ------------------------------------------------------------------------
#
def ParseTargetFile(self):
"""Parses the target.txt file and adds values as env settings.
"Sets them so they can be overriden.
"""
if (os.path.isfile(self.mws.join(self.ws, "Conf", "target.txt"))):
# parse TargetTxt File
logging.debug("Parse Target.txt file")
ttp = TargetTxtParser()
ttp.ParseFile(self.mws.join(self.ws, "Conf", "target.txt"))
for key, value in ttp.Dict.items():
# set env as overrideable
self.env.SetValue(key, value, "From Target.txt", True)
# Set the two additional edk2 common macros. These will be resolved by now as
# target.txt will set them if they aren't already set.
self.env.SetValue("TOOLCHAIN", self.env.GetValue("TOOL_CHAIN_TAG"),
"DSC Spec macro - set based on tool_Chain_tag")
# need to check how multiple arch are handled
self.env.SetValue("ARCH", self.env.GetValue("TARGET_ARCH"), "DSC Spec macro - set based on target_arch")
else:
logging.error("Failed to find target.txt file")
return -1
return 0
def ParseToolsDefFile(self):
"""Parses the tools_def.txt file and adds values as env settings.
"Sets them so they can be overriden.
"""
if (os.path.isfile(self.mws.join(self.ws, "Conf", "tools_def.txt"))):
# parse ToolsdefTxt File
logging.debug("Parse tools_def.txt file")
tdp = TargetTxtParser()
tdp.ParseFile(self.mws.join(self.ws, "Conf", "tools_def.txt"))
# Get the tool chain tag and then find the family
# need to parse tools_def and find *_<TAG>_*_*_FAMILY
# Example: *_VS2019_*_*_FAMILY = MSFT
tag = "*_" + self.env.GetValue("TOOL_CHAIN_TAG") + "_*_*_FAMILY"
tool_chain_family = tdp.Dict.get(tag, "UNKNOWN")
self.env.SetValue("FAMILY", tool_chain_family, "DSC Spec macro - from tools_def.txt")
else:
logging.error("Failed to find tools_def.txt file")
return -1
return 0
def ParseDscFile(self):
"""Parses the active platform DSC file.
This will get lots of variable info to be used in the build. This
makes it so we don't have to define things twice.
"""
if self.env.GetValue("ACTIVE_PLATFORM") is None:
logging.error("The DSC file was not set. Please set ACTIVE_PLATFORM")
return -1
dsc_file_path = self.mws.join(
self.ws, self.env.GetValue("ACTIVE_PLATFORM"))
if (os.path.isfile(dsc_file_path)):
# parse DSC File
logging.debug(
"Parse Active Platform DSC file: {0}".format(dsc_file_path))
# Get the vars from the environment that are not build keys
input_vars = self.env.GetAllNonBuildKeyValues()
# Update with special environment set build keys
input_vars.update(self.env.GetAllBuildKeyValues())
dscp = DscParser().SetBaseAbsPath(self.ws).SetPackagePaths(
self.pp.split(os.pathsep)).SetInputVars(input_vars)
dscp.ParseFile(dsc_file_path)
for key, value in dscp.LocalVars.items():
# set env as overrideable
self.env.SetValue(key, value, "From Platform DSC File", True)
else:
logging.error("Failed to find DSC file")
return -1
return 0
def ParseFdfFile(self):
"""Parses the active platform FDF file.
This will get lots of variable info to be used in the build. This makes
it so we don't have to define things twice the FDF file usually comes
from the Active Platform DSC file so it needs to be parsed first.
"""
if (self.env.GetValue("FLASH_DEFINITION") is None):
logging.debug("No flash definition set")
return 0
if (os.path.isfile(self.mws.join(self.ws, self.env.GetValue("FLASH_DEFINITION")))):
# parse the FDF file- fdf files have similar syntax to DSC and therefore parser works for both.
logging.debug("Parse Active Flash Definition (FDF) file")
# Get the vars from the environment that are not build keys
input_vars = self.env.GetAllNonBuildKeyValues()
# Update with special environment set build keys
input_vars.update(self.env.GetAllBuildKeyValues())
fdf_parser = FdfParser().SetBaseAbsPath(self.ws).SetPackagePaths(
self.pp.split(os.pathsep)).SetInputVars(input_vars)
pa = self.mws.join(self.ws, self.env.GetValue("FLASH_DEFINITION"))
fdf_parser.ParseFile(pa)
for key, value in fdf_parser.LocalVars.items():
self.env.SetValue(key, value, "From Platform FDF File", True)
else:
logging.error("Failed to find FDF file")
return -2
return 0
def SetBasicDefaults(self):
"""Sets default values for numerous build control flow variables."""
self.env.SetValue("WORKSPACE", self.ws, "DEFAULT")
if (self.pp is not None):
self.env.SetValue("PACKAGES_PATH", self.pp, "DEFAULT")
return 0