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