Refine the code for PCD tools.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / PCDAutoGenAction.java
CommitLineData
878ddf1f 1/** @file\r
2 PCDAutoGenAction class.\r
3\r
4 This class is to manage how to generate the PCD information into Autogen.c and\r
5 Autogen.h.\r
af98370e 6\r
878ddf1f 7Copyright (c) 2006, Intel Corporation\r
8All rights reserved. This program and the accompanying materials\r
9are licensed and made available under the terms and conditions of the BSD License\r
10which accompanies this distribution. The full text of the license may be found at\r
11http://opensource.org/licenses/bsd-license.php\r
af98370e 12\r
878ddf1f 13THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17package org.tianocore.build.pcd.action;\r
18\r
19import java.io.File;\r
11e7b0f6 20import java.util.ArrayList;\r
878ddf1f 21import java.util.List;\r
11e7b0f6 22import java.util.regex.Matcher;\r
23import java.util.regex.Pattern;\r
878ddf1f 24\r
5f907e4a 25import org.tianocore.build.autogen.CommonDefinition;\r
26import org.tianocore.build.exception.PcdAutogenException;\r
878ddf1f 27import org.tianocore.build.global.GlobalData;\r
eece174a 28import org.tianocore.build.id.ModuleIdentification;\r
5f907e4a 29import org.tianocore.pcd.action.ActionMessage;\r
30import org.tianocore.pcd.action.BuildAction;\r
d14ebb43 31import org.tianocore.pcd.entity.MemoryDatabaseManager;\r
32import org.tianocore.pcd.entity.Token;\r
5f907e4a 33import org.tianocore.pcd.entity.UsageIdentification;\r
d14ebb43 34import org.tianocore.pcd.entity.UsageInstance;\r
35import org.tianocore.pcd.exception.BuildActionException;\r
878ddf1f 36\r
11eb278a 37/**\r
38 This class is to manage how to generate the PCD information into Autogen.c\r
39 and Autogen.h.\r
878ddf1f 40**/\r
41public class PCDAutoGenAction extends BuildAction {\r
42 ///\r
43 /// The reference of DBManager in GlobalData class.\r
44 ///\r
45 private MemoryDatabaseManager dbManager;\r
af98370e 46\r
878ddf1f 47 ///\r
d14ebb43 48 /// The identification for a UsageInstance.\r
8840ad58 49 ///\r
af98370e 50 private UsageIdentification usageId;\r
51\r
8840ad58 52 ///\r
8840ad58 53 /// Whether current autogen is for building library used by current module.\r
af98370e 54 ///\r
8840ad58 55 private boolean isBuildUsedLibrary;\r
af98370e 56\r
5f907e4a 57 ///\r
58 /// One of PEI_PCD_DRIVER, DXE_PCD_DRIVER, NOT_PCD_DRIVER \r
59 /// \r
60 private CommonDefinition.PCD_DRIVER_TYPE pcdDriverType;\r
61\r
8840ad58 62 ///\r
878ddf1f 63 /// The generated string for header file.\r
64 ///\r
65 private String hAutoGenString;\r
af98370e 66\r
878ddf1f 67 ///\r
68 /// The generated string for C code file.\r
69 ///\r
ad82307c 70 private String cAutoGenString;\r
af98370e 71\r
ad82307c 72 ///\r
73 /// The name array of <PcdCoded> in a module.\r
af98370e 74 ///\r
eece174a 75 private String[] pcdNameArrayInMsa;\r
af98370e 76\r
878ddf1f 77 /**\r
eece174a 78 Set parameter moduleId\r
af98370e 79\r
878ddf1f 80 @param moduleName the module name parameter.\r
81 **/\r
d14ebb43 82 public void setUsageId(UsageIdentification usageId) {\r
83 this.usageId = usageId;\r
8840ad58 84 }\r
85\r
5f907e4a 86 /**\r
87 Set paramter pcdDriverType\r
88 \r
89 @param pcdDriverType the driver type for PCD\r
90 **/\r
91 public void setPcdDriverType(CommonDefinition.PCD_DRIVER_TYPE pcdDriverType) {\r
92 this.pcdDriverType = pcdDriverType;\r
93 }\r
878ddf1f 94 /**\r
ad82307c 95 set isBuildUsedLibrary parameter.\r
af98370e 96\r
ad82307c 97 @param isBuildUsedLibrary\r
eece174a 98 **/\r
8840ad58 99 public void setIsBuildUsedLibrary(boolean isBuildUsedLibrary) {\r
100 this.isBuildUsedLibrary = isBuildUsedLibrary;\r
101 }\r
eece174a 102\r
ad82307c 103 /**\r
eece174a 104 set pcdNameArrayInMsa parameter.\r
af98370e 105\r
eece174a 106 @param pcdNameArrayInMsa\r
ad82307c 107 */\r
eece174a 108 public void setPcdNameArrayInMsa(String[] pcdNameArrayInMsa) {\r
109 this.pcdNameArrayInMsa = pcdNameArrayInMsa;\r
ad82307c 110 }\r
8840ad58 111\r
878ddf1f 112 /**\r
113 Get the output of generated string for header file.\r
af98370e 114\r
878ddf1f 115 @return the string of header file for PCD\r
116 **/\r
11eb278a 117 public String getHAutoGenString() {\r
878ddf1f 118 return hAutoGenString;\r
119 }\r
120\r
121 /**\r
122 Get the output of generated string for C Code file.\r
af98370e 123\r
878ddf1f 124 @return the string of C code file for PCD\r
125 **/\r
11eb278a 126 public String getCAutoGenString() {\r
878ddf1f 127 return cAutoGenString;\r
128 }\r
129\r
af98370e 130\r
878ddf1f 131 /**\r
eece174a 132 Construct function\r
136adffc 133\r
eece174a 134 This function mainly initialize some member variable.\r
af98370e 135\r
eece174a 136 @param moduleId the identification for module\r
137 @param arch the architecture for module\r
138 @param isBuildUsedLibary Is the current module library.\r
139 @param pcdNameArrayInMsa the pcd name array got from MSA file.\r
5f907e4a 140 @param pcdDriverType one of PEI_PCD_DRIVER, DXE_PCD_DRIVER,\r
141 NOT_PCD_DRIVER\r
eece174a 142 **/\r
af98370e 143 public PCDAutoGenAction(ModuleIdentification moduleId,\r
eece174a 144 String arch,\r
145 boolean isBuildUsedLibrary,\r
5f907e4a 146 String[] pcdNameArrayInMsa,\r
147 CommonDefinition.PCD_DRIVER_TYPE pcdDriverType) {\r
eece174a 148 dbManager = null;\r
149 hAutoGenString = "";\r
150 cAutoGenString = "";\r
151\r
af98370e 152 setUsageId(new UsageIdentification(moduleId.getName(),\r
153 moduleId.getGuid(),\r
154 moduleId.getPackage().getName(),\r
155 moduleId.getPackage().getGuid(),\r
156 arch,\r
157 moduleId.getVersion(),\r
158 moduleId.getModuleType()));\r
eece174a 159 setIsBuildUsedLibrary(isBuildUsedLibrary);\r
160 setPcdNameArrayInMsa(pcdNameArrayInMsa);\r
5f907e4a 161 setPcdDriverType(pcdDriverType);\r
eece174a 162 }\r
163\r
878ddf1f 164 /**\r
8b7bd455 165 Override function: check the parameter for action class.\r
af98370e 166\r
878ddf1f 167 @throws BuildActionException Bad parameter.\r
168 **/\r
af98370e 169 public void checkParameter() {\r
878ddf1f 170 }\r
171\r
172 /**\r
173 Core execution function for this action class.\r
af98370e 174\r
878ddf1f 175 All PCD information of this module comes from memory dabase. The collection\r
176 work should be done before this action execution.\r
af98370e 177 Currently, we should generated all PCD information(maybe all dynamic) as array\r
178 in Pei emulated driver for simulating PCD runtime database.\r
179\r
878ddf1f 180 @throws BuildActionException Failed to execute this aciton class.\r
181 **/\r
af98370e 182 public void performAction() {\r
183 ActionMessage.debug(this,\r
878ddf1f 184 "Starting PCDAutoGenAction to generate autogen.h and autogen.c!...");\r
845fdeba 185\r
186 dbManager = GlobalData.getPCDMemoryDBManager();\r
187\r
188 if(dbManager.getDBSize() == 0) {\r
8840ad58 189 return;\r
845fdeba 190 }\r
191\r
192 ActionMessage.debug(this,\r
391dbbb1 193 "PCD memory database contains " + dbManager.getDBSize() + " PCD tokens.");\r
878ddf1f 194\r
8840ad58 195 generateAutogenForModule();\r
878ddf1f 196 }\r
197\r
198 /**\r
199 Generate the autogen string for a common module.\r
af98370e 200\r
878ddf1f 201 All PCD information of this module comes from memory dabase. The collection\r
202 work should be done before this action execution.\r
203 **/\r
204 private void generateAutogenForModule()\r
205 {\r
ad82307c 206 int index, index2;\r
207 List<UsageInstance> usageInstanceArray, usageContext;\r
11e7b0f6 208 String[] guidStringArray = null;\r
209 String guidStringCName = null;\r
210 String guidString = null;\r
d14ebb43 211 String moduleName = usageId.moduleName;\r
11e7b0f6 212 UsageInstance usageInstance = null;\r
a1eb6401 213 boolean found = false;\r
878ddf1f 214\r
a1eb6401 215 usageInstanceArray = null;\r
8840ad58 216 if (!isBuildUsedLibrary) {\r
b6297711 217 usageInstanceArray = dbManager.getUsageInstanceArrayById(usageId);\r
af98370e 218 MemoryDatabaseManager.UsageInstanceContext = usageInstanceArray;\r
219 MemoryDatabaseManager.CurrentModuleName = moduleName;\r
eece174a 220 } else if ((pcdNameArrayInMsa != null) && (pcdNameArrayInMsa.length > 0)) {\r
af98370e 221 usageContext = MemoryDatabaseManager.UsageInstanceContext;\r
8840ad58 222 //\r
af98370e 223 // For building library package, although all module are library, but PCD entries of\r
8840ad58 224 // these library should be used to autogen.\r
af98370e 225 //\r
ad82307c 226 if (usageContext == null) {\r
b6297711 227 usageInstanceArray = dbManager.getUsageInstanceArrayById(usageId);\r
ad82307c 228 } else {\r
229 usageInstanceArray = new ArrayList<UsageInstance>();\r
a1eb6401 230\r
ad82307c 231 //\r
af98370e 232 // Try to find all PCD defined in library's PCD in all <PcdEntry> in module's\r
a1eb6401 233 // <ModuleSA> in FPD file.\r
af98370e 234 //\r
eece174a 235 for (index = 0; index < pcdNameArrayInMsa.length; index++) {\r
a1eb6401 236 found = false;\r
237 for (index2 = 0; index2 < usageContext.size(); index2 ++) {\r
eece174a 238 if (pcdNameArrayInMsa[index].equalsIgnoreCase(usageContext.get(index2).parentToken.cName)) {\r
a1eb6401 239 usageInstanceArray.add(usageContext.get(index2));\r
240 found = true;\r
ad82307c 241 break;\r
242 }\r
243 }\r
a1eb6401 244\r
245 if (!found) {\r
246 //\r
247 // All library's PCD should instanted in module's <ModuleSA> who\r
248 // use this library instance. If not, give errors.\r
af98370e 249 //\r
391dbbb1 250 throw new BuildActionException (String.format("Module %s using library instance %s; the PCD %s " +\r
251 "is required by this library instance, but can not be found " +\r
252 "in the %s's <ModuleSA> in the FPD file!",\r
af98370e 253 MemoryDatabaseManager.CurrentModuleName,\r
a1eb6401 254 moduleName,\r
eece174a 255 pcdNameArrayInMsa[index],\r
af98370e 256 MemoryDatabaseManager.CurrentModuleName\r
a1eb6401 257 ));\r
258 }\r
ad82307c 259 }\r
8840ad58 260 }\r
261 }\r
878ddf1f 262\r
a1eb6401 263 if (usageInstanceArray == null) {\r
264 return;\r
265 }\r
266\r
11e7b0f6 267 //\r
268 // Generate all PCD entry for a module.\r
af98370e 269 //\r
878ddf1f 270 for(index = 0; index < usageInstanceArray.size(); index ++) {\r
eece174a 271 usageInstance = usageInstanceArray.get(index);\r
272 //\r
273 // Before generate any PCD information into autogen.h/autogen.c for a module,\r
274 // generate TokenSpaceGuid array variable firstly. For every dynamicEx type\r
af98370e 275 // PCD in this module the token, they are all reference to TokenSpaceGuid\r
eece174a 276 // array.\r
af98370e 277 //\r
eece174a 278 if (usageInstanceArray.get(index).modulePcdType == Token.PCD_TYPE.DYNAMIC_EX) {\r
279 guidStringArray = usageInstance.parentToken.tokenSpaceName.split("-");\r
af98370e 280 guidStringCName = "_gPcd_TokenSpaceGuid_" +\r
eece174a 281 usageInstance.parentToken.tokenSpaceName.replaceAll("-", "_");\r
282 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
283 guidStringArray[0],\r
284 guidStringArray[1],\r
285 guidStringArray[2],\r
286 (guidStringArray[3].substring(0, 2)),\r
287 (guidStringArray[3].substring(2, 4)),\r
288 (guidStringArray[4].substring(0, 2)),\r
289 (guidStringArray[4].substring(2, 4)),\r
290 (guidStringArray[4].substring(4, 6)),\r
291 (guidStringArray[4].substring(6, 8)),\r
292 (guidStringArray[4].substring(8, 10)),\r
293 (guidStringArray[4].substring(10, 12)));\r
af98370e 294\r
eece174a 295 Pattern pattern = Pattern.compile("(" + guidStringCName + ")+?");\r
296 Matcher matcher = pattern.matcher(cAutoGenString + " ");\r
11e7b0f6 297 //\r
eece174a 298 // Find whether this guid array variable has been generated into autogen.c\r
299 // For different DyanmicEx pcd token who use same token space guid, the token space\r
300 // guid array should be only generated once.\r
af98370e 301 //\r
eece174a 302 if (!matcher.find()) {\r
af98370e 303 hAutoGenString += String.format("extern EFI_GUID %s;\r\n", guidStringCName);\r
eece174a 304 if (!isBuildUsedLibrary) {\r
305 cAutoGenString += String.format("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID %s = %s;\r\n",\r
306 guidStringCName,\r
307 guidString);\r
af98370e 308 }\r
11e7b0f6 309 }\r
878ddf1f 310 }\r
eece174a 311\r
312 usageInstance.generateAutoGen(isBuildUsedLibrary);\r
313 //\r
314 // For every PCD entry for this module(usage instance), autogen string would\r
315 // be appand.\r
af98370e 316 //\r
eece174a 317 hAutoGenString += usageInstance.getHAutogenStr() + "\r\n";\r
318 cAutoGenString += usageInstance.getCAutogenStr();\r
878ddf1f 319 }\r
320\r
5f907e4a 321 if (pcdDriverType == CommonDefinition.PCD_DRIVER_TYPE.PEI_PCD_DRIVER) {\r
af98370e 322 hAutoGenString += MemoryDatabaseManager.PcdPeimHString;\r
323 cAutoGenString += MemoryDatabaseManager.PcdPeimCString;\r
5f907e4a 324 } else if (pcdDriverType == CommonDefinition.PCD_DRIVER_TYPE.DXE_PCD_DRIVER) {\r
af98370e 325 hAutoGenString += MemoryDatabaseManager.PcdDxeHString;\r
326 cAutoGenString += MemoryDatabaseManager.PcdDxeCString;\r
32648c62 327 }\r
878ddf1f 328 }\r
878ddf1f 329}\r