From da92f27632d2c89fa8726948ac9b02461ca8b61e Mon Sep 17 00:00:00 2001
From: lgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>
Date: Wed, 11 May 2011 10:26:49 +0000
Subject: Sync BaseTools Branch (version r2149) to EDKII main trunk.

  BaseTool Branch:
  https://edk2-buildtools.svn.sourceforge.net/svnroot/edk2-buildtools/branches/Releases/BaseTools_r2100





git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11640 6f19259b-4bc3-4df7-8a09-765794883524
---
 BaseTools/Source/Python/AutoGen/AutoGen.py        | 156 +++++++++++++++++++++-
 BaseTools/Source/Python/AutoGen/GenC.py           |  44 ++++--
 BaseTools/Source/Python/AutoGen/GenMake.py        |   2 +-
 BaseTools/Source/Python/AutoGen/UniClassObject.py |  27 +++-
 4 files changed, 211 insertions(+), 18 deletions(-)

(limited to 'BaseTools/Source/Python/AutoGen')

diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index 4ecf2eafe7..8090a06bf8 100644
--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
@@ -1,7 +1,7 @@
 ## @file
 # Generate AutoGen.h, AutoGen.c and *.depex files
 #
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
 # This program and the accompanying materials
 # are licensed and made available under the terms and conditions of the BSD License
 # which accompanies this distribution.  The full text of the license may be found at
@@ -53,6 +53,39 @@ gAutoGenStringFileName = "%(module_name)sStrDefs.h"
 gAutoGenStringFormFileName = "%(module_name)sStrDefs.hpk"
 gAutoGenDepexFileName = "%(module_name)s.depex"
 
+#
+# Template string to generic AsBuilt INF
+#
+gAsBuiltInfHeaderString = TemplateString("""## @file
+# ${module_name}
+#
+# DO NOT EDIT
+# FILE auto-generated Binary INF
+#
+##
+
+[Defines]
+  INF_VERSION                = 0x00010016
+  BASE_NAME                  = ${module_name}
+  FILE_GUID                  = ${module_guid}
+  MODULE_TYPE                = ${module_module_type}
+  VERSION_STRING             = ${module_version_string}${BEGIN}
+  UEFI_SPECIFICATION_VERSION = ${module_uefi_specification_version}${END}${BEGIN}
+  PI_SPECIFICATION_VERSION   = ${module_pi_specification_version}${END}
+
+[Packages]${BEGIN}
+  ${package_item}${END}
+
+[Binaries.${module_arch}]${BEGIN}
+  ${binary_item}${END}
+
+[PcdEx]${BEGIN}
+  ${pcd_item}${END}
+
+## @AsBuilt${BEGIN}
+##   ${flags_item}${END}
+""")
+
 ## Base class for AutoGen
 #
 #   This class just implements the cache mechanism of AutoGen objects.
@@ -499,6 +532,7 @@ class PlatformAutoGen(AutoGen):
                 Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget,
                                    self.ToolChain, self.Arch, self.MetaFile)
                 Ma.CreateMakeFile(True)
+                Ma.CreateAsBuiltInf()
 
         # no need to create makefile for the platform more than once
         if self.IsMakeFileCreated:
@@ -1036,9 +1070,14 @@ class PlatformAutoGen(AutoGen):
         PlatformModule = self.Platform.Modules[str(Module)]
 
         # add forced library instances (specified under LibraryClasses sections)
-        for LibraryClass in self.Platform.LibraryClasses.GetKeys():
-            if LibraryClass.startswith("NULL"):
-                Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass]
+        #
+        # If a module has a MODULE_TYPE of USER_DEFINED,
+        # do not link in NULL library class instances from the global [LibraryClasses.*] sections.
+        #
+        if Module.ModuleType != SUP_MODULE_USER_DEFINED:
+            for LibraryClass in self.Platform.LibraryClasses.GetKeys():
+                if LibraryClass.startswith("NULL") and self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]:
+                    Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]
 
         # add forced library instances (specified in module overrides)
         for LibraryClass in PlatformModule.LibraryClasses:
@@ -1596,6 +1635,8 @@ class ModuleAutoGen(AutoGen):
 
         self.IsMakeFileCreated = False
         self.IsCodeFileCreated = False
+        self.IsAsBuiltInfCreated = False
+        self.DepexGenerated = False
 
         self.BuildDatabase = self.Workspace.BuildDatabase
 
@@ -1987,6 +2028,9 @@ class ModuleAutoGen(AutoGen):
                 CreateDirectory(Source.Dir)
 
             if File.IsBinary and File == Source and self._BinaryFileList != None and File in self._BinaryFileList:
