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