]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java
Update GenBuild to append FLAGS from FPD files to the FLAGS defined in tools_def.txt
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / global / GlobalData.java
index 611758a4effd0950e5e20f5e8a2f19badbef3e08..ceb19d91db7d78c9400a26f819255e43feec0f1b 100644 (file)
@@ -1,10 +1,10 @@
 /** @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
-  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
@@ -17,621 +17,942 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 package org.tianocore.build.global;\r
 \r
 import java.io.File;\r
+import java.io.IOException;\r
 import java.util.HashMap;\r
 import java.util.HashSet;\r
 import java.util.Iterator;\r
 import java.util.List;\r
 import java.util.Map;\r
 import java.util.Set;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
 \r
-import org.apache.tools.ant.BuildException;\r
+import org.apache.xmlbeans.XmlException;\r
 import org.apache.xmlbeans.XmlObject;\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.MsaFilesDocument;\r
-import org.tianocore.PackageListDocument;\r
-import org.tianocore.PackageSurfaceAreaDocument;\r
-import org.tianocore.MsaHeaderDocument.MsaHeader;\r
-import org.tianocore.MsaLibHeaderDocument.MsaLibHeader;\r
-import org.tianocore.build.pcd.entity.MemoryDatabaseManager;\r
-import org.tianocore.build.autogen.CommonDefinition;\r
-import org.tianocore.build.fpd.FpdParserTask;\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
-  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
-\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
+    /// Record current WORKSPACE Directory\r
     ///\r
-    public static final int ONLY_MSA = 1;\r
+    private static String workspaceDir = "";\r
 \r
     ///\r
-    /// means only Library MSA\r
+    /// Be used to ensure Global data will be initialized only once.\r
     ///\r
-    public static final int ONLY_LIBMSA = 2;\r
+    private static boolean globalFlag = false;\r
 \r
     ///\r
-    /// means both MSA and MBD\r
+    /// Framework Database information: package list and platform list\r
     ///\r
-    public static final int MSA_AND_MBD = 3;\r
+    private static Set<PackageIdentification> packageList = new HashSet<PackageIdentification>();\r
 \r
-    ///\r
-    /// means both Library MSA and Library MBD\r
-    ///\r
-    public static final int LIBMSA_AND_LIBMBD = 4;\r
+    private static Set<PlatformIdentification> platformList = new HashSet<PlatformIdentification>();\r
 \r
     ///\r
-    /// Be used to ensure Global data will be initialized only once.\r
+    /// Every detail SPD informations: Module list, Library class definition,\r
+    ///   Package header file, GUID/PPI/Protocol definitions\r
     ///\r
-    public static boolean globalFlag = false;\r
+    private static final Map<PackageIdentification, Spd> spdTable = new HashMap<PackageIdentification, Spd>();\r
 \r
     ///\r
-    /// Record current WORKSPACE Directory\r
+    /// Build informations are divided into three parts:\r
+    /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA\r
     ///\r
-    private static String workspaceDir = "";\r
+    private static Map<ModuleIdentification, Map<String, XmlObject>> nativeMsa = new HashMap<ModuleIdentification, Map<String, XmlObject>>();\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 Map<FpdModuleIdentification, Map<String, XmlObject>> fpdModuleSA= new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();\r
 \r
-    ///\r
-    /// spdTable\r
-    /// Key: Package Name, Value: SPD detail info\r
-    ///\r
-    private static final Map<String, Spd> spdTable = new HashMap<String, Spd>();\r
+    private static Map<String, XmlObject> fpdBuildOptionsMap = new HashMap<String, XmlObject>();\r
+    \r
+    private static XmlObject fpdBuildOptions;\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
-    ///\r
-    private static final Map<String, String[]> moduleInfo = new HashMap<String, String[]>();\r
+    private static XmlObject fpdDynamicPcds;\r
 \r
     ///\r
-    /// List all libraries for current build module\r
-    /// Key: Library BaseName, Value: output library path+name\r
+    /// Parsed modules list\r
     ///\r
-    private static final Map<String, String> libraries = new HashMap<String, String>();\r
+    private static Map<FpdModuleIdentification, Map<String, XmlObject>> parsedModules = new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();\r
 \r
     ///\r
-    /// Store every module's relative library instances BaseName\r
-    /// Key: Module BaseName, Value: All library instances module depends on.\r
+    /// built modules list with ARCH, TARGET, TOOLCHAIN\r
     ///\r
-    private static final Map<String, Set<String> > moduleLibraryMap = new HashMap<String, Set<String> >();\r
+    private static Set<FpdModuleIdentification> builtModules = new HashSet<FpdModuleIdentification>();\r
 \r
     ///\r
-    /// Key: Module BaseName, Value: original MSA info\r
+    /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.\r
     ///\r
-    private static final Map<String, Map<String, XmlObject> > nativeMsa = new HashMap<String, Map<String, XmlObject> >();\r
+    private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();\r
 \r
     ///\r
-    /// Key: Module BaseName, Value: original MBD info\r
+    /// build target + tool chain family/tag name + arch + command types + command options\r
     ///\r
-    private static final Map<String, Map<String, XmlObject> > nativeMbd = new HashMap<String, Map<String, XmlObject> >();\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
+    /// 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
-    private static final Map<String, Map<String, XmlObject> > parsedModules = new HashMap<String, Map<String, XmlObject> >();\r
+    private static ToolChainConfig toolsDef;\r
 \r
-    ///\r
-    /// List all built Module; Value is Module BaseName + Arch. TBD\r
-    ///\r
-    private static final Set<String> builtModules = new HashSet<String>();\r
+    private static ToolChainInfo toolChainInfo;\r
+    private static ToolChainInfo toolChainEnvInfo;\r
+    private static ToolChainInfo toolChainPlatformInfo;\r
 \r
-    ///\r
-    /// Library instance information table which recored the library and it's\r
-    /// constructor and distructor function\r
-    ///\r
-    private static final Map<String, String[]> libInstanceInfo = new HashMap<String, String[]>();\r
+    private static ToolChainMap platformToolChainOption;\r
+    private static ToolChainMap platformToolChainFamilyOption;\r
 \r
-    ///\r
-    /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.\r
-    ///\r
-    private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();\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
-      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
+      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
-    /**\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
+      @param workspaceDatabaseFile the file name of framework database\r
+      @param workspaceDir current workspace directory path\r
       @throws BuildException\r
-              Base name is not registered in any SPD files\r
+            Framework Dababase or SPD or MSA file is not valid\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
+    public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir, String toolsDefFilename ) throws EdkException {\r
+        //\r
+        // ensure this method will be revoked only once\r
+        //\r
+        if (globalFlag) {\r
+            return;\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
+        globalFlag = true;\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
+        // 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
+        EdkLog.log("Init", EdkLog.EDK_ALWAYS, "Using tool definition file [" + toolsDefFile.getPath() + "].");\r
+        toolsDef = new ToolChainConfig(toolsDefFile);\r
+\r
+        //\r
+        // Parse Framework Database\r
+        //\r
+        File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);\r
+        try {\r
+            FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);\r
+            //\r
+            // validate FrameworkDatabaseFile\r
+            //\r
+            if (!db.validate()) {\r
+                throw new EdkException("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
+                    //\r
+                    // Report warning if existing two packages with same GUID and Version\r
+                    //\r
+                    if (spdTable.containsKey(spd.getPackageId())) {\r
+                        //\r
+                        // BUGBUG\r
+                        //\r
+                        EdkLog.log("Init", EdkLog.EDK_WARNING, "Warning: Existing two packages with same GUID and Version. They are ... " + spd.getPackageId().getSpdFile().getPath());\r
+                    }\r
+                    spdTable.put(spd.getPackageId(), spd);\r
+                }\r
+            }\r
+\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 EdkException("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 EdkException("Framework Platform Surface Area file [" + fpdFile.getPath() + "] format is invalid!");\r
+                    }\r
+                    //\r
+                    // We can change Map to XmlObject\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
+                    //\r
+                    // Report warning if existing two platfrom with same GUID and Version\r
+                    //\r
+                    if (platformList.contains(platformId)) {\r
+                        //\r
+                        // BUGBUG\r
+                        //\r
+                        EdkLog.log("Init", EdkLog.EDK_WARNING, "Warning: Existing two platforms with same GUID and Version. They are ... " + fpdFile.getPath());\r
+                    }\r
+                    platformList.add(platformId);\r
+                }\r
+            }\r
+        } catch(IOException ex) {\r
+            EdkException edkException = new EdkException("Parse WORKSPACE Database file [" + dbFile.getPath() + "] Error.\n" + ex.getMessage());\r
+            edkException.setStackTrace(ex.getStackTrace());\r
+            throw edkException;\r
+        } catch(XmlException ex) {\r
+            EdkException edkException = new EdkException("Parse WORKSPACE Database file [" + dbFile.getPath() + "] Error.\n" + ex.getMessage());\r
+            edkException.setStackTrace(ex.getStackTrace());\r
+            throw edkException;\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
+      Get the current WORKSPACE Directory.\r
+\r
       @return current workspace directory\r
     **/\r
     public synchronized static String getWorkspacePath() {\r
         return workspaceDir;\r
     }\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
