]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Source/GenBuild/org/tianocore/build/GenBuildTask.java
Fixed EDKT102;
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / GenBuildTask.java
index 2d91991b8a9b92fe07eac3d8d33c5eff4ff5896b..bac506abfa3f0161ff999a6c096b326474b77f2a 100644 (file)
@@ -16,54 +16,45 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 package org.tianocore.build;\r
 \r
 import java.io.File;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
+import java.util.Hashtable;\r
 import java.util.Iterator;\r
 import java.util.LinkedHashSet;\r
 import java.util.List;\r
 import java.util.Map;\r
 import java.util.Set;\r
+import java.util.Stack;\r
 import java.util.Vector;\r
 import java.util.regex.Matcher;\r
 import java.util.regex.Pattern;\r
 \r
-import javax.xml.parsers.DocumentBuilder;\r
-import javax.xml.parsers.DocumentBuilderFactory;\r
-import javax.xml.transform.OutputKeys;\r
-import javax.xml.transform.Result;\r
-import javax.xml.transform.Source;\r
-import javax.xml.transform.Transformer;\r
-import javax.xml.transform.TransformerFactory;\r
-import javax.xml.transform.dom.DOMSource;\r
-import javax.xml.transform.stream.StreamResult;\r
-\r
 import org.apache.tools.ant.BuildException;\r
-import org.apache.tools.ant.Project;\r
-import org.apache.tools.ant.Task;\r
 import org.apache.tools.ant.taskdefs.Ant;\r
+import org.apache.tools.ant.taskdefs.Property;\r
 import org.apache.xmlbeans.XmlObject;\r
-import org.w3c.dom.Comment;\r
-import org.w3c.dom.Document;\r
-import org.w3c.dom.Element;\r
-import org.w3c.dom.Node;\r
 \r
 import org.tianocore.build.autogen.AutoGen;\r
-import org.tianocore.build.autogen.CommonDefinition;\r
 import org.tianocore.build.fpd.FpdParserTask;\r
+import org.tianocore.build.global.GenBuildLogger;\r
 import org.tianocore.build.global.GlobalData;\r
 import org.tianocore.build.global.OutputManager;\r
 import org.tianocore.build.global.SurfaceAreaQuery;\r
-import org.tianocore.build.toolchain.ToolChainFactory;\r
-import org.tianocore.FilenameDocument;\r
-import org.tianocore.MsaHeaderDocument;\r
-import org.tianocore.MsaLibHeaderDocument;\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.tools.ModuleItem;\r
+import org.tianocore.exception.EdkException;\r
+import org.tianocore.logger.EdkLog;\r
 \r
 /**\r
   <p>\r
   <code>GenBuildTask</code> is an ANT task that can be used in ANT build\r
   system. The main function of this task is to parse module's surface area,\r
   then generate the corresponding <em>BaseName_build.xml</em> (the real ANT\r
-  build script) and call this to build the module.\r
+  build script) and call this to build the module. The whole process including:\r
+  1. generate AutoGen.c and AutoGen.h; 2. build all dependent library instances; \r
+  3. build all source files inlcude AutoGen.c; 4. generate sections;\r
+  5. generate FFS file if it is driver module while LIB file if it is Library module. \r
   </p>\r
   \r
   <p>\r
@@ -71,11 +62,16 @@ import org.tianocore.MsaLibHeaderDocument;
   </p>\r
   \r
   <pre>\r
-   &lt;GenBuild baseName=&quot;HelloWorld&quot; \r
-             mbdFilename=&quot;${MODULE_DIR}/HelloWorld.mbd&quot; \r
-             msaFilename=&quot;${MODULE_DIR}/HelloWorld.msa&quot;/&gt;\r
+   &lt;GenBuild  \r
+             msaFilename=&quot;HelloWorld.msa&quot;/&gt; \r
+             processTo=&quot;ALL&quot;/&gt;\r
   </pre>\r
   \r
+  <p><code>processTo</code> provides a way to customize the whole build process. \r
+  processTo can be one value of ALL, AUTOGEN, FILES, LIBRARYINSTANCES, SECTIONS, NONE. \r
+  Default is ALL, means whole \r
+  </p>\r
+  \r
   <p>\r
   This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and\r
   <em>AutoGen.h</em>. The task also parses the development environment\r
@@ -86,85 +82,29 @@ import org.tianocore.MsaLibHeaderDocument;
   \r
   @since GenBuild 1.0\r
 **/\r
