]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java
Remove static from SurfaceAreaQuery.java for preparing parallel build.(1)
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / global / GlobalData.java
index 97096f6b4f32b156907f70fa359e50c169bd416a..7e1e2c68523d31f9e0b2f94c340473a6aa42329e 100644 (file)
@@ -1,10 +1,10 @@
 /** @file\r
 /** @file\r
-  GlobalData class. \r
-  \r
+  GlobalData class.\r
+\r
   GlobalData provide initializing, instoring, querying and update global data.\r
   It is a bridge to intercommunicate between multiple component, such as AutoGen,\r
   GlobalData provide initializing, instoring, querying and update global data.\r
   It is a bridge to intercommunicate between multiple component, such as AutoGen,\r
-  PCD and so on.   \r
\r
+  PCD and so on.\r
+\r
 Copyright (c) 2006, Intel Corporation\r
 All rights reserved. This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 Copyright (c) 2006, Intel Corporation\r
 All rights reserved. This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
@@ -17,7 +17,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 package org.tianocore.build.global;\r
 \r
 import java.io.File;\r
 package org.tianocore.build.global;\r
 \r
 import java.io.File;\r
-import java.util.ArrayList;\r
 import java.util.HashMap;\r
 import java.util.HashSet;\r
 import java.util.Iterator;\r
 import java.util.HashMap;\r
 import java.util.HashSet;\r
 import java.util.Iterator;\r
@@ -27,632 +26,810 @@ import java.util.Set;
 \r
 import org.apache.tools.ant.BuildException;\r
 import org.apache.xmlbeans.XmlObject;\r
 \r
 import org.apache.tools.ant.BuildException;\r
 import org.apache.xmlbeans.XmlObject;\r
-import org.tianocore.FilenameDocument;\r
-import org.tianocore.FilenameDocument.Filename;\r
+\r
+import org.tianocore.common.exception.EdkException;\r
+import org.tianocore.common.logger.EdkLog;\r
+import org.tianocore.pcd.entity.MemoryDatabaseManager;\r
+import org.tianocore.DbPathAndFilename;\r
 import org.tianocore.FrameworkDatabaseDocument;\r
 import org.tianocore.FrameworkDatabaseDocument;\r
-import org.tianocore.MsaFilesDocument;\r
-import org.tianocore.MsaFilesDocument.MsaFiles.MsaFile;\r
-import org.tianocore.MsaHeaderDocument.MsaHeader;\r
-import org.tianocore.MsaLibHeaderDocument.MsaLibHeader;\r
-import org.tianocore.PackageListDocument;\r
-import org.tianocore.PackageSurfaceAreaDocument;\r
-import org.tianocore.build.autogen.CommonDefinition;\r
-import org.tianocore.build.fpd.FpdParserTask;\r
-import org.tianocore.build.pcd.entity.MemoryDatabaseManager;\r
+import org.tianocore.ModuleSurfaceAreaDocument;\r
+import org.tianocore.ModuleSurfaceAreaDocument.ModuleSurfaceArea;\r
+import org.tianocore.build.id.FpdModuleIdentification;\r
+import org.tianocore.build.id.ModuleIdentification;\r
+import org.tianocore.build.id.PackageIdentification;\r
+import org.tianocore.build.id.PlatformIdentification;\r
+import org.tianocore.build.toolchain.ToolChainAttribute;\r
+import org.tianocore.build.toolchain.ToolChainConfig;\r
+import org.tianocore.build.toolchain.ToolChainElement;\r
+import org.tianocore.build.toolchain.ToolChainInfo;\r
+import org.tianocore.build.toolchain.ToolChainKey;\r
+import org.tianocore.build.toolchain.ToolChainMap;\r
 \r
 /**\r
   GlobalData provide initializing, instoring, querying and update global data.\r
   It is a bridge to intercommunicate between multiple component, such as AutoGen,\r
 \r
 /**\r
   GlobalData provide initializing, instoring, querying and update global data.\r
   It is a bridge to intercommunicate between multiple component, such as AutoGen,\r
-  PCD and so on. \r
-  \r
-  <p>Note that all global information are initialized incrementally. All data will \r
-  parse and record only it is necessary during build time. </p>\r
-  \r
+  PCD and so on.\r
+\r
+  <p>Note that all global information are initialized incrementally. All data will\r
+  parse and record only of necessary during build time. </p>\r
+\r
   @since GenBuild 1.0\r
 **/\r
 public class GlobalData {\r
   @since GenBuild 1.0\r
 **/\r
 public class GlobalData {\r
-\r
     ///\r
     ///\r
-    /// means no surface area information for module\r
-    ///\r
-    public static final int NO_SA = 0;\r
-\r
-    ///\r
-    /// means only MSA\r
-    ///\r
-    public static final int ONLY_MSA = 1;\r
-\r
-    ///\r
-    /// means only Library MSA\r
-    ///\r
-    public static final int ONLY_LIBMSA = 2;\r
-\r
-    ///\r
-    /// means both MSA and MBD\r
-    ///\r
-    public static final int MSA_AND_MBD = 3;\r
-\r
-    ///\r
-    /// means both Library MSA and Library MBD\r
+    /// Record current WORKSPACE Directory\r
     ///\r
     ///\r
-    public static final int LIBMSA_AND_LIBMBD = 4;\r
+    private static String workspaceDir = "";\r
 \r
     ///\r
     /// Be used to ensure Global data will be initialized only once.\r
     ///\r
 \r
     ///\r
     /// Be used to ensure Global data will be initialized only once.\r
     ///\r
-    public static boolean globalFlag = false;\r
+    private static boolean globalFlag = false;\r
 \r
     ///\r
 \r
     ///\r
-    /// Record current WORKSPACE Directory\r
+    /// Framework Database information: package list and platform list\r
     ///\r
     ///\r
-    private static String workspaceDir = "";\r
+    private static Set<PackageIdentification> packageList = new HashSet<PackageIdentification>();\r
 \r
 \r
-    ///\r
-    /// Two columns: Package Name (Key), Package Path(ralative to WORKSPACE)\r
-    ///\r
-    private static final Map<String, String> packageInfo = new HashMap<String, String>();\r
+    private static Set<PlatformIdentification> platformList = new HashSet<PlatformIdentification>();\r
 \r
     ///\r
 \r
     ///\r
-    /// spdTable\r
-    /// Key: Package Name, Value: SPD detail info\r
+    /// Every detail SPD informations: Module list, Library class definition,\r
+    ///   Package header file, GUID/PPI/Protocol definitions\r
     ///\r
     ///\r
-    private static final Map<String, Spd> spdTable = new HashMap<String, Spd>();\r
+    private static final Map<PackageIdentification, Spd> spdTable = new HashMap<PackageIdentification, Spd>();\r
 \r
     ///\r
 \r
     ///\r
-    /// Three columns:\r
-    /// 1. Module Name | BaseName (Key)\r
-    /// 2. Module Path + Msa file name (relative to Package)\r
-    /// 3. Package Name (This module belong to which package)\r
+    /// Build informations are divided into three parts:\r
+    /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA\r
     ///\r
     ///\r
-    private static final Map<String, String[]> moduleInfo = new HashMap<String, String[]>();\r
+    private static Map<ModuleIdentification, Map<String, XmlObject>> nativeMsa = new HashMap<ModuleIdentification, Map<String, XmlObject>>();\r
 \r
 \r
-    ///\r
-    /// List all libraries for current build module\r
-    /// Key: Library BaseName, Value: output library path+name\r
-    ///\r
-    private static final Map<String, String> libraries = new HashMap<String, String>();\r
+    private static Map<FpdModuleIdentification, Map<String, XmlObject>> fpdModuleSA= new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();\r
 \r
 \r
-    ///\r
-    /// Store every module's relative library instances BaseName\r
-    /// Key: Module BaseName, Value: All library instances module depends on.\r
-    ///\r
-    private static final Map<String, Set<String> > moduleLibraryMap = new HashMap<String, Set<String> >();\r
+    private static XmlObject fpdBuildOptions;\r
 \r
 \r
-    ///\r
-    /// Key: Module BaseName, Value: original MSA info\r
-    ///\r
-    private static final Map<String, Map<String, XmlObject> > nativeMsa = new HashMap<String, Map<String, XmlObject> >();\r
+    private static XmlObject fpdDynamicPcds;\r
 \r
     ///\r
 \r
     ///\r
-    /// Key: Module BaseName, Value: original MBD info\r
+    /// Parsed modules list\r
     ///\r
     ///\r
-    private static final Map<String, Map<String, XmlObject> > nativeMbd = new HashMap<String, Map<String, XmlObject> >();\r
+    private static Map<FpdModuleIdentification, Map<String, XmlObject>> parsedModules = new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();\r
 \r
     ///\r
 \r
     ///\r
-    /// Two columns: Module Name or Base Name as Key\r
-    /// Value is a HashMap with overridden data from MSA/MBD or/and Platform\r
+    /// built modules list with ARCH, TARGET, TOOLCHAIN\r
     ///\r
     ///\r
-    private static final Map<String, Map<String, XmlObject> > parsedModules = new HashMap<String, Map<String, XmlObject> >();\r
+    private static Set<FpdModuleIdentification> builtModules = new HashSet<FpdModuleIdentification>();\r
 \r
     ///\r
 \r
     ///\r
-    /// List all built Module; Value is Module BaseName + Arch. TBD\r
+    /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.\r
     ///\r
     ///\r
-    private static final Set<String> builtModules = new HashSet<String>();\r
+    private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();\r
 \r
     ///\r
 \r
     ///\r
-    /// Library instance information table which recored the library and it's\r
-    /// constructor and distructor function\r
+    /// build target + tool chain family/tag name + arch + command types + command options\r
     ///\r
     ///\r
-    private static final Map<String, String[]> libInstanceInfo = new HashMap<String, String[]>();\r
-\r
     ///\r
     ///\r
-    /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.\r
+    /// Tool Chain Data\r
+    /// toolsDef - build tool program information\r
+    /// fpdBuildOption - all modules's build options for tool tag or tool chain families\r
+    /// moduleSaBuildOption - build options for a specific module\r
     ///\r
     ///\r
-    private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();\r
+    private static ToolChainConfig toolsDef;\r
 \r
 \r
-    /**\r
-      Query the module's absolute path with module base name. \r
-      \r
-      @param moduleName the base name of the module\r
-      @return the absolute module path\r
-    **/\r
-    public synchronized static String getModulePath(String moduleName) {\r
-        String[] info = moduleInfo.get(moduleName);\r
-        String packagePath = (String) packageInfo.get(info[1]);\r
-        File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);\r
-        return convertFile.getParent();\r
-    }\r
+    private static ToolChainInfo toolChainInfo;\r
+    private static ToolChainInfo toolChainEnvInfo;\r
+    private static ToolChainInfo toolChainPlatformInfo;\r
 \r
 \r
-    /**\r
-      Query the module's absolute MSA file path with module base name. \r
-    \r
-      @param moduleName the base name of the module\r
-      @return the absolute MSA file name\r
-      @throws BuildException\r
-              Base name is not registered in any SPD files\r
-    **/\r
-    private synchronized static String getMsaFilename(String moduleName) throws BuildException {\r
-        String[] info = moduleInfo.get(moduleName);\r
-        if (info == null) {\r
-            throw new BuildException("Module base name [" + moduleName + "] can't found in all SPD.");\r
-        }\r
-        String packagePath = (String) packageInfo.get(info[1]);\r
-        File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);\r
-        return convertFile.getPath();\r
-    }\r
-\r
-    /**\r
-      Query the module's absolute MBD file path with module base name. \r
-    \r
-      @param moduleName the base name of the module\r
-      @return the absolute MBD file name\r
-      @throws BuildException\r
-              Base name is not registered in any SPD files\r
-    **/\r
-    private synchronized static String getMbdFilename(String moduleName) throws BuildException {\r
-        String[] info = moduleInfo.get(moduleName);\r
-        if (info == null) {\r
-            throw new BuildException("Info: Module base name [" + moduleName + "] can't found in all SPD.");\r
-        }\r
-        String packagePath = (String) packageInfo.get(info[1]);\r
-        File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);\r
-        return convertFile.getPath().substring(0, convertFile.getPath().length() - 4) + ".mbd";\r
-    }\r
-\r
-    /**\r
-      Get the current WORKSPACE Directory. \r
-      @return current workspace directory\r
-    **/\r
-    public synchronized static String getWorkspacePath() {\r
-        return workspaceDir;\r
-    }\r
-\r
-    /**\r
-      Query package relative path to WORKSPACE_DIR with package name. \r
-      \r
-      @param packageName the name of the package\r
-      @return the path relative to WORKSPACE_DIR \r
-    **/\r
-    public synchronized static String getPackagePath(String packageName) {\r
-        return (String) packageInfo.get(packageName);\r
-    }\r
-\r
-    /**\r
-      Query package (which the module belongs to) relative path to WORSPACE_DIR.  \r
-    \r
-      @param moduleName the base name of the module\r
-      @return the relative path to WORKSPACE_DIR of the package which the module belongs to\r
-    **/\r
-    public synchronized static String getPackagePathForModule(String moduleName) {\r
-        String[] info = moduleInfo.get(moduleName);\r
-        String packagePath = (String) packageInfo.get(info[1]);\r
-        return packagePath;\r
-    }\r
+    private static ToolChainMap platformToolChainOption;\r
+    private static ToolChainMap platformToolChainFamilyOption;\r
 \r
 \r
