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