-public class GenBuildTask extends Task {\r
-\r
+public class GenBuildTask extends Ant {\r
+    \r
     ///\r
     /// Module surface area file.\r
     ///\r
-    File msaFilename;\r
-\r
-    ///\r
-    /// Module build description file.\r
-    ///\r
-    File mbdFilename;\r
-\r
-    ///\r
-    /// Module surface area information after overrided.\r
-    ///\r
-    public Map<String, XmlObject> map = new HashMap<String, XmlObject>();\r
-\r
-    ///\r
-    /// Module's base name.\r
-    ///\r
-    private String baseName;\r
+    File msaFile;\r
 \r
     ///\r
-    /// Current build Arch, such as IA32, X64, IPF and so on.\r
-    ///\r
-    private String arch;\r
-\r
-    ///\r
-    /// Module's GUID (Globally Unique Identifier).\r
-    ///\r
-    private String guid;\r
-\r
-    ///\r
-    /// Module's component type, such as SEC, LIBRARY, BS_DRIVER and so on.\r
-    ///\r
-    private String componentType;\r
-\r
-    ///\r
-    /// This value is used in build time. Override module's component type. When\r
-    /// search FFS (Sections information) in common file, buildtype instead of\r
-    /// component type.\r
-    ///\r
-    private String buildType;\r
-\r
-    ///\r
-    /// List all required includes for current build module.\r
-    ///\r
-    public Set<String> includes = new LinkedHashSet<String>();\r
-\r
-    ///\r
-    /// List all libraries for current build module.\r
-    ///\r
-    public Set<String> libraries = new LinkedHashSet<String>();\r
-\r
-    ///\r
-    /// List all source files for current build module.\r
-    ///\r
-    public Set<String> sourceFiles = new LinkedHashSet<String>();\r
-\r
-    ///\r
-    /// Flag to identify what surface area files are specified. Current value is\r
-    /// <em>NO_SA</em>, <em>ONLY_MSA</em>, <em>ONLY_LIBMSA</em>,\r
-    /// <em>MSA_AND_MBD</em> or <em>LIBMSA_AND_LIBMBD</em>.\r
     /// \r
-    /// @see org.tianocore.build.global.GlobaData\r
     ///\r
-    private int flag = GlobalData.NO_SA;\r
-\r
+    private String type = "all"; // = "build";\r
+    \r
     ///\r
-    /// The information at the header of <em>build.xml</em>.\r
+    /// Module's Identification.\r
     ///\r
-    private String info = "====================================================================\n"\r
-                        + "DO NOT EDIT \n"\r
-                        + "File auto-generated by build utility\n"\r
-                        + "\n"\r
-                        + "Abstract:\n"\r
-                        + "Auto-generated ANT build file for building of EFI Modules/Platforms\n"\r
-                        + "=====================================================================";\r
+    private ModuleIdentification moduleId;\r
 \r
+    private Vector<Property> properties = new Vector<Property>();\r
+\r
+    private static Stack<Hashtable> backupPropertiesStack = new Stack<Hashtable>();\r
+    \r
+    private boolean isSingleModuleBuild = false;\r
+    \r
     /**\r
       Public construct method. It is necessary for ANT task.\r
     **/\r
@@ -172,920 +112,546 @@ public class GenBuildTask extends Task {
     }\r
 \r
     /**\r
-      ANT task's entry point, will be called after init(). The main steps is described\r
-      as following: \r
-      <ul>\r
-      <li> Judge current build mode (MODULE | PACKAGE | PLATFORM). This step will execute\r
-      only once in whole build process; </li>\r
-      <li> Initialize global information (Framework DB, SPD files and all MSA files \r
-      listed in SPD). This step will execute only once in whole build process; </li>\r
-      <li> Restore some important ANT property. If current build is single module \r
-      build, here will set many default values; </li>\r
-      <li> Get the current module's overridded surface area information from \r
-      global data; </li> \r
-      <li> Set up the output directories, including BIN_DIR, DEST_DIR_OUTPUT and\r
-      DEST_DIR_DEBUG; </li>\r
-      <li> Get module dependent library instances and include pathes; </li>\r
-      <li> Judge whether current module is built. If yes, skip it; </li>\r
-      <li> Call AutoGen and PCD to generate AutoGen.c & AutoGen.h </li>\r
-      <li> Set up the compile flags; </li>\r
-      <li> Generate BaseName_build.xml; </li>\r
-      <li> Call to BaseName_build.xml, and build the current module. </li>\r
-      </ul>\r
-      \r
-      <p>Build is dependent on BuildMacro.xml which define many macro. </p> \r
-      \r
+  \r
       @throws BuildException\r
               From module build, exception from module surface area invalid.\r
     **/\r
     public void execute() throws BuildException {\r
-        System.out.println("Module [" + baseName + "] start.");\r
-        OutputManager.update(getProject());\r
-        GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db",\r
-                            getProject().getProperty("WORKSPACE_DIR"));\r
-        recallFixedProperties();\r
-        arch = getProject().getProperty("ARCH");\r
-        arch = arch.toUpperCase();\r
-        map = GlobalData.getDoc(baseName);\r
-        //\r
-        // Initialize SurfaceAreaQuery\r
-        //\r
-        SurfaceAreaQuery.setDoc(map);\r
-        //\r
-        // Setup Output Management\r
-        //\r
-        String[] outdir = SurfaceAreaQuery.getOutputDirectory();\r
-        OutputManager.update(getProject(), outdir[1], outdir[0]);\r
-\r
-        updateIncludesAndLibraries();\r
-\r
-        if (GlobalData.isModuleBuilt(baseName, arch)) {\r
-            return;\r
-        } else {\r
-            GlobalData.registerBuiltModule(baseName, arch);\r
-        }\r
-        //\r
-        // Call AutoGen\r
-        //\r
-        AutoGen autogen = new AutoGen(getProject().getProperty("DEST_DIR_DEBUG"), baseName, arch);\r
-        autogen.genAutogen();\r
-        //\r
-        // Update parameters\r
+       //\r
+        // set Logger\r
         //\r
-        updateParameters();\r
-        //\r
-        // Update flags like CC_FLAGS, LIB_FLAGS etc.\r
-        //\r
-        flagsSetup();\r
-        GlobalData.addLibrary(baseName, getProject().getProperty("BIN_DIR") + File.separatorChar + baseName + ".lib");\r
-        GlobalData.addModuleLibrary(baseName, libraries);\r
+        GenBuildLogger logger = new GenBuildLogger(getProject());\r
+        EdkLog.setLogLevel(getProject().getProperty("env.LOGLEVEL"));\r
+        EdkLog.setLogger(logger);\r
+        // remove !!\r
+        try {\r
+        pushProperties();\r
         //\r
-        // If ComponentType is USER_DEFINED,\r
-        // then call the exist BaseName_build.xml directly.\r
+        // Enable all specified properties\r
         //\r
-        if (buildType.equalsIgnoreCase("CUSTOM_BUILD")) {\r
-            System.out.println("Call user-defined " + baseName + "_build.xml");\r
-            Ant ant = new Ant();\r
-            ant.setProject(getProject());\r
-            ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + baseName + "_build.xml");\r
-            ant.setInheritAll(true);\r
-            ant.init();\r
-            ant.execute();\r
-            return;\r
+        Iterator<Property> iter = properties.iterator();\r
+        while (iter.hasNext()) {\r
+            Property item = iter.next();\r
+            getProject().setProperty(item.getName(), item.getValue());\r
         }\r
+        \r
         //\r
-        // Generate ${BASE_NAME}_build.xml file\r
+        // GenBuild should specify either msaFile or moduleGuid & packageGuid\r
         //\r
-        System.out.println("Generate " + baseName + "_build.xml");\r
-        genBuildFile();\r
-        System.out.println("Call the " + baseName + "_build.xml");\r
-        Ant ant = new Ant();\r
-        ant.setProject(getProject());\r
-        ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName + "_build.xml");\r
-        ant.setInheritAll(true);\r
-        ant.init();\r
-        ant.execute();\r
-    }\r
-\r
-    /**\r
-      Get the dependent library instances and include package name from \r
-      surface area, and initialize module include pathes. \r
-     \r
-    **/\r
-    private void updateIncludesAndLibraries() {\r
-        List<String> rawIncludes = SurfaceAreaQuery.getIncludePackageName(arch);\r
-        if (rawIncludes != null) {\r
-            Iterator iter = rawIncludes.iterator();\r
-            while (iter.hasNext()) {\r
-                String packageName = (String) iter.next();\r
-                includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)\r
-                             + File.separatorChar + "Include");\r
-                includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)\r
-                             + File.separatorChar + "Include" + File.separatorChar + "${ARCH}");\r
+        if (msaFile == null ) {\r
+            String moduleGuid = getProject().getProperty("MODULE_GUID");\r
+            String moduleVersion = getProject().getProperty("MODULE_VERSION");\r
+            String packageGuid = getProject().getProperty("PACKAGE_GUID");\r
+            String packageVersion = getProject().getProperty("PACKAGE_VERSION");\r
+            if (moduleGuid == null || packageGuid == null) {\r
+                throw new BuildException("GenBuild parameters error. ");\r
             }\r
+            PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion);\r
+            moduleId = new ModuleIdentification(moduleGuid, moduleVersion);\r
+            moduleId.setPackage(packageId);\r
+            Map<String, XmlObject> doc = GlobalData.getNativeMsa(moduleId);\r
+            SurfaceAreaQuery.setDoc(doc);\r
+            moduleId = SurfaceAreaQuery.getMsaHeader();\r
         }\r
-        includes.add("${DEST_DIR_DEBUG}");\r
-        List<String> rawLibraries = SurfaceAreaQuery.getLibraryInstance(this.arch, CommonDefinition.AlwaysConsumed);\r
-        if (rawLibraries != null) {\r
-            Iterator iter = rawLibraries.iterator();\r
-            while (iter.hasNext()) {\r
-                libraries.add((String) iter.next());\r
-            }\r
+        else {\r
+            Map<String, XmlObject> doc = GlobalData.getNativeMsa(msaFile);\r
+            SurfaceAreaQuery.setDoc(doc);\r
+            moduleId = SurfaceAreaQuery.getMsaHeader();\r
         }\r
-        normalize();\r
-    }\r
-\r
-    /**\r
-      Normalize all dependent library instance and include pathes' format. \r
-     \r
-    **/\r
-    private void normalize() {\r
-        String[] includesArray = includes.toArray(new String[includes.size()]);\r
-        includes.clear();\r
-        for (int i = 0; i < includesArray.length; i++) {\r
-            includes.add((new File(includesArray[i])).getPath());\r
+        String[] producedLibraryClasses = SurfaceAreaQuery.getLibraryClasses("ALWAYS_PRODUCED",null);\r
+        if (producedLibraryClasses.length == 0) {\r
+            moduleId.setLibrary(false);\r
         }\r
-        String[] librariesArray = libraries.toArray(new String[libraries.size()]);\r
-        libraries.clear();\r
-        for (int i = 0; i < librariesArray.length; i++) {\r
-            libraries.add((new File(librariesArray[i])).getPath());\r
+        else {\r
+            moduleId.setLibrary(true);\r
         }\r
-    }\r
-\r
-    /**\r
-      Restore some important ANT property. If current build is single module \r
-      build, here will set many default values.\r
-      \r
-      <p> If current build is single module build, then the default <code>ARCH</code>\r
-      is <code>IA32</code>. Also set up the properties <code>PACKAGE</code>, \r
-      <code>PACKAGE_DIR</code>, <code>TARGET</code> and <code>MODULE_DIR</code></p>\r
-      \r
-      <p> Note that for package build, package name is stored in <code>PLATFORM</code>\r
-      and package directory is stored in <code>PLATFORM_DIR</code>. </p> \r
-     \r
-      @see org.tianocore.build.global.OutputManager\r
-    **/\r
-    private void recallFixedProperties() {\r
+        \r
         //\r
-        // If build is for module build\r
+        // Judge whether it is single module build or not\r
         //\r
-        if (getProject().getProperty("PACKAGE_DIR") == null) {\r
-            ToolChainFactory toolChainFactory = new ToolChainFactory(getProject());\r
-            toolChainFactory.setupToolChain();\r
+        if (isSingleModuleBuild) {\r
             //\r
-            // PACKAGE PACKAGE_DIR ARCH (Default) COMMON_FILE BUILD_MACRO\r
+            // Single Module build\r
             //\r
-            if (getProject().getProperty("ARCH") == null) {\r
-                getProject().setProperty("ARCH", "IA32");\r
-            }\r
-            String packageName = GlobalData.getPackageNameForModule(baseName);\r
-            getProject().setProperty("PACKAGE", packageName);\r
-            \r
-            String packageDir = GlobalData.getPackagePath(packageName);\r
-            getProject().setProperty("PACKAGE_DIR",\r
-                                     getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + packageDir);\r
-            \r
-            getProject().setProperty("TARGET", toolChainFactory.getCurrentTarget());\r
+            prepareSingleModuleBuild();\r
+        }\r
+        else {\r
+            //\r
+            // Platform build. Restore the platform related info\r
+            //\r
+            String filename = getProject().getProperty("PLATFORM_FILE");\r
+            PlatformIdentification platformId = GlobalData.getPlatform(filename);\r
+            getProject().setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));\r
+            getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));\r
             \r
-            getProject().setProperty("MODULE_DIR",\r
-                                     getProject().replaceProperties(getProject().getProperty("MODULE_DIR")));\r
+            String packageGuid = getProject().getProperty("PACKAGE_GUID");\r
+            String packageVersion = getProject().getProperty("PACKAGE_VERSION");\r
+            PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion);\r
+            moduleId.setPackage(packageId);\r
         }\r