-    /**\r
-      Query the package name which the module belongs to with the module's base name.\r
-    \r
-      @param moduleName the base name of the module\r
-      @return the package name which the module belongs to\r
-    **/\r
-    public synchronized static String getPackageNameForModule(String moduleName) {\r
-        return moduleInfo.get(moduleName)[1];\r
-    }\r
+    private static Map<FpdModuleIdentification, ToolChainMap> moduleToolChainOption = new HashMap<FpdModuleIdentification, ToolChainMap>();\r
+    private static Map<FpdModuleIdentification, ToolChainMap> moduleToolChainFamilyOption = new HashMap<FpdModuleIdentification, ToolChainMap>();\r
 \r
     /**\r
       Parse framework database (DB) and all SPD files listed in DB to initialize\r
       the environment for next build. This method will only be executed only once\r
 \r
     /**\r
       Parse framework database (DB) and all SPD files listed in DB to initialize\r
       the environment for next build. This method will only be executed only once\r
-      in the whole build process.  \r
-      \r
+      in the whole build process.\r
+\r
       @param workspaceDatabaseFile the file name of framework database\r
       @param workspaceDir current workspace directory path\r
       @throws BuildException\r
       @param workspaceDatabaseFile the file name of framework database\r
       @param workspaceDir current workspace directory path\r
       @throws BuildException\r
-              Framework Dababase or SPD or MSA file is not valid\r
+            Framework Dababase or SPD or MSA file is not valid\r
     **/\r
     **/\r
