]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/AutoGen/AutoGen.py
Sync tool code to BuildTools project r1739.
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / AutoGen.py
CommitLineData
30fdf114
LG
1## @file
2# Generate AutoGen.h, AutoGen.c and *.depex files
3#
030529de 4# Copyright (c) 2007 - 2009, Intel Corporation
30fdf114
LG
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#
16import os
17import re
18import os.path as path
19import copy
20
21import GenC
22import GenMake
23import GenDepex
b303ea72 24from StringIO import StringIO
30fdf114
LG
25
26from StrGather import *
27from BuildEngine import BuildRule
28
29from Common.BuildToolError import *
30from Common.DataType import *
31from Common.Misc import *
32from Common.String import *
33import Common.GlobalData as GlobalData
34from GenFds.FdfParser import *
35from CommonDataClass.CommonClass import SkuInfoClass
36from Workspace.BuildClassObject import *
37
38## Regular expression for splitting Dependency Expression stirng into tokens
39gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")
40
41## Mapping Makefile type
42gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}
43
44
45## Build rule configuration file
46gBuildRuleFile = 'Conf/build_rule.txt'
47
48## default file name for AutoGen
49gAutoGenCodeFileName = "AutoGen.c"
50gAutoGenHeaderFileName = "AutoGen.h"
51gAutoGenStringFileName = "%(module_name)sStrDefs.h"
b303ea72 52gAutoGenStringFormFileName = "%(module_name)sStrDefs.hpk"
30fdf114 53gAutoGenDepexFileName = "%(module_name)s.depex"
30fdf114
LG
54
55## Base class for AutoGen
56#
57# This class just implements the cache mechanism of AutoGen objects.
58#
59class 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#
121class 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,
b303ea72
LG
141 BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=[], Fvs=[], SkuId='',
142 ReportFile=None, ReportType=None):
30fdf114
LG
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
b303ea72
LG
150 self.ReportFile = ReportFile
151 self.ReportType = ReportType
30fdf114
LG
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
b303ea72
LG
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
30fdf114
LG
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#
616class 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)
b303ea72
LG
747
748 self.Platform.Modules[F].M = M
749
30fdf114
LG
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 = {}
fd171542 1390 FamilyMatch = False
1391 FamilyIsNull = True
30fdf114
LG
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
fd171542 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 =="":
30fdf114 1424 continue
fd171542 1425 # option has been added before
1426 if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:
1427 continue
1428
30fdf114
LG
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#
1509class 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
b303ea72 1589 self._DepexExpressionList = None
30fdf114
LG
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
b303ea72 1763 self._DepexList[self.ModuleType] = []
30fdf114
LG
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
b303ea72
LG
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
30fdf114
LG
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
b303ea72
LG
1942 if File.IsBinary and File == Source:
1943 RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE]
1944 elif FileType in self.BuildRules:
30fdf114
LG
1945 RuleObject = self.BuildRules[FileType]
1946 elif Source.Ext in self.BuildRules:
1947 RuleObject = self.BuildRules[Source.Ext]
30fdf114
LG
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:
b303ea72
LG
1961 if LastTarget:
1962 self._FinalBuildTargetList.add(LastTarget)
30fdf114
LG
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):
b303ea72
LG
2031 UniStringAutoGenC = True
2032 UniStringBinBuffer = None
2033 if self.BuildType == 'UEFI_HII':
2034 UniStringBinBuffer = StringIO()
2035 UniStringAutoGenC = False
30fdf114
LG
2036 if self._AutoGenFileList == None:
2037 self._AutoGenFileList = {}
2038 AutoGenC = TemplateString()
2039 AutoGenH = TemplateString()
2040 StringH = TemplateString()
b303ea72 2041 GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer)
30fdf114
LG
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)
b303ea72
LG
2054 if UniStringBinBuffer != None and UniStringBinBuffer.getvalue() != "":
2055 AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir)
2056 self._AutoGenFileList[AutoFile] = UniStringBinBuffer.getvalue()\r
2057 AutoFile.IsBinary = True
2058 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
2059 if UniStringBinBuffer != None:\r
2060 UniStringBinBuffer.close()\r
30fdf114
LG
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:
b303ea72 2213 if GenC.Generate(File.Path, self.AutoGenFileList[File], File.IsBinary):
30fdf114
LG
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
030529de 2222 # Skip the following code for EDK I inf
2223 if self.AutoGenVersion < 0x00010005:
2224 return
2225
30fdf114
LG
2226 for ModuleType in self.DepexList:
2227 if len(self.DepexList[ModuleType]) == 0:
2228 continue
2229 Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True)
b303ea72 2230 DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}
30fdf114
LG
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)
b303ea72 2319 DepexExpressionList = property(_GetDepexExpressionTokenList)
30fdf114
LG
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.
2324if __name__ == '__main__':
2325 pass
2326