-        if (OutputManager.PLATFORM != null) {\r
-            getProject().setProperty("PLATFORM", OutputManager.PLATFORM);\r
+        \r
+        //\r
+        // If single module : intersection MSA supported ARCHs and tools def!!\r
+        // else, get arch from pass down\r
+        //\r
+        String[] archList = new String[0];\r
+        if ( getProject().getProperty("ARCH") != null ) {\r
+            archList = getProject().getProperty("ARCH").split(" ");\r
         }\r
-        if (OutputManager.PLATFORM_DIR != null) {\r
-            getProject().setProperty("PLATFORM_DIR", OutputManager.PLATFORM_DIR);\r
+        else {\r
+            archList = GlobalData.getToolChainInfo().getArchs();\r
         }\r
-    }\r
-\r
-    /**\r
-      The whole BaseName_build.xml is composed of seven part. \r
-      <ul>\r
-      <li> ANT properties; </li>\r
-      <li> Dependent module (dependent library instances in most case); </li>\r
-      <li> Source files; </li>\r
-      <li> Sections if module is not library; </li>\r
-      <li> Output (different for library module and driver module); </li>\r
-      <li> Clean; </li>\r
-      <li> Clean all. </li>\r
-      </ul>\r
-      \r
-      @throws BuildException\r
-              Error throws during BaseName_build.xml generating. \r
-    **/\r
-    private void genBuildFile() throws BuildException {\r
-        FfsProcess fp = new FfsProcess();\r
-        DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();\r
-        try {\r
-            DocumentBuilder dombuilder = domfac.newDocumentBuilder();\r
-            Document document = dombuilder.newDocument();\r
-            Comment rootComment = document.createComment(info);\r
-            //\r
-            // create root element and its attributes\r
-            //\r
-            Element root = document.createElement("project");\r
-            //\r
-            // root.setAttribute("name", base_name);\r
-            //\r
-            root.setAttribute("default", "main");\r
-            root.setAttribute("basedir", ".");\r
-            //\r
-            // element for External ANT tasks\r
-            //\r
-            root.appendChild(document.createComment("Apply external ANT tasks"));\r
-            Element ele = document.createElement("taskdef");\r
-            ele.setAttribute("resource", "frameworktasks.tasks");\r
-            root.appendChild(ele);\r
-            ele = document.createElement("taskdef");\r
-            ele.setAttribute("resource", "cpptasks.tasks");\r
-            root.appendChild(ele);\r
-            ele = document.createElement("typedef");\r
-            ele.setAttribute("resource", "cpptasks.types");\r
-            root.appendChild(ele);\r
-            ele = document.createElement("taskdef");\r
-            ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");\r
-            root.appendChild(ele);\r
-            //\r
-            // elements for Properties\r
-            //\r
-            root.appendChild(document.createComment("All Properties"));\r
-            ele = document.createElement("property");\r
-            ele.setAttribute("name", "BASE_NAME");\r
-            ele.setAttribute("value", baseName);\r
-            root.appendChild(ele);\r
-            //\r
-            // Generate the default target,\r
-            // which depends on init, sections and output target\r
-            //\r
-            root.appendChild(document.createComment("Default target"));\r
-            ele = document.createElement("target");\r
-            ele.setAttribute("name", "main");\r
-            ele.setAttribute("depends", "libraries, sourcefiles, sections, output");\r
-            root.appendChild(ele);\r
-            //\r
-            // compile all source files\r
-            //\r
-            root.appendChild(document.createComment("Compile all dependency Library instances."));\r
-            ele = document.createElement("target");\r
-            ele.setAttribute("name", "libraries");\r
-            //\r
-            // Parse all sourfiles but files specified in sections\r
-            //\r
-            applyLibraryInstance(document, ele);\r
-            root.appendChild(ele);\r
-            //\r
-            // compile all source files\r
-            //\r
-            root.appendChild(document.createComment("sourcefiles target"));\r
-            ele = document.createElement("target");\r
-            ele.setAttribute("name", "sourcefiles");\r
-            //\r
-            // Parse all sourfiles but files specified in sections\r
-            //\r
-            applyCompileElement(document, ele);\r
-            root.appendChild(ele);\r
-            //\r
-            // generate the init target\r
-            // main purpose is create all nessary pathes\r
-            // generate the sections target\r
-            //\r
-            root.appendChild(document.createComment("sections target"));\r
-            ele = document.createElement("target");\r
-            ele.setAttribute("name", "sections");\r
-            applySectionsElement(document, ele, fp);\r
-            root.appendChild(ele);\r
-            //\r
-            // generate the output target\r
-            //\r
-            root.appendChild(document.createComment("output target"));\r
-            ele = document.createElement("target");\r
-            ele.setAttribute("name", "output");\r
-            applyOutputElement(document, ele, fp);\r
-            root.appendChild(ele);\r
-            //\r
-            // generate the clean target\r
-            //\r
-            root.appendChild(document.createComment("clean target"));\r
-            ele = document.createElement("target");\r
-            ele.setAttribute("name", "clean");\r
-            applyCleanElement(document, ele);\r
-            root.appendChild(ele);\r
-            //\r
-            // generate the Clean All target\r
-            //\r
-            root.appendChild(document.createComment("Clean All target"));\r
-            ele = document.createElement("target");\r
-            ele.setAttribute("name", "cleanall");\r
-            applyDeepcleanElement(document, ele);\r
-            root.appendChild(ele);\r
-            //\r
-            // add the root element to the document\r
-            //\r
-            document.appendChild(rootComment);\r
-            document.appendChild(root);\r
-            //\r
-            // Prepare the DOM document for writing\r
-            //\r
-            Source source = new DOMSource(document);\r
-            //\r
-            // Prepare the output file\r
-            //\r
-            File file = new File(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName\r
-                                 + "_build.xml");\r
-            //\r
-            // generate all directory path\r
-            //\r
-            (new File(file.getParent())).mkdirs();\r
-            Result result = new StreamResult(file);\r
-            //\r
-            // Write the DOM document to the file\r
-            //\r
-            Transformer xformer = TransformerFactory.newInstance().newTransformer();\r
-            xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");\r
-            xformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
-            xformer.transform(source, result);\r
-        } catch (Exception ex) {\r
-            throw new BuildException("Module [" + baseName + "] generating build file failed.\n" + ex.getMessage());\r
+        \r
+        \r
+        //\r
+        // Judge if arch is all supported by current module. If not, throw Exception.\r
+        //\r
+        List moduleSupportedArchs = SurfaceAreaQuery.getModuleSupportedArchs();\r
+        if (moduleSupportedArchs != null) {\r
+            for (int k = 0; k < archList.length; k++) {\r
+                if ( ! moduleSupportedArchs.contains(archList[k])) {\r
+                    throw new BuildException("ARCH [" + archList[k] + "] is not supported by " + moduleId + ". " + moduleId + " only supports [" + moduleSupportedArchs + "].");\r
+                }\r
+            }\r
         }\r
-    }\r
-\r
-    /**\r
-      Generate the clean elements for BaseName_build.xml. \r
-      \r
-      @param document current BaseName_build.xml XML document\r
-      @param root Root element for current\r
-    **/\r
-    private void applyCleanElement(Document document, Node root) {\r
-        String[] libinstances = libraries.toArray(new String[libraries.size()]);\r
-        for (int i = 0; i < libinstances.length; i++) {\r
-            File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");\r
-\r
-            Element ifEle = document.createElement("if");\r
-            Element availableEle = document.createElement("available");\r
-            availableEle.setAttribute("file", file.getPath());\r
-            ifEle.appendChild(availableEle);\r
-            Element elseEle = document.createElement("then");\r
-\r
-            Element ele = document.createElement("ant");\r
-            ele.setAttribute("antfile", file.getPath());\r
-            ele.setAttribute("inheritAll", "false");\r
-            ele.setAttribute("target", libinstances[i] + "_clean");\r
-            //\r
-            // Workspace_DIR\r
-            //\r
-            Element property = document.createElement("property");\r
-            property.setAttribute("name", "WORKSPACE_DIR");\r
-            property.setAttribute("value", "${WORKSPACE_DIR}");\r
-            ele.appendChild(property);\r
-            //\r
-            // Package Dir\r
-            //\r
-            property = document.createElement("property");\r
-            property.setAttribute("name", "PACKAGE_DIR");\r
-            property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar\r
-                                           + GlobalData.getPackagePathForModule(libinstances[i]));\r
-            ele.appendChild(property);\r
-            //\r
-            // ARCH\r
-            //\r
-            property = document.createElement("property");\r
-            property.setAttribute("name", "ARCH");\r
-            property.setAttribute("value", "${ARCH}");\r
-            ele.appendChild(property);\r
-            //\r
-            // TARGET\r
+        \r
+        for (int k = 0; k < archList.length; k++) {\r
+            getProject().setProperty("ARCH", archList[k]);\r
+            \r
+            FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, archList[k]);\r
+            \r
             //\r
-            property = document.createElement("property");\r
-            property.setAttribute("name", "TARGET");\r
-            property.setAttribute("value", "${TARGET}");\r
-            ele.appendChild(property);\r
+            // Whether the module is built before\r
             //\r
-            // PACKAGE\r
+            if (GlobalData.isModuleBuilt(fpdModuleId)) {\r
+                return ;\r
+            }\r
+            else {\r
+                GlobalData.registerBuiltModule(fpdModuleId);\r
+            }\r
+            \r
             //\r
-            property = document.createElement("property");\r
-            property.setAttribute("name", "PACKAGE");\r
-            property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));\r
-            ele.appendChild(property);\r
-\r
-            elseEle.appendChild(ele);\r
-            ifEle.appendChild(elseEle);\r
-            root.appendChild(ifEle);\r
+            // For Every TOOLCHAIN, TARGET\r
+            //\r
+            String[] targetList =  GlobalData.getToolChainInfo().getTargets();\r
+            for (int i = 0; i < targetList.length; i ++){\r
+                //\r
+                // Prepare for target related common properties\r
+                // TARGET\r
+                //\r
+                getProject().setProperty("TARGET", targetList[i]);\r
+                String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
+                for(int j = 0; j < toolchainList.length; j ++){\r
+                    //\r
+                    // check if any tool is defined for current target + toolchain + arch\r
+                    // don't do anything if no tools found\r
+                    // \r
+                    if (GlobalData.isCommandSet(targetList[i], toolchainList[j], archList[k]) == false) {\r
+                        System.out.println("Warning: No build issued. No tools found for [target=" + targetList[i] + " toolchain=" + toolchainList[j] + " arch=" + archList[k] + "]\n");\r
+                        continue;\r
+                    }\r
+\r
+                    //\r
+                    // Prepare for toolchain related common properties\r
+                    // TOOLCHAIN\r
+                    //\r
+                    getProject().setProperty("TOOLCHAIN", toolchainList[j]);\r
+\r
+                    System.out.println("Build " + moduleId + " start >>>");\r
+                    System.out.println("Target: " + targetList[i] + " Tagname: " + toolchainList[j] + " Arch: " + archList[k]);\r
+                    SurfaceAreaQuery.setDoc(GlobalData.getDoc(fpdModuleId));\r
+                    \r
+                    //\r
+                    // Prepare for all other common properties\r
+                    // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR\r
+                    // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE\r
+                    // MODULE_DIR, MODULE_RELATIVE_DIR\r
+                    // SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH\r
+                    // LIBS, OBJECTS, SDB_FILES\r
+                    //\r
+                    setModuleCommonProperties(archList[k]);\r
+                    \r
+                    //\r
+                    // OutputManage prepare for \r
+                    // BIN_DIR, DEST_DIR_DEBUG, DEST_DIR_OUTPUT, BUILD_DIR, FV_DIR\r
+                    //\r
+                    OutputManager.getInstance().update(getProject());\r
+                    \r
+                    if (type.equalsIgnoreCase("all") || type.equalsIgnoreCase("build")) {\r
+                        applyBuild(targetList[i], toolchainList[j], fpdModuleId);\r
+                    }\r
+                    else if (type.equalsIgnoreCase("clean")) {\r
+                        applyClean(fpdModuleId);\r
+                    }\r
+                    else if (type.equalsIgnoreCase("cleanall")) {\r
+                        applyCleanall(fpdModuleId);\r
+                    }\r
+                }\r
+            }\r
         }\r
