]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/AutoGen/AutoGen.py
Fix build break caused by adding DebugAgentLib to the DXE Core.
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / AutoGen.py
1 ## @file
2 # Generate AutoGen.h, AutoGen.c and *.depex files
3 #
4 # Copyright (c) 2007 - 2009, Intel Corporation
5 # All rights reserved. This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
9 #
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 #
13
14 ## Import Modules
15 #
16 import os
17 import re
18 import os.path as path
19 import copy
20
21 import GenC
22 import GenMake
23 import GenDepex
24 from StringIO import StringIO
25
26 from StrGather import *
27 from BuildEngine import BuildRule
28
29 from Common.BuildToolError import *
30 from Common.DataType import *
31 from Common.Misc import *
32 from Common.String import *
33 import Common.GlobalData as GlobalData
34 from GenFds.FdfParser import *
35 from CommonDataClass.CommonClass import SkuInfoClass
36 from Workspace.BuildClassObject import *
37
38 ## Regular expression for splitting Dependency Expression stirng into tokens
39 gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")
40
41 ## Mapping Makefile type
42 gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}
43
44
45 ## Build rule configuration file
46 gBuildRuleFile = 'Conf/build_rule.txt'
47
48 ## default file name for AutoGen
49 gAutoGenCodeFileName = "AutoGen.c"
50 gAutoGenHeaderFileName = "AutoGen.h"
51 gAutoGenStringFileName = "%(module_name)sStrDefs.h"
52 gAutoGenStringFormFileName = "%(module_name)sStrDefs.hpk"
53 gAutoGenDepexFileName = "%(module_name)s.depex"
54
55 ## Base class for AutoGen
56 #
57 # This class just implements the cache mechanism of AutoGen objects.
58 #
59 class AutoGen(object):
60 # database to maintain the objects of xxxAutoGen
61 _CACHE_ = {} # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}
62
63 ## Factory method
64 #
65 # @param Class class object of real AutoGen class
66 # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)
67 # @param Workspace Workspace directory or WorkspaceAutoGen object
68 # @param MetaFile The path of meta file
69 # @param Target Build target
70 # @param Toolchain Tool chain name
71 # @param Arch Target arch
72 # @param *args The specific class related parameters
73 # @param **kwargs The specific class related dict parameters
74 #
75 def __new__(Class, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):
76 # check if the object has been created
77 Key = (Target, Toolchain)
78 if Key not in Class._CACHE_ or Arch not in Class._CACHE_[Key] \
79 or MetaFile not in Class._CACHE_[Key][Arch]:
80 AutoGenObject = super(AutoGen, Class).__new__(Class)
81 # call real constructor
82 if not AutoGenObject._Init(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):
83 return None
84 if Key not in Class._CACHE_:
85 Class._CACHE_[Key] = {}
86 if Arch not in Class._CACHE_[Key]:
87 Class._CACHE_[Key][Arch] = {}
88 Class._CACHE_[Key][Arch][MetaFile] = AutoGenObject
89 else:
90 AutoGenObject = Class._CACHE_[Key][Arch][MetaFile]
91
92 return AutoGenObject
93
94 ## hash() operator
95 #
96 # The file path of platform file will be used to represent hash value of this object
97 #
98 # @retval int Hash value of the file path of platform file
99 #
100 def __hash__(self):
101 return hash(self.MetaFile)
102
103 ## str() operator
104 #
105 # The file path of platform file will be used to represent this object
106 #
107 # @retval string String of platform file path
108 #
109 def __str__(self):
110 return str(self.MetaFile)
111
112 ## "==" operator
113 def __eq__(self, Other):
114 return Other and self.MetaFile == Other
115
116 ## Workspace AutoGen class
117 #
118 # This class is used mainly to control the whole platform build for different
119 # architecture. This class will generate top level makefile.
120 #
121 class WorkspaceAutoGen(AutoGen):
122 ## Real constructor of WorkspaceAutoGen
123 #
124 # This method behaves the same as __init__ except that it needs explict invoke
125 # (in super class's __new__ method)
126 #
127 # @param WorkspaceDir Root directory of workspace
128 # @param ActivePlatform Meta-file of active platform
129 # @param Target Build target
130 # @param Toolchain Tool chain name
131 # @param ArchList List of architecture of current build
132 # @param MetaFileDb Database containing meta-files
133 # @param BuildConfig Configuration of build
134 # @param ToolDefinition Tool chain definitions
135 # @param FlashDefinitionFile File of flash definition
136 # @param Fds FD list to be generated
137 # @param Fvs FV list to be generated
138 # @param SkuId SKU id from command line
139 #
140 def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,
141 BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=[], Fvs=[], SkuId='',
142 ReportFile=None, ReportType=None):
143 self.MetaFile = ActivePlatform.MetaFile
144 self.WorkspaceDir = WorkspaceDir
145 self.Platform = ActivePlatform
146 self.BuildTarget = Target
147 self.ToolChain = Toolchain
148 self.ArchList = ArchList
149 self.SkuId = SkuId
150 self.ReportFile = ReportFile
151 self.ReportType = ReportType
152
153 self.BuildDatabase = MetaFileDb
154 self.TargetTxt = BuildConfig
155 self.ToolDef = ToolDefinition
156 self.FdfFile = FlashDefinitionFile
157 self.FdTargetList = Fds
158 self.FvTargetList = Fvs
159 self.AutoGenObjectList = []
160
161 # there's many relative directory operations, so ...
162 os.chdir(self.WorkspaceDir)
163
164 # parse FDF file to get PCDs in it, if any
165 if self.FdfFile != None and self.FdfFile != '':
166 Fdf = FdfParser(self.FdfFile.Path)
167 Fdf.ParseFile()
168 PcdSet = Fdf.Profile.PcdDict
169 ModuleList = Fdf.Profile.InfList
170 else:
171 PcdSet = {}
172 ModuleList = []
173
174 # apply SKU and inject PCDs from Flash Definition file
175 for Arch in self.ArchList:
176 Platform = self.BuildDatabase[self.MetaFile, Arch]
177 Platform.SkuName = self.SkuId
178 for Name, Guid in PcdSet:
179 Platform.AddPcd(Name, Guid, PcdSet[Name, Guid])
180
181 Pa = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
182 #
183 # Explicitly collect platform's dynamic PCDs
184 #
185 Pa.CollectPlatformDynamicPcds()
186 self.AutoGenObjectList.append(Pa)
187
188 AllPcds = {}
189 MaxLen = 0
190 for Pcd in Pa._DynaPcdList_ + Pa._NonDynaPcdList_:
191 if Pcd.TokenSpaceGuidCName not in AllPcds:
192 AllPcds[Pcd.TokenSpaceGuidCName] = {}
193 if Pcd.Type not in AllPcds[Pcd.TokenSpaceGuidCName]:
194 AllPcds[Pcd.TokenSpaceGuidCName][Pcd.Type] = []
195 AllPcds[Pcd.TokenSpaceGuidCName][Pcd.Type] += [Pcd]
196 if len(Pcd.TokenCName) > MaxLen:
197 MaxLen = len(Pcd.TokenCName)
198
199 if self.ReportFile <> None:
200 try:
201 if os.path.exists(self.ReportFile):
202 os.remove(self.ReportFile)
203
204 Fd = open(self.ReportFile, "w")
205
206 Fd.write ('===============================================================================\n')
207 Fd.write ('Platform Configuration Database Report\n')
208 Fd.write ('===============================================================================\n')
209 Fd.write (' *P - Platform scoped PCD override in DSC file\n')
210 Fd.write (' *F - Platform scoped PCD override in FDF file\n')
211 Fd.write (' *M - Module scoped PCD override in DSC file\n')
212 Fd.write (' *C - Library has a constructor\n')
213 Fd.write (' *D - Library has a destructor\n')
214 Fd.write (' *CD - Library has both a constructor and a destructor\n')
215 Fd.write ('===============================================================================\n')
216 Fd.write ('\n')
217 Fd.write ('===============================================================================\n')
218 Fd.write ('PLATFORM: %s\n' % (ActivePlatform.MetaFile))
219 Fd.write ('===============================================================================\n')
220 for Key in AllPcds:
221 Fd.write ('%s\n' % (Key))
222 for Type in AllPcds[Key]:
223 TypeName = ''
224 DecType = Type
225 if Type == 'FixedAtBuild':
226 TypeName = 'FIXED'
227 if Type == 'PatchableInModule':
228 TypeName = 'PATCH'
229 if Type == 'FeatureFlag':
230 TypeName = 'FLAG'
231 if Type == 'Dynamic':
232 TypeName = 'DYN'
233 if Type == 'DynamicHii':
234 TypeName = 'DYNHII'
235 DecType = 'Dynamic'
236 if Type == 'DynamicVpd':
237 TypeName = 'DYNVPD'
238 DecType = 'Dynamic'
239 if Type == 'DynamicEx':
240 TypeName = 'DEX'
241 DecType = 'Dynamic'
242 if Type == 'DynamicExHii':
243 TypeName = 'DEXHII'
244 DecType = 'Dynamic'
245 if Type == 'DynamicExVpd':
246 TypeName = 'DEXVPD'
247 DecType = 'Dynamic'
248 for Pcd in AllPcds[Key][Type]:
249
250 DecDefaultValue = None
251 for F in Pa.Platform.Modules.keys():
252 for Package in Pa.Platform.Modules[F].M.Module.Packages:
253 if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType) in Package.Pcds:
254 if DecDefaultValue == None:
255 DecDefaultValue = Package.Pcds[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType].DefaultValue
256
257 DscDefaultValue = None
258 if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in self.BuildDatabase.WorkspaceDb.PlatformList[0].Pcds:
259 DscDefaultValue = self.BuildDatabase.WorkspaceDb.PlatformList[0].Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)].DefaultValue
260
261 if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):
262 if Pcd.DefaultValue.strip()[0:2].upper() == '0X':
263 PcdDefaultValueNumber = int(Pcd.DefaultValue.strip(), 16)
264 else:
265 PcdDefaultValueNumber = int(Pcd.DefaultValue.strip())
266
267 if DecDefaultValue == None:
268 DecMatch = True
269 else:
270 if DecDefaultValue.strip()[0:2].upper() == '0X':
271 DecDefaultValueNumber = int(DecDefaultValue.strip(), 16)
272 else:
273 DecDefaultValueNumber = int(DecDefaultValue.strip())
274 DecMatch = (DecDefaultValueNumber == PcdDefaultValueNumber)
275
276 if DscDefaultValue == None:
277 DscMatch = True
278 else:
279 if DscDefaultValue.strip()[0:2].upper() == '0X':
280 DscDefaultValueNumber = int(DscDefaultValue.strip(), 16)
281 else:
282 DscDefaultValueNumber = int(DscDefaultValue.strip())
283 DscMatch = (DscDefaultValueNumber == PcdDefaultValueNumber)
284 else:
285 if DecDefaultValue == None:
286 DecMatch = True
287 else:
288 DecMatch = (DecDefaultValue == Pcd.DefaultValue)
289
290 if DscDefaultValue == None:
291 DscMatch = True
292 else:
293 DscMatch = (DscDefaultValue == Pcd.DefaultValue)
294
295 if DecMatch:
296 Fd.write (' %-*s: %6s %10s = %-22s\n' % (MaxLen + 2, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', Pcd.DefaultValue))
297 else:
298 if DscMatch:
299 if (Pcd.TokenCName, Key) in PcdSet:
300 Fd.write (' *F %-*s: %6s %10s = %-22s\n' % (MaxLen + 2, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', Pcd.DefaultValue))
301 else:
302 Fd.write (' *P %-*s: %6s %10s = %-22s\n' % (MaxLen + 2, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', Pcd.DefaultValue))
303
304 for F in Pa.Platform.Modules.keys():
305 for ModulePcd in Pa.Platform.Modules[F].M.ModulePcdList + Pa.Platform.Modules[F].M.LibraryPcdList:
306 if ModulePcd.TokenSpaceGuidCName <> Pcd.TokenSpaceGuidCName:
307 continue
308 if ModulePcd.TokenCName <> Pcd.TokenCName:
309 continue
310 if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):
311 if ModulePcd.DefaultValue.strip()[0:2].upper() == '0X':
312 ModulePcdDefaultValueNumber = int(ModulePcd.DefaultValue.strip(), 16)
313 else:
314 ModulePcdDefaultValueNumber = int(ModulePcd.DefaultValue.strip())
315 Match = (ModulePcdDefaultValueNumber == PcdDefaultValueNumber)
316 else:
317 Match = (ModulePcd.DefaultValue == Pcd.DefaultValue)
318 if Match:
319 continue
320 Fd.write (' *M %*s = %s\n' % (MaxLen + 21, str(F).split('\\')[-1], ModulePcd.DefaultValue))
321
322 if not DecMatch and DscMatch and DecDefaultValue <> None:
323 Fd.write (' %*s = %s\n' % (MaxLen + 21, 'DEC DEFAULT', DecDefaultValue))
324
325 Fd.write ('\n')
326
327 Fd.write ('===============================================================================\n')
328 Fd.write ('===============================================================================\n')
329
330 for F in Pa.Platform.Modules.keys():
331 Fd.write ('\n')
332 Fd.write ('===============================================================================\n')
333 Fd.write ('MODULE: %s\n' % (F))
334 Fd.write ('===============================================================================\n')
335
336 Fd.write ('PLATFORM CONFIGURATION DATABASE\n')
337 Fd.write ('-------------------------------------------------------------------------------\n')
338 ModuleFirst = True
339 for Key in AllPcds:
340 First = True
341 for Type in AllPcds[Key]:
342 TypeName = ''
343 DecType = Type
344 if Type == 'FixedAtBuild':
345 TypeName = 'FIXED'
346 if Type == 'PatchableInModule':
347 TypeName = 'PATCH'
348 if Type == 'FeatureFlag':
349 TypeName = 'FLAG'
350 if Type == 'Dynamic':
351 TypeName = 'DYN'
352 if Type == 'DynamicHii':
353 TypeName = 'DYNHII'
354 DecType = 'Dynamic'
355 if Type == 'DynamicVpd':
356 TypeName = 'DYNVPD'
357 DecType = 'Dynamic'
358 if Type == 'DynamicEx':
359 TypeName = 'DEX'
360 DecType = 'Dynamic'
361 if Type == 'DynamicExHii':
362 TypeName = 'DEXHII'
363 DecType = 'Dynamic'
364 if Type == 'DynamicExVpd':
365 TypeName = 'DEXVPD'
366 DecType = 'Dynamic'
367 for Pcd in AllPcds[Key][Type]:
368 for ModulePcd in Pa.Platform.Modules[F].M.ModulePcdList + Pa.Platform.Modules[F].M.LibraryPcdList:
369 if ModulePcd.TokenSpaceGuidCName <> Pcd.TokenSpaceGuidCName:
370 continue
371 if ModulePcd.TokenCName <> Pcd.TokenCName:
372 continue
373 if ModulePcd.Type <> Pcd.Type:
374 continue
375 if First:
376 if ModuleFirst:
377 ModuleFirst = False
378 else:
379 Fd.write ('\n')
380 Fd.write ('%s\n' % (Key))
381 First = False
382
383 InfDefaultValue = ModulePcd.InfDefaultValue
384 if InfDefaultValue == '':
385 InfDefaultValue = None
386
387 DecDefaultValue = None
388 for Package in Pa.Platform.Modules[F].M.Module.Packages:
389 if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType) in Package.Pcds:
390 if DecDefaultValue == None:
391 DecDefaultValue = Package.Pcds[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType].DefaultValue
392
393 DscDefaultValue = None
394 if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in self.BuildDatabase.WorkspaceDb.PlatformList[0].Pcds:
395 DscDefaultValue = self.BuildDatabase.WorkspaceDb.PlatformList[0].Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)].DefaultValue
396
397 DscModuleOverrideDefaultValue = None
398 if F in self.BuildDatabase.WorkspaceDb.PlatformList[0].Modules:
399 if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in self.BuildDatabase.WorkspaceDb.PlatformList[0].Modules[F].Pcds:
400 DscModuleOverrideDefaultValue = self.BuildDatabase.WorkspaceDb.PlatformList[0].Modules[F].Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)].DefaultValue
401
402 if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):
403 if ModulePcd.DefaultValue.strip()[0:2].upper() == '0X':
404 ModulePcdDefaultValueNumber = int(ModulePcd.DefaultValue.strip(), 16)
405 else:
406 ModulePcdDefaultValueNumber = int(ModulePcd.DefaultValue.strip())
407
408 if DecDefaultValue == None:
409 DecMatch = True
410 else:
411 if DecDefaultValue.strip()[0:2].upper() == '0X':
412 DecDefaultValueNumber = int(DecDefaultValue.strip(), 16)
413 else:
414 DecDefaultValueNumber = int(DecDefaultValue.strip())
415 DecMatch = (DecDefaultValueNumber == ModulePcdDefaultValueNumber)
416
417 if InfDefaultValue == None:
418 InfMatch = True
419 else:
420 if InfDefaultValue.strip()[0:2].upper() == '0X':
421 InfDefaultValueNumber = int(InfDefaultValue.strip(), 16)
422 else:
423 InfDefaultValueNumber = int(InfDefaultValue.strip())
424 InfMatch = (InfDefaultValueNumber == ModulePcdDefaultValueNumber)
425
426 if DscDefaultValue == None:
427 DscMatch = True
428 else:
429 if DscDefaultValue.strip()[0:2].upper() == '0X':
430 DscDefaultValueNumber = int(DscDefaultValue.strip(), 16)
431 else:
432 DscDefaultValueNumber = int(DscDefaultValue.strip())
433 DscMatch = (DscDefaultValueNumber == ModulePcdDefaultValueNumber)
434 else:
435 if DecDefaultValue == None:
436 DecMatch = True
437 else:
438 DecMatch = (DecDefaultValue == ModulePcd.DefaultValue)
439
440 if InfDefaultValue == None:
441 InfMatch = True
442 else:
443 InfMatch = (InfDefaultValue == ModulePcd.DefaultValue)
444
445 if DscDefaultValue == None:
446 DscMatch = True
447 else:
448 DscMatch = (DscDefaultValue == ModulePcd.DefaultValue)
449
450 if DecMatch and InfMatch:
451 Fd.write (' %-*s: %6s %10s = %-22s\n' % (MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', ModulePcd.DefaultValue))
452 else:
453 if DscMatch and DscModuleOverrideDefaultValue == None:
454 if (Pcd.TokenCName, Key) in PcdSet:
455 Fd.write (' *F %-*s: %6s %10s = %-22s\n' % (MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', ModulePcd.DefaultValue))
456 else:
457 Fd.write (' *P %-*s: %6s %10s = %-22s\n' % (MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', ModulePcd.DefaultValue))
458 else:
459 Fd.write (' *M %-*s: %6s %10s = %-22s\n' % (MaxLen, Pcd.TokenCName, TypeName, '('+Pcd.DatumType+')', ModulePcd.DefaultValue))
460 if DscDefaultValue <> None:
461 Fd.write (' %*s = %s\n' % (MaxLen + 19, 'DSC DEFAULT', DscDefaultValue))
462 if InfDefaultValue <> None:
463 Fd.write (' %*s = %s\n' % (MaxLen + 19, 'INF DEFAULT', InfDefaultValue))
464 if DecDefaultValue <> None and not DecMatch:
465 Fd.write (' %*s = %s\n' % (MaxLen + 19, 'DEC DEFAULT', DecDefaultValue))
466 Fd.write ('-------------------------------------------------------------------------------\n')
467 Fd.write ('LIBRARIES\n')
468 Fd.write ('-------------------------------------------------------------------------------\n')
469 for Lib in Pa.Platform.Modules[F].M.DependentLibraryList:
470 if len(Lib.ConstructorList) > 0:
471 if len(Lib.DestructorList) > 0:
472 Fd.write (' *CD')
473 else:
474 Fd.write (' *C ')
475 else:
476 if len(Lib.DestructorList) > 0:
477 Fd.write (' *D ')
478 else:
479 Fd.write (' ')
480 Fd.write (' %s\n' % (Lib))
481 for Depex in Lib.DepexExpression[Pa.Platform.Modules[F].M.Arch, Pa.Platform.Modules[F].M.ModuleType]:
482 Fd.write (' DEPEX = %s\n' % (Depex))
483 Fd.write ('-------------------------------------------------------------------------------\n')
484
485 Fd.write ('MODULE DEPENDENCY EXPRESSION\n')
486 if len(Pa.Platform.Modules[F].M.Module.DepexExpression[Pa.Platform.Modules[F].M.Arch, Pa.Platform.Modules[F].M.ModuleType]) == 0:
487 Fd.write (' NONE\n')
488 else:
489 for Depex in Pa.Platform.Modules[F].M.Module.DepexExpression[Pa.Platform.Modules[F].M.Arch, Pa.Platform.Modules[F].M.ModuleType]:
490 Fd.write (' %s\n' % (Depex))
491 Fd.write ('-------------------------------------------------------------------------------\n')
492
493 Fd.write ('MODULE + LIBRARY DEPENDENCY EXPRESSION\n')
494 if Pa.Platform.Modules[F].M.ModuleType in Pa.Platform.Modules[F].M.DepexExpressionList:
495 if Pa.Platform.Modules[F].M.DepexExpressionList[Pa.Platform.Modules[F].M.ModuleType] == '':
496 Fd.write (' NONE\n')
497 else:
498 Fd.write (' %s\n' % (Pa.Platform.Modules[F].M.DepexExpressionList[Pa.Platform.Modules[F].M.ModuleType]))
499 else:
500 Fd.write (' NONE\n')
501 Fd.write ('-------------------------------------------------------------------------------\n')
502
503 Fd.close()
504 except:
505 EdkLogger.error(None, FILE_OPEN_FAILURE, ExtraData=self.ReportFile)
506
507 self._BuildDir = None
508 self._FvDir = None
509 self._MakeFileDir = None
510 self._BuildCommand = None
511
512 return True
513
514 def __repr__(self):
515 return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList))
516
517 ## Return the directory to store FV files
518 def _GetFvDir(self):
519 if self._FvDir == None:
520 self._FvDir = path.join(self.BuildDir, 'FV')
521 return self._FvDir
522
523 ## Return the directory to store all intermediate and final files built
524 def _GetBuildDir(self):
525 return self.AutoGenObjectList[0].BuildDir
526
527 ## Return the build output directory platform specifies
528 def _GetOutputDir(self):
529 return self.Platform.OutputDirectory
530
531 ## Return platform name
532 def _GetName(self):
533 return self.Platform.PlatformName
534
535 ## Return meta-file GUID
536 def _GetGuid(self):
537 return self.Platform.Guid
538
539 ## Return platform version
540 def _GetVersion(self):
541 return self.Platform.Version
542
543 ## Return paths of tools
544 def _GetToolDefinition(self):
545 return self.AutoGenObjectList[0].ToolDefinition
546
547 ## Return directory of platform makefile
548 #
549 # @retval string Makefile directory
550 #
551 def _GetMakeFileDir(self):
552 if self._MakeFileDir == None:
553 self._MakeFileDir = self.BuildDir
554 return self._MakeFileDir
555
556 ## Return build command string
557 #
558 # @retval string Build command string
559 #
560 def _GetBuildCommand(self):
561 if self._BuildCommand == None:
562 # BuildCommand should be all the same. So just get one from platform AutoGen
563 self._BuildCommand = self.AutoGenObjectList[0].BuildCommand
564 return self._BuildCommand
565
566 ## Create makefile for the platform and mdoules in it
567 #
568 # @param CreateDepsMakeFile Flag indicating if the makefile for
569 # modules will be created as well
570 #
571 def CreateMakeFile(self, CreateDepsMakeFile=False):
572 # create makefile for platform
573 Makefile = GenMake.TopLevelMakefile(self)
574 if Makefile.Generate():
575 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for platform [%s] %s\n" %
576 (self.MetaFile, self.ArchList))
577 else:
578 EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for platform [%s] %s\n" %
579 (self.MetaFile, self.ArchList))
580
581 if CreateDepsMakeFile:
582 for Pa in self.AutoGenObjectList:
583 Pa.CreateMakeFile(CreateDepsMakeFile)
584
585 ## Create autogen code for platform and modules
586 #
587 # Since there's no autogen code for platform, this method will do nothing
588 # if CreateModuleCodeFile is set to False.
589 #
590 # @param CreateDepsCodeFile Flag indicating if creating module's
591 # autogen code file or not
592 #
593 def CreateCodeFile(self, CreateDepsCodeFile=False):
594 if not CreateDepsCodeFile:
595 return
596 for Pa in self.AutoGenObjectList:
597 Pa.CreateCodeFile(CreateDepsCodeFile)
598
599 Name = property(_GetName)
600 Guid = property(_GetGuid)
601 Version = property(_GetVersion)
602 OutputDir = property(_GetOutputDir)
603
604 ToolDefinition = property(_GetToolDefinition) # toolcode : tool path
605
606 BuildDir = property(_GetBuildDir)
607 FvDir = property(_GetFvDir)
608 MakeFileDir = property(_GetMakeFileDir)
609 BuildCommand = property(_GetBuildCommand)
610
611 ## AutoGen class for platform
612 #
613 # PlatformAutoGen class will process the original information in platform
614 # file in order to generate makefile for platform.
615 #
616 class PlatformAutoGen(AutoGen):
617 #
618 # Used to store all PCDs for both PEI and DXE phase, in order to generate
619 # correct PCD database
620 #
621 _DynaPcdList_ = []
622 _NonDynaPcdList_ = []
623
624 ## The real constructor of PlatformAutoGen
625 #
626 # This method is not supposed to be called by users of PlatformAutoGen. It's
627 # only used by factory method __new__() to do real initialization work for an
628 # object of PlatformAutoGen
629 #
630 # @param Workspace WorkspaceAutoGen object
631 # @param PlatformFile Platform file (DSC file)
632 # @param Target Build target (DEBUG, RELEASE)
633 # @param Toolchain Name of tool chain
634 # @param Arch arch of the platform supports
635 #
636 def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch):
637 EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen platform [%s] [%s]" % (PlatformFile, Arch))
638 GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (PlatformFile, Arch, Toolchain, Target)
639
640 self.MetaFile = PlatformFile
641 self.Workspace = Workspace
642 self.WorkspaceDir = Workspace.WorkspaceDir
643 self.ToolChain = Toolchain
644 self.BuildTarget = Target
645 self.Arch = Arch
646 self.SourceDir = PlatformFile.SubDir
647 self.SourceOverrideDir = None
648 self.FdTargetList = self.Workspace.FdTargetList
649 self.FvTargetList = self.Workspace.FvTargetList
650
651 # flag indicating if the makefile/C-code file has been created or not
652 self.IsMakeFileCreated = False
653 self.IsCodeFileCreated = False
654
655 self._Platform = None
656 self._Name = None
657 self._Guid = None
658 self._Version = None
659
660 self._BuildRule = None
661 self._SourceDir = None
662 self._BuildDir = None
663 self._OutputDir = None
664 self._FvDir = None
665 self._MakeFileDir = None
666 self._FdfFile = None
667
668 self._PcdTokenNumber = None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
669 self._DynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
670 self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
671
672 self._ToolDefinitions = None
673 self._ToolDefFile = None # toolcode : tool path
674 self._ToolChainFamily = None
675 self._BuildRuleFamily = None
676 self._BuildOption = None # toolcode : option
677 self._PackageList = None
678 self._ModuleAutoGenList = None
679 self._LibraryAutoGenList = None
680 self._BuildCommand = None
681
682 # get the original module/package/platform objects
683 self.BuildDatabase = Workspace.BuildDatabase
684 return True
685
686 def __repr__(self):
687 return "%s [%s]" % (self.MetaFile, self.Arch)
688
689 ## Create autogen code for platform and modules
690 #
691 # Since there's no autogen code for platform, this method will do nothing
692 # if CreateModuleCodeFile is set to False.
693 #
694 # @param CreateModuleCodeFile Flag indicating if creating module's
695 # autogen code file or not
696 #
697 def CreateCodeFile(self, CreateModuleCodeFile=False):
698 # only module has code to be greated, so do nothing if CreateModuleCodeFile is False
699 if self.IsCodeFileCreated or not CreateModuleCodeFile:
700 return
701
702 for Ma in self.ModuleAutoGenList:
703 Ma.CreateCodeFile(True)
704
705 # don't do this twice
706 self.IsCodeFileCreated = True
707
708 ## Create makefile for the platform and mdoules in it
709 #
710 # @param CreateModuleMakeFile Flag indicating if the makefile for
711 # modules will be created as well
712 #
713 def CreateMakeFile(self, CreateModuleMakeFile=False):
714 if CreateModuleMakeFile:
715 for ModuleFile in self.Platform.Modules:
716 Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget,
717 self.ToolChain, self.Arch, self.MetaFile)
718 Ma.CreateMakeFile(True)
719
720 # no need to create makefile for the platform more than once
721 if self.IsMakeFileCreated:
722 return
723
724 # create makefile for platform
725 Makefile = GenMake.PlatformMakefile(self)
726 if Makefile.Generate():
727 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for platform [%s] [%s]\n" %
728 (self.MetaFile, self.Arch))
729 else:
730 EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for platform [%s] [%s]\n" %
731 (self.MetaFile, self.Arch))
732 self.IsMakeFileCreated = True
733
734 ## Collect dynamic PCDs
735 #
736 # Gather dynamic PCDs list from each module and their settings from platform
737 # This interface should be invoked explicitly when platform action is created.
738 #
739 def CollectPlatformDynamicPcds(self):
740 # for gathering error information
741 NoDatumTypePcdList = set()
742
743 self._GuidValue = {}
744 for F in self.Platform.Modules.keys():
745 M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile)
746 #GuidValue.update(M.Guids)
747
748 self.Platform.Modules[F].M = M
749
750 for PcdFromModule in M.ModulePcdList+M.LibraryPcdList:
751 # make sure that the "VOID*" kind of datum has MaxDatumSize set
752 if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize == None:
753 NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, F))
754
755 if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd:
756 #
757 # If a dynamic PCD used by a PEM module/PEI module & DXE module,
758 # it should be stored in Pcd PEI database, If a dynamic only
759 # used by DXE module, it should be stored in DXE PCD database.
760 # The default Phase is DXE
761 #
762 if M.ModuleType in ["PEIM", "PEI_CORE"]:
763 PcdFromModule.Phase = "PEI"
764 if PcdFromModule not in self._DynaPcdList_:
765 self._DynaPcdList_.append(PcdFromModule)
766 elif PcdFromModule.Phase == 'PEI':
767 # overwrite any the same PCD existing, if Phase is PEI
768 Index = self._DynaPcdList_.index(PcdFromModule)
769 self._DynaPcdList_[Index] = PcdFromModule
770 elif PcdFromModule not in self._NonDynaPcdList_:
771 self._NonDynaPcdList_.append(PcdFromModule)
772
773 # print out error information and break the build, if error found
774 if len(NoDatumTypePcdList) > 0:
775 NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)
776 EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",
777 File=self.MetaFile,
778 ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
779 % NoDatumTypePcdListString)
780 self._NonDynamicPcdList = self._NonDynaPcdList_
781 self._DynamicPcdList = self._DynaPcdList_
782
783 #
784 # Sort dynamic PCD list to:
785 # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should
786 # try to be put header of dynamicd List
787 # 2) If PCD is HII type, the PCD item should be put after unicode type PCD
788 #
789 # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.
790 #
791 UnicodePcdArray = []
792 HiiPcdArray = []
793 OtherPcdArray = []
794 for Pcd in self._DynamicPcdList:
795 # just pick the a value to determine whether is unicode string type
796 Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]
797 PcdValue = Sku.DefaultValue
798 if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):
799 # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex
800 UnicodePcdArray.append(Pcd)
801 elif len(Sku.VariableName) > 0:
802 # if found HII type PCD then insert to right of UnicodeIndex
803 HiiPcdArray.append(Pcd)
804 else:
805 OtherPcdArray.append(Pcd)
806 del self._DynamicPcdList[:]
807 self._DynamicPcdList.extend(UnicodePcdArray)
808 self._DynamicPcdList.extend(HiiPcdArray)
809 self._DynamicPcdList.extend(OtherPcdArray)
810
811
812 ## Return the platform build data object
813 def _GetPlatform(self):
814 if self._Platform == None:
815 self._Platform = self.BuildDatabase[self.MetaFile, self.Arch]
816 return self._Platform
817
818 ## Return platform name
819 def _GetName(self):
820 return self.Platform.PlatformName
821
822 ## Return the meta file GUID
823 def _GetGuid(self):
824 return self.Platform.Guid
825
826 ## Return the platform version
827 def _GetVersion(self):
828 return self.Platform.Version
829
830 ## Return the FDF file name
831 def _GetFdfFile(self):
832 if self._FdfFile == None:
833 if self.Workspace.FdfFile != "":
834 self._FdfFile= path.join(self.WorkspaceDir, self.Workspace.FdfFile)
835 else:
836 self._FdfFile = ''
837 return self._FdfFile
838
839 ## Return the build output directory platform specifies
840 def _GetOutputDir(self):
841 return self.Platform.OutputDirectory
842
843 ## Return the directory to store all intermediate and final files built
844 def _GetBuildDir(self):
845 if self._BuildDir == None:
846 if os.path.isabs(self.OutputDir):
847 self._BuildDir = path.join(
848 path.abspath(self.OutputDir),
849 self.BuildTarget + "_" + self.ToolChain,
850 )
851 else:
852 self._BuildDir = path.join(
853 self.WorkspaceDir,
854 self.OutputDir,
855 self.BuildTarget + "_" + self.ToolChain,
856 )
857 return self._BuildDir
858
859 ## Return directory of platform makefile
860 #
861 # @retval string Makefile directory
862 #
863 def _GetMakeFileDir(self):
864 if self._MakeFileDir == None:
865 self._MakeFileDir = path.join(self.BuildDir, self.Arch)
866 return self._MakeFileDir
867
868 ## Return build command string
869 #
870 # @retval string Build command string
871 #
872 def _GetBuildCommand(self):
873 if self._BuildCommand == None:
874 self._BuildCommand = []
875 if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]:
876 self._BuildCommand += SplitOption(self.ToolDefinition["MAKE"]["PATH"])
877 if "FLAGS" in self.ToolDefinition["MAKE"]:
878 NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip()
879 if NewOption != '':
880 self._BuildCommand += SplitOption(NewOption)
881 return self._BuildCommand
882
883 ## Get tool chain definition
884 #
885 # Get each tool defition for given tool chain from tools_def.txt and platform
886 #
887 def _GetToolDefinition(self):
888 if self._ToolDefinitions == None:
889 ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary
890 if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase:
891 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration",
892 ExtraData="[%s]" % self.MetaFile)
893 self._ToolDefinitions = {}
894 DllPathList = set()
895 for Def in ToolDefinition:
896 Target, Tag, Arch, Tool, Attr = Def.split("_")
897 if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:
898 continue
899
900 Value = ToolDefinition[Def]
901 # don't record the DLL
902 if Attr == "DLL":
903 DllPathList.add(Value)
904 continue
905
906 if Tool not in self._ToolDefinitions:
907 self._ToolDefinitions[Tool] = {}
908 self._ToolDefinitions[Tool][Attr] = Value
909
910 ToolsDef = ''
911 MakePath = ''
912 if GlobalData.gOptions.SilentMode and "MAKE" in self._ToolDefinitions:
913 if "FLAGS" not in self._ToolDefinitions["MAKE"]:
914 self._ToolDefinitions["MAKE"]["FLAGS"] = ""
915 self._ToolDefinitions["MAKE"]["FLAGS"] += " -s"
916 MakeFlags = ''
917 for Tool in self._ToolDefinitions:
918 for Attr in self._ToolDefinitions[Tool]:
919 Value = self._ToolDefinitions[Tool][Attr]
920 if Tool in self.BuildOption and Attr in self.BuildOption[Tool]:
921 # check if override is indicated
922 if self.BuildOption[Tool][Attr].startswith('='):
923 Value = self.BuildOption[Tool][Attr][1:]
924 else:
925 Value += " " + self.BuildOption[Tool][Attr]
926
927 if Attr == "PATH":
928 # Don't put MAKE definition in the file
929 if Tool == "MAKE":
930 MakePath = Value
931 else:
932 ToolsDef += "%s = %s\n" % (Tool, Value)
933 elif Attr != "DLL":
934 # Don't put MAKE definition in the file
935 if Tool == "MAKE":
936 if Attr == "FLAGS":
937 MakeFlags = Value
938 else:
939 ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value)
940 ToolsDef += "\n"
941
942 SaveFileOnChange(self.ToolDefinitionFile, ToolsDef)
943 for DllPath in DllPathList:
944 os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"]
945 os.environ["MAKE_FLAGS"] = MakeFlags
946
947 return self._ToolDefinitions
948
949 ## Return the paths of tools
950 def _GetToolDefFile(self):
951 if self._ToolDefFile == None:
952 self._ToolDefFile = os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch)
953 return self._ToolDefFile
954
955 ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.
956 def _GetToolChainFamily(self):
957 if self._ToolChainFamily == None:
958 ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase
959 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
960 or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
961 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]:
962 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
963 % self.ToolChain)
964 self._ToolChainFamily = "MSFT"
965 else:
966 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]
967 return self._ToolChainFamily
968
969 def _GetBuildRuleFamily(self):
970 if self._BuildRuleFamily == None:
971 ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase
972 if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \
973 or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \
974 or not ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]:
975 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
976 % self.ToolChain)
977 self._BuildRuleFamily = "MSFT"
978 else:
979 self._BuildRuleFamily = ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]
980 return self._BuildRuleFamily
981
982 ## Return the build options specific to this platform
983 def _GetBuildOptions(self):
984 if self._BuildOption == None:
985 self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)
986 return self._BuildOption
987
988 ## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt
989 #
990 # @retval BuildRule object
991 #
992 def _GetBuildRule(self):
993 if self._BuildRule == None:
994 BuildRuleFile = None
995 if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary:
996 BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]
997 if BuildRuleFile in [None, '']:
998 BuildRuleFile = gBuildRuleFile
999 self._BuildRule = BuildRule(BuildRuleFile)
1000 return self._BuildRule
1001
1002 ## Summarize the packages used by modules in this platform
1003 def _GetPackageList(self):
1004 if self._PackageList == None:
1005 self._PackageList = set()
1006 for La in self.LibraryAutoGenList:
1007 self._PackageList.update(La.DependentPackageList)
1008 for Ma in self.ModuleAutoGenList:
1009 self._PackageList.update(Ma.DependentPackageList)
1010 self._PackageList = list(self._PackageList)
1011 return self._PackageList
1012
1013 ## Get list of non-dynamic PCDs
1014 def _GetNonDynamicPcdList(self):
1015 return self._NonDynamicPcdList
1016
1017 ## Get list of dynamic PCDs
1018 def _GetDynamicPcdList(self):
1019 return self._DynamicPcdList
1020
1021 ## Generate Token Number for all PCD
1022 def _GetPcdTokenNumbers(self):
1023 if self._PcdTokenNumber == None:
1024 self._PcdTokenNumber = sdict()
1025 TokenNumber = 1
1026 for Pcd in self.DynamicPcdList:
1027 if Pcd.Phase == "PEI":
1028 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
1029 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
1030 TokenNumber += 1
1031
1032 for Pcd in self.DynamicPcdList:
1033 if Pcd.Phase == "DXE":
1034 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
1035 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
1036 TokenNumber += 1
1037
1038 for Pcd in self.NonDynamicPcdList:
1039 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
1040 TokenNumber += 1
1041 return self._PcdTokenNumber
1042
1043 ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform
1044 def _GetAutoGenObjectList(self):
1045 self._ModuleAutoGenList = []
1046 self._LibraryAutoGenList = []
1047 for ModuleFile in self.Platform.Modules:
1048 Ma = ModuleAutoGen(
1049 self.Workspace,
1050 ModuleFile,
1051 self.BuildTarget,
1052 self.ToolChain,
1053 self.Arch,
1054 self.MetaFile
1055 )
1056 if Ma not in self._ModuleAutoGenList:
1057 self._ModuleAutoGenList.append(Ma)
1058 for La in Ma.LibraryAutoGenList:
1059 if La not in self._LibraryAutoGenList:
1060 self._LibraryAutoGenList.append(La)
1061
1062 ## Summarize ModuleAutoGen objects of all modules to be built for this platform
1063 def _GetModuleAutoGenList(self):
1064 if self._ModuleAutoGenList == None:
1065 self._GetAutoGenObjectList()
1066 return self._ModuleAutoGenList
1067
1068 ## Summarize ModuleAutoGen objects of all libraries to be built for this platform
1069 def _GetLibraryAutoGenList(self):
1070 if self._LibraryAutoGenList == None:
1071 self._GetAutoGenObjectList()
1072 return self._LibraryAutoGenList
1073
1074 ## Test if a module is supported by the platform
1075 #
1076 # An error will be raised directly if the module or its arch is not supported
1077 # by the platform or current configuration
1078 #
1079 def ValidModule(self, Module):
1080 return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances
1081
1082 ## Resolve the library classes in a module to library instances
1083 #
1084 # This method will not only resolve library classes but also sort the library
1085 # instances according to the dependency-ship.
1086 #
1087 # @param Module The module from which the library classes will be resolved
1088 #
1089 # @retval library_list List of library instances sorted
1090 #
1091 def ApplyLibraryInstance(self, Module):
1092 ModuleType = Module.ModuleType
1093
1094 # for overridding library instances with module specific setting
1095 PlatformModule = self.Platform.Modules[str(Module)]
1096
1097 # add forced library instances (specified under LibraryClasses sections)
1098 for LibraryClass in self.Platform.LibraryClasses.GetKeys():
1099 if LibraryClass.startswith("NULL"):
1100 Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass]
1101
1102 # add forced library instances (specified in module overrides)
1103 for LibraryClass in PlatformModule.LibraryClasses:
1104 if LibraryClass.startswith("NULL"):
1105 Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]
1106
1107 # R9 module
1108 LibraryConsumerList = [Module]
1109 Constructor = []
1110 ConsumedByList = sdict()
1111 LibraryInstance = sdict()
1112
1113 EdkLogger.verbose("")
1114 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))
1115 while len(LibraryConsumerList) > 0:
1116 M = LibraryConsumerList.pop()
1117 for LibraryClassName in M.LibraryClasses:
1118 if LibraryClassName not in LibraryInstance:
1119 # override library instance for this module
1120 if LibraryClassName in PlatformModule.LibraryClasses:
1121 LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]
1122 else:
1123 LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]
1124 if LibraryPath == None or LibraryPath == "":
1125 LibraryPath = M.LibraryClasses[LibraryClassName]
1126 if LibraryPath == None or LibraryPath == "":
1127 EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
1128 "Instance of library class [%s] is not found" % LibraryClassName,
1129 File=self.MetaFile,
1130 ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module)))
1131
1132 LibraryModule = self.BuildDatabase[LibraryPath, self.Arch]
1133 # for those forced library instance (NULL library), add a fake library class
1134 if LibraryClassName.startswith("NULL"):
1135 LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))
1136 elif LibraryModule.LibraryClass == None \
1137 or len(LibraryModule.LibraryClass) == 0 \
1138 or (ModuleType != 'USER_DEFINED'
1139 and ModuleType not in LibraryModule.LibraryClass[0].SupModList):
1140 # only USER_DEFINED can link against any library instance despite of its SupModList
1141 EdkLogger.error("build", OPTION_MISSING,
1142 "Module type [%s] is not supported by library instance [%s]" \
1143 % (ModuleType, LibraryPath), File=self.MetaFile,
1144 ExtraData="consumed by [%s]" % str(Module))
1145
1146 LibraryInstance[LibraryClassName] = LibraryModule
1147 LibraryConsumerList.append(LibraryModule)
1148 EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))
1149 else:
1150 LibraryModule = LibraryInstance[LibraryClassName]
1151
1152 if LibraryModule == None:
1153 continue
1154
1155 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:
1156 Constructor.append(LibraryModule)
1157
1158 if LibraryModule not in ConsumedByList:
1159 ConsumedByList[LibraryModule] = []
1160 # don't add current module itself to consumer list
1161 if M != Module:
1162 if M in ConsumedByList[LibraryModule]:
1163 continue
1164 ConsumedByList[LibraryModule].append(M)
1165 #
1166 # Initialize the sorted output list to the empty set
1167 #
1168 SortedLibraryList = []
1169 #
1170 # Q <- Set of all nodes with no incoming edges
1171 #
1172 LibraryList = [] #LibraryInstance.values()
1173 Q = []
1174 for LibraryClassName in LibraryInstance:
1175 M = LibraryInstance[LibraryClassName]
1176 LibraryList.append(M)
1177 if ConsumedByList[M] == []:
1178 Q.append(M)
1179
1180 #
1181 # start the DAG algorithm
1182 #
1183 while True:
1184 EdgeRemoved = True
1185 while Q == [] and EdgeRemoved:
1186 EdgeRemoved = False
1187 # for each node Item with a Constructor
1188 for Item in LibraryList:
1189 if Item not in Constructor:
1190 continue
1191 # for each Node without a constructor with an edge e from Item to Node
1192 for Node in ConsumedByList[Item]:
1193 if Node in Constructor:
1194 continue
1195 # remove edge e from the graph if Node has no constructor
1196 ConsumedByList[Item].remove(Node)
1197 EdgeRemoved = True
1198 if ConsumedByList[Item] == []:
1199 # insert Item into Q
1200 Q.insert(0, Item)
1201 break
1202 if Q != []:
1203 break
1204 # DAG is done if there's no more incoming edge for all nodes
1205 if Q == []:
1206 break
1207
1208 # remove node from Q
1209 Node = Q.pop()
1210 # output Node
1211 SortedLibraryList.append(Node)
1212
1213 # for each node Item with an edge e from Node to Item do
1214 for Item in LibraryList:
1215 if Node not in ConsumedByList[Item]:
1216 continue
1217 # remove edge e from the graph
1218 ConsumedByList[Item].remove(Node)
1219
1220 if ConsumedByList[Item] != []:
1221 continue
1222 # insert Item into Q, if Item has no other incoming edges
1223 Q.insert(0, Item)
1224
1225 #
1226 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
1227 #
1228 for Item in LibraryList:
1229 if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:
1230 ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])
1231 EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),
1232 ExtraData=ErrorMessage, File=self.MetaFile)
1233 if Item not in SortedLibraryList:
1234 SortedLibraryList.append(Item)
1235
1236 #
1237 # Build the list of constructor and destructir names
1238 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
1239 #
1240 SortedLibraryList.reverse()
1241 return SortedLibraryList
1242
1243
1244 ## Override PCD setting (type, value, ...)
1245 #
1246 # @param ToPcd The PCD to be overrided
1247 # @param FromPcd The PCD overrideing from
1248 #
1249 def _OverridePcd(self, ToPcd, FromPcd, Module=""):
1250 #
1251 # in case there's PCDs coming from FDF file, which have no type given.
1252 # at this point, ToPcd.Type has the type found from dependent
1253 # package
1254 #
1255 if FromPcd != None:
1256 if ToPcd.Pending and FromPcd.Type not in [None, '']:
1257 ToPcd.Type = FromPcd.Type
1258 elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \
1259 and ToPcd.Type != FromPcd.Type:
1260 EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",
1261 ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
1262 % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName,
1263 ToPcd.Type, Module, FromPcd.Type),
1264 File=self.MetaFile)
1265
1266 if FromPcd.MaxDatumSize not in [None, '']:
1267 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
1268 if FromPcd.DefaultValue not in [None, '']:
1269 ToPcd.DefaultValue = FromPcd.DefaultValue
1270 if FromPcd.TokenValue not in [None, '']:
1271 ToPcd.TokenValue = FromPcd.TokenValue
1272 if FromPcd.MaxDatumSize not in [None, '']:
1273 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
1274 if FromPcd.DatumType not in [None, '']:
1275 ToPcd.DatumType = FromPcd.DatumType
1276 if FromPcd.SkuInfoList not in [None, '', []]:
1277 ToPcd.SkuInfoList = FromPcd.SkuInfoList
1278
1279 # check the validation of datum
1280 IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)
1281 if not IsValid:
1282 EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,
1283 ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))
1284
1285 if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:
1286 EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \
1287 % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))
1288 Value = ToPcd.DefaultValue
1289 if Value in [None, '']:
1290 ToPcd.MaxDatumSize = 1
1291 elif Value[0] == 'L':
1292 ToPcd.MaxDatumSize = str(len(Value) * 2)
1293 elif Value[0] == '{':
1294 ToPcd.MaxDatumSize = str(len(Value.split(',')))
1295 else:
1296 ToPcd.MaxDatumSize = str(len(Value))
1297
1298 # apply default SKU for dynamic PCDS if specified one is not available
1299 if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \
1300 and ToPcd.SkuInfoList in [None, {}, '']:
1301 if self.Platform.SkuName in self.Platform.SkuIds:
1302 SkuName = self.Platform.SkuName
1303 else:
1304 SkuName = 'DEFAULT'
1305 ToPcd.SkuInfoList = {
1306 SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue)
1307 }
1308
1309 ## Apply PCD setting defined platform to a module
1310 #
1311 # @param Module The module from which the PCD setting will be overrided
1312 #
1313 # @retval PCD_list The list PCDs with settings from platform
1314 #
1315 def ApplyPcdSetting(self, Module, Pcds):
1316 # for each PCD in module
1317 for Name,Guid in Pcds:
1318 PcdInModule = Pcds[Name,Guid]
1319 # find out the PCD setting in platform
1320 if (Name,Guid) in self.Platform.Pcds:
1321 PcdInPlatform = self.Platform.Pcds[Name,Guid]
1322 else:
1323 PcdInPlatform = None
1324 # then override the settings if any
1325 self._OverridePcd(PcdInModule, PcdInPlatform, Module)
1326 # resolve the VariableGuid value
1327 for SkuId in PcdInModule.SkuInfoList:
1328 Sku = PcdInModule.SkuInfoList[SkuId]
1329 if Sku.VariableGuid == '': continue
1330 Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList)
1331 if Sku.VariableGuidValue == None:
1332 PackageList = "\n\t".join([str(P) for P in self.PackageList])
1333 EdkLogger.error(
1334 'build',
1335 RESOURCE_NOT_AVAILABLE,
1336 "Value of GUID [%s] is not found in" % Sku.VariableGuid,
1337 ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \
1338 % (Guid, Name, str(Module)),
1339 File=self.MetaFile
1340 )
1341
1342 # override PCD settings with module specific setting
1343 if Module in self.Platform.Modules:
1344 PlatformModule = self.Platform.Modules[str(Module)]
1345 for Key in PlatformModule.Pcds:
1346 if Key in Pcds:
1347 self._OverridePcd(Pcds[Key], PlatformModule.Pcds[Key], Module)
1348 return Pcds.values()
1349
1350 ## Resolve library names to library modules
1351 #
1352 # (for R8.x modules)
1353 #
1354 # @param Module The module from which the library names will be resolved
1355 #
1356 # @retval library_list The list of library modules
1357 #
1358 def ResolveLibraryReference(self, Module):
1359 EdkLogger.verbose("")
1360 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))
1361 LibraryConsumerList = [Module]
1362
1363 # "CompilerStub" is a must for R8 modules
1364 if Module.Libraries:
1365 Module.Libraries.append("CompilerStub")
1366 LibraryList = []
1367 while len(LibraryConsumerList) > 0:
1368 M = LibraryConsumerList.pop()
1369 for LibraryName in M.Libraries:
1370 Library = self.Platform.LibraryClasses[LibraryName, ':dummy:']
1371 if Library == None:
1372 for Key in self.Platform.LibraryClasses.data.keys():
1373 if LibraryName.upper() == Key.upper():
1374 Library = self.Platform.LibraryClasses[Key, ':dummy:']
1375 break
1376 if Library == None:
1377 EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M),
1378 ExtraData="\t%s [%s]" % (str(Module), self.Arch))
1379 continue
1380
1381 if Library not in LibraryList:
1382 LibraryList.append(Library)
1383 LibraryConsumerList.append(Library)
1384 EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library)))
1385 return LibraryList
1386
1387 ## Expand * in build option key
1388 #
1389 # @param Options Options to be expanded
1390 #
1391 # @retval options Options expanded
1392 #
1393 def _ExpandBuildOption(self, Options):
1394 BuildOptions = {}
1395 FamilyMatch = False
1396 FamilyIsNull = True
1397 for Key in Options:
1398 Family = Key[0]
1399 Target, Tag, Arch, Tool, Attr = Key[1].split("_")
1400 # if tool chain family doesn't match, skip it
1401 if Tool in self.ToolDefinition and Family != "":
1402 FamilyIsNull = False
1403 if self.ToolDefinition[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
1404 if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
1405 continue
1406 elif Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:
1407 continue
1408 FamilyMatch = True
1409 # expand any wildcard
1410 if Target == "*" or Target == self.BuildTarget:
1411 if Tag == "*" or Tag == self.ToolChain:
1412 if Arch == "*" or Arch == self.Arch:
1413 if Tool not in BuildOptions:
1414 BuildOptions[Tool] = {}
1415 if Attr != "FLAGS" or Attr not in BuildOptions[Tool]:
1416 BuildOptions[Tool][Attr] = Options[Key]
1417 else:
1418 # append options for the same tool
1419 BuildOptions[Tool][Attr] += " " + Options[Key]
1420 # Build Option Family has been checked, which need't to be checked again for family.
1421 if FamilyMatch or FamilyIsNull:
1422 return BuildOptions
1423
1424 for Key in Options:
1425 Family = Key[0]
1426 Target, Tag, Arch, Tool, Attr = Key[1].split("_")
1427 # if tool chain family doesn't match, skip it
1428 if Tool not in self.ToolDefinition or Family =="":
1429 continue
1430 # option has been added before
1431 if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:
1432 continue
1433
1434 # expand any wildcard
1435 if Target == "*" or Target == self.BuildTarget:
1436 if Tag == "*" or Tag == self.ToolChain:
1437 if Arch == "*" or Arch == self.Arch:
1438 if Tool not in BuildOptions:
1439 BuildOptions[Tool] = {}
1440 if Attr != "FLAGS" or Attr not in BuildOptions[Tool]:
1441 BuildOptions[Tool][Attr] = Options[Key]
1442 else:
1443 # append options for the same tool
1444 BuildOptions[Tool][Attr] += " " + Options[Key]
1445 return BuildOptions
1446
1447 ## Append build options in platform to a module
1448 #
1449 # @param Module The module to which the build options will be appened
1450 #
1451 # @retval options The options appended with build options in platform
1452 #
1453 def ApplyBuildOption(self, Module):
1454 PlatformOptions = self.BuildOption
1455 ModuleOptions = self._ExpandBuildOption(Module.BuildOptions)
1456 if Module in self.Platform.Modules:
1457 PlatformModule = self.Platform.Modules[str(Module)]
1458 PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions)
1459 else:
1460 PlatformModuleOptions = {}
1461
1462 AllTools = set(ModuleOptions.keys() + PlatformOptions.keys() + PlatformModuleOptions.keys() + self.ToolDefinition.keys())
1463 BuildOptions = {}
1464 for Tool in AllTools:
1465 if Tool not in BuildOptions:
1466 BuildOptions[Tool] = {}
1467
1468 for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, PlatformModuleOptions]:
1469 if Tool not in Options:
1470 continue
1471 for Attr in Options[Tool]:
1472 Value = Options[Tool][Attr]
1473 if Attr not in BuildOptions[Tool]:
1474 BuildOptions[Tool][Attr] = ""
1475 # check if override is indicated
1476 if Value.startswith('='):
1477 BuildOptions[Tool][Attr] = Value[1:]
1478 else:
1479 BuildOptions[Tool][Attr] += " " + Value
1480 return BuildOptions
1481
1482 Platform = property(_GetPlatform)
1483 Name = property(_GetName)
1484 Guid = property(_GetGuid)
1485 Version = property(_GetVersion)
1486
1487 OutputDir = property(_GetOutputDir)
1488 BuildDir = property(_GetBuildDir)
1489 MakeFileDir = property(_GetMakeFileDir)
1490 FdfFile = property(_GetFdfFile)
1491
1492 PcdTokenNumber = property(_GetPcdTokenNumbers) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
1493 DynamicPcdList = property(_GetDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1494 NonDynamicPcdList = property(_GetNonDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1495 PackageList = property(_GetPackageList)
1496
1497 ToolDefinition = property(_GetToolDefinition) # toolcode : tool path
1498 ToolDefinitionFile = property(_GetToolDefFile) # toolcode : lib path
1499 ToolChainFamily = property(_GetToolChainFamily)
1500 BuildRuleFamily = property(_GetBuildRuleFamily)
1501 BuildOption = property(_GetBuildOptions) # toolcode : option
1502
1503 BuildCommand = property(_GetBuildCommand)
1504 BuildRule = property(_GetBuildRule)
1505 ModuleAutoGenList = property(_GetModuleAutoGenList)
1506 LibraryAutoGenList = property(_GetLibraryAutoGenList)
1507
1508 ## ModuleAutoGen class
1509 #
1510 # This class encapsules the AutoGen behaviors for the build tools. In addition to
1511 # the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according
1512 # to the [depex] section in module's inf file.
1513 #
1514 class ModuleAutoGen(AutoGen):
1515 ## The real constructor of ModuleAutoGen
1516 #
1517 # This method is not supposed to be called by users of ModuleAutoGen. It's
1518 # only used by factory method __new__() to do real initialization work for an
1519 # object of ModuleAutoGen
1520 #
1521 # @param Workspace EdkIIWorkspaceBuild object
1522 # @param ModuleFile The path of module file
1523 # @param Target Build target (DEBUG, RELEASE)
1524 # @param Toolchain Name of tool chain
1525 # @param Arch The arch the module supports
1526 # @param PlatformFile Platform meta-file
1527 #
1528 def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):
1529 EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen module [%s] [%s]" % (ModuleFile, Arch))
1530 GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (ModuleFile, Arch, Toolchain, Target)
1531
1532 self.Workspace = Workspace
1533 self.WorkspaceDir = Workspace.WorkspaceDir
1534
1535 self.MetaFile = ModuleFile
1536 self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)
1537 # check if this module is employed by active platform
1538 if not self.PlatformInfo.ValidModule(self.MetaFile):
1539 EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \
1540 % (self.MetaFile, Arch))
1541 return False
1542
1543 self.SourceDir = self.MetaFile.SubDir
1544 self.SourceOverrideDir = None
1545 # use overrided path defined in DSC file
1546 if self.MetaFile.Key in GlobalData.gOverrideDir:
1547 self.SourceOverrideDir = GlobalData.gOverrideDir[self.MetaFile.Key]
1548
1549 self.ToolChain = Toolchain
1550 self.BuildTarget = Target
1551 self.Arch = Arch
1552 self.ToolChainFamily = self.PlatformInfo.ToolChainFamily
1553 self.BuildRuleFamily = self.PlatformInfo.BuildRuleFamily
1554
1555 self.IsMakeFileCreated = False
1556 self.IsCodeFileCreated = False
1557
1558 self.BuildDatabase = self.Workspace.BuildDatabase
1559
1560 self._Module = None
1561 self._Name = None
1562 self._Guid = None
1563 self._Version = None
1564 self._ModuleType = None
1565 self._ComponentType = None
1566 self._PcdIsDriver = None
1567 self._AutoGenVersion = None
1568 self._LibraryFlag = None
1569 self._CustomMakefile = None
1570 self._Macro = None
1571
1572 self._BuildDir = None
1573 self._OutputDir = None
1574 self._DebugDir = None
1575 self._MakeFileDir = None
1576
1577 self._IncludePathList = None
1578 self._AutoGenFileList = None
1579 self._UnicodeFileList = None
1580 self._SourceFileList = None
1581 self._ObjectFileList = None
1582 self._BinaryFileList = None
1583
1584 self._DependentPackageList = None
1585 self._DependentLibraryList = None
1586 self._LibraryAutoGenList = None
1587 self._DerivedPackageList = None
1588 self._ModulePcdList = None
1589 self._LibraryPcdList = None
1590 self._GuidList = None
1591 self._ProtocolList = None
1592 self._PpiList = None
1593 self._DepexList = None
1594 self._DepexExpressionList = None
1595 self._BuildOption = None
1596 self._BuildTargets = None
1597 self._IntroBuildTargetList = None
1598 self._FinalBuildTargetList = None
1599 self._FileTypes = None
1600 self._BuildRules = None
1601
1602 return True
1603
1604 def __repr__(self):
1605 return "%s [%s]" % (self.MetaFile, self.Arch)
1606
1607 # Macros could be used in build_rule.txt (also Makefile)
1608 def _GetMacros(self):
1609 if self._Macro == None:
1610 self._Macro = sdict()
1611 self._Macro["WORKSPACE" ] = self.WorkspaceDir
1612 self._Macro["MODULE_NAME" ] = self.Name
1613 self._Macro["MODULE_GUID" ] = self.Guid
1614 self._Macro["MODULE_VERSION" ] = self.Version
1615 self._Macro["MODULE_TYPE" ] = self.ModuleType
1616 self._Macro["MODULE_FILE" ] = str(self.MetaFile)
1617 self._Macro["MODULE_FILE_BASE_NAME" ] = self.MetaFile.BaseName
1618 self._Macro["MODULE_RELATIVE_DIR" ] = self.SourceDir
1619 self._Macro["MODULE_DIR" ] = self.SourceDir
1620
1621 self._Macro["BASE_NAME" ] = self.Name
1622
1623 self._Macro["ARCH" ] = self.Arch
1624 self._Macro["TOOLCHAIN" ] = self.ToolChain
1625 self._Macro["TOOLCHAIN_TAG" ] = self.ToolChain
1626 self._Macro["TARGET" ] = self.BuildTarget
1627
1628 self._Macro["BUILD_DIR" ] = self.PlatformInfo.BuildDir
1629 self._Macro["BIN_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)
1630 self._Macro["LIB_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)
1631 self._Macro["MODULE_BUILD_DIR" ] = self.BuildDir
1632 self._Macro["OUTPUT_DIR" ] = self.OutputDir
1633 self._Macro["DEBUG_DIR" ] = self.DebugDir
1634 return self._Macro
1635
1636 ## Return the module build data object
1637 def _GetModule(self):
1638 if self._Module == None:
1639 self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch]
1640 return self._Module
1641
1642 ## Return the module name
1643 def _GetBaseName(self):
1644 return self.Module.BaseName
1645
1646 ## Return the module SourceOverridePath
1647 def _GetSourceOverridePath(self):
1648 return self.Module.SourceOverridePath
1649
1650 ## Return the module meta-file GUID
1651 def _GetGuid(self):
1652 return self.Module.Guid
1653
1654 ## Return the module version
1655 def _GetVersion(self):
1656 return self.Module.Version
1657
1658 ## Return the module type
1659 def _GetModuleType(self):
1660 return self.Module.ModuleType
1661
1662 ## Return the component type (for R8.x style of module)
1663 def _GetComponentType(self):
1664 return self.Module.ComponentType
1665
1666 ## Return the build type
1667 def _GetBuildType(self):
1668 return self.Module.BuildType
1669
1670 ## Return the PCD_IS_DRIVER setting
1671 def _GetPcdIsDriver(self):
1672 return self.Module.PcdIsDriver
1673
1674 ## Return the autogen version, i.e. module meta-file version
1675 def _GetAutoGenVersion(self):
1676 return self.Module.AutoGenVersion
1677
1678 ## Check if the module is library or not
1679 def _IsLibrary(self):
1680 if self._LibraryFlag == None:
1681 if self.Module.LibraryClass != None and self.Module.LibraryClass != []:
1682 self._LibraryFlag = True
1683 else:
1684 self._LibraryFlag = False
1685 return self._LibraryFlag
1686
1687 ## Return the directory to store intermediate files of the module
1688 def _GetBuildDir(self):
1689 if self._BuildDir == None:
1690 self._BuildDir = path.join(
1691 self.PlatformInfo.BuildDir,
1692 self.Arch,
1693 self.SourceDir,
1694 self.MetaFile.BaseName
1695 )
1696 CreateDirectory(self._BuildDir)
1697 return self._BuildDir
1698
1699 ## Return the directory to store the intermediate object files of the mdoule
1700 def _GetOutputDir(self):
1701 if self._OutputDir == None:
1702 self._OutputDir = path.join(self.BuildDir, "OUTPUT")
1703 CreateDirectory(self._OutputDir)
1704 return self._OutputDir
1705
1706 ## Return the directory to store auto-gened source files of the mdoule
1707 def _GetDebugDir(self):
1708 if self._DebugDir == None:
1709 self._DebugDir = path.join(self.BuildDir, "DEBUG")
1710 CreateDirectory(self._DebugDir)
1711 return self._DebugDir
1712
1713 ## Return the path of custom file
1714 def _GetCustomMakefile(self):
1715 if self._CustomMakefile == None:
1716 self._CustomMakefile = {}
1717 for Type in self.Module.CustomMakefile:
1718 if Type in gMakeTypeMap:
1719 MakeType = gMakeTypeMap[Type]
1720 else:
1721 MakeType = 'nmake'
1722 if self.SourceOverrideDir != None:
1723 File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type])
1724 if not os.path.exists(File):
1725 File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
1726 else:
1727 File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
1728 self._CustomMakefile[MakeType] = File
1729 return self._CustomMakefile
1730
1731 ## Return the directory of the makefile
1732 #
1733 # @retval string The directory string of module's makefile
1734 #
1735 def _GetMakeFileDir(self):
1736 return self.BuildDir
1737
1738 ## Return build command string
1739 #
1740 # @retval string Build command string
1741 #
1742 def _GetBuildCommand(self):
1743 return self.PlatformInfo.BuildCommand
1744
1745 ## Get object list of all packages the module and its dependent libraries belong to
1746 #
1747 # @retval list The list of package object
1748 #
1749 def _GetDerivedPackageList(self):
1750 PackageList = []
1751 for M in [self.Module] + self.DependentLibraryList:
1752 for Package in M.Packages:
1753 if Package in PackageList:
1754 continue
1755 PackageList.append(Package)
1756 return PackageList
1757
1758 ## Merge dependency expression
1759 #
1760 # @retval list The token list of the dependency expression after parsed
1761 #
1762 def _GetDepexTokenList(self):
1763 if self._DepexList == None:
1764 self._DepexList = {}
1765 if self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
1766 return self._DepexList
1767
1768 self._DepexList[self.ModuleType] = []
1769
1770 for ModuleType in self._DepexList:
1771 DepexList = self._DepexList[ModuleType]
1772 #
1773 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
1774 #
1775 for M in [self.Module] + self.DependentLibraryList:
1776 Inherited = False
1777 for D in M.Depex[self.Arch, ModuleType]:
1778 if DepexList != []:
1779 DepexList.append('AND')
1780 DepexList.append('(')
1781 DepexList.extend(D)
1782 if DepexList[-1] == 'END': # no need of a END at this time
1783 DepexList.pop()
1784 DepexList.append(')')
1785 Inherited = True
1786 if Inherited:
1787 EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexList))
1788 if 'BEFORE' in DepexList or 'AFTER' in DepexList:
1789 break
1790 if len(DepexList) > 0:
1791 EdkLogger.verbose('')
1792 return self._DepexList
1793
1794 ## Merge dependency expression
1795 #
1796 # @retval list The token list of the dependency expression after parsed
1797 #
1798 def _GetDepexExpressionTokenList(self):
1799 if self._DepexExpressionList == None:
1800 self._DepexExpressionList = {}
1801 if self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
1802 return self._DepexExpressionList
1803
1804 self._DepexExpressionList[self.ModuleType] = ''
1805
1806 for ModuleType in self._DepexExpressionList:
1807 DepexExpressionList = self._DepexExpressionList[ModuleType]
1808 #
1809 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
1810 #
1811 for M in [self.Module] + self.DependentLibraryList:
1812 Inherited = False
1813 for D in M.DepexExpression[self.Arch, ModuleType]:
1814 if DepexExpressionList != '':
1815 DepexExpressionList += ' AND '
1816 DepexExpressionList += '('
1817 DepexExpressionList += D
1818 DepexExpressionList = DepexExpressionList.rstrip('END').strip()
1819 DepexExpressionList += ')'
1820 Inherited = True
1821 if Inherited:
1822 EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexExpressionList))
1823 if 'BEFORE' in DepexExpressionList or 'AFTER' in DepexExpressionList:
1824 break
1825 if len(DepexExpressionList) > 0:
1826 EdkLogger.verbose('')
1827 self._DepexExpressionList[ModuleType] = DepexExpressionList
1828 return self._DepexExpressionList
1829
1830 ## Return the list of specification version required for the module
1831 #
1832 # @retval list The list of specification defined in module file
1833 #
1834 def _GetSpecification(self):
1835 return self.Module.Specification
1836
1837 ## Tool option for the module build
1838 #
1839 # @param PlatformInfo The object of PlatformBuildInfo
1840 # @retval dict The dict containing valid options
1841 #
1842 def _GetModuleBuildOption(self):
1843 if self._BuildOption == None:
1844 self._BuildOption = self.PlatformInfo.ApplyBuildOption(self.Module)
1845 return self._BuildOption
1846
1847 ## Return a list of files which can be built from source
1848 #
1849 # What kind of files can be built is determined by build rules in
1850 # $(WORKSPACE)/Conf/build_rule.txt and toolchain family.
1851 #
1852 def _GetSourceFileList(self):
1853 if self._SourceFileList == None:
1854 self._SourceFileList = []
1855 for F in self.Module.Sources:
1856 # match tool chain
1857 if F.TagName != "" and F.TagName != self.ToolChain:
1858 EdkLogger.debug(EdkLogger.DEBUG_9, "The toolchain [%s] for processing file [%s] is found, "
1859 "but [%s] is needed" % (F.TagName, str(F), self.ToolChain))
1860 continue
1861 # match tool chain family
1862 if F.ToolChainFamily != "" and F.ToolChainFamily != self.ToolChainFamily:
1863 EdkLogger.debug(
1864 EdkLogger.DEBUG_0,
1865 "The file [%s] must be built by tools of [%s], " \
1866 "but current toolchain family is [%s]" \
1867 % (str(F), F.ToolChainFamily, self.ToolChainFamily))
1868 continue
1869
1870 # add the file path into search path list for file including
1871 if F.Dir not in self.IncludePathList and self.AutoGenVersion >= 0x00010005:
1872 self.IncludePathList.insert(0, F.Dir)
1873 self._SourceFileList.append(F)
1874 self._ApplyBuildRule(F, TAB_UNKNOWN_FILE)
1875 return self._SourceFileList
1876
1877 ## Return the list of unicode files
1878 def _GetUnicodeFileList(self):
1879 if self._UnicodeFileList == None:
1880 if TAB_UNICODE_FILE in self.FileTypes:
1881 self._UnicodeFileList = self.FileTypes[TAB_UNICODE_FILE]
1882 else:
1883 self._UnicodeFileList = []
1884 return self._UnicodeFileList
1885
1886 ## Return a list of files which can be built from binary
1887 #
1888 # "Build" binary files are just to copy them to build directory.
1889 #
1890 # @retval list The list of files which can be built later
1891 #
1892 def _GetBinaryFiles(self):
1893 if self._BinaryFileList == None:
1894 self._BinaryFileList = []
1895 for F in self.Module.Binaries:
1896 if F.Target not in ['COMMON', '*'] and F.Target != self.BuildTarget:
1897 continue
1898 self._BinaryFileList.append(F)
1899 self._ApplyBuildRule(F, F.Type)
1900 return self._BinaryFileList
1901
1902 def _GetBuildRules(self):
1903 if self._BuildRules == None:
1904 BuildRules = {}
1905 BuildRuleDatabase = self.PlatformInfo.BuildRule
1906 for Type in BuildRuleDatabase.FileTypeList:
1907 #first try getting build rule by BuildRuleFamily
1908 RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.BuildRuleFamily]
1909 if not RuleObject:
1910 # build type is always module type, but ...
1911 if self.ModuleType != self.BuildType:
1912 RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.BuildRuleFamily]
1913 #second try getting build rule by ToolChainFamily
1914 if not RuleObject:
1915 RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.ToolChainFamily]
1916 if not RuleObject:
1917 # build type is always module type, but ...
1918 if self.ModuleType != self.BuildType:
1919 RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.ToolChainFamily]
1920 if not RuleObject:
1921 continue
1922 RuleObject = RuleObject.Instantiate(self.Macros)
1923 BuildRules[Type] = RuleObject
1924 for Ext in RuleObject.SourceFileExtList:
1925 BuildRules[Ext] = RuleObject
1926 self._BuildRules = BuildRules
1927 return self._BuildRules
1928
1929 def _ApplyBuildRule(self, File, FileType):
1930 if self._BuildTargets == None:
1931 self._IntroBuildTargetList = set()
1932 self._FinalBuildTargetList = set()
1933 self._BuildTargets = {}
1934 self._FileTypes = {}
1935
1936 LastTarget = None
1937 RuleChain = []
1938 SourceList = [File]
1939 Index = 0
1940 while Index < len(SourceList):
1941 Source = SourceList[Index]
1942 Index = Index + 1
1943
1944 if Source != File:
1945 CreateDirectory(Source.Dir)
1946
1947 if File.IsBinary and File == Source and self._BinaryFileList != None and File in self._BinaryFileList:
1948 RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE]
1949 elif FileType in self.BuildRules:
1950 RuleObject = self.BuildRules[FileType]
1951 elif Source.Ext in self.BuildRules:
1952 RuleObject = self.BuildRules[Source.Ext]
1953 else:
1954 # stop at no more rules
1955 if LastTarget:
1956 self._FinalBuildTargetList.add(LastTarget)
1957 break
1958
1959 FileType = RuleObject.SourceFileType
1960 if FileType not in self._FileTypes:
1961 self._FileTypes[FileType] = set()
1962 self._FileTypes[FileType].add(Source)
1963
1964 # stop at STATIC_LIBRARY for library
1965 if self.IsLibrary and FileType == TAB_STATIC_LIBRARY:
1966 if LastTarget:
1967 self._FinalBuildTargetList.add(LastTarget)
1968 break
1969
1970 Target = RuleObject.Apply(Source)
1971 if not Target:
1972 if LastTarget:
1973 self._FinalBuildTargetList.add(LastTarget)
1974 break
1975 elif not Target.Outputs:
1976 # Only do build for target with outputs
1977 self._FinalBuildTargetList.add(Target)
1978
1979 if FileType not in self._BuildTargets:
1980 self._BuildTargets[FileType] = set()
1981 self._BuildTargets[FileType].add(Target)
1982
1983 if not Source.IsBinary and Source == File:
1984 self._IntroBuildTargetList.add(Target)
1985
1986 # to avoid cyclic rule
1987 if FileType in RuleChain:
1988 break
1989
1990 RuleChain.append(FileType)
1991 SourceList.extend(Target.Outputs)
1992 LastTarget = Target
1993 FileType = TAB_UNKNOWN_FILE
1994
1995 def _GetTargets(self):
1996 if self._BuildTargets == None:
1997 self._IntroBuildTargetList = set()
1998 self._FinalBuildTargetList = set()
1999 self._BuildTargets = {}
2000 self._FileTypes = {}
2001
2002 #TRICK: call _GetSourceFileList to apply build rule for binary files
2003 if self.SourceFileList:
2004 pass
2005
2006 #TRICK: call _GetBinaryFileList to apply build rule for binary files
2007 if self.BinaryFileList:
2008 pass
2009
2010 return self._BuildTargets
2011
2012 def _GetIntroTargetList(self):
2013 self._GetTargets()
2014 return self._IntroBuildTargetList
2015
2016 def _GetFinalTargetList(self):
2017 self._GetTargets()
2018 return self._FinalBuildTargetList
2019
2020 def _GetFileTypes(self):
2021 self._GetTargets()
2022 return self._FileTypes
2023
2024 ## Get the list of package object the module depends on
2025 #
2026 # @retval list The package object list
2027 #
2028 def _GetDependentPackageList(self):
2029 return self.Module.Packages
2030
2031 ## Return the list of auto-generated code file
2032 #
2033 # @retval list The list of auto-generated file
2034 #
2035 def _GetAutoGenFileList(self):
2036 UniStringAutoGenC = True
2037 UniStringBinBuffer = None
2038 if self.BuildType == 'UEFI_HII':
2039 UniStringBinBuffer = StringIO()
2040 UniStringAutoGenC = False
2041 if self._AutoGenFileList == None:
2042 self._AutoGenFileList = {}
2043 AutoGenC = TemplateString()
2044 AutoGenH = TemplateString()
2045 StringH = TemplateString()
2046 GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer)
2047 if str(AutoGenC) != "" and TAB_C_CODE_FILE in self.FileTypes:
2048 AutoFile = PathClass(gAutoGenCodeFileName, self.DebugDir)
2049 self._AutoGenFileList[AutoFile] = str(AutoGenC)
2050 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
2051 if str(AutoGenH) != "":
2052 AutoFile = PathClass(gAutoGenHeaderFileName, self.DebugDir)
2053 self._AutoGenFileList[AutoFile] = str(AutoGenH)
2054 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
2055 if str(StringH) != "":
2056 AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir)
2057 self._AutoGenFileList[AutoFile] = str(StringH)
2058 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
2059 if UniStringBinBuffer != None and UniStringBinBuffer.getvalue() != "":
2060 AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir)
2061 self._AutoGenFileList[AutoFile] = UniStringBinBuffer.getvalue()
2062 AutoFile.IsBinary = True
2063 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
2064 if UniStringBinBuffer != None:
2065 UniStringBinBuffer.close()
2066 return self._AutoGenFileList
2067
2068 ## Return the list of library modules explicitly or implicityly used by this module
2069 def _GetLibraryList(self):
2070 if self._DependentLibraryList == None:
2071 # only merge library classes and PCD for non-library module
2072 if self.IsLibrary:
2073 self._DependentLibraryList = []
2074 else:
2075 if self.AutoGenVersion < 0x00010005:
2076 self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module)
2077 else:
2078 self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module)
2079 return self._DependentLibraryList
2080
2081 ## Get the list of PCDs from current module
2082 #
2083 # @retval list The list of PCD
2084 #
2085 def _GetModulePcdList(self):
2086 if self._ModulePcdList == None:
2087 # apply PCD settings from platform
2088 self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds)
2089 return self._ModulePcdList
2090
2091 ## Get the list of PCDs from dependent libraries
2092 #
2093 # @retval list The list of PCD
2094 #
2095 def _GetLibraryPcdList(self):
2096 if self._LibraryPcdList == None:
2097 Pcds = {}
2098 if not self.IsLibrary:
2099 # get PCDs from dependent libraries
2100 for Library in self.DependentLibraryList:
2101 for Key in Library.Pcds:
2102 # skip duplicated PCDs
2103 if Key in self.Module.Pcds or Key in Pcds:
2104 continue
2105 Pcds[Key] = copy.copy(Library.Pcds[Key])
2106 # apply PCD settings from platform
2107 self._LibraryPcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, Pcds)
2108 else:
2109 self._LibraryPcdList = []
2110 return self._LibraryPcdList
2111
2112 ## Get the GUID value mapping
2113 #
2114 # @retval dict The mapping between GUID cname and its value
2115 #
2116 def _GetGuidList(self):
2117 if self._GuidList == None:
2118 self._GuidList = self.Module.Guids
2119 for Library in self.DependentLibraryList:
2120 self._GuidList.update(Library.Guids)
2121 return self._GuidList
2122
2123 ## Get the protocol value mapping
2124 #
2125 # @retval dict The mapping between protocol cname and its value
2126 #
2127 def _GetProtocolList(self):
2128 if self._ProtocolList == None:
2129 self._ProtocolList = self.Module.Protocols
2130 for Library in self.DependentLibraryList:
2131 self._ProtocolList.update(Library.Protocols)
2132 return self._ProtocolList
2133
2134 ## Get the PPI value mapping
2135 #
2136 # @retval dict The mapping between PPI cname and its value
2137 #
2138 def _GetPpiList(self):
2139 if self._PpiList == None:
2140 self._PpiList = self.Module.Ppis
2141 for Library in self.DependentLibraryList:
2142 self._PpiList.update(Library.Ppis)
2143 return self._PpiList
2144
2145 ## Get the list of include search path
2146 #
2147 # @retval list The list path
2148 #
2149 def _GetIncludePathList(self):
2150 if self._IncludePathList == None:
2151 self._IncludePathList = []
2152 if self.AutoGenVersion < 0x00010005:
2153 for Inc in self.Module.Includes:
2154 if Inc not in self._IncludePathList:
2155 self._IncludePathList.append(Inc)
2156 # for r8 modules
2157 Inc = path.join(Inc, self.Arch.capitalize())
2158 if os.path.exists(Inc) and Inc not in self._IncludePathList:
2159 self._IncludePathList.append(Inc)
2160 # r8 module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time
2161 self._IncludePathList.append(self.DebugDir)
2162 else:
2163 self._IncludePathList.append(self.MetaFile.Dir)
2164 self._IncludePathList.append(self.DebugDir)
2165
2166 for Package in self.Module.Packages:
2167 PackageDir = path.join(self.WorkspaceDir, Package.MetaFile.Dir)
2168 if PackageDir not in self._IncludePathList:
2169 self._IncludePathList.append(PackageDir)
2170 for Inc in Package.Includes:
2171 if Inc not in self._IncludePathList:
2172 self._IncludePathList.append(str(Inc))
2173 return self._IncludePathList
2174
2175 ## Create makefile for the module and its dependent libraries
2176 #
2177 # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of
2178 # dependent libraries will be created
2179 #
2180 def CreateMakeFile(self, CreateLibraryMakeFile=True):
2181 if self.IsMakeFileCreated:
2182 return
2183
2184 if not self.IsLibrary and CreateLibraryMakeFile:
2185 for LibraryAutoGen in self.LibraryAutoGenList:
2186 LibraryAutoGen.CreateMakeFile()
2187
2188 if len(self.CustomMakefile) == 0:
2189 Makefile = GenMake.ModuleMakefile(self)
2190 else:
2191 Makefile = GenMake.CustomMakefile(self)
2192 if Makefile.Generate():
2193 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for module %s [%s]" %
2194 (self.Name, self.Arch))
2195 else:
2196 EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" %
2197 (self.Name, self.Arch))
2198
2199 self.IsMakeFileCreated = True
2200
2201 ## Create autogen code for the module and its dependent libraries
2202 #
2203 # @param CreateLibraryCodeFile Flag indicating if or not the code of
2204 # dependent libraries will be created
2205 #
2206 def CreateCodeFile(self, CreateLibraryCodeFile=True):
2207 if self.IsCodeFileCreated:
2208 return
2209
2210 if not self.IsLibrary and CreateLibraryCodeFile:
2211 for LibraryAutoGen in self.LibraryAutoGenList:
2212 LibraryAutoGen.CreateCodeFile()
2213
2214 AutoGenList = []
2215 IgoredAutoGenList = []
2216
2217 for File in self.AutoGenFileList:
2218 if GenC.Generate(File.Path, self.AutoGenFileList[File], File.IsBinary):
2219 #Ignore R8 AutoGen.c
2220 if self.AutoGenVersion < 0x00010005 and File.Name == 'AutoGen.c':
2221 continue
2222
2223 AutoGenList.append(str(File))
2224 else:
2225 IgoredAutoGenList.append(str(File))
2226
2227 # Skip the following code for EDK I inf
2228 if self.AutoGenVersion < 0x00010005:
2229 return
2230
2231 for ModuleType in self.DepexList:
2232 if len(self.DepexList[ModuleType]) == 0:
2233 continue
2234 Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True)
2235 DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}
2236
2237 if Dpx.Generate(path.join(self.OutputDir, DpxFile)):
2238 AutoGenList.append(str(DpxFile))
2239 else:
2240 IgoredAutoGenList.append(str(DpxFile))
2241
2242 if IgoredAutoGenList == []:
2243 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] files for module %s [%s]" %
2244 (" ".join(AutoGenList), self.Name, self.Arch))
2245 elif AutoGenList == []:
2246 EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of [%s] files for module %s [%s]" %
2247 (" ".join(IgoredAutoGenList), self.Name, self.Arch))
2248 else:
2249 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] (skipped %s) files for module %s [%s]" %
2250 (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch))
2251
2252 self.IsCodeFileCreated = True
2253 return AutoGenList
2254
2255 ## Summarize the ModuleAutoGen objects of all libraries used by this module
2256 def _GetLibraryAutoGenList(self):
2257 if self._LibraryAutoGenList == None:
2258 self._LibraryAutoGenList = []
2259 for Library in self.DependentLibraryList:
2260 La = ModuleAutoGen(
2261 self.Workspace,
2262 Library.MetaFile,
2263 self.BuildTarget,
2264 self.ToolChain,
2265 self.Arch,
2266 self.PlatformInfo.MetaFile
2267 )
2268 if La not in self._LibraryAutoGenList:
2269 self._LibraryAutoGenList.append(La)
2270 for Lib in La.CodaTargetList:
2271 self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)
2272 return self._LibraryAutoGenList
2273
2274 ## Return build command string
2275 #
2276 # @retval string Build command string
2277 #
2278 def _GetBuildCommand(self):
2279 return self.PlatformInfo.BuildCommand
2280
2281
2282 Module = property(_GetModule)
2283 Name = property(_GetBaseName)
2284 Guid = property(_GetGuid)
2285 Version = property(_GetVersion)
2286 ModuleType = property(_GetModuleType)
2287 ComponentType = property(_GetComponentType)
2288 BuildType = property(_GetBuildType)
2289 PcdIsDriver = property(_GetPcdIsDriver)
2290 AutoGenVersion = property(_GetAutoGenVersion)
2291 Macros = property(_GetMacros)
2292 Specification = property(_GetSpecification)
2293
2294 IsLibrary = property(_IsLibrary)
2295
2296 BuildDir = property(_GetBuildDir)
2297 OutputDir = property(_GetOutputDir)
2298 DebugDir = property(_GetDebugDir)
2299 MakeFileDir = property(_GetMakeFileDir)
2300 CustomMakefile = property(_GetCustomMakefile)
2301
2302 IncludePathList = property(_GetIncludePathList)
2303 AutoGenFileList = property(_GetAutoGenFileList)
2304 UnicodeFileList = property(_GetUnicodeFileList)
2305 SourceFileList = property(_GetSourceFileList)
2306 BinaryFileList = property(_GetBinaryFiles) # FileType : [File List]
2307 Targets = property(_GetTargets)
2308 IntroTargetList = property(_GetIntroTargetList)
2309 CodaTargetList = property(_GetFinalTargetList)
2310 FileTypes = property(_GetFileTypes)
2311 BuildRules = property(_GetBuildRules)
2312
2313 DependentPackageList = property(_GetDependentPackageList)
2314 DependentLibraryList = property(_GetLibraryList)
2315 LibraryAutoGenList = property(_GetLibraryAutoGenList)
2316 DerivedPackageList = property(_GetDerivedPackageList)
2317
2318 ModulePcdList = property(_GetModulePcdList)
2319 LibraryPcdList = property(_GetLibraryPcdList)
2320 GuidList = property(_GetGuidList)
2321 ProtocolList = property(_GetProtocolList)
2322 PpiList = property(_GetPpiList)
2323 DepexList = property(_GetDepexTokenList)
2324 DepexExpressionList = property(_GetDepexExpressionTokenList)
2325 BuildOption = property(_GetModuleBuildOption)
2326 BuildCommand = property(_GetBuildCommand)
2327
2328 # This acts like the main() function for the script, unless it is 'import'ed into another script.
2329 if __name__ == '__main__':
2330 pass
2331