Changed the import path
[people/mcb30/basetools.git] / Source / Python / AutoGen / AutoGen.py
1 #!/usr/bin/env python
2 import sys
3 import os
4 import re
5 import os.path as path
6 import imp
7
8 import Common.EdkLogger
9 import GenC
10 import GenMake
11 import GenDepex
12
13 from BuildInfo import *
14 from StrGather import *
15 from Common.BuildToolError import *
16 from Common.EdkIIWorkspaceBuild import *
17 from Common.EdkIIWorkspace import *
18 from Common.DataType import *
19
20 #
21 # generate AutoGen.c, AutoGen.h
22 # parse unicode file and generate XXXXString.h, XXXXString.c
23 # generate makefile
24 #
25
26 gPlatformDatabase = {}      # {arch : {dsc file path : PlatformBuildClassObject}}
27 gModuleDatabase = {}        # {arch : {inf file path : ModuleBuildClassObject}}
28 gPackageDatabase = {}       # {arch : {dec file path : PackageBuildClassObject}}
29 gAutoGenDatabase = {}       # (module/package/platform obj, BuildTarget, ToolChain, Arch) : build info
30 gWorkspace = None
31 gWorkspaceDir = ""
32 gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")
33 gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}
34
35 def FindModuleOwnerPackage(module, pkgdb):
36     for pkg in pkgdb:
37         pkgDir = path.dirname(pkg)
38         if module.DescFilePath.find(pkgDir) == 0:
39             return pkgdb[pkg]
40     return None
41
42 class AutoGen(object):
43
44     def __init__(self, moduleFile, platformFile, workspace, target, toolchain, arch):
45         global gModuleDatabase, gPackageDatabase, gPlatformDatabase, gAutoGenDatabase, gWorkspace, gWorkspaceDir
46
47         if gWorkspace == None:
48             gWorkspace = workspace
49         if gWorkspaceDir == "":
50             gWorkspaceDir = workspace.Workspace.WorkspaceDir
51
52         if gModuleDatabase == {}:
53             for a in workspace.Build:
54                 gModuleDatabase[a] = gWorkspace.Build[a].ModuleDatabase
55         if gPackageDatabase == {}:
56             for a in workspace.Build:
57                 gPackageDatabase[a] = gWorkspace.Build[a].PackageDatabase
58         if gPlatformDatabase == {}:
59             for a in workspace.Build:
60                 gPlatformDatabase[a] = gWorkspace.Build[a].PlatformDatabase
61
62         self.ToolChain = toolchain
63         self.BuildTarget = target
64         self.IsMakefileCreated = False
65         self.IsAutoGenCodeCreated = False
66
67         key = (self.BuildTarget, self.ToolChain, str(platformFile))
68         if moduleFile == None:
69             #
70             # autogen for platform
71             #
72             self.PlatformBuildInfo = {}     # arch : PlatformBuildInfo Object
73             self.Platform = {}
74             self.IsPlatformAutoGen = True
75             if type(arch) == type([]):
76                 self.Arch = arch
77             else:
78                 self.Arch = [arch]
79                 
80             self.Platform = {}
81             self.BuildInfo = {}
82             for a in self.Arch:
83                 if a not in gPlatformDatabase or str(platformFile) not in gPlatformDatabase[a]:
84                     raise AutoGenError(msg="[%s] is not active platform, or %s is not supported!" % (platformFile, a))
85                 p = gPlatformDatabase[a][str(platformFile)]
86                 self.Platform[a] = p
87                 self.BuildInfo[a] = self.GetPlatformBuildInfo(p, self.BuildTarget, self.ToolChain, a)
88             gAutoGenDatabase[key] = self
89             return
90         elif key not in gAutoGenDatabase:
91             gAutoGenDatabase[key] = AutoGen(None, platformFile, workspace, target, toolchain, arch)
92
93         #print "-------------",moduleFile,"----------------"
94         #
95         # autogen for module
96         #
97         self.IsPlatformAutoGen = False
98         if type(arch) == type([]):
99             if len(arch) > 1:
100                 raise AutoGenError(msg="Cannot AutoGen a module for more than one platform objects at the same time!")
101             self.Arch = arch[0]
102         else:
103             self.Arch = arch
104
105         if self.Arch not in gPlatformDatabase or str(platformFile) not in gPlatformDatabase[arch]:
106             raise AutoGenError(msg="[%s] is not active platform, or %s is not supported!" % (platformFile, self.Arch))
107         if self.Arch not in gModuleDatabase or str(moduleFile) not in gModuleDatabase[self.Arch]:
108             raise AutoGenError(msg="[%s] for %s is not found in active platform [%s]!" % (moduleFile, self.Arch, platformFile))
109         self.Module = gModuleDatabase[self.Arch][str(moduleFile)]
110         self.Platform = gPlatformDatabase[arch][str(platformFile)]
111
112         self.Package = FindModuleOwnerPackage(self.Module, gPackageDatabase[arch])
113         if self.Package == None:
114             raise AutoGenError(msg="Cannot find owner package for [%s]!" % (moduleFile))
115
116         self.AutoGenC = GenC.AutoGenString()
117         self.AutoGenH = GenC.AutoGenString()
118
119         self.BuildInfo = None
120         self.GetModuleBuildInfo()
121         gAutoGenDatabase[self.BuildTarget, self.ToolChain, self.Arch, self.Module] = self
122
123     def GetModuleBuildInfo(self):
124         key = (self.BuildTarget, self.ToolChain, self.Arch, self.Module)
125         if key in gAutoGenDatabase:
126             self.BuildInfo = gAutoGenDatabase[key].BuildInfo
127             self.IsAutoGenCodeCreated = gAutoGenDatabase[key].IsAutoGenCodeCreated
128             self.IsMakefileCreated = gAutoGenDatabase[key].IsMakefileCreated
129             return gAutoGenDatabase[key].BuildInfo
130         
131         info = ModuleBuildInfo(self.Module)
132         self.BuildInfo = info
133         info.PlatformInfo = self.GetPlatformBuildInfo(self.Platform, self.BuildTarget, self.ToolChain, self.Arch)
134
135         key = (self.Package, self.BuildTarget, self.ToolChain, self.Arch)
136         if key in gAutoGenDatabase:
137             info.PackageInfo = gAutoGenDatabase[key]
138         else:
139             info.PackageInfo = PackageBuildInfo(self.Package)
140             self.InitPackageBuildInfo(info.PackageInfo)
141             gAutoGenDatabase[key] = info.PackageInfo
142
143         # basic information
144         info.WorkspaceDir = gWorkspaceDir
145         info.BuildTarget = self.BuildTarget
146         info.ToolChain = self.ToolChain
147         info.Arch = self.Arch
148         info.IsBinary = False
149         info.BaseName = self.Module.BaseName
150         info.FileBase, info.FileExt = path.splitext(path.basename(self.Module.DescFilePath))
151         info.SourceDir = path.dirname(self.Module.DescFilePath)
152         info.BuildDir = os.path.join(info.PlatformInfo.BuildDir,
153                                      info.Arch,
154                                      info.SourceDir,
155                                      info.FileBase)
156         info.OutputDir = os.path.join(info.BuildDir, "OUTPUT")
157         info.DebugDir = os.path.join(info.BuildDir, "DEBUG")
158         info.MakefileDir = info.BuildDir
159         if os.path.isabs(info.BuildDir):
160             CreateDirectory(info.OutputDir)
161             CreateDirectory(info.DebugDir)
162         else:
163             CreateDirectory(os.path.join(gWorkspaceDir, info.OutputDir))
164             CreateDirectory(os.path.join(gWorkspaceDir, info.DebugDir))
165
166         for type in self.Module.CustomMakefile:
167             makeType = gMakeTypeMap[type]
168             info.CustomMakefile[makeType] = os.path.join(info.SourceDir, self.Module.CustomMakefile[type])
169
170         if self.Module.LibraryClass != None and self.Module.LibraryClass != "":
171             info.IsLibrary = True
172             info.DependentLibraryList = []
173         else:
174             info.IsLibrary = False
175             info.DependentLibraryList = self.GetSortedLibraryList()
176
177         info.DependentPackageList = self.GetDependentPackageList()
178
179         info.BuildOption = self.GetModuleBuildOption(info.PlatformInfo)
180
181         info.PcdIsDriver = self.Module.PcdIsDriver
182         info.PcdList = self.GetPcdList(info.DependentLibraryList)
183         info.GuidList = self.GetGuidList()
184         info.ProtocolList = self.GetProtocolGuidList()
185         info.PpiList = self.GetPpiGuidList()
186         info.MacroList = self.GetMacroList()
187         info.DepexList = self.GetDepexTokenList(info)
188         
189         info.IncludePathList = [info.SourceDir, info.DebugDir]
190         info.IncludePathList.extend(self.GetIncludePathList(info.DependentPackageList))
191
192         info.SourceFileList = self.GetBuildFileList(info.PlatformInfo)
193         info.AutoGenFileList = self.GetAutoGenFileList(info)
194
195         return info
196
197     def InitPackageBuildInfo(self, info):
198         info.SourceDir = path.dirname(info.Package.DescFilePath)
199         info.IncludePathList.append(info.SourceDir)
200         for inc in info.Package.Includes:
201             info.IncludePathList.append(os.path.join(info.SourceDir, inc))
202
203     def GetPlatformBuildInfo(self, platform, target, toolchain, arch):
204         key = target, toolchain, platform
205         platformAutoGen = None
206         if key in gAutoGenDatabase:
207             platformAutoGen = gAutoGenDatabase[key]
208             if arch in platformAutoGen.BuildInfo:
209                 return platformAutoGen.BuildInfo[arch]
210
211         info = PlatformBuildInfo(platform)
212
213         ruleFile = gWorkspace.Workspace.WorkspaceFile(r'Conf\build_rule.txt')
214         info.BuildRule = imp.load_source("BuildRule", ruleFile)
215
216         info.Arch = arch
217         info.ToolChain = self.ToolChain
218         info.BuildTarget = self.BuildTarget
219
220         info.WorkspaceDir = gWorkspace.Workspace.WorkspaceDir
221         info.SourceDir = path.dirname(platform.DescFilePath)
222         info.OutputDir = platform.OutputDirectory
223         info.BuildDir = path.join(info.OutputDir, self.BuildTarget + "_" + self.ToolChain)
224         info.MakefileDir = info.BuildDir
225         if platform.FlashDefinition != "":
226             info.FdfFileList.append(path.join(gWorkspaceDir, platform.FlashDefinition))
227
228         info.DynamicPcdList = self.GetDynamicPcdList(platform, arch)
229         info.PcdTokenNumber = self.GeneratePcdTokenNumber(platform, info.DynamicPcdList)
230         info.PackageList = gPackageDatabase[arch].values()
231
232         self.ProcessToolDefinition(info)
233
234         if platformAutoGen != None:
235             platformAutoGen.BuildInfo = info
236         return info
237
238     def GetDepexTokenList(self, info):
239         dxs = self.Module.Depex
240         #
241         # Append depex from dependent libraries
242         #
243         for lib in info.DependentLibraryList:
244             if lib.Depex != "":
245                 dxs += " AND " + lib.Depex
246         if dxs == "":
247             return []
248
249         tokenList = gDepexTokenPattern.findall(self.Module.Depex)
250         for i in range(0, len(tokenList)):
251             token = tokenList[i].strip()
252             if token.endswith(".inf"):  # module file name
253                 moduleFile = os.path.normpath(token)
254                 token = gModuleDatabase[moduleFile].Guid
255             elif token.upper() in GenDepex.DependencyExpression.SupportedOpcode: # Opcode name
256                 token = token.upper()
257             else:   # GUID C Name
258                 guidCName = token
259                 for p in info.DependentPackageList:
260                     if guidCName in p.Protocols:
261                         token = p.Protocols[guidCName]
262                         break
263                     elif guidCName in p.Ppis:
264                         token = p.Ppis[guidCName]
265                         break
266                     elif guidCName in p.Guids:
267                         token = p.Guids[guidCName]
268                         break
269                 else:
270                     raise AutoGenError(msg="%s used in module %s cannot be found in any package!" % (guidCName, info.Name))
271             tokenList[i] = token
272         return tokenList
273
274     def GetMacroList(self):
275         return ["%s %s" % (name, self.Module.Specification[name]) for name in self.Module.Specification]
276     
277     def ProcessToolDefinition(self, info):
278         toolDefinition = gWorkspace.ToolDef.ToolsDefTxtDictionary
279         toolCodeList = gWorkspace.ToolDef.ToolsDefTxtDatabase["COMMAND_TYPE"]
280         for tool in toolCodeList:
281             keyBaseString = "%s_%s_%s_%s" % (info.BuildTarget, info.ToolChain, info.Arch, tool)
282             key = "%s_NAME" % keyBaseString
283             if key not in toolDefinition:
284                 continue
285             name = toolDefinition[key]
286             
287             key = "%s_PATH" % keyBaseString
288             if key in toolDefinition:
289                 path = toolDefinition[key]
290             else:
291                 path = ""
292
293             key = "%s_FAMILY" % keyBaseString
294             if key in toolDefinition:
295                 family = toolDefinition[key]
296             else:
297                 family = ""
298
299             key = "%s_FLAGS" % keyBaseString
300             if key in toolDefinition:
301                 option = toolDefinition[key]
302             else:
303                 option = ""
304                 
305             key = "%s_DPATH" % keyBaseString
306             if key in toolDefinition:
307                 dll = toolDefinition[key]
308             else:
309                 dll = ""
310                 
311             key = "%s_SPATH" % keyBaseString
312             if key in toolDefinition:
313                 lib = toolDefinition[key]
314             else:
315                 lib = ""
316
317             info.ToolPath[tool] = os.path.join(path, name)
318             info.ToolDynamicLib[tool] = dll
319             info.ToolStaticLib[tool] = lib
320             info.ToolChainFamily[tool] = family
321             info.DefaultToolOption[tool] = option
322
323         if self.IsPlatformAutoGen:
324             buildOptions = self.Platform[info.Arch].BuildOptions
325         else:
326             buildOptions = self.Platform.BuildOptions
327
328         for key in buildOptions:
329             family = key[0]
330             target, tag, arch, tool, attr = key[1].split("_")
331             if tool not in info.ToolPath:
332                 continue
333             if family != None and family != "" and family != info.ToolChainFamily[tool]:
334                 continue
335             if target == "*" or target == info.BuildTarget:
336                 if tag == "*" or tag == info.ToolChain:
337                     if arch == "*" or arch == info.Arch:
338                         info.BuildOption[tool] = buildOptions[key]
339         for tool in info.DefaultToolOption:
340             if tool not in info.BuildOption:
341                 info.BuildOption[tool] = ""
342
343     def GetModuleBuildOption(self, platformInfo):
344         buildOption = self.Module.BuildOptions
345         optionList = {}
346         for key in buildOption:
347             family = key[0]
348             target, tag, arch, tool, attr = key[1].split("_")
349             if tool not in platformInfo.ToolPath:
350                 continue
351             if family != None and family != "" and family != platformInfo.ToolChainFamily[tool]:
352                 continue
353             if target == "*" or target == self.BuildTarget:
354                 if tag == "*" or tag == self.ToolChain:
355                     if arch == "*" or arch == self.Arch:
356                         optionList[tool] = buildOption[key]
357         for tool in platformInfo.DefaultToolOption:
358             if tool not in optionList:
359                 optionList[tool] = ""
360         return optionList
361     
362     def GetBuildFileList(self, platformInfo):
363         buildRule = platformInfo.BuildRule
364         buildFileList = []
365         fileList = self.Module.Sources
366         for f in fileList:
367             if f.TagName != "" and f.TagName != self.ToolChain:
368                 continue
369             if f.ToolCode != "" and f.ToolCode not in platformInfo.ToolPath:
370                 continue
371
372             dir = path.dirname(f.SourceFile)
373             if dir != "":
374                 dir = path.join(self.BuildInfo.SourceDir, dir)
375                 if dir not in self.BuildInfo.IncludePathList:
376                     self.BuildInfo.IncludePathList.insert(0, dir)
377
378             # skip unknown file
379             base, ext = path.splitext(f.SourceFile)
380             if ext not in buildRule.FileTypeMapping:
381                 EdkLogger.verbose("Don't know how to process file %s (%s)" % (f.SourceFile, ext))
382                 continue
383             
384             # skip file which needs a tool having no matching toolchain family
385             fileType = buildRule.FileTypeMapping[ext]
386             if f.ToolCode != "":
387                 toolCode = f.ToolCode
388             else:
389                 toolCode = buildRule.ToolCodeMapping[fileType]
390             # get the toolchain family from tools definition
391             if f.ToolChainFamily != "" and f.ToolChainFamily != platformInfo.ToolChainFamily[toolCode]:
392                 EdkLogger.verbose("File %s for toolchain family %s is not supported" % (f.SourceFile, f.ToolChainFamily))
393                 continue
394             if fileType == "Unicode-Text":
395                 self.BuildInfo.UnicodeFileList.append(os.path.join(gWorkspaceDir, self.BuildInfo.SourceDir, f.SourceFile))
396             buildFileList.append(f.SourceFile)
397         return buildFileList
398
399     def GetDependentPackageList(self):
400         if self.Package not in self.Module.Packages:
401             self.Module.Packages.insert(0, str(self.Package))
402
403         if self.Arch not in gPackageDatabase:
404             raise AutoGenError(msg="[%s] is not supported!")
405         packageDatabase = gPackageDatabase[self.Arch]
406
407         packageList = []
408         for pf in self.Module.Packages:
409             if pf in packageList:
410                 continue
411             if pf not in packageDatabase:
412                 raise AutoGenError(FILE_NOT_FOUND, name=pf)
413             packageList.append(packageDatabase[pf])
414         return packageList
415
416     def GetAutoGenFileList(self, buildInfo):
417         GenC.CreateCode(buildInfo, self.AutoGenC, self.AutoGenH)
418         fileList = []
419         if self.AutoGenC.String != "":
420             fileList.append("AutoGen.c")
421         if self.AutoGenH.String != "":
422             fileList.append("AutoGen.h")
423             #print self.AutoGenH.String
424         return fileList
425     
426     def GetSortedLibraryList(self):
427         moduleType = self.Module.ModuleType
428         libraryConsumerList = [self.Module]
429         
430         libraryList         = []
431         constructor         = []
432         consumedByList      = {}
433         libraryClassList    = []
434
435         EdkLogger.verbose("")
436         EdkLogger.verbose("Library instances of module [%s]:" % str(self.Module))
437         while len(libraryConsumerList) > 0:
438             module = libraryConsumerList.pop()
439             for libc, libf in module.LibraryClasses.iteritems():
440                 if moduleType not in libc:
441                     EdkLogger.debug(EdkLogger.DEBUG_5, "\t%s for module type %s is not supported" % libc)
442                     continue
443                 if libf == None or libf == "":
444                     EdkLogger.info("\tLibrary instance of library class %s is not found" % libc[0])
445                     continue
446                 
447                 libm = gModuleDatabase[self.Arch][libf]
448                 if libm not in libraryList and libc not in libraryClassList:
449                     libraryConsumerList.append(libm)
450                     libraryList.append(libm)
451                     libraryClassList.append(libc)
452                     EdkLogger.verbose("\t" + libc[0] + " : " + str(libm))
453
454                 if libm.ConstructorList != [] and libm not in constructor:
455                     constructor.append(libm)
456                     
457                 if libm not in consumedByList:
458                     consumedByList[libm] = []
459                 if module != self.Module:
460                     if module in consumedByList[libm]:
461                         continue
462                     consumedByList[libm].append(module)
463         #
464         # Initialize the sorted output list to the empty set
465         #
466         SortedLibraryList = []
467         #
468         # Q <- Set of all nodes with no incoming edges
469         #
470         Q = []
471         for m in libraryList:
472             if consumedByList[m] == []:
473                 Q.insert(0, m)
474         #
475         # while Q is not empty do
476         #
477         while Q != []:
478             #
479             # remove node n from Q
480             #
481             n = Q.pop()
482             #
483             # output n
484             #
485             SortedLibraryList.append(n)
486             #
487             # for each node m with an edge e from n to m do
488             #
489             for m in libraryList:
490                 if n not in consumedByList[m]:
491                     continue
492                 #
493                 # remove edge e from the graph
494                 #
495                 consumedByList[m].remove(n)
496                 #
497                 # If m has no other incoming edges then
498                 #
499                 if consumedByList[m] == []:
500                     #
501                     # insert m into Q
502                     #
503                     Q.insert(0,m)
504
505             EdgeRemoved = True
506             while Q == [] and EdgeRemoved:
507                 EdgeRemoved = False
508                 #
509                 # for each node m with a constructor
510                 #
511                 for m in libraryList:
512                     if m in constructor:
513                         #
514                         # for each node n without a constructor with an edge e from m to n
515                         #
516                         for n in consumedByList[m]:
517                             if n not in constructor:
518                                 #
519                                 # remove edge e from the graph
520                                 #
521                                 consumedByList[m].remove(n)
522                                 EdgeRemoved = True
523                                 if consumedByList[m] == []:
524                                     #
525                                     # insert m into Q
526                                     #
527                                     Q.insert(0,m)
528                                     break
529                     if Q != []:
530                         break
531
532         #
533         # if any remaining node m in the graph has a constructor and an incoming edge, then the graph has a cycle
534         #
535         for m in libraryList:
536             if consumedByList[m] != [] and m in constructor:
537                 errorMessage = 'Module library [%s] with constructors have a cycle:\n\t' % str(m)
538                 errorMessage += "\n\tconsumed by ".join([str(l) for l in consumedByList[m]])
539                 raise AutoGenError(msg=errorMessage)
540             if m not in SortedLibraryList:
541                 SortedLibraryList.append(m)
542
543         #
544         # Build the list of constructor and destructir names
545         # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order
546         #
547         SortedLibraryList.reverse()
548         return SortedLibraryList
549
550     def GetDynamicPcdList(self, platform, arch):
551         pcdList = []
552         for f in gModuleDatabase[arch]:
553             m = gModuleDatabase[arch][f]
554             for key in m.Pcds:
555                 if key not in platform.Pcds:
556                     raise AutoGenError(msg="PCD [%s %s] not found in platform" % key)
557                 mPcd = m.Pcds[key]
558                 pPcd = platform.Pcds[key]
559                 if pPcd.Type in GenC.gDynamicPcd + GenC.gDynamicExPcd:
560                     if m.ModuleType in ["PEIM", "PEI_CORE"]:
561                         pPcd.Phase = "PEI"
562                     if pPcd not in pcdList:
563                         pPcd.DatumType = mPcd.DatumType
564                         pcdList.append(pPcd)
565         return pcdList
566
567     def GeneratePcdTokenNumber(self, platform, dynamicPcdList):
568         pcdTokenNumber = {}
569         tokenNumber = 1
570         for pcd in dynamicPcdList:
571             #print "@@@",tokenNumber,"=",pcd.TokenCName, pcd.TokenSpaceGuidCName, pcd.DatumType
572             pcdTokenNumber[pcd.TokenCName, pcd.TokenSpaceGuidCName] = tokenNumber
573             tokenNumber += 1
574
575         platformPcds = platform.Pcds
576         for key in platformPcds:
577             pcd = platformPcds[key]
578             #print "###",key
579             if key not in pcdTokenNumber:
580                 pcdTokenNumber[key] = tokenNumber
581                 tokenNumber += 1
582         return pcdTokenNumber
583
584     def GetPcdList(self, dependentLibraryList):
585         platformPcds = self.Platform.Pcds
586
587         pcdList = []
588         for m in dependentLibraryList + [self.Module]:
589             for pcdKey in m.Pcds:
590                 pcd = m.Pcds[pcdKey]
591                 if (pcd.Type in GenC.gDynamicPcd + GenC.gDynamicExPcd) and self.Module.ModuleType in ["PEIM", "PEI_CORE"]:
592                     #platformPcds[pcdKey].Phase = "PEI"
593                     pcd.Phase = "PEI"
594                 if pcd not in pcdList:
595                     pcdList.append(pcd)
596         return pcdList
597
598     def GetGuidList(self):
599         packageListString = "\n\t".join([p.PackageName for p in self.BuildInfo.DependentPackageList])
600         guid = {}
601         Key = ""
602         for Key in self.Module.Guids:
603             for p in self.BuildInfo.DependentPackageList:
604                 if Key in p.Guids:
605                     guid[Key] = p.Guids[Key]
606                     break
607                 if Key in p.Protocols:
608                     guid[Key] = p.Protocols[Key]
609                     break
610                 if Key in p.Ppis:
611                     guid[Key] = p.Ppis[Key]
612                     break
613             else:
614                 raise AutoGenError(msg='GUID [%s] used by [%s] cannot be found in dependent packages:\n\t%s' % (Key, self.BuildInfo.Name, packageListString))
615
616         for lib in self.BuildInfo.DependentLibraryList:
617             if lib.Guids == []:
618                 continue
619
620             for Key in lib.Guids:
621                 for p in lib.Packages:
622                     # print gPackageDatabase
623                     p = gPackageDatabase[self.Arch][p]
624                     if Key in p.Guids:
625                         guid[Key] = p.Guids[Key]
626                         break
627                     if Key in p.Protocols:
628                         guid[Key] = p.Protocols[Key]
629                         break
630                     if Key in p.Ppis:
631                         guid[Key] = p.Ppis[Key]
632                         break
633                 else:
634                     raise AutoGenError(msg='GUID [%s] used by [%s] cannot be found in dependent packages:\n\t%s' % (Key, lib.BaseName, packageListString))
635         return guid
636
637     def GetProtocolGuidList(self):
638         packageListString = "\n\t".join([p.PackageName for p in self.BuildInfo.DependentPackageList])
639         guid = {}
640         Key = ""
641         for Key in self.Module.Protocols:
642             for p in self.BuildInfo.DependentPackageList:
643                     if Key in p.Guids:
644                         guid[Key] = p.Guids[Key]
645                         break
646                     if Key in p.Protocols:
647                         guid[Key] = p.Protocols[Key]
648                         break
649                     if Key in p.Ppis:
650                         guid[Key] = p.Ppis[Key]
651                         break
652             else:
653                 raise AutoGenError(msg='Protocol [%s] used by [%s] cannot be found in dependent packages:\n\t%s' % (Key, self.BuildInfo.Name, packageListString))
654
655         for lib in self.BuildInfo.DependentLibraryList:
656             if lib.Protocols == []:
657                 continue
658             for Key in lib.Protocols:
659                 for p in lib.Packages:
660                     p = gPackageDatabase[self.Arch][p]
661                     if Key in p.Guids:
662                         guid[Key] = p.Guids[Key]
663                         break
664                     if Key in p.Protocols:
665                         guid[Key] = p.Protocols[Key]
666                         break
667                     if Key in p.Ppis:
668                         guid[Key] = p.Ppis[Key]
669                         break
670                 else:
671                     raise AutoGenError(msg='Protocol [%s] used by [%s] cannot be found in dependent packages:\n\t%s' % (Key, lib.BaseName, packageListString))
672
673         return guid
674
675     def GetPpiGuidList(self):
676         packageListString = "\n\t".join([p.PackageName for p in self.BuildInfo.DependentPackageList])
677         guid = {}
678         Key = ""
679         for Key in self.Module.Ppis:
680             for p in self.BuildInfo.DependentPackageList:
681                 if Key in p.Guids:
682                     guid[Key] = p.Guids[Key]
683                     break
684                 if Key in p.Protocols:
685                     guid[Key] = p.Protocols[Key]
686                     break
687                 if Key in p.Ppis:
688                     guid[Key] = p.Ppis[Key]
689                     break
690             else:
691                 raise AutoGenError(msg='PPI [%s] used by [%s] cannot be found in dependent packages:\n\t%s' % (Key, self.BuildInfo.Name, packageListString))
692
693         for lib in self.BuildInfo.DependentLibraryList:
694             if lib.Ppis == []:
695                 continue
696             for Key in lib.Ppis:
697                 for p in lib.Packages:
698                     p = gPackageDatabase[self.Arch][p]
699                     if Key in p.Guids:
700                         guid[Key] = p.Guids[Key]
701                         break
702                     if Key in p.Protocols:
703                         guid[Key] = p.Protocols[Key]
704                         break
705                     if Key in p.Ppis:
706                         guid[Key] = p.Ppis[Key]
707                         break
708                 else:
709                     raise AutoGenError(msg='PPI [%s] used by [%s] cannot be found in dependent packages:\n\t%s' % (Key, lib.BaseName, packageListString))
710         return guid
711
712     def GetIncludePathList(self, dependentPackageList):
713         includePathList = []
714         for inc in self.Module.Includes:
715             includePathList.append(inc)
716             
717         for package in dependentPackageList:
718             packageDir = path.dirname(package.DescFilePath)
719             includePathList.append(packageDir)
720             for inc in package.Includes:
721                 inc = os.path.join(packageDir, inc)
722                 if inc not in includePathList:
723                     includePathList.append(inc)
724         return includePathList
725
726     def CreateMakefile(self, filePath=None):
727         myBuildOption = {
728             "ENABLE_PCH"        :   False,
729             "ENABLE_LOCAL_LIB"  :   True,
730         }
731         if self.IsMakefileCreated:
732             return
733
734         if self.IsPlatformAutoGen:
735             for arch in self.BuildInfo:
736                 info = self.BuildInfo[arch]
737                 for moduleFile in info.Platform.Modules:
738                     key = (info.BuildTarget, info.ToolChain, arch, moduleFile)
739                     moduleAutoGen = None
740                     if key not in gAutoGenDatabase:
741                         moduleAutoGen = AutoGen(moduleFile, info.Platform, gWorkspace,
742                                                 info.BuildTarget, info.ToolChain, info.Arch)
743                     else:
744                         moduleAutoGen = gAutoGenDatabase[key]
745                     moduleAutoGen.CreateMakefile()
746         else:
747             platformInfo = self.BuildInfo.PlatformInfo
748             if not self.BuildInfo.IsLibrary:
749                 if self not in platformInfo.ModuleAutoGenList:
750                     platformInfo.ModuleAutoGenList.append(self)
751             elif self not in platformInfo.LibraryAutoGenList:
752                 platformInfo.LibraryAutoGenList.append(self)
753
754             for lib in self.BuildInfo.DependentLibraryList:
755                 EdkLogger.debug(EdkLogger.DEBUG_2, "###" + str(lib))
756                 key = (self.BuildTarget, self.ToolChain, self.Arch, lib)
757                 libraryAutoGen = None
758                 if key not in gAutoGenDatabase:
759                     libraryAutoGen = AutoGen(lib, self.Platform, gWorkspace,
760                                              self.BuildTarget, self.ToolChain, self.Arch)
761                 else:
762                     libraryAutoGen = gAutoGenDatabase[key]
763                 if libraryAutoGen not in self.BuildInfo.LibraryAutoGenList:
764                     self.BuildInfo.LibraryAutoGenList.append(libraryAutoGen)
765                 libraryAutoGen.CreateMakefile()
766
767             makefile = GenMake.Makefile(self.BuildInfo, myBuildOption)
768             f = makefile.Generate()
769             self.IsMakefileCreated = True
770             EdkLogger.info("Generated [%s] for module %s" % (path.basename(f), self.BuildInfo.Name))
771             return f
772
773         makefile = GenMake.Makefile(self.BuildInfo, myBuildOption)
774         f = makefile.Generate()
775         self.IsMakefileCreated = True
776         EdkLogger.info("Generated [%s] for platform %s" % (path.basename(f), self.BuildInfo[self.Arch[0]].Name))
777
778         return f
779
780     def CreateAutoGenFile(self, filePath=None):
781         if self.IsAutoGenCodeCreated:
782             return
783         
784         if self.IsPlatformAutoGen:
785             for arch in self.BuildInfo:
786                 info = self.BuildInfo[arch]
787                 for moduleFile in info.Platform.Modules:
788                     key = (info.BuildTarget, info.ToolChain, arch, moduleFile)
789                     moduleAutoGen = None
790                     if key not in gAutoGenDatabase:
791                         moduleAutoGen = AutoGen(moduleFile, info.Platform, gWorkspace,
792                                                 info.BuildTarget, info.ToolChain, info.Arch)
793                     else:
794                         moduleAutoGen = gAutoGenDatabase[key]
795                     moduleAutoGen.CreateAutoGenFile()
796             print
797         else:
798             platformInfo = self.BuildInfo.PlatformInfo
799             if not self.BuildInfo.IsLibrary and self not in platformInfo.ModuleAutoGenList:
800                 platformInfo.ModuleAutoGenList.append(self)
801             elif self.BuildInfo.IsLibrary and self not in platformInfo.LibraryAutoGenList:
802                 platformInfo.LibraryAutoGenList.append(self)
803
804             for lib in self.BuildInfo.DependentLibraryList:
805                 key = (self.BuildTarget, self.ToolChain, self.Arch, lib)
806                 libraryAutoGen = None
807                 if key not in gAutoGenDatabase:
808                     libraryAutoGen = AutoGen(lib, self.Platform, gWorkspace,
809                                              self.BuildTarget, self.ToolChain, self.Arch)
810                 else:
811                     libraryAutoGen = gAutoGenDatabase[key]
812                 if libraryAutoGen not in self.BuildInfo.LibraryAutoGenList:
813                     self.BuildInfo.LibraryAutoGenList.append(libraryAutoGen)
814                 libraryAutoGen.CreateAutoGenFile()
815
816             autoGenList = GenC.Generate(os.path.join(self.BuildInfo.WorkspaceDir, self.BuildInfo.DebugDir),
817                                         self.AutoGenC, self.AutoGenH)
818                           
819             if self.BuildInfo.DepexList != []:
820                 dpx = GenDepex.DependencyExpression(self.BuildInfo.DepexList, self.BuildInfo.ModuleType)
821                 dpxFile = dpx.Generate(os.path.join(gWorkspaceDir, self.BuildInfo.OutputDir, self.BuildInfo.Name + ".depex"))
822                 autoGenList.append(dpxFile)
823
824             self.IsAutoGenCodeCreated = True
825             EdkLogger.info("Generated [%s] files for module %s" % (" ".join([path.basename(f) for f in autoGenList]), self.BuildInfo.Name))
826
827             return autoGenList
828
829 # This acts like the main() function for the script, unless it is 'import'ed into another
830 # script.
831 if __name__ == '__main__':
832     print "Running Operating System =", sys.platform
833     ewb = WorkspaceBuild()
834     #print ewb.Build.keys()
835
836     myArch = ewb.Build["IA32"].Arch
837     print myArch
838
839     myBuild = ewb.Build["IA32"]
840
841     myWorkspace = ewb
842     apf = os.path.normpath(ewb.TargetTxt.TargetTxtDictionary["ACTIVE_PLATFORM"][0])
843     myPlatform = myBuild.PlatformDatabase[os.path.normpath(apf)]
844
845     #LoadBuildRule(myWorkspace.Workspace.WorkspaceFile('Tools/Conf/build.rule'))
846
847     myToolchain = ewb.TargetTxt.TargetTxtDictionary["TOOL_CHAIN_TAG"][0]
848     #print myToolchain
849
850     myBuildTarget = ewb.TargetTxt.TargetTxtDictionary["TARGET"][0]
851     #print myBuildTarget
852
853     myBuildOption = {
854         "ENABLE_PCH"        :   False,
855         "ENABLE_LOCAL_LIB"  :   True,
856     }
857     
858     def PrintAutoGen(ag):
859         bi = ag.ModuleBuildInfo
860
861         print " WorkSpaceDir =",bi.WorkspaceDir
862         print " SourceDir =",bi.SourceDir
863         print " Is Library =",bi.IsLibrary
864         print " BaseName =",bi.BaseName
865         print " FileBase =",bi.FileBase
866         print " FileExt =",bi.FileExt
867         print " BuildDir =",bi.BuildDir
868         print " OutputDir =",bi.OutputDir
869         print " DebugDir =",bi.DebugDir
870         print " MakefileDir =",bi.MakefileDir
871
872         print " Include Path:","\n   ","\n    ".join(bi.InclduePathList)
873         print " SourceFileList:","\n   ","\n    ".join(bi.SourceFileList)
874
875         print " BuildOption:","\n   ","\n    ".join(["%s = %s" % (tool,bi.BuildOption[tool]) for tool in bi.BuildOption])
876         print " PcdList:","\n   ","\n    ".join([pcd.TokenCName for pcd in bi.PcdList])
877         print " GuidList:","\n   ","\n    ".join(bi.GuidList)
878         print " ProtocolList:","\n   ","\n    ".join(bi.ProtocolList)
879         print " PpiList:","\n   ","\n    ".join(bi.PpiList)
880         print " LibraryList:","\n   ","\n    ".join([str(l) for l in bi.DependentLibraryList])
881
882         print
883
884 ##        for key in gAutoGenDatabase:
885 ##            if str(myPlatform) == str(key[0]):
886 ##                pi = gAutoGenDatabase[key]
887 ##                print " BuildDir =",pi.BuildDir
888 ##                print " OutputDir =",pi.OutputDir
889 ##                print " DebugDir =",pi.DebugDir
890 ##                print " LibraryDir =",pi.LibraryDir
891 ##                print " FvDir =",pi.FvDir
892 ##                print " MakefileDir =",pi.MakefileDir
893 ##                print " PcdTokenNumber:","\n   ","\n    ".join(["%s = %s" % (pcd,pi.PcdTokenNumber[pcd]) for pcd in pi.PcdTokenNumber])
894 ##                print " DynamicPcdList:","\n   ","\n    ".join([str(pcd) for pcd in pi.DynamicPcdList])
895 ##
896 ##                print " ToolPath:","\n   ","\n    ".join(["%s = %s" % (tool,pi.ToolPath[tool]) for tool in pi.ToolPath])
897 ##                print " ToolDynamicLib:","\n   ","\n    ".join(["%s = %s" % (tool,pi.ToolDynamicLib[tool]) for tool in pi.ToolDynamicLib])
898 ##                print " ToolStaticLib:","\n   ","\n    ".join(["%s = %s" % (tool,pi.ToolStaticLib[tool]) for tool in pi.ToolStaticLib])
899 ##                print " ToolChainFamily:","\n   ","\n    ".join(["%s = %s" % (tool,pi.ToolChainFamily[tool]) for tool in pi.ToolChainFamily])
900 ##                print " BuildOption:","\n   ","\n    ".join(["%s = %s" % (tool,pi.BuildOption[tool]) for tool in pi.BuildOption])
901 ##                print " DefaultToolOption:","\n   ","\n    ".join(["%s = %s" % (tool,pi.DefaultToolOption[tool]) for tool in pi.DefaultToolOption])
902
903     for mf in myBuild.ModuleDatabase:
904         #mf = "MdePkg\\Library\\BaseLib\\BaseLib.inf"
905         #if mf in myPlatform.Modules and mf in myBuild.ModuleDatabase:
906         #print mf
907         myModule = myBuild.ModuleDatabase[mf]
908         ag = AutoGen(myModule, myPlatform, myWorkspace, myBuildTarget, myToolchain, myArch)
909         ag.CreateAutoGenFile()
910         ag.CreateMakefile()
911
912         #PrintAutoGen(ag)
913 ##        for lib in ag.ModuleBuildInfo.DependentLibraryList:
914 ##            ag = AutoGen(lib, myPlatform, myWorkspace, myArch, myToolchain, myBuildTarget)
915 ##            ag.CreateAutoGenFile()
916 ##            ag.CreateMakefile()
917 ##            #PrintAutoGen(ag)
918     platformAutoGen = AutoGen(None, apf, myWorkspace, myBuildTarget, myToolchain, myWorkspace.SupArchList)
919     platformAutoGen.CreateAutoGenFile()
920     platformAutoGen.CreateMakefile()