-    public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir) throws BuildException {\r
+    public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir, String toolsDefFilename ) throws BuildException {\r
+        //\r
+        // ensure this method will be revoked only once\r
+        //\r
         if (globalFlag) {\r
             return;\r
         }\r
         globalFlag = true;\r
         if (globalFlag) {\r
             return;\r
         }\r
         globalFlag = true;\r
-        GlobalData.workspaceDir = workspaceDir;\r
-        File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);\r
-        try {\r
-            FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);\r
-            List<PackageListDocument.PackageList.Package> packages = db.getFrameworkDatabase().getPackageList()\r
-                                                                       .getPackageList();\r
-            Iterator iter = packages.iterator();\r
-            while (iter.hasNext()) {\r
-                PackageListDocument.PackageList.Package packageItem = (PackageListDocument.PackageList.Package) iter\r
-                                                                                                                    .next();\r
-                String name = packageItem.getPackageNameArray(0).getStringValue();\r
-                String path = packageItem.getPathArray(0).getStringValue();\r
-                packageInfo.put(name, path);\r
-                File spdFile = new File(workspaceDir + File.separatorChar + path + File.separatorChar + name + ".spd");\r
-                initPackageInfo(spdFile.getPath(), name);\r
-                // \r
-                // SPD Parse.\r
-                //\r
-                PackageSurfaceAreaDocument spdDoc = (PackageSurfaceAreaDocument) XmlObject.Factory.parse(spdFile);\r
-                Spd spd = new Spd(spdDoc, path);\r
-                spdTable.put(name, spd);\r
 \r
 \r
-            }\r
+               //\r
+        // Backup workspace directory. It will be used by other method\r
+        //\r
+        GlobalData.workspaceDir = workspaceDir.replaceAll("(\\\\)", "/");\r
+\r
+        //\r
+        // Parse tools definition file\r
+        //\r
+        //\r
+        // If ToolChain has been set up before, do nothing.\r
+        // CONF dir + tools definition file name\r
+        //\r
+        File toolsDefFile = new File(workspaceDir + File.separatorChar + toolsDefFilename);\r
+        System.out.println("Using tool definiton file [" + toolsDefFile.getPath() + "].");\r
+        try {\r
+            toolsDef = new ToolChainConfig(toolsDefFile);\r
         } catch (Exception e) {\r
         } catch (Exception e) {\r
-            throw new BuildException("Parse workspace Database [" + dbFile.getPath() + "] Error.\n" + e.getMessage());\r
+            throw new BuildException(e.getMessage());\r
         }\r
         }\r
-    }\r
 \r
 \r
-    /**\r
-      Parse every MSA files, get base name from MSA Header. And record those\r
-      values to ModuleInfo.\r
-      \r
-      @param packageFilename the file name of the package\r
-      @param packageName the name of the package\r
-      @throws BuildException\r
-              SPD or MSA file is not valid\r
-    **/\r
-    private synchronized static void initPackageInfo(String packageFilename, String packageName) throws BuildException {\r
-        File packageFile = new File(packageFilename);\r
+        //\r
+        // Parse Framework Database\r
+        //\r
+        File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);\r
         try {\r
         try {\r
-            PackageSurfaceAreaDocument spd = (PackageSurfaceAreaDocument) XmlObject.Factory.parse(packageFile);\r
-            List<String> msaFilenameList;\r
-\r
-            List<MsaFilesDocument.MsaFiles.MsaFile> msasList = spd.getPackageSurfaceArea().getMsaFiles()\r
-                                                                  .getMsaFileList();\r
-            if (msasList.size() == 0) {\r
-                msaFilenameList = spd.getPackageSurfaceArea().getMsaFiles().getFilenameList();\r
-            } else {\r
-                msaFilenameList = new ArrayList<String>(msasList.size());\r
-                Iterator msasIter = msasList.iterator();\r
-                while (msasIter.hasNext()) {\r
-                    MsaFilesDocument.MsaFiles.MsaFile msaFile = (MsaFilesDocument.MsaFiles.MsaFile)msasIter.next();\r
-                    msaFilenameList.add(msaFile.getFilename().getStringValue());\r
+            FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);\r
+            //\r
+            // validate FrameworkDatabaseFile\r
+            //\r
+            if (!db.validate()) {\r
+                throw new BuildException("Framework Database file [" + dbFile.getPath() + "] format is invalid!");\r
+            }\r
+            //\r
+            // Get package list\r
+            //\r
+            if (db.getFrameworkDatabase().getPackageList() != null ) {\r
+                List<DbPathAndFilename> packages = db.getFrameworkDatabase().getPackageList().getFilenameList();\r
+                Iterator<DbPathAndFilename> iter = packages.iterator();\r
+                while (iter.hasNext()) {\r
+                    String fileName = iter.next().getStringValue().trim();\r
+                    Spd spd = new Spd(new File(workspaceDir + File.separatorChar + fileName));\r
+                    packageList.add(spd.getPackageId());\r
+                    spdTable.put(spd.getPackageId(), spd);\r
                 }\r
             }\r
 \r
                 }\r
             }\r
 \r
-            Iterator msaFilenameIter = msaFilenameList.iterator();\r
-            while (msaFilenameIter.hasNext()) {\r
-                String filename = (String)msaFilenameIter.next();\r
-                File msaFile = new File(workspaceDir + File.separatorChar + GlobalData.getPackagePath(packageName)\r
-                                        + File.separatorChar + filename);\r
-                SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();\r
-                Map<String, XmlObject> map = surfaceAreaParser.parseFile(msaFile);\r
-                String baseName = "";\r
-                XmlObject header = null;\r
-                if ((header = map.get("MsaHeader")) != null) {\r
-                    if (((MsaHeader) header).isSetBaseName()) {\r
-                        baseName = ((MsaHeader) header).getBaseName().getStringValue();\r
-                    } else {\r
-                        baseName = ((MsaHeader) header).getModuleName();\r
+            //\r
+            // Get platform list\r
+            //\r
+            if (db.getFrameworkDatabase().getPlatformList() != null) {\r
+                List<DbPathAndFilename> platforms = db.getFrameworkDatabase().getPlatformList().getFilenameList();\r
+                Iterator<DbPathAndFilename> iter = platforms.iterator();\r
+                while (iter.hasNext()) {\r
+                    String fileName = iter.next().getStringValue().trim();\r
+                    File fpdFile = new File(workspaceDir + File.separatorChar + fileName);\r
+                    if ( !fpdFile.exists() ) {\r
+                        throw new BuildException("Platform file [" + fpdFile.getPath() + "] not exists. ");\r
+                    }\r
+                    XmlObject fpdDoc = XmlObject.Factory.parse(fpdFile);\r
+                    //\r
+                    // Verify FPD file, if is invalid, throw Exception\r
+                    //\r
+                    if (!fpdDoc.validate()) {\r
+                        throw new BuildException("Framework Platform Surface Area file [" + fpdFile.getPath() + "] format is invalid!");\r
                     }\r
                     }\r
-                } else if ((header = map.get("MsaLibHeader")) != null) {\r
-                    baseName = ((MsaLibHeader) header).getBaseName().getStringValue();\r
-                } else {\r
-                    continue;\r
+                    //\r
+                    // We can change Map to XmlObject\r
+                    //\r
+                    //\r
+                    // TBD check SPD or FPD is existed in FS\r
+                    //\r
+                    Map<String, XmlObject> fpdDocMap = new HashMap<String, XmlObject>();\r
+                    fpdDocMap.put("PlatformSurfaceArea", fpdDoc);\r
+                    SurfaceAreaQuery saq = new SurfaceAreaQuery(fpdDocMap);\r
+                    PlatformIdentification platformId = saq.getFpdHeader();\r
+                    platformId.setFpdFile(fpdFile);\r
+                    platformList.add(platformId);\r
                 }\r
                 }\r
-                nativeMsa.put(baseName, map);\r
-                String[] info = { filename, packageName };\r
-                moduleInfo.put(baseName, info);\r
             }\r
         } catch (Exception e) {\r
             }\r
         } catch (Exception e) {\r
-            throw new BuildException("Parse package description file [" + packageFile.getPath() + "] Error.\n"\r
-                                     + e.getMessage());\r
+            throw new BuildException("Parse WORKSPACE Database file [" + dbFile.getPath() + "] Error.\n" + e.getMessage());\r
         }\r
     }\r
 \r
     /**\r
         }\r
     }\r
 \r
     /**\r
-      Query the libraries which the module depends on.\r
-    \r
-      @param moduleName the base name of the module\r
-      @return the libraries which the module depends on\r
+      Get the current WORKSPACE Directory.\r
+\r
+      @return current workspace directory\r
     **/\r
     **/\r