+      Get the MSA file name with absolute path\r
+     */\r
+    public synchronized static File getMsaFile(ModuleIdentification moduleId) throws EdkException {\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 EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!");\r
+        } else {\r
+            return msaFile;\r
+        }\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
+    public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) throws EdkException {\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
+            File tempMsaFile = null;\r
+            if ((tempMsaFile = spd.getModuleFile(moduleId)) != null ) {\r
+                if (tempMsaFile.getParent().equalsIgnoreCase(moduleId.getMsaFile().getParent())) {\r
+                    break ;\r
+                }\r
+                tempMsaFile = null;\r
+            }\r
+        }\r
+        if (packageId == null){\r
+            throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!");\r
+        } else {\r
+            return packageId;\r
+        }\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
+      Difference between build and parse: ToolChain and Target\r
     **/\r
-    public synchronized static String getPackageNameForModule(String moduleName) {\r
-        return moduleInfo.get(moduleName)[1];\r
+    public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) {\r
+        return builtModules.contains(moduleId);\r
+    }\r
+\r
+    public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) {\r
+        builtModules.add(fpdModuleId);\r
+    }\r
+\r
+\r
+    public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map<String, XmlObject> doc) throws EdkException{\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
+    public synchronized static boolean hasFpdModuleSA(FpdModuleIdentification fpdModuleId) {\r
+        return fpdModuleSA.containsKey(fpdModuleId);\r
     }\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
-      @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
+      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
+      @param fpdModuleId Module ID with arch\r
+      @return ModuleSA info and MSA info for fpdModuleId\r
+      @throws BuildException Can't find MSA\r
     **/\r
-    public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir) throws BuildException {\r
-        if (globalFlag) {\r
-            return;\r
+    public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws EdkException{\r
+        if (parsedModules.containsKey(fpdModuleId)) {\r
+            return parsedModules.get(fpdModuleId);\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
+        Map<String, XmlObject> doc = new HashMap<String, XmlObject>();\r
+        ModuleIdentification moduleId = fpdModuleId.getModule();\r
+        //\r
+        // First part: get the MSA files info\r
+        //\r
+        doc.putAll(getNativeMsa(moduleId));\r
 \r
-            }\r
-        } catch (Exception e) {\r
-            throw new BuildException("Parse workspace Database [" + dbFile.getPath() + "] Error.\n" + e.getMessage());\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
+        parsedModules.put(fpdModuleId, doc);\r
+        return doc;\r
     }\r
 \r
+    public synchronized static Map<String, XmlObject> getDoc(ModuleIdentification moduleId, String arch) throws EdkException{\r
+        FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);\r
+        return getDoc(fpdModuleId);\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
+      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
+\r
+      @param moduleName the base name of the module\r
+      @return the native MSA information\r
       @throws BuildException\r
-              SPD or MSA file is not valid\r
+              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
+    public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws EdkException {\r
+        if (nativeMsa.containsKey(moduleId)) {\r
+            return nativeMsa.get(moduleId);\r
+        }\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 EdkException {\r
+        if (!msaFile.exists()) {\r
+            throw new EdkException("Module Surface Area file [" + msaFile.getPath() + "] can't be found!");\r
+        }\r
         try {\r
-            PackageSurfaceAreaDocument spd = (PackageSurfaceAreaDocument) XmlObject.Factory.parse(packageFile);\r
-            List<MsaFilesDocument.MsaFiles.MsaFile> msasList = spd.getPackageSurfaceArea().getMsaFiles()\r
-                                                                  .getMsaFileList();\r
-            Iterator msasIter = msasList.iterator();\r
-            while (msasIter.hasNext()) {\r
-                MsaFilesDocument.MsaFiles.MsaFile msas = (MsaFilesDocument.MsaFiles.MsaFile) msasIter.next();\r
-                String msaFilename = msas.getFilename().getStringValue();\r
-                File msaFile = new File(workspaceDir + File.separatorChar + GlobalData.getPackagePath(packageName)\r
-                                        + File.separatorChar + msaFilename);\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
-                    baseName = ((MsaHeader) header).getBaseName().getStringValue();\r
-                } else if ((header = map.get("MsaLibHeader")) != null) {\r
-                    baseName = ((MsaLibHeader) header).getBaseName().getStringValue();\r
-                } else {\r
-                    continue;\r
-                }\r
-                nativeMsa.put(baseName, map);\r
-                String[] info = { msaFilename, packageName };\r
-                moduleInfo.put(baseName, info);\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 EdkException("Module Surface Area file [" + msaFile.getPath() + "] format is invalid!");\r
             }\r
-        } catch (Exception e) {\r
-            throw new BuildException("Parse package description file [" + packageFile.getPath() + "] Error.\n"\r
-                                     + e.getMessage());\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
+        } catch(IOException ex) {\r
+            EdkException edkException = new EdkException("Parsing MSA file [" + msaFile.getPath() + "] error. \n" + ex.getMessage());\r
+            edkException.setStackTrace(ex.getStackTrace());\r
+            throw edkException;\r
+        } catch(XmlException ex) {\r
+            EdkException edkException = new EdkException("Parsing MSA file [" + msaFile.getPath() + "] error. \n" + ex.getMessage());\r
+            edkException.setStackTrace(ex.getStackTrace());\r
+            throw edkException;\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
-    **/\r
-    public synchronized static String[] getModuleLibrary(String moduleName) {\r
-        Set<String> set = moduleLibraryMap.get(moduleName);\r
-        return set.toArray(new String[set.size()]);\r
+    public static Map<String, XmlObject> getFpdBuildOptionsMap() {\r
+        return fpdBuildOptionsMap;\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, Set<String> libraryList) {\r
-        moduleLibraryMap.put(moduleName, libraryList);\r
+    public static void setFpdBuildOptions(XmlObject fpdBuildOptions) throws EdkException {\r
+        GlobalData.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true);\r
+        fpdBuildOptionsMap.put("BuildOptions", GlobalData.fpdBuildOptions);\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) {\r
-        return libraries.get(library);\r
+    public static XmlObject getFpdDynamicPcds() {\r
+        return fpdDynamicPcds;\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
-    **/\r
-    public synchronized static void addLibrary(String library, String resultPath) {\r
-        libraries.put(library, resultPath);\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 static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) {\r
+        GlobalData.fpdDynamicPcds = fpdDynamicPcds;\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
+    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
-      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
+     * The header file path is relative to workspace dir\r
+     */\r
+    public static String[] getLibraryClassHeaderFiles(\r
+            PackageIdentification[] packages, String name) throws EdkException{\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 EdkException("Can not find library class [" + name\r
+                + "] declaration in any SPD package!");\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
-    \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
-    **/\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
+     * The header file path is relative to workspace dir\r
+     */\r
+    public static String getPackageHeaderFiles(PackageIdentification packages,\r
+            String moduleType) {\r
+        if (packages == null) {\r
+            return new String("");\r
+        }\r
+        Spd spd = spdTable.get(packages);\r
         //\r
-        // IF IT IS A PALTFORM BUILD, OVERRIDE FROM PLATFORM\r
+        // If can't find package header file, skip it\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
+        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
         } else {\r
-            parsedModules.put(moduleName, map);\r
-            return map;\r
+            return null;\r
         }\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
-      only to parse the MSA files when never parsed before. </p>\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
+     * return two values: {cName, GuidValue}\r
+     */\r
+    public static String[] getGuid(List<PackageIdentification> packages, String name) {\r
+        if (packages == null) {\r
+            // throw Exception or not????\r
+            return new String[0];\r
         }\r
-        String msaFilename = getMsaFilename(moduleName);\r
-        File msaFile = new File(msaFilename);\r
-        if (!msaFile.exists()) {\r
-            throw new BuildException("Info: Surface Area file [" + msaFile.getPath() + "] can't found.");\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
-        SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();\r
-        Map<String, XmlObject> map = surfaceAreaParser.parseFile(msaFile);\r
-        nativeMsa.put(moduleName, map);\r
-        return map;\r
+\r
+        return null;\r
     }\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
+     * return two values: {cName, GuidValue}\r
+     */\r
+    public static String[] getPpiGuid(List<PackageIdentification> packages,\r
+            String name) {\r
+        if (packages == null) {\r
+            return new String[0];\r
         }\r
-        String mbdFilename = getMbdFilename(moduleName);\r
-        File mbdFile = new File(mbdFilename);\r
-        if (!mbdFile.exists()) {\r
-            throw new BuildException("Info: Surface Area file [" + mbdFile.getPath() + "] can't found.");\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
-        SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();\r
-        Map<String, XmlObject> map = surfaceAreaParser.parseFile(mbdFile);\r
-        nativeMbd.put(moduleName, map);\r
-        return map;\r
+        return null;\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
+     * return two values: {cName, GuidValue}\r
+     */\r
+    public static String[] getProtocolGuid(List<PackageIdentification> packages,\r
+            String name) {\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
 \r
-    /**\r
-     * \r
-     * @param protocolName\r
-     * @return\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 synchronized static PlatformIdentification getPlatformByName(String name) throws EdkException {\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
+        throw new EdkException("Can't find platform [" + name + "] in the current WORKSPACE database!");\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
+    public synchronized static PlatformIdentification getPlatform(String filename) throws EdkException {\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
-        return cNameGuid;\r
+        throw new EdkException("Can't find platform file [" + filename + "] in the current WORKSPACE database!");\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
+    public synchronized static PackageIdentification refreshPackageIdentification(PackageIdentification packageId) throws EdkException {\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
+        throw new EdkException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!");\r
+    }\r
 \r
+    public synchronized static ModuleIdentification refreshModuleIdentification(ModuleIdentification moduleId) throws EdkException {\r
+        PackageIdentification packageId = getPackageForModule(moduleId);\r
+        moduleId.setPackage(packageId);\r
+        Spd spd = spdTable.get(packageId);\r
+        if (spd == null) {\r
+            throw new EdkException("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
-            Spd spd = (Spd) spdTable.get(iter.next());\r
-            cNameGuid = spd.getPpiCnameGuidArray(ppiName);\r
-\r
-            if (cNameGuid != null) {\r
-                break;\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
-        return cNameGuid;\r
+        throw new EdkException("Can't find module GUID value " + moduleId.toGuidString() + " in " + packageId + " under the current workspace!");\r
+    }\r
+\r
+    public synchronized static Set<PackageIdentification> getPackageList(){\r
+        return packageList;\r
     }\r
 \r
     /**\r
-     * \r
-     * @param guidName\r
-     * @return\r
-     */\r
-    public synchronized static String[] getGuidInfoGuid(String guidName) {\r
-        String[] cNameGuid = null;\r
-        Set set = spdTable.keySet();\r
-        Iterator iter = set.iterator();\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 EdkException {\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 (XmlException ex) {\r
+            EdkException edkException = new EdkException(ex.getMessage());\r
+            edkException.setStackTrace(ex.getStackTrace());\r
+            throw edkException;\r
+        }\r
+        return result;\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
+    /// Tool Chain Related, try to refine and put some logic process to ToolChainFactory\r
+    ///\r
+    public synchronized static ToolChainInfo getToolChainInfo() {\r
+        if (toolChainInfo == null) {\r
+            toolChainInfo = toolsDef.getConfigInfo().intersection(toolChainEnvInfo);\r
+            if (toolChainPlatformInfo != null) {\r
+                toolChainInfo = toolChainInfo.intersection(toolChainPlatformInfo);\r
             }\r
+            toolChainInfo.addCommands(toolsDef.getConfigInfo().getCommands());\r
+            toolChainInfo.normalize();\r
+            EdkLog.log("Init", EdkLog.EDK_ALWAYS, "Current build tool chain information summary: ");\r
+            EdkLog.log("Init", EdkLog.EDK_ALWAYS, toolChainInfo + "");\r
         }\r
-        return cNameGuid;\r
+        return toolChainInfo;\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 static void setPlatformToolChainFamilyOption(ToolChainMap map) {\r
+        platformToolChainFamilyOption = map;\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
-            }\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
+    public static void setPlatformToolChainOption(ToolChainMap map) {\r
+        platformToolChainOption = map;\r
+    }\r
+\r
+    public static void addModuleToolChainOption(FpdModuleIdentification fpdModuleId,\r
+        ToolChainMap toolChainOption) {\r
+        moduleToolChainOption.put(fpdModuleId, toolChainOption);\r
+    }\r
+\r
+    public static void addModuleToolChainFamilyOption(FpdModuleIdentification fpdModuleId,\r
+        ToolChainMap toolChainOption) {\r
+        moduleToolChainFamilyOption.put(fpdModuleId, toolChainOption);\r
+    }\r
+\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
-        return libIncluder;\r
+\r
+        return false;\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 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
+        setting = toolChainConfig.get(toolChainKey);\r
+        if (setting == null) {\r
+          setting = "";\r
+        }\r
+        if (!commandDescription[ToolChainElement.ATTRIBUTE.value].equals(ToolChainAttribute.FLAGS.toString())) {\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.get(toolChainKey) != null)  \r
+        {\r
+          String str = option.get(toolChainKey);\r
+\r
+          Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");\r
+          Matcher matcher = myPattern.matcher(str + " ");\r
+          while (matcher.find()) \r
+          {\r
+            setting = setting + " " + str.substring(matcher.start(1), matcher.end(1));\r
+          }\r
+        } \r
+//        else \r
+//        {\r
+          if (toolChainFamilyKey == null) \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
+\r
+          option = moduleToolChainFamilyOption.get(fpdModuleId);\r
+          if (option != null && option.get(toolChainFamilyKey) != null) \r
+          {\r
+            String str = option.get(toolChainFamilyKey);\r
+\r
+            Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");\r
+            Matcher matcher = myPattern.matcher(str + " ");\r
+            while (matcher.find()) \r
+            {\r
+              setting = setting + " " + str.substring(matcher.start(1), matcher.end(1));\r
+            }\r
+          }\r
+//        }\r
+\r
+        //\r
+        // get platform options, if any\r
+        //\r
+        // tool tag first\r
+//        if (platformToolChainOption != null && platformToolChainOption.get(toolChainKey) != null) \r
+        if (platformToolChainOption.get(toolChainKey) != null) \r
+        {\r
+          String str = platformToolChainOption.get(toolChainKey);\r
+\r
+          Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");\r
+          Matcher matcher = myPattern.matcher(str + " ");\r
+          while (matcher.find()) \r
+          {\r
+            setting = setting + " " + str.substring(matcher.start(1), matcher.end(1));\r
+          }\r
+        } \r
+//        else \r
+//        {\r
+          // then tool chain family\r
+          if (toolChainFamilyKey == null) \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
+\r
+//          if (platformToolChainFamilyOption != null && platformToolChainFamilyOption.get(toolChainFamilyKey) != null) \r
+          if (platformToolChainFamilyOption.get(toolChainFamilyKey) != null) \r
+          {\r
+            String str = platformToolChainFamilyOption.get(toolChainFamilyKey);\r
+\r
+            setting = setting + " " + str;\r
+\r
+//            Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");\r
+//            Matcher matcher = myPattern.matcher(str + " ");\r
+//            while (matcher.find()) \r
+//            {\r
+//              setting = setting + " " + str.substring(matcher.start(1), matcher.end(1));\r
+//            }\r
+          }\r
+//        }\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
+            //\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
-        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
+        // 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
-            if (cleanPath.charAt(spd.packagePath.length() - 1) != File.separatorChar) {\r
-                cleanPath = cleanPath + File.separatorChar;\r
+                setting = platformToolChainFamilyOption.get(toolChainFamilyKey);\r
             }\r
-            includeStr = includeStr + cleanPath;\r
-            includeStr = includeStr + includeFile;\r
-            includeStr = includeStr + ">\r\n";\r
         }\r
 \r
-        return includeStr;\r
-    }\r
+        if (setting == null) {\r
+            setting = "";\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
+        return setting;\r
+*/\r
+    }\r
 \r
-        libInstanceInfo.put(libName, libConsDes);\r
+    public static void setToolChainEnvInfo(ToolChainInfo envInfo) {\r
+        toolChainEnvInfo = envInfo;\r
+    }\r
+    public static void setToolChainPlatformInfo(ToolChainInfo platformInfo) {\r
+        toolChainPlatformInfo = platformInfo;\r
     }\r
 \r
-    public synchronized static boolean isHaveLibInstance(String libName) {\r
-        return libInstanceInfo.containsKey(libName);\r
+    //\r
+    // for PCD\r
+    //\r
+    public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {\r
+        return pcdDbManager;\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
+    //\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
-    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
+    //\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 MemoryDatabaseManager getPCDMemoryDBManager() {\r
-        return pcdDbManager;\r
+    public synchronized static Map<FpdModuleIdentification,XmlObject> getFpdPcdBuildDefinitions() {\r
+        Map<FpdModuleIdentification,XmlObject> pcdBuildDef = getFpdModuleSaXmlObject ("PcdBuildDefinition");\r
+\r
+        return pcdBuildDef;\r
     }\r
 }\r
+\r