]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java
Restructuring for better separation of Tool packages.
[mirror_edk2.git] / Tools / Java / Source / GenBuild / org / tianocore / build / pcd / action / PCDAutoGenAction.java
diff --git a/Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java b/Tools/Java/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java
new file mode 100644 (file)
index 0000000..a2f1c6a
--- /dev/null
@@ -0,0 +1,384 @@
+/** @file\r
+  PCDAutoGenAction class.\r
+\r
+  This class is to manage how to generate the PCD information into Autogen.c and\r
+  Autogen.h.\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
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+package org.tianocore.build.pcd.action;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.tianocore.build.FrameworkBuildTask;\r
+import org.tianocore.build.autogen.CommonDefinition;\r
+import org.tianocore.build.global.GlobalData;\r
+import org.tianocore.build.id.ModuleIdentification;\r
+import org.tianocore.common.logger.EdkLog;\r
+import org.tianocore.pcd.action.BuildAction;\r
+import org.tianocore.pcd.entity.MemoryDatabaseManager;\r
+import org.tianocore.pcd.entity.Token;\r
+import org.tianocore.pcd.entity.UsageIdentification;\r
+import org.tianocore.pcd.entity.UsageInstance;\r
+import org.tianocore.pcd.exception.BuildActionException;\r
+\r
+/**\r
+    This class is to manage how to generate the PCD information into Autogen.c\r
+    and Autogen.h.\r
+**/\r
+public class PCDAutoGenAction extends BuildAction {\r
+    ///\r
+    /// The reference of DBManager in GlobalData class.\r
+    ///\r
+    private MemoryDatabaseManager dbManager;\r
+\r
+    ///\r
+    /// The identification for a UsageInstance.\r
+    ///\r
+    private UsageIdentification   usageId;\r
+\r
+    ///\r
+    /// Whether current autogen is for building library used by current module.\r
+    ///\r
+    private boolean               isBuildUsedLibrary;\r
+\r
+    ///\r
+    /// One of PEI_PCD_DRIVER, DXE_PCD_DRIVER, NOT_PCD_DRIVER \r
+    /// \r
+    private CommonDefinition.PCD_DRIVER_TYPE pcdDriverType;\r
+\r
+    ///\r
+    /// The generated string for header file.\r
+    ///\r
+    private String                hAutoGenString;\r
+\r
+    ///\r
+    /// The generated string for C code file.\r
+    ///\r
+    private String                cAutoGenString;\r
+\r
+    ///\r
+    /// The name array of <PcdCoded> in a module.\r
+    ///\r
+    private String[]              pcdNameArrayInMsa;\r
+\r
+    private UsageIdentification parentId = null;\r
+    /**\r
+      Set parameter moduleId\r
+\r
+      @param moduleName   the module name parameter.\r
+    **/\r
+    public void setUsageId(UsageIdentification usageId) {\r
+        this.usageId = usageId;\r
+    }\r
+\r
+    /**\r
+       Set paramter pcdDriverType\r
+       \r
+       @param pcdDriverType the driver type for PCD\r
+    **/\r
+    public void setPcdDriverType(CommonDefinition.PCD_DRIVER_TYPE pcdDriverType) {\r
+        this.pcdDriverType = pcdDriverType;\r
+    }\r
+    /**\r
+       set isBuildUsedLibrary parameter.\r
+\r
+       @param isBuildUsedLibrary\r
+    **/\r
+    public void setIsBuildUsedLibrary(boolean isBuildUsedLibrary) {\r
+        this.isBuildUsedLibrary = isBuildUsedLibrary;\r
+    }\r
+\r
+    /**\r
+       set pcdNameArrayInMsa parameter.\r
+\r
+       @param pcdNameArrayInMsa\r
+     */\r
+    public void setPcdNameArrayInMsa(String[] pcdNameArrayInMsa) {\r
+        this.pcdNameArrayInMsa = pcdNameArrayInMsa;\r
+    }\r
+\r
+    /**\r
+      Get the output of generated string for header file.\r
+\r
+      @return the string of header file for PCD\r
+    **/\r
+    public String getHAutoGenString() {\r
+        return hAutoGenString;\r
+    }\r
+\r
+    /**\r
+      Get the output of generated string for C Code file.\r
+\r
+      @return the string of C code file for PCD\r
+    **/\r
+    public String getCAutoGenString() {\r
+        return cAutoGenString;\r
+    }\r
+\r
+\r
+    /**\r
+        Construct function\r
+\r
+        This function mainly initialize some member variable.\r
+\r
+        @param moduleId             the identification for module\r
+        @param arch                 the architecture for module\r
+        @param isBuildUsedLibary    Is the current module library.\r
+        @param pcdNameArrayInMsa    the pcd name array got from MSA file.\r
+        @param pcdDriverType        one of PEI_PCD_DRIVER, DXE_PCD_DRIVER,\r
+                                    NOT_PCD_DRIVER\r
+    **/\r
+    public PCDAutoGenAction(ModuleIdentification moduleId,\r
+                            String               arch,\r
+                            boolean              isBuildUsedLibrary,\r
+                            String[]             pcdNameArrayInMsa,\r
+                            CommonDefinition.PCD_DRIVER_TYPE pcdDriverType,\r
+                            ModuleIdentification parentId) {\r
+        dbManager       = null;\r
+        hAutoGenString  = "";\r
+        cAutoGenString  = "";\r
+\r
+        setUsageId(new UsageIdentification(moduleId.getName(),\r
+                                           moduleId.getGuid(),\r
+                                           moduleId.getPackage().getName(),\r
+                                           moduleId.getPackage().getGuid(),\r
+                                           arch,\r
+                                           moduleId.getVersion(),\r
+                                           moduleId.getModuleType()));\r
+        if (parentId != null) {\r
+            this.parentId = new UsageIdentification(parentId.getName(),\r
+                        parentId.getGuid(),\r
+                        parentId.getPackage().getName(),\r
+                        parentId.getPackage().getGuid(),\r
+                        arch,\r
+                        parentId.getVersion(),\r
+                        parentId.getModuleType());\r
+        }\r
+        setIsBuildUsedLibrary(isBuildUsedLibrary);\r
+        setPcdNameArrayInMsa(pcdNameArrayInMsa);\r
+        setPcdDriverType(pcdDriverType);\r
+    }\r
+\r
+    /**\r
+      Override function: check the parameter for action class.\r
+\r
+      @throws BuildActionException Bad parameter.\r
+    **/\r
+    public void checkParameter() {\r
+    }\r
+\r
+    /**\r
+      Core execution function for this action class.\r
+\r
+      All PCD information of this module comes from memory dabase. The collection\r
+      work should be done before this action execution.\r
+      Currently, we should generated all PCD information(maybe all dynamic) as array\r
+      in Pei emulated driver for simulating PCD runtime database.\r
+\r
+      @throws BuildActionException Failed to execute this aciton class.\r
+    **/\r
+    public void performAction() {\r
+        EdkLog.log(EdkLog.EDK_DEBUG, "Starting PCDAutoGenAction to generate autogen.h and autogen.c!...");\r
+\r
+        dbManager = GlobalData.getPCDMemoryDBManager();\r
+\r
+        if(dbManager.getDBSize() == 0) {\r
+            return;\r
+        }\r
+\r
+        EdkLog.log(EdkLog.EDK_DEBUG, "PCD memory database contains " + dbManager.getDBSize() + " PCD tokens.");\r
+\r
+        generateAutogenForModule();\r
+    }\r
+\r
+    /**\r
+      Generate the autogen string for a common module.\r
+\r
+      All PCD information of this module comes from memory dabase. The collection\r
+      work should be done before this action execution.\r
+    **/\r
+    private void generateAutogenForModule()\r
+    {\r
+        int                   index, index2;\r
+        List<UsageInstance>   usageInstanceArray, usageContext;\r
+        String[]              guidStringArray = null;\r
+        String                guidStringCName = null;\r
+        String                guidString      = null;\r
+        String                moduleName      = usageId.moduleName;\r
+        UsageInstance         usageInstance   = null;\r
+        boolean               found           = false;\r
+\r
+        usageInstanceArray = null;\r
+        \r
+        if (FrameworkBuildTask.multithread) {\r
+            if (parentId == null) {\r
+                usageInstanceArray  = dbManager.getUsageInstanceArrayById(usageId);\r
+            } else if ((pcdNameArrayInMsa != null) && (pcdNameArrayInMsa.length > 0)) {\r
+                usageContext = dbManager.getUsageInstanceArrayById(parentId);\r
+                //\r
+                // For building library package, although all module are library, but PCD entries of\r
+                // these library should be used to autogen.\r
+                //\r
+                if (usageContext == null) {\r
+                    usageInstanceArray  = dbManager.getUsageInstanceArrayById(usageId);\r
+                } else {\r
+                    usageInstanceArray = new ArrayList<UsageInstance>();\r
+\r
+                    //\r
+                    // Try to find all PCD defined in library's PCD in all <PcdEntry> in module's\r
+                    // <ModuleSA> in FPD file.\r
+                    //\r
+                    for (index = 0; index < pcdNameArrayInMsa.length; index++) {\r
+                        found = false;\r
+                        for (index2 = 0; index2 < usageContext.size(); index2 ++) {\r
+                            if (pcdNameArrayInMsa[index].equalsIgnoreCase(usageContext.get(index2).parentToken.cName)) {\r
+                                usageInstanceArray.add(usageContext.get(index2));\r
+                                found = true;\r
+                                break;\r
+                            }\r
+                        }\r
+\r
+                        if (!found) {\r
+                            //\r
+                            // All library's PCD should instanted in module's <ModuleSA> who\r
+                            // use this library instance. If not, give errors.\r
+                            //\r
+                            throw new BuildActionException (String.format("Module %s using library instance %s; the PCD %s " +\r
+                                                                          "is required by this library instance, but can not be found " +\r
+                                                                          "in the %s's <ModuleSA> in the FPD file!",\r
+                                                                          MemoryDatabaseManager.CurrentModuleName,\r
+                                                                          moduleName,\r
+                                                                          pcdNameArrayInMsa[index],\r
+                                                                          MemoryDatabaseManager.CurrentModuleName\r
+                                                                          ));\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        } else {\r
+            if (!isBuildUsedLibrary) {\r
+                usageInstanceArray  = dbManager.getUsageInstanceArrayById(usageId);\r
+                MemoryDatabaseManager.UsageInstanceContext = usageInstanceArray;\r
+                MemoryDatabaseManager.CurrentModuleName    = moduleName;\r
+            } else if ((pcdNameArrayInMsa != null) && (pcdNameArrayInMsa.length > 0)) {\r
+                usageContext = MemoryDatabaseManager.UsageInstanceContext;\r
+                //\r
+                // For building library package, although all module are library, but PCD entries of\r
+                // these library should be used to autogen.\r
+                //\r
+                if (usageContext == null) {\r
+                    usageInstanceArray  = dbManager.getUsageInstanceArrayById(usageId);\r
+                } else {\r
+                    usageInstanceArray = new ArrayList<UsageInstance>();\r
+    \r
+                    //\r
+                    // Try to find all PCD defined in library's PCD in all <PcdEntry> in module's\r
+                    // <ModuleSA> in FPD file.\r
+                    //\r
+                    for (index = 0; index < pcdNameArrayInMsa.length; index++) {\r
+                        found = false;\r
+                        for (index2 = 0; index2 < usageContext.size(); index2 ++) {\r
+                            if (pcdNameArrayInMsa[index].equalsIgnoreCase(usageContext.get(index2).parentToken.cName)) {\r
+                                usageInstanceArray.add(usageContext.get(index2));\r
+                                found = true;\r
+                                break;\r
+                            }\r
+                        }\r
+    \r
+                        if (!found) {\r
+                            //\r
+                            // All library's PCD should instanted in module's <ModuleSA> who\r
+                            // use this library instance. If not, give errors.\r
+                            //\r
+                            throw new BuildActionException (String.format("Module %s using library instance %s; the PCD %s " +\r
+                                                                          "is required by this library instance, but can not be found " +\r
+                                                                          "in the %s's <ModuleSA> in the FPD file!",\r
+                                                                          MemoryDatabaseManager.CurrentModuleName,\r
+                                                                          moduleName,\r
+                                                                          pcdNameArrayInMsa[index],\r
+                                                                          MemoryDatabaseManager.CurrentModuleName\r
+                                                                          ));\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        if (usageInstanceArray == null) {\r
+            return;\r
+        }\r
+\r
+        //\r
+        // Generate all PCD entry for a module.\r
+        //\r
+        for(index = 0; index < usageInstanceArray.size(); index ++) {\r
+            usageInstance = usageInstanceArray.get(index);\r
+            //\r
+            // Before generate any PCD information into autogen.h/autogen.c for a module,\r
+            // generate TokenSpaceGuid array variable firstly. For every dynamicEx type\r
+            // PCD in this module the token, they are all reference to TokenSpaceGuid\r
+            // array.\r
+            //\r
+            if (usageInstanceArray.get(index).modulePcdType == Token.PCD_TYPE.DYNAMIC_EX) {\r
+                guidStringArray = usageInstance.parentToken.tokenSpaceName.split("-");\r
+                guidStringCName = "_gPcd_TokenSpaceGuid_" +\r
+                                  usageInstance.parentToken.tokenSpaceName.replaceAll("-", "_");\r
+                guidString      = String.format("{ 0x%s, 0x%s, 0x%s, {0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s}}",\r
+                                                guidStringArray[0],\r
+                                                guidStringArray[1],\r
+                                                guidStringArray[2],\r
+                                                (guidStringArray[3].substring(0, 2)),\r
+                                                (guidStringArray[3].substring(2, 4)),\r
+                                                (guidStringArray[4].substring(0, 2)),\r
+                                                (guidStringArray[4].substring(2, 4)),\r
+                                                (guidStringArray[4].substring(4, 6)),\r
+                                                (guidStringArray[4].substring(6, 8)),\r
+                                                (guidStringArray[4].substring(8, 10)),\r
+                                                (guidStringArray[4].substring(10, 12)));\r
+\r
+                Pattern pattern = Pattern.compile("(" + guidStringCName + ")+?");\r
+                Matcher matcher = pattern.matcher(cAutoGenString + " ");\r
+                //\r
+                // Find whether this guid array variable has been generated into autogen.c\r
+                // For different DyanmicEx pcd token who use same token space guid, the token space\r
+                // guid array should be only generated once.\r
+                //\r
+                if (!matcher.find()) {\r
+                    hAutoGenString += String.format("extern EFI_GUID %s;\r\n", guidStringCName);\r
+                    if (!isBuildUsedLibrary) {\r
+                        cAutoGenString += String.format("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID %s = %s;\r\n",\r
+                                                        guidStringCName,\r
+                                                        guidString);\r
+                    }\r
+                }\r
+            }\r
+\r
+            usageInstance.generateAutoGen(isBuildUsedLibrary);\r
+            //\r
+            // For every PCD entry for this module(usage instance), autogen string would\r
+            // be appand.\r
+            //\r
+            hAutoGenString += usageInstance.getHAutogenStr() + "\r\n";\r
+            cAutoGenString += usageInstance.getCAutogenStr();\r
+        }\r
+\r
+        if (pcdDriverType == CommonDefinition.PCD_DRIVER_TYPE.PEI_PCD_DRIVER) {\r
+            hAutoGenString += MemoryDatabaseManager.PcdPeimHString;\r
+            cAutoGenString += MemoryDatabaseManager.PcdPeimCString;\r
+        } else if (pcdDriverType == CommonDefinition.PCD_DRIVER_TYPE.DXE_PCD_DRIVER) {\r
+            hAutoGenString += MemoryDatabaseManager.PcdDxeHString;\r
+            cAutoGenString += MemoryDatabaseManager.PcdDxeCString;\r
+        }\r
+    }\r
+}\r