+                # Skip all files that are not binary libraries
+                if not self.IsLibrary:
+                    continue
                 RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE]
             elif FileType in self.BuildRules:
                 RuleObject = self.BuildRules[FileType]
@@ -2214,6 +2258,107 @@ class ModuleAutoGen(AutoGen):
                         self._IncludePathList.append(str(Inc))
         return self._IncludePathList
 
+    ## Create AsBuilt INF file the module
+    #
+    def CreateAsBuiltInf(self):
+        if self.IsAsBuiltInfCreated:
+            return
+            
+        # Skip the following code for EDK I inf
+        if self.AutoGenVersion < 0x00010005:
+            return
+            
+        # Skip the following code for libraries
+        if self.IsLibrary:
+            return
+            
+        # Skip the following code for modules with no source files
+        if self.SourceFileList == None or self.SourceFileList == []:
+            return
+
+        # Skip the following code for modules without any binary files
+        if self.BinaryFileList <> None and self.BinaryFileList <> []:
+            return
+            
+        ### TODO: How to handles mixed source and binary modules
+
+        # Find all DynamicEx PCDs used by this module and dependent libraries
+        # Also find all packages that the DynamicEx PCDs depend on
+        Pcds = []
+        Packages = []        
+        for Pcd in self.ModulePcdList + self.LibraryPcdList:
+          if Pcd.Type in GenC.gDynamicExPcd:
+            if Pcd not in Pcds:
+              Pcds += [Pcd]
+            for Package in self.DerivedPackageList:
+              if Package not in Packages:
+                if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'DynamicEx') in Package.Pcds:
+                  Packages += [Package]
+                elif (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'Dynamic') in Package.Pcds:
+                  Packages += [Package]
+
+        ModuleType = self.ModuleType
+        if ModuleType == 'UEFI_DRIVER' and self.DepexGenerated:
+          ModuleType = 'DXE_DRIVER'
+
+        AsBuiltInfDict = {
+          'module_name'                       : self.Name,
+          'module_guid'                       : self.Guid,
+          'module_module_type'                : ModuleType,
+          'module_version_string'             : self.Version,
+          'module_uefi_specification_version' : [],
+          'module_pi_specification_version'   : [],
+          'module_arch'                       : self.Arch,
+          'package_item'                      : ['%s' % (Package.MetaFile.File.replace('\\','/')) for Package in Packages],
+          'binary_item'                       : [],
+          'pcd_item'                          : [],
+          'flags_item'                        : []
+        }
+
+        if 'UEFI_SPECIFICATION_VERSION' in self.Specification:
+          AsBuiltInfDict['module_uefi_specification_version'] += [self.Specification['UEFI_SPECIFICATION_VERSION']]
+        if 'PI_SPECIFICATION_VERSION' in self.Specification:
+          AsBuiltInfDict['module_pi_specification_version'] += [self.Specification['PI_SPECIFICATION_VERSION']]
+
+        OutputDir = self.OutputDir.replace('\\','/').strip('/')
+        if self.ModuleType in ['BASE', 'USER_DEFINED']:
+          for Item in self.CodaTargetList:
+            File = Item.Target.Path.replace('\\','/').strip('/').replace(OutputDir,'').strip('/')
+            if Item.Target.Ext.lower() == '.aml': 
+              AsBuiltInfDict['binary_item'] += ['ASL|' + File]
+            elif Item.Target.Ext.lower() == '.acpi': 
+              AsBuiltInfDict['binary_item'] += ['ACPI|' + File]
+            else:
+              AsBuiltInfDict['binary_item'] += ['BIN|' + File]
+        else:
+          for Item in self.CodaTargetList:
+            File = Item.Target.Path.replace('\\','/').strip('/').replace(OutputDir,'').strip('/')
+            if Item.Target.Ext.lower() == '.efi': 
+              AsBuiltInfDict['binary_item'] += ['PE32|' + self.Name + '.efi']
+            else:
+              AsBuiltInfDict['binary_item'] += ['BIN|' + File]
+          if self.DepexGenerated:
+            if self.ModuleType in ['PEIM']:
+              AsBuiltInfDict['binary_item'] += ['PEI_DEPEX|' + self.Name + '.depex']
+            if self.ModuleType in ['DXE_DRIVER','DXE_RUNTIME_DRIVER','DXE_SAL_DRIVER','UEFI_DRIVER']:
+              AsBuiltInfDict['binary_item'] += ['DXE_DEPEX|' + self.Name + '.depex']
+            if self.ModuleType in ['DXE_SMM_DRIVER']:
+              AsBuiltInfDict['binary_item'] += ['SMM_DEPEX|' + self.Name + '.depex']
+
+        for Pcd in Pcds:
+          AsBuiltInfDict['pcd_item'] += [Pcd.TokenSpaceGuidCName + '.' + Pcd.TokenCName]
+         
+        for Item in self.BuildOption:
+          if 'FLAGS' in self.BuildOption[Item]:
+            AsBuiltInfDict['flags_item'] += ['%s:%s_%s_%s_%s_FLAGS = %s' % (self.ToolChainFamily, self.BuildTarget, self.ToolChain, self.Arch, Item, self.BuildOption[Item]['FLAGS'].strip())]
+        
+        AsBuiltInf = TemplateString()
+        AsBuiltInf.Append(gAsBuiltInfHeaderString.Replace(AsBuiltInfDict))
+        
+        SaveFileOnChange(os.path.join(self.OutputDir, self.Name + '.inf'), str(AsBuiltInf), False)
+        
+        self.IsAsBuiltInfCreated = True
+        
     ## Create makefile for the module and its dependent libraries
     #
     #   @param      CreateLibraryMakeFile   Flag indicating if or not the makefiles of