-    public synchronized static String[] getModuleLibrary(String moduleName, String arch) {\r
-        Set<String> set = moduleLibraryMap.get(moduleName + "-" + arch);\r
-        return set.toArray(new String[set.size()]);\r
+    public synchronized static String getWorkspacePath() {\r
+        return workspaceDir;\r
     }\r
 \r
     }\r
 \r
+\r
     /**\r
     /**\r
-      Register module's library list which it depends on for later use. \r
-      \r
-      @param moduleName the base name of the module\r
-      @param libraryList the libraries which the module depends on\r
-    **/\r
-    public synchronized static void addModuleLibrary(String moduleName, String arch, Set<String> libraryList) {\r
-        moduleLibraryMap.put(moduleName + "-" + arch, libraryList);\r
+      Get the MSA file name with absolute path\r
+     */\r
+    public synchronized static File getMsaFile(ModuleIdentification moduleId) throws BuildException {\r
+        File msaFile = null;\r
+        //\r
+        // TBD. Do only when package is null.\r
+        //\r
+        Iterator iter = packageList.iterator();\r
+        while (iter.hasNext()) {\r
+            PackageIdentification packageId = (PackageIdentification)iter.next();\r
+            Spd spd = spdTable.get(packageId);\r
+            msaFile = spd.getModuleFile(moduleId);\r
+            if (msaFile != null ) {\r
+                break ;\r
+            }\r
+        }\r
+        if (msaFile == null){\r
+            throw new BuildException("Can't find Module [" + moduleId.getName() + "] in any SPD package!");\r
+        } else {\r
+            return msaFile;\r
+        }\r
     }\r
 \r
     }\r
 \r
-    /**\r
-      Query the library absolute file name with library name. \r
-      \r
-      @param library the base name of the library\r
-      @return the library absolute file name\r
-    **/\r
-    public synchronized static String getLibrary(String library, String arch) {\r
-        return libraries.get(library + "-" + arch);\r
+    public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) {\r
+        //\r
+        // If package already defined in module\r
+        //\r
+        if (moduleId.getPackage() != null) {\r
+            return moduleId.getPackage();\r
+        }\r
+\r
+        PackageIdentification packageId = null;\r
+        Iterator iter = packageList.iterator();\r
+        while (iter.hasNext()) {\r
+            packageId = (PackageIdentification)iter.next();\r
+            moduleId.setPackage(packageId);\r
+            Spd spd = spdTable.get(packageId);\r
+            if (spd.getModuleFile(moduleId) != null ) {\r
+                break ;\r
+            }\r
+        }\r
+        if (packageId == null){\r
+            throw new BuildException("Can't find Module [" + moduleId.getName() + "] in any SPD package!");\r
+        } else {\r
+            return packageId;\r
+        }\r
     }\r
 \r
     /**\r
     }\r
 \r
     /**\r
-      Register library absolute file name for later use.\r
-      \r
-      @param library the base name of the library\r
-      @param resultPath the library absolute file name\r
+      Difference between build and parse: ToolChain and Target\r
     **/\r
     **/\r
-    public synchronized static void addLibrary(String library, String arch, String resultPath) {\r
-        libraries.put(library + "-" + arch, resultPath);\r
+    public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) {\r
+        return builtModules.contains(moduleId);\r
     }\r
 \r
     }\r
 \r
-    /**\r
-      Whether the module with ARCH has built in the previous build. \r
-      \r
-      @param moduleName the base name of the module\r
-      @param arch current build ARCH\r
-      @return true if the module has built in previous, otherwise return false\r
-    **/\r
-    public synchronized static boolean isModuleBuilt(String moduleName, String arch) {\r
-        return builtModules.contains(moduleName + "-" + arch);\r
+    public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) {\r
+        builtModules.add(fpdModuleId);\r
     }\r
 \r
     }\r
 \r
-    /**\r
-      Register the module with ARCH has built. \r
-    \r
-      @param moduleName the base name of the module\r
-      @param arch current build ARCH\r
-    **/\r
-    public synchronized static void registerBuiltModule(String moduleName, String arch) {\r
-        builtModules.add(moduleName + "-" + arch);\r
+\r
+    public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map<String, XmlObject> doc) {\r
+        Map<String, XmlObject> result = new HashMap<String, XmlObject>();\r
+        Set keySet = doc.keySet();\r
+        Iterator iter = keySet.iterator();\r
+        while (iter.hasNext()){\r
+            String key = (String)iter.next();\r
+            XmlObject item = cloneXmlObject(doc.get(key), true);\r
+            result.put(key, item);\r
+        }\r
+        fpdModuleSA.put(fpdModuleId, result);\r
     }\r
 \r
     }\r
 \r