-    }\r
-\r
-    /**\r
-      Generate the cleanall elements for BaseName_build.xml. \r
-      \r
-      @param document current BaseName_build.xml XML document\r
-      @param root Root element for current\r
-    **/\r
-    private void applyDeepcleanElement(Document document, Node root) {\r
-        String[] libinstances = libraries.toArray(new String[libraries.size()]);\r
-        for (int i = 0; i < libinstances.length; i++) {\r
-            File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");\r
-\r
-            Element ifEle = document.createElement("if");\r
-            Element availableEle = document.createElement("available");\r
-            availableEle.setAttribute("file", file.getPath());\r
-            ifEle.appendChild(availableEle);\r
-            Element elseEle = document.createElement("then");\r
-\r
-            Element ele = document.createElement("ant");\r
-            ele.setAttribute("antfile", file.getPath());\r
-            ele.setAttribute("inheritAll", "false");\r
-            ele.setAttribute("target", libinstances[i] + "_cleanall");\r
-            //\r
-            // Workspace_DIR\r
-            //\r
-            Element property = document.createElement("property");\r
-            property.setAttribute("name", "WORKSPACE_DIR");\r
-            property.setAttribute("value", "${WORKSPACE_DIR}");\r
-            ele.appendChild(property);\r
-            //\r
-            // Package Dir\r
-            //\r
-            property = document.createElement("property");\r
-            property.setAttribute("name", "PACKAGE_DIR");\r
-            property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar\r
-                                           + GlobalData.getPackagePathForModule(libinstances[i]));\r
-            ele.appendChild(property);\r
-            //\r
-            // ARCH\r
-            //\r
-            property = document.createElement("property");\r
-            property.setAttribute("name", "ARCH");\r
-            property.setAttribute("value", "${ARCH}");\r
-            ele.appendChild(property);\r
-            //\r
-            // TARGET\r
-            //\r
-            property = document.createElement("property");\r
-            property.setAttribute("name", "TARGET");\r
-            property.setAttribute("value", "${TARGET}");\r
-            ele.appendChild(property);\r
-            //\r
-            // PACKAGE\r
-            //\r
-            property = document.createElement("property");\r
-            property.setAttribute("name", "PACKAGE");\r
-            property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));\r
-            ele.appendChild(property);\r
-\r
-            elseEle.appendChild(ele);\r
-            ifEle.appendChild(elseEle);\r
-            root.appendChild(ifEle);\r
+        popProperties();\r
+        }catch (Exception e){\r
+            throw new BuildException(e.getMessage());\r
         }\r
     }\r
 \r
     /**\r
-      Generate the dependent library instances elements for BaseName_build.xml\r
+      This method is used to prepare Platform-related information\r
       \r
-      @param document current BaseName_build.xml XML document\r
-      @param root Root element for current\r
-    **/\r
-    private void applyLibraryInstance(Document document, Node root) {\r
-        String[] libinstances = libraries.toArray(new String[libraries.size()]);\r
-        for (int i = 0; i < libinstances.length; i++) {\r
-            Element ele = document.createElement("ant");\r
-            File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");\r
-            ele.setAttribute("antfile", file.getPath());\r
-            ele.setAttribute("inheritAll", "false");\r
-            ele.setAttribute("target", libinstances[i]);\r
-            //\r
-            // Workspace_DIR\r
-            //\r
-            Element property = document.createElement("property");\r
-            property.setAttribute("name", "WORKSPACE_DIR");\r
-            property.setAttribute("value", "${WORKSPACE_DIR}");\r
-            ele.appendChild(property);\r
-            //\r
-            // Package Dir\r
-            //\r
-            property = document.createElement("property");\r
-            property.setAttribute("name", "PACKAGE_DIR");\r
-            property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar\r
-                                           + GlobalData.getPackagePathForModule(libinstances[i]));\r
-            ele.appendChild(property);\r
-            //\r
-            // ARCH\r
-            //\r
-            property = document.createElement("property");\r
-            property.setAttribute("name", "ARCH");\r
-            property.setAttribute("value", "${ARCH}");\r
-            ele.appendChild(property);\r
-            //\r
-            // TARGET\r
-            //\r
-            property = document.createElement("property");\r
-            property.setAttribute("name", "TARGET");\r
-            property.setAttribute("value", "${TARGET}");\r
-            ele.appendChild(property);\r
-            //\r
-            // PACKAGE\r
-            //\r
-            property = document.createElement("property");\r
-            property.setAttribute("name", "PACKAGE");\r
-            property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));\r
-            ele.appendChild(property);\r
-            root.appendChild(ele);\r
-        }\r
-        Element expand = document.createElement("Expand");\r
-        root.appendChild(expand);\r
-    }\r
-    \r
-    /**\r
-      Generate the build source files elements for BaseName_build.xml. \r
-      \r
-      @param document current BaseName_build.xml XML document\r
-      @param root Root element for current\r
+      <p>In Single Module Build mode, platform-related information is not ready.\r
+      The method read the system environment variable <code>ACTIVE_PLATFORM</code> \r
+      and search in the Framework Database. Note that platform name in the Framework\r
+      Database must be unique. </p>\r
+     \r
     **/\r