@@ -2278,6 +2423,9 @@ class ModuleAutoGen(AutoGen):
             Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True)
             DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}
 
+            if len(Dpx.PostfixNotation) <> 0:
+              self.DepexGenerated = True
+
             if Dpx.Generate(path.join(self.OutputDir, DpxFile)):
                 AutoGenList.append(str(DpxFile))
             else:
diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py
index 3c256c8b74..e6e8847623 100644
--- a/BaseTools/Source/Python/AutoGen/GenC.py
+++ b/BaseTools/Source/Python/AutoGen/GenC.py
@@ -1,7 +1,7 @@
 ## @file
 # Routines for generating AutoGen.h and AutoGen.c
 #
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
 # This program and the accompanying materials
 # are licensed and made available under the terms and conditions of the BSD License
 # which accompanies this distribution.  The full text of the license may be found at
@@ -1098,6 +1098,10 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
                         ExtraData="[%s]" % str(Info))
     TokenNumber = PcdTokenNumber[TokenCName, TokenSpaceGuidCName]
 
+    # If PCD is DynamicEx, then use TokenNumber declared in DEC file
+    if Pcd.Type in gDynamicExPcd:
+        TokenNumber = int(Pcd.TokenValue, 0)
+
     if Pcd.Type not in gItemTypeStringDatabase:
         EdkLogger.error("build", AUTOGEN_ERROR,
                         "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
@@ -1677,11 +1681,11 @@ def CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH):
     if 'PI_SPECIFICATION_VERSION' in Info.Module.Specification:
         PiSpecVersion = Info.Module.Specification['PI_SPECIFICATION_VERSION']
     else:
-        PiSpecVersion = 0
+        PiSpecVersion = '0x00000000'
     if 'UEFI_SPECIFICATION_VERSION' in Info.Module.Specification:
         UefiSpecVersion = Info.Module.Specification['UEFI_SPECIFICATION_VERSION']
     else:
-        UefiSpecVersion = 0
+        UefiSpecVersion = '0x00000000'
     Dict = {
         'Function'       :   Info.Module.ModuleEntryPointList,
         'PiSpecVersion'  :   PiSpecVersion,
@@ -1689,14 +1693,15 @@ def CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH):
     }
 
     if Info.ModuleType in ['PEI_CORE', 'DXE_CORE', 'SMM_CORE']:
-        if NumEntryPoints != 1:
-            EdkLogger.error(
-                "build",
-                AUTOGEN_ERROR,
-                '%s must have exactly one entry point' % Info.ModuleType,
-                File=str(Info),
-                ExtraData= ", ".join(Info.Module.ModuleEntryPointList)
-                )
+        if Info.SourceFileList <> None and Info.SourceFileList <> []:
+          if NumEntryPoints != 1:
+              EdkLogger.error(
+                  "build",
+                  AUTOGEN_ERROR,
+                  '%s must have exactly one entry point' % Info.ModuleType,
+                  File=str(Info),
+                  ExtraData= ", ".join(Info.Module.ModuleEntryPointList)
+                  )
     if Info.ModuleType == 'PEI_CORE':
         AutoGenC.Append(gPeiCoreEntryPointString.Replace(Dict))
         AutoGenH.Append(gPeiCoreEntryPointPrototype.Replace(Dict))