-    /**\r
-      Whether the module's surface area has parsed in the previous build.\r
-      \r
-      @param moduleName the base name of the module\r
-      @return true if the module's surface area has parsed in previous, otherwise\r
-      return false\r
-    **/\r
-    public synchronized static boolean isModuleParsed(String moduleName) {\r
-        return parsedModules.containsKey(moduleName);\r
+    public synchronized static boolean hasFpdModuleSA(FpdModuleIdentification fpdModuleId) {\r
+        return fpdModuleSA.containsKey(fpdModuleId);\r
     }\r
 \r
     /**\r
     }\r
 \r
     /**\r
-      Query overrided module surface area information. If current is Package\r
-      or Platform build, also include the information from FPD file. \r
-      \r
-      <p>Note that surface area parsing is incremental. That means the method will \r
-      only to parse the MSA and MBD files when never parsed before. </p>\r
+      Query module surface area information.\r
+\r
+      <p>Note that surface area parsing is incremental. That means the method will\r
+      only parse the MSA files if necessary. </p>\r
     \r
     \r
-      @param moduleName the base name of the module\r
-      @return the overrided module surface area information\r
-      @throws BuildException\r
-              MSA or MBD is not valid\r
+      @param fpdModuleId Module ID with arch\r
+      @return ModuleSA info and MSA info for fpdModuleId\r
+      @throws BuildException Can't find MSA\r
     **/\r
     **/\r
-    public synchronized static Map<String, XmlObject> getDoc(String moduleName) throws BuildException {\r
-        if (parsedModules.containsKey(moduleName)) {\r
-            return parsedModules.get(moduleName);\r
-        }\r
-        Map<String, XmlObject> msaMap = getNativeMsa(moduleName);\r
-        Map<String, XmlObject> mbdMap = getNativeMbd(moduleName);\r
-        OverrideProcess op = new OverrideProcess();\r
-        Map<String, XmlObject> map = op.override(mbdMap, msaMap);\r
+    public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws BuildException {\r
+        if (parsedModules.containsKey(fpdModuleId)) {\r
+            return parsedModules.get(fpdModuleId);\r
+        }\r
+        Map<String, XmlObject> doc = new HashMap<String, XmlObject>();\r
+        ModuleIdentification moduleId = fpdModuleId.getModule();\r
         //\r
         //\r
-        // IF IT IS A PALTFORM BUILD, OVERRIDE FROM PLATFORM\r
+        // First part: get the MSA files info\r
         //\r
         //\r
-        if (FpdParserTask.platformBuildOptions != null) {\r
-            Map<String, XmlObject> platformMap = new HashMap<String, XmlObject>();\r
-            platformMap.put("BuildOptions", FpdParserTask.platformBuildOptions);\r
-            Map<String, XmlObject> overrideMap = op.override(platformMap, OverrideProcess.deal(map));\r
-            GlobalData.registerModule(moduleName, overrideMap);\r
-            return overrideMap;\r
-        } else {\r
-            parsedModules.put(moduleName, map);\r
-            return map;\r
+        doc.putAll(getNativeMsa(moduleId));\r
+\r
+        //\r
+        // Second part: put build options\r
+        //\r
+        doc.put("BuildOptions", fpdBuildOptions);\r
+\r
+        //\r
+        // Third part: get Module info from FPD, such as Library instances, PCDs\r
+        //\r
+        if (fpdModuleSA.containsKey(fpdModuleId)){\r
+            //\r
+            // merge module info in FPD to final Doc\r
+            // For Library Module, do nothing here\r
+            //\r
+            doc.putAll(fpdModuleSA.get(fpdModuleId));\r
         }\r
         }\r
+        parsedModules.put(fpdModuleId, doc);\r
+        return doc;\r
     }\r
 \r
     }\r
 \r
+    public synchronized static Map<String, XmlObject> getDoc(ModuleIdentification moduleId, String arch) throws BuildException {\r
+        FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);\r
+        return getDoc(fpdModuleId);\r
+    }\r
     /**\r
     /**\r
-      Query the native MSA information with module base name. \r
-      \r
-      <p>Note that MSA parsing is incremental. That means the method will \r
+      Query the native MSA information with module base name.\r
+\r
+      <p>Note that MSA parsing is incremental. That means the method will\r
       only to parse the MSA files when never parsed before. </p>\r
       only to parse the MSA files when never parsed before. </p>\r
-      \r
+\r
       @param moduleName the base name of the module\r
       @return the native MSA information\r
       @throws BuildException\r
               MSA file is not valid\r
     **/\r
       @param moduleName the base name of the module\r
       @return the native MSA information\r
       @throws BuildException\r
               MSA file is not valid\r
     **/\r
-    public synchronized static Map<String, XmlObject> getNativeMsa(String moduleName) throws BuildException {\r
-        if (nativeMsa.containsKey(moduleName)) {\r
-            return nativeMsa.get(moduleName);\r
+    public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws BuildException {\r
+        if (nativeMsa.containsKey(moduleId)) {\r
+            return nativeMsa.get(moduleId);\r
         }\r
         }\r
-        String msaFilename = getMsaFilename(moduleName);\r
-        File msaFile = new File(msaFilename);\r
+        File msaFile = getMsaFile(moduleId);\r
+        Map<String, XmlObject> msaMap = getNativeMsa(msaFile);\r
+        nativeMsa.put(moduleId, msaMap);\r
+        return msaMap;\r
+    }\r
+\r
+    public synchronized static Map<String, XmlObject> getNativeMsa(File msaFile) throws BuildException {\r
         if (!msaFile.exists()) {\r
         if (!msaFile.exists()) {\r
-            throw new BuildException("Info: Surface Area file [" + msaFile.getPath() + "] can't found.");\r
+            throw new BuildException("Module Surface Area file [" + msaFile.getPath() + "] can't be found!");\r
         }\r
         }\r
-        SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();\r
-        Map<String, XmlObject> map = surfaceAreaParser.parseFile(msaFile);\r
-        nativeMsa.put(moduleName, map);\r
-        return map;\r
-    }\r
-    \r
-    /**\r
-      Query the native MBD information with module base name. \r
-      \r
-      <p>Note that MBD parsing is incremental. That means the method will \r
-      only to parse the MBD files when never parsed before. </p>\r
-    \r
-      @param moduleName the base name of the module\r
-      @return the native MBD information\r
-      @throws BuildException\r
-              MBD file is not valid\r
-    **/\r
-    public synchronized static Map<String, XmlObject> getNativeMbd(String moduleName) throws BuildException {\r
-        if (nativeMbd.containsKey(moduleName)) {\r
-            return nativeMbd.get(moduleName);\r
+        try {\r
+            ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)XmlObject.Factory.parse(msaFile);\r
+            //\r
+            // Validate File if they accord with XML Schema\r
+            //\r
+            if ( !doc.validate()){\r
+                throw new BuildException("Module Surface Area file [" + msaFile.getPath() + "] format is invalid!");\r
+            }\r
+            //\r
+            // parse MSA file\r
+            //\r
+            ModuleSurfaceArea msa= doc.getModuleSurfaceArea();\r
+            Map<String, XmlObject> msaMap = new HashMap<String, XmlObject>();\r
+            msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true));\r
+            msaMap.put("ModuleDefinitions", cloneXmlObject(msa.getModuleDefinitions(), true));\r
+            msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true));\r
+            msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true));\r
+            msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true));\r
+            msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true));\r
+            msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true));\r
+            msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true));\r
+            msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true));\r
+            msaMap.put("PcdCoded", cloneXmlObject(msa.getPcdCoded(), true));\r
+            return msaMap;\r
         }\r
         }\r
-        String mbdFilename = getMbdFilename(moduleName);\r
-        File mbdFile = new File(mbdFilename);\r
-        if (!mbdFile.exists()) {\r
-            return null;\r
-            //throw new BuildException("Info: Surface Area file [" + mbdFile.getPath() + "] can't found.");\r
+        catch (Exception ex){\r
+            throw new BuildException("Parsing MSA file [" + msaFile.getPath() + "] error. \n" + ex.getMessage() );\r
         }\r
         }\r