-    private void applyCompileElement(Document document, Node root) {\r
-        FileProcess fileProcess = new FileProcess();\r
-        fileProcess.init(getProject(), includes, sourceFiles, document);\r
-        Node[] files = this.getSourceFiles();\r
+    private void prepareSingleModuleBuild(){\r
         //\r
-        // Parse all unicode files\r
+        // Find out the package which the module belongs to\r
+        // TBD: Enhance it!!!!\r
         //\r
-        for (int i = 0; i < files.length; i++) {\r
-            String filetype = getFiletype(files[i]);\r
-            if (filetype != null) {\r
-                fileProcess.parseFile(getFilename(files[i]), filetype, root, true);\r
-            } else {\r
-                fileProcess.parseFile(getFilename(files[i]), root, true);\r
-            }\r
-        }\r
-        if (fileProcess.isUnicodeExist()) {\r
-            Element ele = document.createElement("Build_Unicode_Database");\r
-            ele.setAttribute("FILEPATH", ".");\r
-            ele.setAttribute("FILENAME", "${BASE_NAME}");\r
-            root.appendChild(ele);\r
-        }\r
-\r
+        PackageIdentification packageId = GlobalData.getPackageForModule(moduleId);\r
+        \r
+        moduleId.setPackage(packageId);\r
+        \r
         //\r
-        // Parse AutoGen.c & AutoGen.h\r
+        // Read ACTIVE_PLATFORM's FPD file (Call FpdParserTask's method)\r
         //\r
-        if (!baseName.equalsIgnoreCase("Shell")) {\r
-            fileProcess.parseFile(getProject().getProperty("DEST_DIR_DEBUG") + File.separatorChar + "AutoGen.c", root,\r
-                                  false);\r
+        String filename = getProject().getProperty("PLATFORM_FILE");\r
+        \r
+        if (filename == null){\r
+            throw new BuildException("Plese set ACTIVE_PLATFORM if you want to build a single module. ");\r
         }\r
+        \r
+        PlatformIdentification platformId = GlobalData.getPlatform(filename);\r
+        \r
         //\r
-        // Parse all source files\r
+        // Read FPD file\r
         //\r
-        for (int i = 0; i < files.length; i++) {\r
-            String filetype = getFiletype(files[i]);\r
-            if (filetype != null) {\r
-                fileProcess.parseFile(getFilename(files[i]), filetype, root, false);\r
-            } else {\r
-                fileProcess.parseFile(getFilename(files[i]), root, false);\r
-            }\r
-        }\r
+        FpdParserTask fpdParser = new FpdParserTask();\r
+        fpdParser.setProject(getProject());\r
+        fpdParser.parseFpdFile(platformId.getFpdFile());\r
+        \r
         //\r
-        // root.appendChild(parallelEle);\r
+        // Prepare for Platform related common properties\r
+        // PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR\r
         //\r
-        Iterator iter = sourceFiles.iterator();\r
-        String str = "";\r
-        while (iter.hasNext()) {\r
-            str += " " + (String) iter.next();\r
-        }\r
-        getProject().setProperty("SOURCE_FILES", str);\r
+        getProject().setProperty("PLATFORM", platformId.getName());\r
+        getProject().setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));\r
+        getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));\r
     }\r
 \r
-    /**\r
-      Generate the section elements for BaseName_build.xml. Library module will\r
-      skip this process.  \r
-      \r
-      @param document current BaseName_build.xml XML document\r
-      @param root Root element for current\r
-    **/\r
-    private void applySectionsElement(Document document, Node root, FfsProcess fp) {\r
-        if (fp.initSections(buildType, getProject())) {\r
-            String targetFilename = guid + "-" + baseName + FpdParserTask.getSuffix(componentType);\r
-            String[] list = fp.getGenSectionElements(document, baseName, guid, targetFilename);\r
-\r
-            for (int i = 0; i < list.length; i++) {\r
-                Element ele = document.createElement(list[i]);\r
-                ele.setAttribute("FILEPATH", ".");\r
-                ele.setAttribute("FILENAME", "${BASE_NAME}");\r
-                root.appendChild(ele);\r
-            }\r
-        }\r
-    }\r
 \r
     /**\r
-      Generate the output elements for BaseName_build.xml. If module is library,\r
-      call the <em>LIB</em> command, else call the <em>GenFfs</em> command. \r
-      \r
-      @param document current BaseName_build.xml XML document\r
-      @param root Root element for current\r
+      Set Module-Related information to properties.\r
     **/\r
