]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/AutoGen/AutoGen.py
Sync tool code to BuildTools project r1739.
[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 instance
1098 for LibraryClass in PlatformModule.LibraryClasses:
1099 if LibraryClass.startswith("NULL"):
1100 Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]
1101
1102 # R9 module
1103 LibraryConsumerList = [Module]
1104 Constructor = []
1105 ConsumedByList = sdict()
1106 LibraryInstance = sdict()
1107
1108 EdkLogger.verbose("")
1109 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))
1110 while len(LibraryConsumerList) > 0:
1111 M = LibraryConsumerList.pop()
1112 for LibraryClassName in M.LibraryClasses:
1113 if LibraryClassName not in LibraryInstance:
1114 # override library instance for this module
1115 if LibraryClassName in PlatformModule.LibraryClasses:
1116 LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]
1117 else:
1118 LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]
1119 if LibraryPath == None or LibraryPath == "":
1120 LibraryPath = M.LibraryClasses[LibraryClassName]
1121 if LibraryPath == None or LibraryPath == "":
1122 EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
1123 "Instance of library class [%s] is not found" % LibraryClassName,
1124 File=self.MetaFile,
1125 ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module)))
1126
1127 LibraryModule = self.BuildDatabase[LibraryPath, self.Arch]
1128 # for those forced library instance (NULL library), add a fake library class
1129 if LibraryClassName.startswith("NULL"):
1130 LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))
1131 elif LibraryModule.LibraryClass == None \
1132 or len(LibraryModule.LibraryClass) == 0 \
1133 or (ModuleType != 'USER_DEFINED'
1134 and ModuleType not in LibraryModule.LibraryClass[0].SupModList):
1135 # only USER_DEFINED can link against any library instance despite of its SupModList
1136 EdkLogger.error("build", OPTION_MISSING,
1137 "Module type [%s] is not supported by library instance [%s]" \
1138 % (ModuleType, LibraryPath), File=self.MetaFile,
1139 ExtraData="consumed by [%s]" % str(Module))
1140
1141 LibraryInstance[LibraryClassName] = LibraryModule
1142 LibraryConsumerList.append(LibraryModule)
1143 EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))
1144 else:
1145 LibraryModule = LibraryInstance[LibraryClassName]
1146
1147 if LibraryModule == None:
1148 continue
1149
1150 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:
1151 Constructor.append(LibraryModule)
1152
1153 if LibraryModule not in ConsumedByList:
1154 ConsumedByList[LibraryModule] = []
1155 # don't add current module itself to consumer list
1156 if M != Module:
1157 if M in ConsumedByList[LibraryModule]:
1158 continue
1159 ConsumedByList[LibraryModule].append(M)
1160 #
1161 # Initialize the sorted output list to the empty set
1162 #
1163 SortedLibraryList = []
1164 #
1165 # Q <- Set of all nodes with no incoming edges
1166 #
1167 LibraryList = [] #LibraryInstance.values()
1168 Q = []
1169 for LibraryClassName in LibraryInstance:
1170 M = LibraryInstance[LibraryClassName]
1171 LibraryList.append(M)
1172 if ConsumedByList[M] == []:
1173 Q.insert(0, M)
1174
1175 #
1176 # start the DAG algorithm
1177 #
1178 while True:
1179 EdgeRemoved = True
1180 while Q == [] and EdgeRemoved:
1181 EdgeRemoved = False
1182 # for each node Item with a Constructor
1183 for Item in LibraryList:
1184 if Item not in Constructor:
1185 continue
1186 # for each Node without a constructor with an edge e from Item to Node
1187 for Node in ConsumedByList[Item]:
1188 if Node in Constructor:
1189 continue
1190 # remove edge e from the graph if Node has no constructor
1191 ConsumedByList[Item].remove(Node)
1192 EdgeRemoved = True
1193 if ConsumedByList[Item] == []:
1194 # insert Item into Q
1195 Q.insert(0, Item)
1196 break
1197 if Q != []:
1198 break
1199 # DAG is done if there's no more incoming edge for all nodes
1200 if Q == []:
1201 break
1202
1203 # remove node from Q
1204 Node = Q.pop()
1205 # output Node
1206 SortedLibraryList.append(Node)
1207
1208 # for each node Item with an edge e from Node to Item do
1209 for Item in LibraryList:
1210 if Node not in ConsumedByList[Item]:
1211 continue
1212 # remove edge e from the graph
1213 ConsumedByList[Item].remove(Node)
1214
1215 if ConsumedByList[Item] != []:
1216 continue
1217 # insert Item into Q, if Item has no other incoming edges
1218 Q.insert(0, Item)
1219
1220 #
1221 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle
1222 #
1223 for Item in LibraryList:
1224 if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:
1225 ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])
1226 EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),
1227 ExtraData=ErrorMessage, File=self.MetaFile)
1228 if Item not in SortedLibraryList:
1229 SortedLibraryList.append(Item)
1230
1231 #
1232 # Build the list of constructor and destructir names
1233 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
1234 #
1235 SortedLibraryList.reverse()
1236 return SortedLibraryList
1237
1238
1239 ## Override PCD setting (type, value, ...)
1240 #
1241 # @param ToPcd The PCD to be overrided
1242 # @param FromPcd The PCD overrideing from
1243 #
1244 def _OverridePcd(self, ToPcd, FromPcd, Module=""):
1245 #
1246 # in case there's PCDs coming from FDF file, which have no type given.
1247 # at this point, ToPcd.Type has the type found from dependent
1248 # package
1249 #
1250 if FromPcd != None:
1251 if ToPcd.Pending and FromPcd.Type not in [None, '']:
1252 ToPcd.Type = FromPcd.Type
1253 elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \
1254 and ToPcd.Type != FromPcd.Type:
1255 EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",
1256 ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
1257 % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName,
1258 ToPcd.Type, Module, FromPcd.Type),
1259 File=self.MetaFile)
1260
1261 if FromPcd.MaxDatumSize not in [None, '']:
1262 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
1263 if FromPcd.DefaultValue not in [None, '']:
1264 ToPcd.DefaultValue = FromPcd.DefaultValue
1265 if FromPcd.TokenValue not in [None, '']:
1266 ToPcd.TokenValue = FromPcd.TokenValue
1267 if FromPcd.MaxDatumSize not in [None, '']:
1268 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
1269 if FromPcd.DatumType not in [None, '']:
1270 ToPcd.DatumType = FromPcd.DatumType
1271 if FromPcd.SkuInfoList not in [None, '', []]:
1272 ToPcd.SkuInfoList = FromPcd.SkuInfoList
1273
1274 # check the validation of datum
1275 IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)
1276 if not IsValid:
1277 EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,
1278 ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))
1279
1280 if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:
1281 EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \
1282 % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))
1283 Value = ToPcd.DefaultValue
1284 if Value in [None, '']:
1285 ToPcd.MaxDatumSize = 1
1286 elif Value[0] == 'L':
1287 ToPcd.MaxDatumSize = str(len(Value) * 2)
1288 elif Value[0] == '{':
1289 ToPcd.MaxDatumSize = str(len(Value.split(',')))
1290 else:
1291 ToPcd.MaxDatumSize = str(len(Value))
1292
1293 # apply default SKU for dynamic PCDS if specified one is not available
1294 if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \
1295 and ToPcd.SkuInfoList in [None, {}, '']:
1296 if self.Platform.SkuName in self.Platform.SkuIds:
1297 SkuName = self.Platform.SkuName
1298 else:
1299 SkuName = 'DEFAULT'
1300 ToPcd.SkuInfoList = {
1301 SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue)
1302 }
1303
1304 ## Apply PCD setting defined platform to a module
1305 #
1306 # @param Module The module from which the PCD setting will be overrided
1307 #
1308 # @retval PCD_list The list PCDs with settings from platform
1309 #
1310 def ApplyPcdSetting(self, Module, Pcds):
1311 # for each PCD in module
1312 for Name,Guid in Pcds:
1313 PcdInModule = Pcds[Name,Guid]
1314 # find out the PCD setting in platform
1315 if (Name,Guid) in self.Platform.Pcds:
1316 PcdInPlatform = self.Platform.Pcds[Name,Guid]
1317 else:
1318 PcdInPlatform = None
1319 # then override the settings if any
1320 self._OverridePcd(PcdInModule, PcdInPlatform, Module)
1321 # resolve the VariableGuid value
1322 for SkuId in PcdInModule.SkuInfoList:
1323 Sku = PcdInModule.SkuInfoList[SkuId]
1324 if Sku.VariableGuid == '': continue
1325 Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList)
1326 if Sku.VariableGuidValue == None:
1327 PackageList = "\n\t".join([str(P) for P in self.PackageList])
1328 EdkLogger.error(
1329 'build',
1330 RESOURCE_NOT_AVAILABLE,
1331 "Value of GUID [%s] is not found in" % Sku.VariableGuid,
1332 ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \
1333 % (Guid, Name, str(Module)),
1334 File=self.MetaFile
1335 )
1336
1337 # override PCD settings with module specific setting
1338 if Module in self.Platform.Modules:
1339 PlatformModule = self.Platform.Modules[str(Module)]
1340 for Key in PlatformModule.Pcds:
1341 if Key in Pcds:
1342 self._OverridePcd(Pcds[Key], PlatformModule.Pcds[Key], Module)
1343 return Pcds.values()
1344
1345 ## Resolve library names to library modules
1346 #
1347 # (for R8.x modules)
1348 #
1349 # @param Module The module from which the library names will be resolved
1350 #
1351 # @retval library_list The list of library modules
1352 #
1353 def ResolveLibraryReference(self, Module):
1354 EdkLogger.verbose("")
1355 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))
1356 LibraryConsumerList = [Module]
1357
1358 # "CompilerStub" is a must for R8 modules
1359 if Module.Libraries:
1360 Module.Libraries.append("CompilerStub")
1361 LibraryList = []
1362 while len(LibraryConsumerList) > 0:
1363 M = LibraryConsumerList.pop()
1364 for LibraryName in M.Libraries:
1365 Library = self.Platform.LibraryClasses[LibraryName, ':dummy:']
1366 if Library == None:
1367 for Key in self.Platform.LibraryClasses.data.keys():
1368 if LibraryName.upper() == Key.upper():
1369 Library = self.Platform.LibraryClasses[Key, ':dummy:']
1370 break
1371 if Library == None:
1372 EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M),
1373 ExtraData="\t%s [%s]" % (str(Module), self.Arch))
1374 continue
1375
1376 if Library not in LibraryList:
1377 LibraryList.append(Library)
1378 LibraryConsumerList.append(Library)
1379 EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library)))
1380 return LibraryList
1381
1382 ## Expand * in build option key
1383 #
1384 # @param Options Options to be expanded
1385 #
1386 # @retval options Options expanded
1387 #
1388 def _ExpandBuildOption(self, Options):
1389 BuildOptions = {}
1390 FamilyMatch = False
1391 FamilyIsNull = True
1392 for Key in Options:
1393 Family = Key[0]
1394 Target, Tag, Arch, Tool, Attr = Key[1].split("_")
1395 # if tool chain family doesn't match, skip it
1396 if Tool in self.ToolDefinition and Family != "":
1397 FamilyIsNull = False
1398 if self.ToolDefinition[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
1399 if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
1400 continue
1401 elif Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:
1402 continue
1403 FamilyMatch = True
1404 # expand any wildcard
1405 if Target == "*" or Target == self.BuildTarget:
1406 if Tag == "*" or Tag == self.ToolChain:
1407 if Arch == "*" or Arch == self.Arch:
1408 if Tool not in BuildOptions:
1409 BuildOptions[Tool] = {}
1410 if Attr != "FLAGS" or Attr not in BuildOptions[Tool]:
1411 BuildOptions[Tool][Attr] = Options[Key]
1412 else:
1413 # append options for the same tool
1414 BuildOptions[Tool][Attr] += " " + Options[Key]
1415 # Build Option Family has been checked, which need't to be checked again for family.
1416 if FamilyMatch or FamilyIsNull:
1417 return BuildOptions
1418
1419 for Key in Options:
1420 Family = Key[0]
1421 Target, Tag, Arch, Tool, Attr = Key[1].split("_")
1422 # if tool chain family doesn't match, skip it
1423 if Tool not in self.ToolDefinition or Family =="":
1424 continue
1425 # option has been added before
1426 if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:
1427 continue
1428
1429 # expand any wildcard
1430 if Target == "*" or Target == self.BuildTarget:
1431 if Tag == "*" or Tag == self.ToolChain:
1432 if Arch == "*" or Arch == self.Arch:
1433 if Tool not in BuildOptions:
1434 BuildOptions[Tool] = {}
1435 if Attr != "FLAGS" or Attr not in BuildOptions[Tool]:
1436 BuildOptions[Tool][Attr] = Options[Key]
1437 else:
1438 # append options for the same tool
1439 BuildOptions[Tool][Attr] += " " + Options[Key]
1440 return BuildOptions
1441
1442 ## Append build options in platform to a module
1443 #
1444 # @param Module The module to which the build options will be appened
1445 #
1446 # @retval options The options appended with build options in platform
1447 #
1448 def ApplyBuildOption(self, Module):
1449 PlatformOptions = self.BuildOption
1450 ModuleOptions = self._ExpandBuildOption(Module.BuildOptions)
1451 if Module in self.Platform.Modules:
1452 PlatformModule = self.Platform.Modules[str(Module)]
1453 PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions)
1454 else:
1455 PlatformModuleOptions = {}
1456
1457 AllTools = set(ModuleOptions.keys() + PlatformOptions.keys() + PlatformModuleOptions.keys() + self.ToolDefinition.keys())
1458 BuildOptions = {}
1459 for Tool in AllTools:
1460 if Tool not in BuildOptions:
1461 BuildOptions[Tool] = {}
1462
1463 for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, PlatformModuleOptions]:
1464 if Tool not in Options:
1465 continue
1466 for Attr in Options[Tool]:
1467 Value = Options[Tool][Attr]
1468 if Attr not in BuildOptions[Tool]:
1469 BuildOptions[Tool][Attr] = ""
1470 # check if override is indicated
1471 if Value.startswith('='):
1472 BuildOptions[Tool][Attr] = Value[1:]
1473 else:
1474 BuildOptions[Tool][Attr] += " " + Value
1475 return BuildOptions
1476
1477 Platform = property(_GetPlatform)
1478 Name = property(_GetName)
1479 Guid = property(_GetGuid)
1480 Version = property(_GetVersion)
1481
1482 OutputDir = property(_GetOutputDir)
1483 BuildDir = property(_GetBuildDir)
1484 MakeFileDir = property(_GetMakeFileDir)
1485 FdfFile = property(_GetFdfFile)
1486
1487 PcdTokenNumber = property(_GetPcdTokenNumbers) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber
1488 DynamicPcdList = property(_GetDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1489 NonDynamicPcdList = property(_GetNonDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]
1490 PackageList = property(_GetPackageList)
1491
1492 ToolDefinition = property(_GetToolDefinition) # toolcode : tool path
1493 ToolDefinitionFile = property(_GetToolDefFile) # toolcode : lib path
1494 ToolChainFamily = property(_GetToolChainFamily)
1495 BuildRuleFamily = property(_GetBuildRuleFamily)
1496 BuildOption = property(_GetBuildOptions) # toolcode : option
1497
1498 BuildCommand = property(_GetBuildCommand)
1499 BuildRule = property(_GetBuildRule)
1500 ModuleAutoGenList = property(_GetModuleAutoGenList)
1501 LibraryAutoGenList = property(_GetLibraryAutoGenList)
1502
1503 ## ModuleAutoGen class
1504 #
1505 # This class encapsules the AutoGen behaviors for the build tools. In addition to
1506 # the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according
1507 # to the [depex] section in module's inf file.
1508 #
1509 class ModuleAutoGen(AutoGen):
1510 ## The real constructor of ModuleAutoGen
1511 #
1512 # This method is not supposed to be called by users of ModuleAutoGen. It's
1513 # only used by factory method __new__() to do real initialization work for an
1514 # object of ModuleAutoGen
1515 #
1516 # @param Workspace EdkIIWorkspaceBuild object
1517 # @param ModuleFile The path of module file
1518 # @param Target Build target (DEBUG, RELEASE)
1519 # @param Toolchain Name of tool chain
1520 # @param Arch The arch the module supports
1521 # @param PlatformFile Platform meta-file
1522 #
1523 def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):
1524 EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen module [%s] [%s]" % (ModuleFile, Arch))
1525 GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (ModuleFile, Arch, Toolchain, Target)
1526
1527 self.Workspace = Workspace
1528 self.WorkspaceDir = Workspace.WorkspaceDir
1529
1530 self.MetaFile = ModuleFile
1531 self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)
1532 # check if this module is employed by active platform
1533 if not self.PlatformInfo.ValidModule(self.MetaFile):
1534 EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \
1535 % (self.MetaFile, Arch))
1536 return False
1537
1538 self.SourceDir = self.MetaFile.SubDir
1539 self.SourceOverrideDir = None
1540 # use overrided path defined in DSC file
1541 if self.MetaFile.Key in GlobalData.gOverrideDir:
1542 self.SourceOverrideDir = GlobalData.gOverrideDir[self.MetaFile.Key]
1543
1544 self.ToolChain = Toolchain
1545 self.BuildTarget = Target
1546 self.Arch = Arch
1547 self.ToolChainFamily = self.PlatformInfo.ToolChainFamily
1548 self.BuildRuleFamily = self.PlatformInfo.BuildRuleFamily
1549
1550 self.IsMakeFileCreated = False
1551 self.IsCodeFileCreated = False
1552
1553 self.BuildDatabase = self.Workspace.BuildDatabase
1554
1555 self._Module = None
1556 self._Name = None
1557 self._Guid = None
1558 self._Version = None
1559 self._ModuleType = None
1560 self._ComponentType = None
1561 self._PcdIsDriver = None
1562 self._AutoGenVersion = None
1563 self._LibraryFlag = None
1564 self._CustomMakefile = None
1565 self._Macro = None
1566
1567 self._BuildDir = None
1568 self._OutputDir = None
1569 self._DebugDir = None
1570 self._MakeFileDir = None
1571
1572 self._IncludePathList = None
1573 self._AutoGenFileList = None
1574 self._UnicodeFileList = None
1575 self._SourceFileList = None
1576 self._ObjectFileList = None
1577 self._BinaryFileList = None
1578
1579 self._DependentPackageList = None
1580 self._DependentLibraryList = None
1581 self._LibraryAutoGenList = None
1582 self._DerivedPackageList = None
1583 self._ModulePcdList = None
1584 self._LibraryPcdList = None
1585 self._GuidList = None
1586 self._ProtocolList = None
1587 self._PpiList = None
1588 self._DepexList = None
1589 self._DepexExpressionList = None
1590 self._BuildOption = None
1591 self._BuildTargets = None
1592 self._IntroBuildTargetList = None
1593 self._FinalBuildTargetList = None
1594 self._FileTypes = None
1595 self._BuildRules = None
1596
1597 return True
1598
1599 def __repr__(self):
1600 return "%s [%s]" % (self.MetaFile, self.Arch)
1601
1602 # Macros could be used in build_rule.txt (also Makefile)
1603 def _GetMacros(self):
1604 if self._Macro == None:
1605 self._Macro = sdict()
1606 self._Macro["WORKSPACE" ] = self.WorkspaceDir
1607 self._Macro["MODULE_NAME" ] = self.Name
1608 self._Macro["MODULE_GUID" ] = self.Guid
1609 self._Macro["MODULE_VERSION" ] = self.Version
1610 self._Macro["MODULE_TYPE" ] = self.ModuleType
1611 self._Macro["MODULE_FILE" ] = str(self.MetaFile)
1612 self._Macro["MODULE_FILE_BASE_NAME" ] = self.MetaFile.BaseName
1613 self._Macro["MODULE_RELATIVE_DIR" ] = self.SourceDir
1614 self._Macro["MODULE_DIR" ] = self.SourceDir
1615
1616 self._Macro["BASE_NAME" ] = self.Name
1617
1618 self._Macro["ARCH" ] = self.Arch
1619 self._Macro["TOOLCHAIN" ] = self.ToolChain
1620 self._Macro["TOOLCHAIN_TAG" ] = self.ToolChain
1621 self._Macro["TARGET" ] = self.BuildTarget
1622
1623 self._Macro["BUILD_DIR" ] = self.PlatformInfo.BuildDir
1624 self._Macro["BIN_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)
1625 self._Macro["LIB_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)
1626 self._Macro["MODULE_BUILD_DIR" ] = self.BuildDir
1627 self._Macro["OUTPUT_DIR" ] = self.OutputDir
1628 self._Macro["DEBUG_DIR" ] = self.DebugDir
1629 return self._Macro
1630
1631 ## Return the module build data object
1632 def _GetModule(self):
1633 if self._Module == None:
1634 self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch]
1635 return self._Module
1636
1637 ## Return the module name
1638 def _GetBaseName(self):
1639 return self.Module.BaseName
1640
1641 ## Return the module SourceOverridePath
1642 def _GetSourceOverridePath(self):
1643 return self.Module.SourceOverridePath
1644
1645 ## Return the module meta-file GUID
1646 def _GetGuid(self):
1647 return self.Module.Guid
1648
1649 ## Return the module version
1650 def _GetVersion(self):
1651 return self.Module.Version
1652
1653 ## Return the module type
1654 def _GetModuleType(self):
1655 return self.Module.ModuleType
1656
1657 ## Return the component type (for R8.x style of module)
1658 def _GetComponentType(self):
1659 return self.Module.ComponentType
1660
1661 ## Return the build type
1662 def _GetBuildType(self):
1663 return self.Module.BuildType
1664
1665 ## Return the PCD_IS_DRIVER setting
1666 def _GetPcdIsDriver(self):
1667 return self.Module.PcdIsDriver
1668
1669 ## Return the autogen version, i.e. module meta-file version
1670 def _GetAutoGenVersion(self):
1671 return self.Module.AutoGenVersion
1672
1673 ## Check if the module is library or not
1674 def _IsLibrary(self):
1675 if self._LibraryFlag == None:
1676 if self.Module.LibraryClass != None and self.Module.LibraryClass != []:
1677 self._LibraryFlag = True
1678 else:
1679 self._LibraryFlag = False
1680 return self._LibraryFlag
1681
1682 ## Return the directory to store intermediate files of the module
1683 def _GetBuildDir(self):
1684 if self._BuildDir == None:
1685 self._BuildDir = path.join(
1686 self.PlatformInfo.BuildDir,
1687 self.Arch,
1688 self.SourceDir,
1689 self.MetaFile.BaseName
1690 )
1691 CreateDirectory(self._BuildDir)
1692 return self._BuildDir
1693
1694 ## Return the directory to store the intermediate object files of the mdoule
1695 def _GetOutputDir(self):
1696 if self._OutputDir == None:
1697 self._OutputDir = path.join(self.BuildDir, "OUTPUT")
1698 CreateDirectory(self._OutputDir)
1699 return self._OutputDir
1700
1701 ## Return the directory to store auto-gened source files of the mdoule
1702 def _GetDebugDir(self):
1703 if self._DebugDir == None:
1704 self._DebugDir = path.join(self.BuildDir, "DEBUG")
1705 CreateDirectory(self._DebugDir)
1706 return self._DebugDir
1707
1708 ## Return the path of custom file
1709 def _GetCustomMakefile(self):
1710 if self._CustomMakefile == None:
1711 self._CustomMakefile = {}
1712 for Type in self.Module.CustomMakefile:
1713 if Type in gMakeTypeMap:
1714 MakeType = gMakeTypeMap[Type]
1715 else:
1716 MakeType = 'nmake'
1717 if self.SourceOverrideDir != None:
1718 File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type])
1719 if not os.path.exists(File):
1720 File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
1721 else:
1722 File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
1723 self._CustomMakefile[MakeType] = File
1724 return self._CustomMakefile
1725
1726 ## Return the directory of the makefile
1727 #
1728 # @retval string The directory string of module's makefile
1729 #
1730 def _GetMakeFileDir(self):
1731 return self.BuildDir
1732
1733 ## Return build command string
1734 #
1735 # @retval string Build command string
1736 #
1737 def _GetBuildCommand(self):
1738 return self.PlatformInfo.BuildCommand
1739
1740 ## Get object list of all packages the module and its dependent libraries belong to
1741 #
1742 # @retval list The list of package object
1743 #
1744 def _GetDerivedPackageList(self):
1745 PackageList = []
1746 for M in [self.Module] + self.DependentLibraryList:
1747 for Package in M.Packages:
1748 if Package in PackageList:
1749 continue
1750 PackageList.append(Package)
1751 return PackageList
1752
1753 ## Merge dependency expression
1754 #
1755 # @retval list The token list of the dependency expression after parsed
1756 #
1757 def _GetDepexTokenList(self):
1758 if self._DepexList == None:
1759 self._DepexList = {}
1760 if self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
1761 return self._DepexList
1762
1763 self._DepexList[self.ModuleType] = []
1764
1765 for ModuleType in self._DepexList:
1766 DepexList = self._DepexList[ModuleType]
1767 #
1768 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
1769 #
1770 for M in [self.Module] + self.DependentLibraryList:
1771 Inherited = False
1772 for D in M.Depex[self.Arch, ModuleType]:
1773 if DepexList != []:
1774 DepexList.append('AND')
1775 DepexList.append('(')
1776 DepexList.extend(D)
1777 if DepexList[-1] == 'END': # no need of a END at this time
1778 DepexList.pop()
1779 DepexList.append(')')
1780 Inherited = True
1781 if Inherited:
1782 EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexList))
1783 if 'BEFORE' in DepexList or 'AFTER' in DepexList:
1784 break
1785 if len(DepexList) > 0:
1786 EdkLogger.verbose('')
1787 return self._DepexList
1788
1789 ## Merge dependency expression
1790 #
1791 # @retval list The token list of the dependency expression after parsed
1792 #
1793 def _GetDepexExpressionTokenList(self):
1794 if self._DepexExpressionList == None:
1795 self._DepexExpressionList = {}
1796 if self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
1797 return self._DepexExpressionList
1798
1799 self._DepexExpressionList[self.ModuleType] = ''
1800
1801 for ModuleType in self._DepexExpressionList:
1802 DepexExpressionList = self._DepexExpressionList[ModuleType]
1803 #
1804 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion
1805 #
1806 for M in [self.Module] + self.DependentLibraryList:
1807 Inherited = False
1808 for D in M.DepexExpression[self.Arch, ModuleType]:
1809 if DepexExpressionList != '':
1810 DepexExpressionList += ' AND '
1811 DepexExpressionList += '('
1812 DepexExpressionList += D
1813 DepexExpressionList = DepexExpressionList.rstrip('END').strip()
1814 DepexExpressionList += ')'
1815 Inherited = True
1816 if Inherited:
1817 EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexExpressionList))
1818 if 'BEFORE' in DepexExpressionList or 'AFTER' in DepexExpressionList:
1819 break
1820 if len(DepexExpressionList) > 0:
1821 EdkLogger.verbose('')
1822 self._DepexExpressionList[ModuleType] = DepexExpressionList
1823 return self._DepexExpressionList
1824
1825 ## Return the list of specification version required for the module
1826 #
1827 # @retval list The list of specification defined in module file
1828 #
1829 def _GetSpecification(self):
1830 return self.Module.Specification
1831
1832 ## Tool option for the module build
1833 #
1834 # @param PlatformInfo The object of PlatformBuildInfo
1835 # @retval dict The dict containing valid options
1836 #
1837 def _GetModuleBuildOption(self):
1838 if self._BuildOption == None:
1839 self._BuildOption = self.PlatformInfo.ApplyBuildOption(self.Module)
1840 return self._BuildOption
1841
1842 ## Return a list of files which can be built from source
1843 #
1844 # What kind of files can be built is determined by build rules in
1845 # $(WORKSPACE)/Conf/build_rule.txt and toolchain family.
1846 #
1847 def _GetSourceFileList(self):
1848 if self._SourceFileList == None:
1849 self._SourceFileList = []
1850 for F in self.Module.Sources:
1851 # match tool chain
1852 if F.TagName != "" and F.TagName != self.ToolChain:
1853 EdkLogger.debug(EdkLogger.DEBUG_9, "The toolchain [%s] for processing file [%s] is found, "
1854 "but [%s] is needed" % (F.TagName, str(F), self.ToolChain))
1855 continue
1856 # match tool chain family
1857 if F.ToolChainFamily != "" and F.ToolChainFamily != self.ToolChainFamily:
1858 EdkLogger.debug(
1859 EdkLogger.DEBUG_0,
1860 "The file [%s] must be built by tools of [%s], " \
1861 "but current toolchain family is [%s]" \
1862 % (str(F), F.ToolChainFamily, self.ToolChainFamily))
1863 continue
1864
1865 # add the file path into search path list for file including
1866 if F.Dir not in self.IncludePathList and self.AutoGenVersion >= 0x00010005:
1867 self.IncludePathList.insert(0, F.Dir)
1868 self._SourceFileList.append(F)
1869 self._ApplyBuildRule(F, TAB_UNKNOWN_FILE)
1870 return self._SourceFileList
1871
1872 ## Return the list of unicode files
1873 def _GetUnicodeFileList(self):
1874 if self._UnicodeFileList == None:
1875 if TAB_UNICODE_FILE in self.FileTypes:
1876 self._UnicodeFileList = self.FileTypes[TAB_UNICODE_FILE]
1877 else:
1878 self._UnicodeFileList = []
1879 return self._UnicodeFileList
1880
1881 ## Return a list of files which can be built from binary
1882 #
1883 # "Build" binary files are just to copy them to build directory.
1884 #
1885 # @retval list The list of files which can be built later
1886 #
1887 def _GetBinaryFiles(self):
1888 if self._BinaryFileList == None:
1889 self._BinaryFileList = []
1890 for F in self.Module.Binaries:
1891 if F.Target not in ['COMMON', '*'] and F.Target != self.BuildTarget:
1892 continue
1893 self._BinaryFileList.append(F)
1894 self._ApplyBuildRule(F, F.Type)
1895 return self._BinaryFileList
1896
1897 def _GetBuildRules(self):
1898 if self._BuildRules == None:
1899 BuildRules = {}
1900 BuildRuleDatabase = self.PlatformInfo.BuildRule
1901 for Type in BuildRuleDatabase.FileTypeList:
1902 #first try getting build rule by BuildRuleFamily
1903 RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.BuildRuleFamily]
1904 if not RuleObject:
1905 # build type is always module type, but ...
1906 if self.ModuleType != self.BuildType:
1907 RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.BuildRuleFamily]
1908 #second try getting build rule by ToolChainFamily
1909 if not RuleObject:
1910 RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.ToolChainFamily]
1911 if not RuleObject:
1912 # build type is always module type, but ...
1913 if self.ModuleType != self.BuildType:
1914 RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.ToolChainFamily]
1915 if not RuleObject:
1916 continue
1917 RuleObject = RuleObject.Instantiate(self.Macros)
1918 BuildRules[Type] = RuleObject
1919 for Ext in RuleObject.SourceFileExtList:
1920 BuildRules[Ext] = RuleObject
1921 self._BuildRules = BuildRules
1922 return self._BuildRules
1923
1924 def _ApplyBuildRule(self, File, FileType):
1925 if self._BuildTargets == None:
1926 self._IntroBuildTargetList = set()
1927 self._FinalBuildTargetList = set()
1928 self._BuildTargets = {}
1929 self._FileTypes = {}
1930
1931 LastTarget = None
1932 RuleChain = []
1933 SourceList = [File]
1934 Index = 0
1935 while Index < len(SourceList):
1936 Source = SourceList[Index]
1937 Index = Index + 1
1938
1939 if Source != File:
1940 CreateDirectory(Source.Dir)
1941
1942 if File.IsBinary and File == Source:
1943 RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE]
1944 elif FileType in self.BuildRules:
1945 RuleObject = self.BuildRules[FileType]
1946 elif Source.Ext in self.BuildRules:
1947 RuleObject = self.BuildRules[Source.Ext]
1948 else:
1949 # stop at no more rules
1950 if LastTarget:
1951 self._FinalBuildTargetList.add(LastTarget)
1952 break
1953
1954 FileType = RuleObject.SourceFileType
1955 if FileType not in self._FileTypes:
1956 self._FileTypes[FileType] = set()
1957 self._FileTypes[FileType].add(Source)
1958
1959 # stop at STATIC_LIBRARY for library
1960 if self.IsLibrary and FileType == TAB_STATIC_LIBRARY:
1961 if LastTarget:
1962 self._FinalBuildTargetList.add(LastTarget)
1963 break
1964
1965 Target = RuleObject.Apply(Source)
1966 if not Target:
1967 if LastTarget:
1968 self._FinalBuildTargetList.add(LastTarget)
1969 break
1970 elif not Target.Outputs:
1971 # Only do build for target with outputs
1972 self._FinalBuildTargetList.add(Target)
1973
1974 if FileType not in self._BuildTargets:
1975 self._BuildTargets[FileType] = set()
1976 self._BuildTargets[FileType].add(Target)
1977
1978 if not Source.IsBinary and Source == File:
1979 self._IntroBuildTargetList.add(Target)
1980
1981 # to avoid cyclic rule
1982 if FileType in RuleChain:
1983 break
1984
1985 RuleChain.append(FileType)
1986 SourceList.extend(Target.Outputs)
1987 LastTarget = Target
1988 FileType = TAB_UNKNOWN_FILE
1989
1990 def _GetTargets(self):
1991 if self._BuildTargets == None:
1992 self._IntroBuildTargetList = set()
1993 self._FinalBuildTargetList = set()
1994 self._BuildTargets = {}
1995 self._FileTypes = {}
1996
1997 #TRICK: call _GetSourceFileList to apply build rule for binary files
1998 if self.SourceFileList:
1999 pass
2000
2001 #TRICK: call _GetBinaryFileList to apply build rule for binary files
2002 if self.BinaryFileList:
2003 pass
2004
2005 return self._BuildTargets
2006
2007 def _GetIntroTargetList(self):
2008 self._GetTargets()
2009 return self._IntroBuildTargetList
2010
2011 def _GetFinalTargetList(self):
2012 self._GetTargets()
2013 return self._FinalBuildTargetList
2014
2015 def _GetFileTypes(self):
2016 self._GetTargets()
2017 return self._FileTypes
2018
2019 ## Get the list of package object the module depends on
2020 #
2021 # @retval list The package object list
2022 #
2023 def _GetDependentPackageList(self):
2024 return self.Module.Packages
2025
2026 ## Return the list of auto-generated code file
2027 #
2028 # @retval list The list of auto-generated file
2029 #
2030 def _GetAutoGenFileList(self):
2031 UniStringAutoGenC = True
2032 UniStringBinBuffer = None
2033 if self.BuildType == 'UEFI_HII':
2034 UniStringBinBuffer = StringIO()
2035 UniStringAutoGenC = False
2036 if self._AutoGenFileList == None:
2037 self._AutoGenFileList = {}
2038 AutoGenC = TemplateString()
2039 AutoGenH = TemplateString()
2040 StringH = TemplateString()
2041 GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer)
2042 if str(AutoGenC) != "" and TAB_C_CODE_FILE in self.FileTypes:
2043 AutoFile = PathClass(gAutoGenCodeFileName, self.DebugDir)
2044 self._AutoGenFileList[AutoFile] = str(AutoGenC)
2045 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
2046 if str(AutoGenH) != "":
2047 AutoFile = PathClass(gAutoGenHeaderFileName, self.DebugDir)
2048 self._AutoGenFileList[AutoFile] = str(AutoGenH)
2049 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
2050 if str(StringH) != "":
2051 AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir)
2052 self._AutoGenFileList[AutoFile] = str(StringH)
2053 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
2054 if UniStringBinBuffer != None and UniStringBinBuffer.getvalue() != "":
2055 AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir)
2056 self._AutoGenFileList[AutoFile] = UniStringBinBuffer.getvalue()
2057 AutoFile.IsBinary = True
2058 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
2059 if UniStringBinBuffer != None:
2060 UniStringBinBuffer.close()
2061 return self._AutoGenFileList
2062
2063 ## Return the list of library modules explicitly or implicityly used by this module
2064 def _GetLibraryList(self):
2065 if self._DependentLibraryList == None:
2066 # only merge library classes and PCD for non-library module
2067 if self.IsLibrary:
2068 self._DependentLibraryList = []
2069 else:
2070 if self.AutoGenVersion < 0x00010005:
2071 self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module)
2072 else:
2073 self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module)
2074 return self._DependentLibraryList
2075
2076 ## Get the list of PCDs from current module
2077 #
2078 # @retval list The list of PCD
2079 #
2080 def _GetModulePcdList(self):
2081 if self._ModulePcdList == None:
2082 # apply PCD settings from platform
2083 self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds)
2084 return self._ModulePcdList
2085
2086 ## Get the list of PCDs from dependent libraries
2087 #
2088 # @retval list The list of PCD
2089 #
2090 def _GetLibraryPcdList(self):
2091 if self._LibraryPcdList == None:
2092 Pcds = {}
2093 if not self.IsLibrary:
2094 # get PCDs from dependent libraries
2095 for Library in self.DependentLibraryList:
2096 for Key in Library.Pcds:
2097 # skip duplicated PCDs
2098 if Key in self.Module.Pcds or Key in Pcds:
2099 continue
2100 Pcds[Key] = copy.copy(Library.Pcds[Key])
2101 # apply PCD settings from platform
2102 self._LibraryPcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, Pcds)
2103 else:
2104 self._LibraryPcdList = []
2105 return self._LibraryPcdList
2106
2107 ## Get the GUID value mapping
2108 #
2109 # @retval dict The mapping between GUID cname and its value
2110 #
2111 def _GetGuidList(self):
2112 if self._GuidList == None:
2113 self._GuidList = self.Module.Guids
2114 for Library in self.DependentLibraryList:
2115 self._GuidList.update(Library.Guids)
2116 return self._GuidList
2117
2118 ## Get the protocol value mapping
2119 #
2120 # @retval dict The mapping between protocol cname and its value
2121 #
2122 def _GetProtocolList(self):
2123 if self._ProtocolList == None:
2124 self._ProtocolList = self.Module.Protocols
2125 for Library in self.DependentLibraryList:
2126 self._ProtocolList.update(Library.Protocols)
2127 return self._ProtocolList
2128
2129 ## Get the PPI value mapping
2130 #
2131 # @retval dict The mapping between PPI cname and its value
2132 #
2133 def _GetPpiList(self):
2134 if self._PpiList == None:
2135 self._PpiList = self.Module.Ppis
2136 for Library in self.DependentLibraryList:
2137 self._PpiList.update(Library.Ppis)
2138 return self._PpiList
2139
2140 ## Get the list of include search path
2141 #
2142 # @retval list The list path
2143 #
2144 def _GetIncludePathList(self):
2145 if self._IncludePathList == None:
2146 self._IncludePathList = []
2147 if self.AutoGenVersion < 0x00010005:
2148 for Inc in self.Module.Includes:
2149 if Inc not in self._IncludePathList:
2150 self._IncludePathList.append(Inc)
2151 # for r8 modules
2152 Inc = path.join(Inc, self.Arch.capitalize())
2153 if os.path.exists(Inc) and Inc not in self._IncludePathList:
2154 self._IncludePathList.append(Inc)
2155 # r8 module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time
2156 self._IncludePathList.append(self.DebugDir)
2157 else:
2158 self._IncludePathList.append(self.MetaFile.Dir)
2159 self._IncludePathList.append(self.DebugDir)
2160
2161 for Package in self.Module.Packages:
2162 PackageDir = path.join(self.WorkspaceDir, Package.MetaFile.Dir)
2163 if PackageDir not in self._IncludePathList:
2164 self._IncludePathList.append(PackageDir)
2165 for Inc in Package.Includes:
2166 if Inc not in self._IncludePathList:
2167 self._IncludePathList.append(str(Inc))
2168 return self._IncludePathList
2169
2170 ## Create makefile for the module and its dependent libraries
2171 #
2172 # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of
2173 # dependent libraries will be created
2174 #
2175 def CreateMakeFile(self, CreateLibraryMakeFile=True):
2176 if self.IsMakeFileCreated:
2177 return
2178
2179 if not self.IsLibrary and CreateLibraryMakeFile:
2180 for LibraryAutoGen in self.LibraryAutoGenList:
2181 LibraryAutoGen.CreateMakeFile()
2182
2183 if len(self.CustomMakefile) == 0:
2184 Makefile = GenMake.ModuleMakefile(self)
2185 else:
2186 Makefile = GenMake.CustomMakefile(self)
2187 if Makefile.Generate():
2188 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for module %s [%s]" %
2189 (self.Name, self.Arch))
2190 else:
2191 EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" %
2192 (self.Name, self.Arch))
2193
2194 self.IsMakeFileCreated = True
2195
2196 ## Create autogen code for the module and its dependent libraries
2197 #
2198 # @param CreateLibraryCodeFile Flag indicating if or not the code of
2199 # dependent libraries will be created
2200 #
2201 def CreateCodeFile(self, CreateLibraryCodeFile=True):
2202 if self.IsCodeFileCreated:
2203 return
2204
2205 if not self.IsLibrary and CreateLibraryCodeFile:
2206 for LibraryAutoGen in self.LibraryAutoGenList:
2207 LibraryAutoGen.CreateCodeFile()
2208
2209 AutoGenList = []
2210 IgoredAutoGenList = []
2211
2212 for File in self.AutoGenFileList:
2213 if GenC.Generate(File.Path, self.AutoGenFileList[File], File.IsBinary):
2214 #Ignore R8 AutoGen.c
2215 if self.AutoGenVersion < 0x00010005 and File.Name == 'AutoGen.c':
2216 continue
2217
2218 AutoGenList.append(str(File))
2219 else:
2220 IgoredAutoGenList.append(str(File))
2221
2222 # Skip the following code for EDK I inf
2223 if self.AutoGenVersion < 0x00010005:
2224 return
2225
2226 for ModuleType in self.DepexList:
2227 if len(self.DepexList[ModuleType]) == 0:
2228 continue
2229 Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True)
2230 DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}
2231
2232 if Dpx.Generate(path.join(self.OutputDir, DpxFile)):
2233 AutoGenList.append(str(DpxFile))
2234 else:
2235 IgoredAutoGenList.append(str(DpxFile))
2236
2237 if IgoredAutoGenList == []:
2238 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] files for module %s [%s]" %
2239 (" ".join(AutoGenList), self.Name, self.Arch))
2240 elif AutoGenList == []:
2241 EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of [%s] files for module %s [%s]" %
2242 (" ".join(IgoredAutoGenList), self.Name, self.Arch))
2243 else:
2244 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] (skipped %s) files for module %s [%s]" %
2245 (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch))
2246
2247 self.IsCodeFileCreated = True
2248 return AutoGenList
2249
2250 ## Summarize the ModuleAutoGen objects of all libraries used by this module
2251 def _GetLibraryAutoGenList(self):
2252 if self._LibraryAutoGenList == None:
2253 self._LibraryAutoGenList = []
2254 for Library in self.DependentLibraryList:
2255 La = ModuleAutoGen(
2256 self.Workspace,
2257 Library.MetaFile,
2258 self.BuildTarget,
2259 self.ToolChain,
2260 self.Arch,
2261 self.PlatformInfo.MetaFile
2262 )
2263 if La not in self._LibraryAutoGenList:
2264 self._LibraryAutoGenList.append(La)
2265 for Lib in La.CodaTargetList:
2266 self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)
2267 return self._LibraryAutoGenList
2268
2269 ## Return build command string
2270 #
2271 # @retval string Build command string
2272 #
2273 def _GetBuildCommand(self):
2274 return self.PlatformInfo.BuildCommand
2275
2276
2277 Module = property(_GetModule)
2278 Name = property(_GetBaseName)
2279 Guid = property(_GetGuid)
2280 Version = property(_GetVersion)
2281 ModuleType = property(_GetModuleType)
2282 ComponentType = property(_GetComponentType)
2283 BuildType = property(_GetBuildType)
2284 PcdIsDriver = property(_GetPcdIsDriver)
2285 AutoGenVersion = property(_GetAutoGenVersion)
2286 Macros = property(_GetMacros)
2287 Specification = property(_GetSpecification)
2288
2289 IsLibrary = property(_IsLibrary)
2290
2291 BuildDir = property(_GetBuildDir)
2292 OutputDir = property(_GetOutputDir)
2293 DebugDir = property(_GetDebugDir)
2294 MakeFileDir = property(_GetMakeFileDir)
2295 CustomMakefile = property(_GetCustomMakefile)
2296
2297 IncludePathList = property(_GetIncludePathList)
2298 AutoGenFileList = property(_GetAutoGenFileList)
2299 UnicodeFileList = property(_GetUnicodeFileList)
2300 SourceFileList = property(_GetSourceFileList)
2301 BinaryFileList = property(_GetBinaryFiles) # FileType : [File List]
2302 Targets = property(_GetTargets)
2303 IntroTargetList = property(_GetIntroTargetList)
2304 CodaTargetList = property(_GetFinalTargetList)
2305 FileTypes = property(_GetFileTypes)
2306 BuildRules = property(_GetBuildRules)
2307
2308 DependentPackageList = property(_GetDependentPackageList)
2309 DependentLibraryList = property(_GetLibraryList)
2310 LibraryAutoGenList = property(_GetLibraryAutoGenList)
2311 DerivedPackageList = property(_GetDerivedPackageList)
2312
2313 ModulePcdList = property(_GetModulePcdList)
2314 LibraryPcdList = property(_GetLibraryPcdList)
2315 GuidList = property(_GetGuidList)
2316 ProtocolList = property(_GetProtocolList)
2317 PpiList = property(_GetPpiList)
2318 DepexList = property(_GetDepexTokenList)
2319 DepexExpressionList = property(_GetDepexExpressionTokenList)
2320 BuildOption = property(_GetModuleBuildOption)
2321 BuildCommand = property(_GetBuildCommand)
2322
2323 # This acts like the main() function for the script, unless it is 'import'ed into another script.
2324 if __name__ == '__main__':
2325 pass
2326