-        SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();\r
-        Map<String, XmlObject> map = surfaceAreaParser.parseFile(mbdFile);\r
-        nativeMbd.put(moduleName, map);\r
+    }\r
+\r
+    public static Map<String, XmlObject> getFpdBuildOptions() {\r
+        Map<String, XmlObject> map = new HashMap<String, XmlObject>();\r
+        map.put("BuildOptions", fpdBuildOptions);\r
         return map;\r
     }\r
 \r
         return map;\r
     }\r
 \r
-    /**\r
-      Register module overrided surface area information. If has existed, then update.\r
-      \r
-      @param moduleName the base name of the module\r
-      @param map the overrided surface area information\r
-    **/\r
-    public synchronized static void registerModule(String moduleName, Map<String, XmlObject> map) {\r
-        parsedModules.put(moduleName, map);\r
+    public static void setFpdBuildOptions(XmlObject fpdBuildOptions) {\r
+        GlobalData.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true);\r
+    }\r
+\r
+    public static XmlObject getFpdDynamicPcds() {\r
+        return fpdDynamicPcds;\r
+    }\r
+\r
+    public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) {\r
+        GlobalData.fpdDynamicPcds = fpdDynamicPcds;\r
+    }\r
+\r
+    public static Set<ModuleIdentification> getModules(PackageIdentification packageId){\r
+        Spd spd = spdTable.get(packageId);\r
+        if (spd == null ) {\r
+            Set<ModuleIdentification> dummy = new HashSet<ModuleIdentification>();\r
+            return dummy;\r
+        } else {\r
+            return spd.getModules();\r
+        }\r
     }\r
 \r
     /**\r
     }\r
 \r
     /**\r
-     * \r
-     * @param protocolName\r
-     * @return\r
+     * The header file path is relative to workspace dir\r
      */\r
      */\r
-    public synchronized static String[] getProtocolInfoGuid(String protocolName) {\r
-        Set set = spdTable.keySet();\r
-        Iterator iter = set.iterator();\r
-        String[] cNameGuid = null;\r
+    public static String[] getLibraryClassHeaderFiles(\r
+            PackageIdentification[] packages, String name)\r
+            throws BuildException {\r
+        if (packages == null) {\r
+            // throw Exception or not????\r
+            return new String[0];\r
+        }\r
+        String[] result = null;\r
+        for (int i = 0; i < packages.length; i++) {\r
+            Spd spd = spdTable.get(packages[i]);\r
+            //\r
+            // If find one package defined the library class\r
+            //\r
+            if ((result = spd.getLibClassIncluder(name)) != null) {\r
+                return result;\r
+            }\r
+        }\r
+        //\r
+        // If can't find library class declaration in every package\r
+        //\r
+        throw new BuildException("Can not find library class [" + name\r
+                + "] declaration in any SPD package!");\r
+    }\r
 \r
 \r
-        while (iter.hasNext()) {\r
-            Spd spd = (Spd) spdTable.get(iter.next());\r
-            cNameGuid = spd.getProtocolNameGuidArray(protocolName);\r
-            if (cNameGuid != null) {\r
-                break;\r
+    /**\r
+     * The header file path is relative to workspace dir\r
+     */\r
+    public static String getPackageHeaderFiles(PackageIdentification packages,\r
+            String moduleType) throws BuildException {\r
+        if (packages == null) {\r
+            return new String("");\r
+        }\r
+        Spd spd = spdTable.get(packages);\r
+        //\r
+        // If can't find package header file, skip it\r
+        //\r
+        String temp = null;\r
+        if (spd != null) {\r
+            if ((temp = spd.getPackageIncluder(moduleType)) != null) {\r
+                return temp;\r
+            } else {\r
+                temp = "";\r
+                return temp;\r
             }\r
             }\r
+        } else {\r
+            return null;\r
         }\r
         }\r
-        return cNameGuid;\r
     }\r
 \r
     }\r
 \r
