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