-    private void applyOutputElement(Document document, Node root, FfsProcess fp) {\r
-        if (flag == GlobalData.ONLY_LIBMSA || flag == GlobalData.LIBMSA_AND_LIBMBD) {\r
-            //\r
-            // call Lib command\r
-            //\r
-            Element cc = document.createElement("Build_Library");\r
-            cc.setAttribute("FILENAME", baseName);\r
-            root.appendChild(cc);\r
-        }\r
+    private void setModuleCommonProperties(String arch) {\r
         //\r
-        // if it is a module but library\r
+        // Prepare for all other common properties\r
+        // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR\r
         //\r
+        PackageIdentification packageId = moduleId.getPackage();\r
+        getProject().setProperty("PACKAGE", packageId.getName());\r
+        getProject().setProperty("PACKAGE_GUID", packageId.getGuid());\r
+        getProject().setProperty("PACKAGE_VERSION", packageId.getVersion());\r
+        getProject().setProperty("PACKAGE_DIR", packageId.getPackageDir().replaceAll("(\\\\)", "/"));\r
+        getProject().setProperty("PACKAGE_RELATIVE_DIR", packageId.getPackageRelativeDir().replaceAll("(\\\\)", "/"));\r
+        \r
+        //\r
+        // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE\r
+        // MODULE_DIR, MODULE_RELATIVE_DIR\r
+        //\r
+        getProject().setProperty("MODULE", moduleId.getName());\r
+        String baseName = SurfaceAreaQuery.getModuleOutputFileBasename();\r
+        if (baseName == null) {\r
+            getProject().setProperty("BASE_NAME", moduleId.getName());\r
+        }\r
         else {\r
-            if (fp.getFfsNode() != null) {\r
-                root.appendChild(fp.getFfsNode());\r
+            getProject().setProperty("BASE_NAME", baseName);\r
+        }\r
+        getProject().setProperty("GUID", moduleId.getGuid());\r
+        getProject().setProperty("FILE_GUID", moduleId.getGuid());\r
+        getProject().setProperty("VERSION", moduleId.getVersion());\r
+        getProject().setProperty("MODULE_TYPE", moduleId.getModuleType());\r
+        getProject().setProperty("MODULE_DIR", moduleId.getMsaFile().getParent().replaceAll("(\\\\)", "/"));\r
+        getProject().setProperty("MODULE_RELATIVE_DIR", moduleId.getModuleRelativePath().replaceAll("(\\\\)", "/"));\r
+        \r
+        //\r
+        // SUBSYSTEM\r
+        //\r
+        String[][] subsystemMap = { { "BASE", "EFI_BOOT_SERVICE_DRIVER"},\r
+                                    { "SEC", "EFI_BOOT_SERVICE_DRIVER" }, \r
+                                    { "PEI_CORE", "EFI_BOOT_SERVICE_DRIVER" }, \r
+                                    { "PEIM", "EFI_BOOT_SERVICE_DRIVER" }, \r
+                                    { "DXE_CORE", "EFI_BOOT_SERVICE_DRIVER" },\r
+                                    { "DXE_DRIVER", "EFI_BOOT_SERVICE_DRIVER" }, \r
+                                    { "DXE_RUNTIME_DRIVER", "EFI_RUNTIME_DRIVER" }, \r
+                                    { "DXE_SAL_DRIVER", "EFI_BOOT_SERVICE_DRIVER" }, \r
+                                    { "DXE_SMM_DRIVER", "EFI_BOOT_SERVICE_DRIVER" }, \r
+                                    { "TOOL", "EFI_BOOT_SERVICE_DRIVER" }, \r
+                                    { "UEFI_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
+                                    { "UEFI_APPLICATION", "EFI_APPLICATION" }, \r
+                                    { "USER_DEFINED", "EFI_BOOT_SERVICE_DRIVER"} }; \r
+        \r
+        String subsystem = "EFI_BOOT_SERVICE_DRIVER";\r
+        for (int i = 0; i < subsystemMap.length; i++) {\r
+            if (moduleId.getModuleType().equalsIgnoreCase(subsystemMap[i][0])) {\r
+                subsystem = subsystemMap[i][1];\r
+                break ;\r
             }\r
         }\r
-    }\r
-\r
-    /**\r
-      Get file name from node. If some wrong, return string with zero length. \r
-      \r
-       @param node Filename node of MSA/MBD or specified in each Section\r
-       @return File name\r
-    **/\r
-    private String getFilename(Node node) {\r
-        String path = null;\r
-        String filename = "${MODULE_DIR}" + File.separatorChar;\r
-        String str = "";\r
-        try {\r
-            FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);\r
-            str = file.getFilename().getStringValue().trim();\r
-            path = file.getFilename().getPath();\r
-        } catch (Exception e) {\r
-            str = "";\r
-        }\r
-        if (path != null) {\r
-            filename += path + File.separatorChar + str;\r
-        } else {\r
-            filename += str;\r
-        }\r
-        return getProject().replaceProperties(filename);\r
-    }\r
-\r
-    /**\r
-      Get file type from node. If some wrong or not specified, return \r
-      <code>null</code>.  \r
-      \r
-      @param node Filename node of MSA/MBD or specified in each Section\r
-      @return File type\r
-    **/\r
-    private String getFiletype(Node node) {\r
-        String str = null;\r
-        try {\r
-            FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);\r
-            str = file.getFilename().getFileType();\r
-        } catch (Exception e) {\r
-            str = null;\r
-        }\r
-        return str;\r
-    }\r
-\r
-    /**\r
-      Return all source files but AutoGen.c.\r
-      \r
-      @return source files Node array\r
-    **/\r
-    public Node[] getSourceFiles() {\r
-        XmlObject[] files = SurfaceAreaQuery.getSourceFiles(arch);\r
-        if (files == null) {\r
-            return new Node[0];\r
+        getProject().setProperty("SUBSYSTEM", subsystem);\r
+        \r
+        //\r
+        // ENTRYPOINT\r
+        //\r
+        if (arch.equalsIgnoreCase("EBC")) {\r
+            getProject().setProperty("ENTRYPOINT", "EfiStart");\r
         }\r
-        Vector<Node> vector = new Vector<Node>();\r
-        for (int i = 0; i < files.length; i++) {\r
-            vector.addElement(files[i].getDomNode());\r
+        else {\r
+            getProject().setProperty("ENTRYPOINT", "_ModuleEntryPoint");\r
         }\r
+        \r
         //\r
-        // To be consider sourcefiles from Sections\r
+        // LIBS, OBJECTS, SDB_FILES\r
         //\r
-        return vector.toArray(new Node[vector.size()]);\r
-    }\r
-\r
-    /**\r
-      Get current module's base name. \r
-      \r
-      @return base name\r
-    **/\r
-    public String getBaseName() {\r
-        return baseName;\r
-    }\r
-\r
-    /**\r
-      Set MBD surface area file. For ANT use.\r
-      \r
-      @param mbdFilename Surface Area file\r
-    **/\r
-    public void setMbdFilename(File mbdFilename) {\r
-        this.mbdFilename = mbdFilename;\r
-    }\r
-\r
-    /**\r
-      Set MSA surface area file. For ANT use.\r
-      \r
-      @param msaFilename Surface Area file\r
-    **/\r
-    public void setMsaFilename(File msaFilename) {\r
-        this.msaFilename = msaFilename;\r
+        getProject().setProperty("OBJECTS", "");\r
+        getProject().setProperty("SDB_FILES", "");\r
+        getProject().setProperty("LIBS", "");\r
     }\r
 \r
-    /**\r
-      Compile flags setup. \r
-      \r
-      <p> Take command <code>CC</code> and arch <code>IA32</code> for example, \r
-      Those flags are from <code>ToolChainFactory</code>: </p>\r
-      <ul>\r
-      <li> IA32_CC </li>\r
-      <li> IA32_CC_STD_FLAGS </li>\r
-      <li> IA32_CC_GLOBAL_FLAGS </li>\r
-      <li> IA32_CC_GLOBAL_ADD_FLAGS </li>\r
-      <li> IA32_CC_GLOBAL_SUB_FLAGS </li>\r
-      </ul>\r
-      Those flags can user-define: \r
-      <ul>\r
-      <li> IA32_CC_PROJ_FLAGS </li>\r
-      <li> IA32_CC_PROJ_ADD_FLAGS </li>\r
-      <li> IA32_CC_PROJ_SUB_FLAGS </li>\r
-      <li> CC_PROJ_FLAGS </li>\r
-      <li> CC_PROJ_ADD_FLAGS </li>\r
-      <li> CC_PROJ_SUB_FLAGS </li>\r
-      <li> CC_FLAGS </li>\r
-      <li> IA32_CC_FLAGS </li>\r
-      </ul>\r
-      \r
-      <p> The final flags is composed of STD, GLOBAL and PROJ. If CC_FLAGS or\r
-      IA32_CC_FLAGS is specified, STD, GLOBAL and PROJ will not affect. </p>\r
-      \r
-      Note that the <code>ToolChainFactory</code> executes only once \r
-      during whole build process. \r
-    **/\r
-    private void flagsSetup() {\r
-        Project project = getProject();\r
-        //\r
-        // If ToolChain has been set up before, do nothing.\r
-        //\r
-        ToolChainFactory toolChainFactory = new ToolChainFactory(project);\r
-        toolChainFactory.setupToolChain();\r
-\r
-        String[] cmd = ToolChainFactory.commandType;\r
-        Set<String> addSet = new HashSet<String>(40);\r
-        Set<String> subSet = new HashSet<String>(40);\r
-        for (int i = 0; i < cmd.length; i++) {\r
-            String str = ToolChainFactory.getValue(arch + "_" + cmd[i]);\r
-            //\r
-            // Command line path+command name\r
-            //\r
-            if (str != null) {\r
-                project.setProperty(cmd[i], str);\r
-            }\r
-            //\r
-            // ARCH_CMD_STD_FLAGS\r
+    private void getCompilerFlags(String target, String toolchain, FpdModuleIdentification fpdModuleId) throws EdkException {\r
+        String[] cmd = GlobalData.getToolChainInfo().getCommands();\r
+        for ( int m = 0; m < cmd.length; m++) {\r
             //\r
-            str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_STD_FLAGS");\r
-            if (str != null) {\r
-                putFlagsToSet(addSet, str);\r
-                project.setProperty(cmd[i] + "_STD_FLAGS", str);\r
-            }\r
-            //\r
-            // ARCH_CMD_GLOBAL_FLAGS\r
-            //\r
-            str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_FLAGS");\r
-            if (str != null) {\r
-                putFlagsToSet(addSet, str);\r
-            }\r
-            //\r
-            // ARCH_CMD_GLOBAL_ADD_FLAGS\r
-            //\r
-            str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_ADD_FLAGS");\r
-            if (str != null) {\r
-                putFlagsToSet(addSet, str);\r
-            }\r
+            // Set cmd, like CC, DLINK\r
             //\r
-            // ARCH_CMD_GLOBAL_SUB_FLAGS\r
-            //\r
-            str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_SUB_FLAGS");\r
-            if (str != null) {\r
-                putFlagsToSet(subSet, str);\r
-            }\r
+            String[] key = new String[]{target, toolchain, fpdModuleId.getArch(), cmd[m], null};\r
+            key[4] = "PATH";\r
+            String cmdPath = GlobalData.getCommandSetting(key, fpdModuleId);\r
+            key[4] = "NAME";\r
+            String cmdName = GlobalData.getCommandSetting(key, fpdModuleId);\r
+            File cmdFile = new File(cmdPath + File.separatorChar + cmdName);\r
+            getProject().setProperty(cmd[m], cmdFile.getPath().replaceAll("(\\\\)", "/"));\r
+            \r
             //\r
-            // ARCH_CMD_PROJ_FLAGS\r
+            // set CC_FLAGS\r
             //\r
-            str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_FLAGS");\r
-            if (str != null) {\r
-                putFlagsToSet(addSet, str);\r
-            }\r
+            key[4] = "FLAGS";\r
+            String cmdFlags = GlobalData.getCommandSetting(key, fpdModuleId);\r
+            Set<String> addset = new LinkedHashSet<String>();\r
+            Set<String> subset = new LinkedHashSet<String>();\r
+            putFlagsToSet(addset, cmdFlags);\r
+            getProject().setProperty(cmd[m] + "_FLAGS", getProject().replaceProperties(getFlags(addset, subset)));\r
+            \r
             //\r
-            // ARCH_CMD_PROG_FLAGS\r
+            // Set CC_EXT\r
             //\r
-            str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_ADD_FLAGS");\r
-            if (str != null) {\r
-                putFlagsToSet(addSet, str);\r
+            key[4] = "EXT";\r
+            String extName = GlobalData.getCommandSetting(key, fpdModuleId);\r
+            if ( extName != null && ! extName.equalsIgnoreCase("")) {\r
+                getProject().setProperty(cmd[m] + "_EXT", extName);\r
             }\r
-            //\r
-            // ARCH_CMD_PROG_FLAGS\r
-            //\r
-            str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_SUB_FLAGS");\r
-            if (str != null) {\r
-                putFlagsToSet(subSet, str);\r
+            else {\r
+                getProject().setProperty(cmd[m] + "_EXT", "");\r
             }\r
+            \r
             //\r
-            // CMD_PROJ_FLAGS\r
+            // set CC_FAMILY\r
             //\r
-            str = project.getProperty(cmd[i] + "_PROJ_FLAGS");\r
-            if (str != null) {\r
-                putFlagsToSet(addSet, str);\r
+            key[4] = "FAMILY";\r
+            String toolChainFamily = GlobalData.getCommandSetting(key, fpdModuleId);\r
+            if (toolChainFamily != null) {\r
+                getProject().setProperty(cmd[m] + "_FAMILY", toolChainFamily);\r
             }\r
+            \r
             //\r
-            // CMD_PROG_FLAGS\r
+            // set CC_SPATH\r
             //\r
-            str = project.getProperty(cmd[i] + "_PROJ_ADD_FLAGS");\r
-            if (str != null) {\r
-                putFlagsToSet(addSet, str);\r
+            key[4] = "SPATH";\r
+            String spath = GlobalData.getCommandSetting(key, fpdModuleId);\r
+            if (spath != null) {\r
+                getProject().setProperty(cmd[m] + "_SPATH", spath.replaceAll("(\\\\)", "/"));\r
             }\r
-            //\r
-            // CMD_PROG_FLAGS\r
-            //\r
-            str = project.getProperty(cmd[i] + "_PROJ_SUB_FLAGS");\r
-            if (str != null) {\r
-                putFlagsToSet(subSet, str);\r
+            else {\r
+                getProject().setProperty(cmd[m] + "_SPATH", "");\r
             }\r
+            \r
             //\r
-            // If IA32_CC_FLAGS or IA32_LIB_FLAGS .. has defined in BuildOptions\r
+            // set CC_DPATH\r
             //\r
-            if ((str = project.getProperty(arch + "_" + cmd[i] + "_FLAGS")) != null) {\r
-                project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));\r
-                addSet.clear();\r
-                subSet.clear();\r
-                putFlagsToSet(addSet, project.replaceProperties(str));\r
-                project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));\r
-                addSet.clear();\r
-                subSet.clear();\r
+            key[4] = "DPATH";\r
+            String dpath = GlobalData.getCommandSetting(key, fpdModuleId);\r
+            if (dpath != null) {\r
+                getProject().setProperty(cmd[m] + "_DPATH", dpath.replaceAll("(\\\\)", "/"));\r
             }\r
-            //\r
-            // If CC_FLAGS or LIB_FLAGS .. has defined in BuildOptions\r
-            //\r
-            else if ((str = project.getProperty(cmd[i] + "_FLAGS")) != null) {\r
-                project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));\r
-                addSet.clear();\r
-                subSet.clear();\r
-                putFlagsToSet(addSet, project.replaceProperties(str));\r
-                project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));\r
-                addSet.clear();\r
-                subSet.clear();\r
-            } else {\r
-                project.setProperty(cmd[i] + "_FLAGS", getFlags(addSet, subSet));\r
-                addSet.clear();\r
-                subSet.clear();\r
+            else {\r
+                getProject().setProperty(cmd[m] + "_DPATH", "");\r
             }\r
         }\r
-        project.setProperty("C_FLAGS", project.getProperty("CC_FLAGS"));\r
+    }\r
+    \r
+    public void setMsaFile(File msaFile) {\r
+        this.msaFile = msaFile;\r
     }\r
 \r
     /**\r
-      Initialize some properties will be used in current module build, including\r
-      user-defined option from <em>Option</em> of <em>BuildOptions</em> in \r
-      surface area. \r
+      Method is for ANT to initialize MSA file. \r
+      \r
+      @param msaFilename MSA file name\r
     **/\r
-    private void updateParameters() {\r
-        getProject().setProperty("OBJECTS", "");\r
-        getProject().setProperty("SDB_FILES", "");\r
-        getProject().setProperty("BASE_NAME", baseName);\r
-        if (map.get("MsaHeader") != null) {\r
-            flag = GlobalData.MSA_AND_MBD;\r
-            MsaHeaderDocument.MsaHeader header = ((MsaHeaderDocument) map.get("MsaHeader")).getMsaHeader();\r
-            guid = header.getGuid().getStringValue();\r
-            componentType = header.getComponentType().toString();\r
-        } \r
+    public void setMsaFile(String msaFilename) {\r
+        String moduleDir = getProject().getProperty("MODULE_DIR");\r
+        \r
+        //\r
+        // If is Single Module Build, then use the Base Dir defined in build.xml\r
+        //\r
+        if (moduleDir == null) {\r
+            moduleDir = getProject().getBaseDir().getPath();\r
+        }\r
+        msaFile = new File(moduleDir + File.separatorChar + msaFilename);\r
+    }\r
+    \r
+    public void addConfiguredModuleItem(ModuleItem moduleItem) {\r
+        PackageIdentification packageId = new PackageIdentification(moduleItem.getPackageGuid(), moduleItem.getPackageVersion());\r
+        ModuleIdentification moduleId = new ModuleIdentification(moduleItem.getModuleGuid(), moduleItem.getModuleVersion());\r
+        moduleId.setPackage(packageId);\r
+        this.moduleId = moduleId;\r
+    }\r
+    \r
+    /**\r
+      Add a property. \r
+    \r
+      @param p property\r
+    **/\r
+    public void addProperty(Property p) {\r
+        properties.addElement(p);\r
+    }\r
+\r
+    public void setType(String type) {\r
+        this.type = type;\r
+    }\r
+    \r
+    private void applyBuild(String buildTarget, String buildTagname, FpdModuleIdentification fpdModuleId) throws EdkException{\r
+        //\r
+        // AutoGen\r
+        //\r
+        \r
+        AutoGen autogen = new AutoGen(getProject().getProperty("FV_DIR"), getProject().getProperty("DEST_DIR_DEBUG"), fpdModuleId.getModule(),fpdModuleId.getArch());\r
+        autogen.genAutogen();\r
         \r
-        else if (map.get("MsaLibHeader") != null) {\r
-            flag = GlobalData.LIBMSA_AND_LIBMBD;\r
-            MsaLibHeaderDocument.MsaLibHeader header = ((MsaLibHeaderDocument) map.get("MsaLibHeader"))\r
-                                                                                                       .getMsaLibHeader();\r
-            guid = header.getGuid().getStringValue();\r
-            componentType = header.getComponentType().toString();\r
+        \r
+        //\r
+        // Get compiler flags\r
+        //\r
+        getCompilerFlags(buildTarget, buildTagname, fpdModuleId);\r
+        \r
+        //\r
+        // Prepare LIBS\r
+        //\r
+        ModuleIdentification[] libinstances = SurfaceAreaQuery.getLibraryInstance(fpdModuleId.getArch());\r
+        String propertyLibs = "";\r
+        for (int i = 0; i < libinstances.length; i++) {\r
+            propertyLibs += " " + getProject().getProperty("BIN_DIR") + File.separatorChar + libinstances[i].getName() + ".lib";\r
         }\r
+        getProject().setProperty("LIBS", propertyLibs.replaceAll("(\\\\)", "/"));\r
         \r
-        if (componentType != null) {\r
-            getProject().setProperty("COMPONENT_TYPE", componentType);\r
+        //\r
+        // if it is CUSTOM_BUILD\r
+        // then call the exist BaseName_build.xml directly.\r
+        //\r
+        if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
+            GlobalData.log.info("Call user-defined " + moduleId.getName() + "_build.xml");\r
+            Ant ant = new Ant();\r
+            ant.setProject(getProject());\r
+            ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml");\r
+            ant.setInheritAll(true);\r
+            ant.init();\r
+            ant.execute();\r
+            return ;\r
         }\r
         \r
-        if (guid != null) {\r
-            getProject().setProperty("FILE_GUID", guid);\r
+        //\r
+        // Generate ${BASE_NAME}_build.xml\r
+        // TBD\r
+        //\r
+        String ffsKeyword = SurfaceAreaQuery.getModuleFfsKeyword();\r
+        ModuleBuildFileGenerator fileGenerator = new ModuleBuildFileGenerator(getProject(), ffsKeyword, fpdModuleId);\r
+        String buildFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
+        fileGenerator.genBuildFile(buildFilename);\r
+        \r
+        //\r
+        // Ant call ${BASE_NAME}_build.xml\r
+        //\r
+        Ant ant = new Ant();\r
+        ant.setProject(getProject());\r
+        ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml");\r
+        ant.setInheritAll(true);\r
+        ant.init();\r
+        ant.execute();\r
+    }\r
+    \r
+    private void applyClean(FpdModuleIdentification fpdModuleId){\r
+        //\r
+        // if it is CUSTOM_BUILD\r
+        // then call the exist BaseName_build.xml directly.\r
+        //\r
+        if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
+            GlobalData.log.info("Call user-defined " + moduleId.getName() + "_build.xml");\r
+            Ant ant = new Ant();\r
+            ant.setProject(getProject());\r
+            ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml");\r
+            ant.setTarget("clean");\r
+            ant.setInheritAll(true);\r
+            ant.init();\r
+            ant.execute();\r
+            return ;\r
         }\r
+        \r
+        Ant ant = new Ant();\r
+        ant.setProject(getProject());\r
+        ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml");\r
+        ant.setTarget("clean");\r
+        ant.setInheritAll(true);\r
+        ant.init();\r
+        ant.execute();\r
+        \r
+        //\r
+        // Delete current module's DEST_DIR_OUTPUT\r
+        // TBD\r
+    }\r
+    \r
+    private void applyCleanall(FpdModuleIdentification fpdModuleId){\r
         //\r
-        // Get all options and set to properties\r
+        // if it is CUSTOM_BUILD\r
+        // then call the exist BaseName_build.xml directly.\r
         //\r
-        String[][] options = SurfaceAreaQuery.getOptions(arch);\r
-        for (int i = 0; i < options.length; i++) {\r
-            if (options[i][0] != null && options[i][1] != null) {\r
-                getProject().setProperty(options[i][0], getProject().replaceProperties(options[i][1]));\r
-            }\r
+        if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
+            GlobalData.log.info("Call user-defined " + moduleId.getName() + "_build.xml");\r
+            Ant ant = new Ant();\r
+            ant.setProject(getProject());\r
+            ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml");\r
+            ant.setTarget("cleanall");\r
+            ant.setInheritAll(true);\r
+            ant.init();\r
+            ant.execute();\r
+            return ;\r
         }\r
+        \r
+        Ant ant = new Ant();\r
+        ant.setProject(getProject());\r
+        ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml");\r
+        ant.setTarget("cleanall");\r
+        ant.setInheritAll(true);\r
+        ant.init();\r
+        ant.execute();\r
+        \r
+        //\r
+        // Delete current module's DEST_DIR_OUTPUT\r
+        // TBD\r
+    }\r
+\r
 \r
-        buildType = getProject().getProperty("BUILD_TYPE");\r
-        if (buildType == null) {\r
-            buildType = componentType;\r
-        }\r
 \r
-    }\r
 \r
     /**\r
       Separate the string and instore in set.\r
@@ -1104,13 +670,15 @@ public class GenBuildTask extends Task {
       @param str string to separate\r
     **/\r
     private void putFlagsToSet(Set<String> set, String str) {\r
+        if (str == null || str.length() == 0) {\r
+            return;\r
+        }\r
+\r
         Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");\r
         Matcher matcher = myPattern.matcher(str + " ");\r
         while (matcher.find()) {\r
             String item = str.substring(matcher.start(1), matcher.end(1));\r
-            if (!set.contains(item)) {\r
-                set.add(item);\r
-            }\r
+            set.add(item);\r
         }\r
     }\r
     \r
@@ -1126,7 +694,7 @@ public class GenBuildTask extends Task {
         add.removeAll(sub);\r
         Iterator iter = add.iterator();\r
         while (iter.hasNext()) {\r
-            String str = getProject().replaceProperties((String) iter.next());\r
+            String str = (String) iter.next();\r
             result += str.substring(1, str.length() - 1) + " ";\r
         }\r
         return result;\r
@@ -1148,23 +716,59 @@ public class GenBuildTask extends Task {
       @return flags with original format\r
     **/\r
     private String getRawFlags(Set<String> add, Set<String> sub) {\r
-        String result = "";\r
+        String result = null;\r
         add.removeAll(sub);\r
         Iterator iter = add.iterator();\r
         while (iter.hasNext()) {\r
-            String str = getProject().replaceProperties((String) iter.next());\r
+            String str = (String) iter.next();\r
             result += "\"" + str.substring(1, str.length() - 1) + "\", ";\r
         }\r
         return result;\r
     }\r
 \r
-    /**\r
-      Set base name. For ANT use.\r
-      \r
-      @param baseName Base name\r
-    **/\r
-    public void setBaseName(String baseName) {\r
-        this.baseName = baseName;\r
+    private String parseOptionString(String optionString, Set<String> addSet, Set<String> subSet) {\r
+        boolean overrideOption = false;\r
+        Pattern pattern = Pattern.compile("ADD\\.\\[(.+)\\]");\r
+        Matcher matcher = pattern.matcher(optionString);\r
+\r
+        while (matcher.find()) {\r
+            overrideOption = true;\r
+            String addOption = optionString.substring(matcher.start(1), matcher.end(1)).trim();\r
+            putFlagsToSet(addSet, addOption);\r
+            \r
+        }\r
+\r
+        pattern = Pattern.compile("SUB\\.\\[(.+)\\]");\r
+        matcher = pattern.matcher(optionString);\r
+\r
+        while (matcher.find()) {\r
+            overrideOption = true;\r
+            String subOption = optionString.substring(matcher.start(1), matcher.end(1)).trim();\r
+            putFlagsToSet(subSet, subOption);\r
+        }\r
+\r
+        if (overrideOption == true) {\r
+            return null;\r
+        }\r
+\r
+        return optionString;\r
+    }\r
+    \r
+    private void pushProperties() {\r
+        backupPropertiesStack.push(getProject().getProperties());\r
+    }\r
+    \r
+    private void popProperties() {\r
+        Hashtable backupProperties = backupPropertiesStack.pop();\r
+        Set keys = backupProperties.keySet();\r
+        Iterator iter = keys.iterator();\r
+        while (iter.hasNext()) {\r
+            String item = (String)iter.next();\r
+            getProject().setProperty(item, (String)backupProperties.get(item));\r
+        }\r
     }\r
 \r
+    public void setSingleModuleBuild(boolean isSingleModuleBuild) {\r
+        this.isSingleModuleBuild = isSingleModuleBuild;\r
+    }\r
 }\r