@@ -1827,6 +1832,23 @@ def CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH):
 #   @param      AutoGenH    The TemplateString object for header file
 #
 def CreatePcdCode(Info, AutoGenC, AutoGenH):
+
+    # Collect Token Space GUIDs used by DynamicEc PCDs
+    TokenSpaceList = []
+    for Pcd in Info.ModulePcdList:
+       if Pcd.Type in gDynamicExPcd and Pcd.TokenSpaceGuidCName not in TokenSpaceList:
+            TokenSpaceList += [Pcd.TokenSpaceGuidCName]
+            
+    # Add extern declarations to AutoGen.h if one or more Token Space GUIDs were found
+    if TokenSpaceList <> []:            
+        AutoGenH.Append("\n// Definition of PCD Token Space GUIDs used in this module\n\n")
+        if Info.ModuleType in ["USER_DEFINED", "BASE"]:
+            GuidType = "GUID"
+        else:
+            GuidType = "EFI_GUID"              
+        for Item in TokenSpaceList:
+            AutoGenH.Append('extern %s %s;\n' % (GuidType, Item))
+
     if Info.IsLibrary:
         if Info.ModulePcdList:
             AutoGenH.Append("\n// PCD definitions\n")
diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py
index 49ac33f47f..6396c612ad 100644
--- a/BaseTools/Source/Python/AutoGen/GenMake.py
+++ b/BaseTools/Source/Python/AutoGen/GenMake.py
@@ -493,7 +493,7 @@ cleanlib:
 
         # convert source files and binary files to build targets
         self.ResultFileList = [str(T.Target) for T in self._AutoGenObject.CodaTargetList]
-        if len(self.ResultFileList) == 0:
+        if len(self.ResultFileList) == 0 and len(self._AutoGenObject.SourceFileList) <> 0:
             EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",
                             ExtraData="[%s]" % str(self._AutoGenObject))
 
diff --git a/BaseTools/Source/Python/AutoGen/UniClassObject.py b/BaseTools/Source/Python/AutoGen/UniClassObject.py
index 1eb65c1e9a..1825c81d91 100644
--- a/BaseTools/Source/Python/AutoGen/UniClassObject.py
+++ b/BaseTools/Source/Python/AutoGen/UniClassObject.py
@@ -121,7 +121,7 @@ def GetLanguageCode(LangName, IsCompatibleMode, File):
         if length == 3 and LangName.isalpha():
             TempLangName = LangConvTable.get(LangName.lower())
             if TempLangName != None:
-               return TempLangName
+                return TempLangName
             return LangName
         else:
             EdkLogger.error("Unicode File Parser", FORMAT_INVALID, "Invalid ISO 639-2 language code : %s" % LangName, File)
@@ -298,13 +298,36 @@ class UniFileClassObject(object):
         #
         # Use unique identifier
         #
+        FindFlag = -1
+        LineCount = 0
         for Line in FileIn:
+            Line = FileIn[LineCount]
+            LineCount += 1
             Line = Line.strip()
             #
             # Ignore comment line and empty line
             #
             if Line == u'' or Line.startswith(u'//'):
                 continue
+            
+            #
+            # Process comment embeded in string define lines
+            #
+            FindFlag = Line.find(u'//')
+            if FindFlag != -1:
+                Line = Line.replace(Line[FindFlag:], u' ')
+                if FileIn[LineCount].strip().startswith('#language'):
+                    Line = Line + FileIn[LineCount]
+                    FileIn[LineCount-1] = Line
+                    FileIn[LineCount] = os.linesep
+                    LineCount -= 1
+                    for Index in xrange (LineCount + 1, len (FileIn) - 1):
+                        if (Index == len(FileIn) -1):
+                            FileIn[Index] = os.linesep
+                        else:
+                            FileIn[Index] = FileIn[Index + 1]
+                    continue
+                              
             Line = Line.replace(u'/langdef', u'#langdef')
             Line = Line.replace(u'/string', u'#string')
             Line = Line.replace(u'/language', u'#language')
@@ -566,6 +589,6 @@ class UniFileClassObject(object):
 if __name__ == '__main__':
     EdkLogger.Initialize()
     EdkLogger.SetLevel(EdkLogger.DEBUG_0)
-    a = UniFileClassObject(['C:\\Edk\\Strings.uni', 'C:\\Edk\\Strings2.uni'])
+    a = UniFileClassObject([PathClass("C:\\Edk\\Strings.uni"), PathClass("C:\\Edk\\Strings2.uni")])
     a.ReToken()
     a.ShowMe()
-- 
cgit v1.2.3