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