-    public synchronized static String[] getPpiInfoGuid(String ppiName) {\r
-        Set set = spdTable.keySet();\r
-        Iterator iter = set.iterator();\r
-        String[] cNameGuid = null;\r
+    /**\r
+     * return two values: {cName, GuidValue}\r
+     */\r
+    public static String[] getGuid(List<PackageIdentification> packages, String name)\r
+            throws BuildException {\r
+        if (packages == null) {\r
+            // throw Exception or not????\r
+            return new String[0];\r
+        }\r
+        String[] result = null;\r
+        Iterator item = packages.iterator();\r
+        while (item.hasNext()){\r
+            Spd spd = spdTable.get(item.next());\r
+            //\r
+            // If find one package defined the GUID\r
+            //\r
+            if ((result = spd.getGuid(name)) != null) {\r
+                return result;\r
+            }\r
+        }\r
 \r
 \r
-        while (iter.hasNext()) {\r
-            Spd spd = (Spd) spdTable.get(iter.next());\r
-            cNameGuid = spd.getPpiCnameGuidArray(ppiName);\r
+        return null;\r
+    }\r
 \r
 \r
-            if (cNameGuid != null) {\r
-                break;\r
+    /**\r
+     * return two values: {cName, GuidValue}\r
+     */\r
+    public static String[] getPpiGuid(List<PackageIdentification> packages,\r
+            String name) throws BuildException {\r
+        if (packages == null) {\r
+            return new String[0];\r
+        }\r
+        String[] result = null;\r
+        Iterator item = packages.iterator();\r
+        while (item.hasNext()){\r
+            Spd spd = spdTable.get(item.next());\r
+            //\r
+            // If find one package defined the Ppi GUID\r
+            //\r
+            if ((result = spd.getPpi(name)) != null) {\r
+                return result;\r
             }\r
         }\r
             }\r
         }\r
-        return cNameGuid;\r
+        return null;\r
     }\r
 \r
     /**\r
     }\r
 \r
     /**\r
-     * \r
-     * @param guidName\r
-     * @return\r
+     * return two values: {cName, GuidValue}\r
      */\r
      */\r
-    public synchronized static String[] getGuidInfoGuid(String guidName) {\r
-        String[] cNameGuid = null;\r
-        Set set = spdTable.keySet();\r
-        Iterator iter = set.iterator();\r
+    public static String[] getProtocolGuid(List<PackageIdentification> packages,\r
+            String name) throws BuildException {\r
+        if (packages == null) {\r
+            return new String[0];\r
+        }\r
+        String[] result = null;\r
+        Iterator item = packages.iterator();\r
+        while (item.hasNext()){\r
+            Spd spd = spdTable.get(item.next());\r
+            //\r
+            // If find one package defined the protocol GUID\r
+            //\r
+            if ((result = spd.getProtocol(name))!= null){\r
+                return result;\r
+            }\r
+        }\r
+        return null;\r
 \r
 \r
-        while (iter.hasNext()) {\r
-            Spd spd = (Spd) spdTable.get(iter.next());\r
-            cNameGuid = spd.getGuidNameArray(guidName);\r
-            if (cNameGuid != null) {\r
-                break;\r
+    }\r
+\r
+    public synchronized static PlatformIdentification getPlatformByName(String name) throws BuildException {\r
+        Iterator iter = platformList.iterator();\r
+        while(iter.hasNext()){\r
+            PlatformIdentification platformId = (PlatformIdentification)iter.next();\r
+            if (platformId.getName().equalsIgnoreCase(name)) {\r
+                return platformId;\r
             }\r
         }\r
             }\r
         }\r
-        return cNameGuid;\r
+        throw new BuildException("Can't find platform [" + name + "] in the current WORKSPACE database!");\r
     }\r
 \r
     }\r
 \r
-    public synchronized static String getLibClassIncluder(String libName) {\r
-        String libIncluder = null;\r
-        Set set = spdTable.keySet();\r
-        Iterator iter = set.iterator();\r
+    public synchronized static PlatformIdentification getPlatform(String filename) throws BuildException {\r
+        File file = new File(workspaceDir + File.separatorChar + filename);\r
+        Iterator iter = platformList.iterator();\r
+        while(iter.hasNext()){\r
+            PlatformIdentification platformId = (PlatformIdentification)iter.next();\r
+            if (platformId.getFpdFile().getPath().equalsIgnoreCase(file.getPath())) {\r
+                return platformId;\r
+            }\r
+        }\r
+        throw new BuildException("Can't find platform file [" + filename + "] in the current WORKSPACE database!");\r
+    }\r
 \r
 \r
-        while (iter.hasNext()) {\r
-            String packageName = (String) iter.next();\r
-            Spd spd = (Spd) spdTable.get(packageName);\r
-            libIncluder = spd.getLibClassIncluder(libName);\r
-            String packagePath = spd.packagePath;\r
-            if (packagePath != null) {\r
-                packagePath = packagePath.replace('\\', File.separatorChar);\r
-                packagePath = packagePath.replace('/', File.separatorChar);\r
-            } else {\r
-                packagePath = packageName;\r
+    public synchronized static PackageIdentification refreshPackageIdentification(PackageIdentification packageId) throws BuildException {\r
+        Iterator iter = packageList.iterator();\r
+        while(iter.hasNext()){\r
+            PackageIdentification packageItem = (PackageIdentification)iter.next();\r
+            if (packageItem.equals(packageId)) {\r
+                packageId.setName(packageItem.getName());\r
+                packageId.setSpdFile(packageItem.getSpdFile());\r
+                return packageId;\r
             }\r
             }\r
-            if (libIncluder != null) {\r
-                libIncluder = libIncluder.replace('\\', File.separatorChar);\r
-                libIncluder = libIncluder.replace('/', File.separatorChar);\r
-                libIncluder = packageName + File.separatorChar + libIncluder;\r
-                break;\r
+        }\r
+        throw new BuildException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!");\r
+    }\r
+\r
+    public synchronized static ModuleIdentification refreshModuleIdentification(ModuleIdentification moduleId) throws BuildException {\r
+        PackageIdentification packageId = getPackageForModule(moduleId);\r
+        moduleId.setPackage(packageId);\r
+        Spd spd = spdTable.get(packageId);\r
+        if (spd == null) {\r
+            throw new BuildException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!");\r
+        }\r
+        Set<ModuleIdentification> modules = spd.getModules();\r
+        Iterator<ModuleIdentification> iter = modules.iterator();\r
+        while (iter.hasNext()) {\r
+            ModuleIdentification item = iter.next();\r
+            if (item.equals(moduleId)) {\r
+                moduleId.setName(item.getName());\r
+                moduleId.setModuleType(item.getModuleType());\r
+                moduleId.setMsaFile(item.getMsaFile());\r
+                return moduleId;\r
             }\r
         }\r
             }\r
         }\r
-        return libIncluder;\r
+        throw new BuildException("Can't find module GUID value " + moduleId.toGuidString() + " in " + packageId + " under the current workspace!");\r
     }\r
 \r
     }\r
 \r
-    public synchronized static String getModuleInfoByPackageName(String packageName, String moduleType) {\r
-        Spd spd;\r
-        String includeFile = null;\r
-        String includeStr = "";\r
-        String cleanPath = "";\r
+    public synchronized static Set<PackageIdentification> getPackageList(){\r
+        return packageList;\r
+    }\r
 \r
 \r
-        spd = (Spd) spdTable.get(packageName);\r
-        includeFile = spd.getModuleTypeIncluder(moduleType);\r
-        if (includeFile != null) {\r
-            includeFile = includeFile.replace('\\', File.separatorChar);\r
-            includeFile = includeFile.replace('/', File.separatorChar);\r
-            includeStr = CommonDefinition.include + " <" + includeStr;\r
-            cleanPath = spd.packagePath;\r
-            cleanPath = cleanPath.replace('\\', File.separatorChar);\r
-            cleanPath = cleanPath.replace('/', File.separatorChar);\r
+    /**\r
+      BUGBUG: It is a walk around method. If do not clone, can't query info with\r
+      XPath correctly. \r
+      \r
+      @param object XmlObject\r
+      @param deep flag for deep clone\r
+      @return XmlObject after clone\r
+      @throws BuildException parse original XmlObject error. \r
+    **/\r
+    private static XmlObject cloneXmlObject(XmlObject object, boolean deep) throws BuildException {\r
+        if ( object == null) {\r
+            return null;\r
+        }\r
+        XmlObject result = null;\r
+        try {\r
+            result = XmlObject.Factory.parse(object.getDomNode()\r
+                            .cloneNode(deep));\r
+        } catch (Exception ex) {\r
+            throw new BuildException(ex.getMessage());\r
+        }\r
+        return result;\r
+    }\r
 \r
 \r
-            if (cleanPath.charAt(spd.packagePath.length() - 1) != File.separatorChar) {\r
-                cleanPath = cleanPath + File.separatorChar;\r
+    ///\r
+    /// Tool Chain Related, try to refine and put some logic process to ToolChainFactory\r
+    ///\r
+    public static ToolChainInfo getToolChainInfo() {\r
+        if (toolChainInfo == null) {\r
+            toolChainInfo = toolsDef.getConfigInfo().intersection(toolChainEnvInfo);\r
+            if (toolChainPlatformInfo != null) {\r
+                toolChainInfo = toolChainInfo.intersection(toolChainPlatformInfo);\r
             }\r
             }\r
-            includeStr = includeStr + cleanPath;\r
-            includeStr = includeStr + includeFile;\r
-            includeStr = includeStr + ">\r\n";\r
+            toolChainInfo.addCommands(toolsDef.getConfigInfo().getCommands());\r
+            toolChainInfo.normalize();\r
+            System.out.println("Current build tool chain information summary: ");\r
+            System.out.println(toolChainInfo + "");\r
         }\r
         }\r
+        return toolChainInfo;\r
+    }\r
 \r
 \r
-        return includeStr;\r
+    public static void setPlatformToolChainFamilyOption(ToolChainMap map) {\r
+        platformToolChainFamilyOption = map;\r
     }\r
 \r
     }\r
 \r
-    public synchronized static void setLibInstanceInfo(String libName, String libConstructor, String libDesturctor) {\r
-        String[] libConsDes = new String[2];\r
-        libConsDes[0] = libConstructor;\r
-        libConsDes[1] = libDesturctor;\r
+    public static void setPlatformToolChainOption(ToolChainMap map) {\r
+        platformToolChainOption = map;\r
+    }\r
 \r
 \r
-        libInstanceInfo.put(libName, libConsDes);\r
+    public static void addModuleToolChainOption(FpdModuleIdentification fpdModuleId,\r
+        ToolChainMap toolChainOption) {\r
+        moduleToolChainOption.put(fpdModuleId, toolChainOption);\r
     }\r
 \r
     }\r
 \r
-    public synchronized static boolean isHaveLibInstance(String libName) {\r
-        return libInstanceInfo.containsKey(libName);\r
+    public static void addModuleToolChainFamilyOption(FpdModuleIdentification fpdModuleId,\r
+        ToolChainMap toolChainOption) {\r
+        moduleToolChainFamilyOption.put(fpdModuleId, toolChainOption);\r
     }\r
 \r
     }\r
 \r
-    public synchronized static String getLibInstanceConstructor(String libName) {\r
-        String[] libInstanceValue;\r
-        libInstanceValue = libInstanceInfo.get(libName);\r
-        if (libInstanceValue != null) {\r
-            return libInstanceValue[0];\r
-        } else {\r
-            return null;\r
+    public static boolean isCommandSet(String target, String toolchain, String arch) {\r
+        String[] commands = getToolChainInfo().getCommands();\r
+\r
+        for (int i = 0; i < commands.length; ++i) {\r
+            String cmdName = toolsDef.getConfig().get(new String[] {target, toolchain, arch, commands[i], ToolChainAttribute.NAME.toString()});\r
+            if (cmdName != null && cmdName.length() != 0) {\r
+                return true;\r
+            }\r
         }\r
         }\r
+\r
+        return false;\r
     }\r
 \r
     }\r
 \r
-    public synchronized static String getLibInstanceDestructor(String libName) {\r
-        String[] libInstanceValue;\r
-        libInstanceValue = libInstanceInfo.get(libName);\r
-        if (libInstanceValue != null) {\r
-            return libInstanceValue[1];\r
-        } else {\r
-            return null;\r
+    public static String getCommandSetting(String[] commandDescription, FpdModuleIdentification fpdModuleId) throws EdkException {\r
+        ToolChainKey toolChainKey = new ToolChainKey(commandDescription);\r
+        ToolChainMap toolChainConfig = toolsDef.getConfig();\r
+        String setting = null;\r
+\r
+        if (!commandDescription[ToolChainElement.ATTRIBUTE.value].equals(ToolChainAttribute.FLAGS.toString())) {\r
+            setting = toolChainConfig.get(toolChainKey);\r
+            if (setting == null) {\r
+                setting = "";\r
+            }\r
+            return setting;\r
+        }\r
+\r
+        //\r
+        // get module specific options, if any\r
+        //\r
+        // tool tag first\r
+        ToolChainMap option = moduleToolChainOption.get(fpdModuleId);\r
+        ToolChainKey toolChainFamilyKey = null;\r
+\r
+        if ((option == null) || (option != null && (setting = option.get(toolChainKey)) == null)) {\r
+            //\r
+            // then tool chain family\r
+            //\r
+            toolChainFamilyKey = new ToolChainKey(commandDescription);\r
+            toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value);\r
+            String family = toolChainConfig.get(toolChainFamilyKey);\r
+            toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);\r
+            toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value);\r
+\r
+            option = moduleToolChainFamilyOption.get(fpdModuleId);\r
+            if (option != null) {\r
+                setting = option.get(toolChainFamilyKey);\r
+            }\r
+        }\r
+\r
+        //\r
+        // get platform options, if any\r
+        //\r
+        if (setting == null) {\r
+            // tool tag first\r
+            if (platformToolChainOption == null || (setting = platformToolChainOption.get(toolChainKey)) == null) {\r
+                // then tool chain family\r
+                if (toolChainFamilyKey == null) {\r
+                    toolChainFamilyKey = new ToolChainKey(commandDescription);\r
+                    toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value);\r
+                    String family = toolChainConfig.get(toolChainFamilyKey);\r
+                    toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);\r
+                    toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value);\r
+                }\r
+\r
+                setting = platformToolChainFamilyOption.get(toolChainFamilyKey);\r
+            }\r
+        }\r
+\r
+        if (setting == null) {\r
+            setting = "";\r
         }\r
         }\r
