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