+\r
+        return setting;\r
     }\r
 \r
     }\r
 \r
+    public static void setToolChainEnvInfo(ToolChainInfo envInfo) {\r
+        toolChainEnvInfo = envInfo;\r
+    }\r
+    public static void setToolChainPlatformInfo(ToolChainInfo platformInfo) {\r
+        toolChainPlatformInfo = platformInfo;\r
+    }\r
+\r
+    //\r
+    // for PCD\r
+    //\r
     public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {\r
         return pcdDbManager;\r
     }\r
     public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {\r
         return pcdDbManager;\r
     }\r
+\r
+    //\r
+    // For PCD get tokenSpaceGUid\r
+    //\r
+    public synchronized static String getGuidInfoFromCname(String cName){\r
+        String cNameGuid = null;\r
+        String guid = null;\r
+        Set set = spdTable.keySet();\r
+        Iterator iter = set.iterator();\r
+\r
+        if (iter == null) {\r
+            return null;\r
+        }\r
+\r
+        while (iter.hasNext()){\r
+            Spd spd = (Spd) spdTable.get(iter.next());\r
+            guid = spd.getGuidFromCname(cName);\r
+            if (guid != null){\r
+                cNameGuid = guid;\r
+                break;\r
+            }\r
+        }\r
+        return cNameGuid;\r
+    }\r
+\r
+    //\r
+    // For PCD\r
+    //\r
+    public synchronized static Map<FpdModuleIdentification, XmlObject>\r
+                               getFpdModuleSaXmlObject(String xmlObjectName) {\r
+        Set<FpdModuleIdentification> fpdModuleSASet = fpdModuleSA.keySet();\r
+        Iterator item = fpdModuleSASet.iterator();\r
+\r
+\r
+        Map<FpdModuleIdentification, XmlObject> SAPcdBuildDef = new HashMap<FpdModuleIdentification, XmlObject>();\r
+        Map<String, XmlObject> SANode = new HashMap<String, XmlObject>();\r
+        FpdModuleIdentification moduleId;\r
+        while (item.hasNext()) {\r
+\r
+            moduleId = (FpdModuleIdentification) item.next();\r
+            SANode = fpdModuleSA.get(moduleId);\r
+            try{\r
+                if (SANode.get(xmlObjectName)!= null){\r
+                    SAPcdBuildDef.put(moduleId,\r
+                            (XmlObject) SANode.get(xmlObjectName));\r
+\r
+                }\r
+            } catch (Exception e){\r
+                EdkLog.log(EdkLog.EDK_INFO, e.getMessage());\r
+            }\r
+        }\r
+        return SAPcdBuildDef;\r
+    }\r
+\r
+    public synchronized static Map<FpdModuleIdentification,XmlObject> getFpdPcdBuildDefinitions() {\r
+        Map<FpdModuleIdentification,XmlObject> pcdBuildDef = getFpdModuleSaXmlObject ("PcdBuildDefinition");\r
+\r
+        return pcdBuildDef;\r
+    }\r
 }\r
 }\r
+\r