Shutdown the PCD's datum verification when building, it can save 2 minutes for full...
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / PlatformPcdPreprocessActionForBuilding.java
CommitLineData
af98370e 1/** @file\r
2 PlatformPcdPreprocessActionForBuilding class.\r
3\r
4 This action class is to collect PCD information from MSA, SPD, FPD xml file.\r
5 This class will be used for wizard and build tools, So it can *not* inherit\r
6 from buildAction or wizardAction.\r
7\r
8Copyright (c) 2006, Intel Corporation\r
9All rights reserved. This program and the accompanying materials\r
10are licensed and made available under the terms and conditions of the BSD License\r
11which accompanies this distribution. The full text of the license may be found at\r
12http://opensource.org/licenses/bsd-license.php\r
13\r
14THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16\r
17**/\r
18package org.tianocore.build.pcd.action;\r
19\r
20import java.io.File;\r
21import java.io.IOException;\r
22import java.math.BigInteger;\r
23import java.util.ArrayList;\r
24import java.util.Iterator;\r
25import java.util.List;\r
26import java.util.Map;\r
27\r
28import org.apache.xmlbeans.XmlException;\r
29import org.apache.xmlbeans.XmlObject;\r
30import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;\r
e55d8a3c 31import org.tianocore.PcdBuildDefinitionDocument;\r
af98370e 32import org.tianocore.PlatformSurfaceAreaDocument;\r
e55d8a3c 33import org.tianocore.build.exception.PlatformPcdPreprocessBuildException;\r
af98370e 34import org.tianocore.build.fpd.FpdParserTask;\r
35import org.tianocore.build.global.GlobalData;\r
36import org.tianocore.build.id.FpdModuleIdentification;\r
37import org.tianocore.pcd.action.ActionMessage;\r
e55d8a3c 38import org.tianocore.pcd.action.PlatformPcdPreprocessAction;\r
af98370e 39import org.tianocore.pcd.entity.MemoryDatabaseManager;\r
e55d8a3c 40import org.tianocore.pcd.entity.ModulePcdInfoFromFpd;\r
af98370e 41import org.tianocore.pcd.entity.Token;\r
42import org.tianocore.pcd.entity.UsageIdentification;\r
43import org.tianocore.pcd.exception.EntityException;\r
8b7bd455 44import org.tianocore.pcd.exception.PlatformPcdPreprocessException;\r
af98370e 45\r
46/**\r
47 This action class is to collect PCD information from MSA, SPD, FPD xml file.\r
48 This class will be used for wizard and build tools, So it can *not* inherit\r
49 from buildAction or UIAction.\r
50**/\r
51public class PlatformPcdPreprocessActionForBuilding extends PlatformPcdPreprocessAction {\r
af98370e 52 ///\r
53 /// FPD file is the root file.\r
54 ///\r
55 private String fpdFilePath;\r
56\r
57 ///\r
58 /// Message level for CollectPCDAction.\r
59 ///\r
60 private int originalMessageLevel;\r
61\r
62 ///\r
63 /// Cache the fpd docment instance for private usage.\r
64 ///\r
65 private PlatformSurfaceAreaDocument fpdDocInstance;\r
66\r
af98370e 67 /**\r
68 Set action message level for CollectPcdAction tool.\r
69\r
70 The message should be restored when this action exit.\r
71\r
72 @param actionMessageLevel parameter for this action\r
73 **/\r
74 public void setActionMessageLevel(int actionMessageLevel) {\r
75 originalMessageLevel = ActionMessage.messageLevel;\r
76 ActionMessage.messageLevel = actionMessageLevel;\r
77 }\r
78\r
79 /**\r
80 Set FPDFileName parameter for this action class.\r
81\r
82 @param fpdFilePath fpd file path\r
83 **/\r
84 public void setFPDFilePath(String fpdFilePath) {\r
85 this.fpdFilePath = fpdFilePath;\r
86 }\r
87\r
88 /**\r
89 Common function interface for outer.\r
90\r
8b7bd455 91 @param fpdFilePath The fpd file path of current build or analysis.\r
92 @param messageLevel The message level for this Action.\r
af98370e 93\r
8b7bd455 94 @throws PlatformPreprocessBuildException \r
95 The exception of this function. Because it can *not* be predict\r
96 where the action class will be used. So only Exception can be throw.\r
af98370e 97\r
98 **/\r
8b7bd455 99 public void perform(String fpdFilePath, int messageLevel) \r
100 throws PlatformPcdPreprocessBuildException {\r
af98370e 101 setFPDFilePath(fpdFilePath);\r
102 setActionMessageLevel(messageLevel);\r
103 checkParameter();\r
104 execute();\r
105 ActionMessage.messageLevel = originalMessageLevel;\r
106 }\r
107\r
108 /**\r
109 Core execution function for this action class.\r
110\r
111 This function work flows will be:\r
112 1) Collect and prepocess PCD information from FPD file, all PCD\r
113 information will be stored into memory database.\r
114 2) Generate 3 strings for\r
115 a) All modules using Dynamic(Ex) PCD entry.(Token Number)\r
116 b) PEI PCDDatabase (C Structure) for PCD Service PEIM.\r
117 c) DXE PCD Database (C structure) for PCD Service DXE.\r
118\r
119\r
120 @throws EntityException Exception indicate failed to execute this action.\r
121\r
122 **/\r
8b7bd455 123 public void execute() throws PlatformPcdPreprocessBuildException {\r
e55d8a3c 124 String errorMessageHeader = "Fail to initialize Pcd memory database for building. Because:";\r
125 String errorsForPreprocess = null;\r
126\r
af98370e 127 //\r
128 // Get memoryDatabaseManager instance from GlobalData.\r
8b7bd455 129 // The memoryDatabaseManager should be initialized as static variable\r
130 // in some Pre-process class.\r
af98370e 131 //\r
8b7bd455 132 setPcdDbManager(GlobalData.getPCDMemoryDBManager());\r
af98370e 133\r
134 //\r
135 // Collect all PCD information defined in FPD file.\r
136 // Evenry token defind in FPD will be created as an token into\r
137 // memory database.\r
138 //\r
8b7bd455 139 try {\r
140 initPcdMemoryDbWithPlatformInfo();\r
141 } catch (PlatformPcdPreprocessException exp) {\r
142 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + exp.getMessage());\r
143 }\r
e55d8a3c 144 errorsForPreprocess = this.getErrorString();\r
145 if (errorsForPreprocess != null) {\r
146 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + errorsForPreprocess);\r
147 }\r
af98370e 148\r
149 //\r
150 // Generate for PEI, DXE PCD DATABASE's definition and initialization.\r
151 //\r
8b7bd455 152 try {\r
153 genPcdDatabaseSourceCode ();\r
154 } catch (EntityException exp) {\r
155 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + exp.getMessage());\r
156 }\r
af98370e 157 }\r
158\r
159 /**\r
160 Override function: implementate the method of get Guid string information from SPD file.\r
161\r
162 @param guidCName Guid CName string.\r
163\r
20c5c53f 164 @return String Guid information from SPD file.\r
8b7bd455 165 @throws PlatformPcdPreprocessException\r
166 Fail to get Guid information from SPD file.\r
af98370e 167 **/\r
20c5c53f 168 public String getGuidInfoFromSpd(String guidCName) throws PlatformPcdPreprocessException {\r
169 String tokenSpaceStrRet = null;\r
af98370e 170 try {\r
171 tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(guidCName);\r
172 } catch ( Exception e ) {\r
8b7bd455 173 throw new PlatformPcdPreprocessException ("Failed get Guid CName " + guidCName + "from SPD file!");\r
af98370e 174 }\r
175 return tokenSpaceStrRet;\r
176 }\r
177\r
178 /**\r
179 This function generates source code for PCD Database.\r
180\r
af98370e 181 @throws EntityException If the token does *not* exist in memory database.\r
182\r
183 **/\r
184 private void genPcdDatabaseSourceCode()\r
185 throws EntityException {\r
186 String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions();\r
187\r
188 ArrayList<Token> alPei = new ArrayList<Token> ();\r
189 ArrayList<Token> alDxe = new ArrayList<Token> ();\r
190\r
191 getPcdDbManager().getTwoPhaseDynamicRecordArray(alPei, alDxe);\r
192 PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);\r
193 pcdPeiDatabase.genCode();\r
194 MemoryDatabaseManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString() +\r
195 PcdDatabase.getPcdPeiDatabaseDefinitions();\r
196 MemoryDatabaseManager.PcdPeimCString = pcdPeiDatabase.getCString();\r
197\r
198 PcdDatabase pcdDxeDatabase = new PcdDatabase(alDxe, "DXE", alPei.size());\r
199 pcdDxeDatabase.genCode();\r
200 MemoryDatabaseManager.PcdDxeHString = MemoryDatabaseManager.PcdPeimHString + pcdDxeDatabase.getHString() +\r
201 PcdDatabase.getPcdDxeDatabaseDefinitions();\r
202 MemoryDatabaseManager.PcdDxeCString = pcdDxeDatabase.getCString();\r
203 }\r
204\r
205 /**\r
206 Override function: Get component array from FPD.\r
207\r
208 This function maybe provided by some Global class.\r
209\r
8b7bd455 210 @return List<ModuleInfo> the component array.\r
211 @throws PlatformPcdPreprocessException get all modules in <ModuleSA> in FPD file.\r
af98370e 212\r
8b7bd455 213 **/\r
af98370e 214 public List<ModulePcdInfoFromFpd> getComponentsFromFpd()\r
8b7bd455 215 throws PlatformPcdPreprocessException {\r
af98370e 216 List<ModulePcdInfoFromFpd> allModules = new ArrayList<ModulePcdInfoFromFpd>();\r
217 Map<FpdModuleIdentification, XmlObject> pcdBuildDefinitions = null;\r
218 UsageIdentification usageId = null;\r
219\r
220 pcdBuildDefinitions = GlobalData.getFpdPcdBuildDefinitions();\r
221 if (pcdBuildDefinitions == null) {\r
222 return null;\r
223 }\r
224\r
225 //\r
226 // Loop map to retrieve all PCD build definition and Module id\r
227 //\r
228 Iterator item = pcdBuildDefinitions.keySet().iterator();\r
229 while (item.hasNext()){\r
230 FpdModuleIdentification id = (FpdModuleIdentification) item.next();\r
231 usageId = new UsageIdentification(id.getModule().getName(),\r
232 id.getModule().getGuid(),\r
233 id.getModule().getPackage().getName(),\r
234 id.getModule().getPackage().getGuid(),\r
235 id.getArch(),\r
236 id.getModule().getVersion(),\r
237 id.getModule().getModuleType());\r
e55d8a3c 238 allModules.add(\r
239 new ModulePcdInfoFromFpd(\r
240 usageId, \r
241 ((PcdBuildDefinitionDocument)pcdBuildDefinitions.get(id)).getPcdBuildDefinition()));\r
af98370e 242 }\r
243 return allModules;\r
244 }\r
245\r
246 /**\r
247 Override function: Verify the datum value according its datum size and datum type, this\r
248 function maybe moved to FPD verification tools in future.\r
249\r
8b7bd455 250 @param cName The token name\r
251 @param moduleName The module who use this PCD token\r
252 @param datum The PCD's datum\r
253 @param datumType The PCD's datum type\r
254 @param maxDatumSize The max size for PCD's Datum.\r
af98370e 255\r
8b7bd455 256 @return String exception strings.\r
af98370e 257 */\r
af98370e 258 public String verifyDatum(String cName,\r
259 String moduleName,\r
260 String datum,\r
261 Token.DATUM_TYPE datumType,\r
262 int maxDatumSize) {\r
4d1939b8 263 //\r
264 // In building system, datum should not be checked, the checking work\r
265 // should be done by wizard tools or PCD verification tools.\r
266 // \r
af98370e 267 return null;\r
268 }\r
269\r
270 /**\r
271 Override function: Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.\r
272\r
273 This function should be implemented in GlobalData in future.\r
274\r
275 @param token The token instance which has hold module's PCD information\r
276 @param moduleName The name of module who will use this Dynamic PCD.\r
277\r
278 @return DynamicPcdBuildDefinitions.PcdBuildData\r
279 **/\r
280 public DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFpd(Token token,\r
281 String moduleName)\r
8b7bd455 282 throws PlatformPcdPreprocessException {\r
af98370e 283 int index = 0;\r
284 String exceptionString = null;\r
285 String dynamicPrimaryKey = null;\r
286 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;\r
287 List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;\r
20c5c53f 288 String tokenSpaceStrRet = null;\r
af98370e 289\r
290 //\r
291 // If FPD document is not be opened, open and initialize it.\r
292 // BUGBUG: The code should be moved into GlobalData in future.\r
293 //\r
294 if (fpdDocInstance == null) {\r
295 try {\r
296 fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
297 } catch(IOException ioE) {\r
8b7bd455 298 throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
af98370e 299 } catch(XmlException xmlE) {\r
8b7bd455 300 throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
af98370e 301 }\r
302 }\r
303\r
304 dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r
305 if (dynamicPcdBuildDefinitions == null) {\r
306 exceptionString = String.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+\r
307 "PCD entry %s in module %s!",\r
308 token.cName,\r
309 moduleName);\r
e55d8a3c 310 putError(exceptionString);\r
311 return null;\r
af98370e 312 }\r
313\r
314 dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
315 for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {\r
20c5c53f 316 tokenSpaceStrRet = getGuidInfoFromSpd(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName());\r
af98370e 317\r
318 if (tokenSpaceStrRet == null) {\r
e55d8a3c 319 exceptionString = "Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName();\r
320 putError(exceptionString);\r
321 continue;\r
af98370e 322 }\r
323\r
324 dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),\r
20c5c53f 325 tokenSpaceStrRet);\r
af98370e 326 if (dynamicPrimaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {\r
327 return dynamicPcdBuildDataArray.get(index);\r
328 }\r
329 }\r
330\r
331 return null;\r
332 }\r
333\r
334 /**\r
335 Override function: get all <DynamicPcdBuildDefinition> from FPD file.\r
336\r
8b7bd455 337 @return List<DynamicPcdBuildDefinitions.PcdBuildData> All DYNAMIC PCD list in <DynamicPcdBuildDefinitions> in FPD file.\r
338 @throws PlatformPcdPreprocessBuildException Failure to get dynamic information list.\r
339\r
af98370e 340 **/\r
341 public List<DynamicPcdBuildDefinitions.PcdBuildData>\r
342 getAllDynamicPcdInfoFromFpd()\r
8b7bd455 343 throws PlatformPcdPreprocessException {\r
af98370e 344 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;\r
345\r
346 //\r
347 // Open fpd document to get <DynamicPcdBuildDefinition> Section.\r
348 // BUGBUG: the function should be move GlobalData in furture.\r
349 //\r
350 if (fpdDocInstance == null) {\r
351 try {\r
352 fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
353 } catch(IOException ioE) {\r
8b7bd455 354 throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
af98370e 355 } catch(XmlException xmlE) {\r
8b7bd455 356 throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
af98370e 357 }\r
358 }\r
359\r
360 dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r
361 if (dynamicPcdBuildDefinitions == null) {\r
e55d8a3c 362 putError("There is no <DynamicPcdBuildDefinitions> in FPD file!");\r
af98370e 363 return null;\r
364 }\r
365\r
366 return dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
367 }\r
368\r
369 /**\r
370 check parameter for this action.\r
371\r
8b7bd455 372 @throws PlatformPcdPreprocessBuildException Bad parameter.\r
af98370e 373 **/\r
8b7bd455 374 private void checkParameter() throws PlatformPcdPreprocessBuildException {\r
af98370e 375 File file = null;\r
376\r
8b7bd455 377 if (fpdFilePath == null) {\r
378 throw new PlatformPcdPreprocessBuildException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
af98370e 379 }\r
380\r
8b7bd455 381 if (fpdFilePath.length() == 0) {\r
382 throw new PlatformPcdPreprocessBuildException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
af98370e 383 }\r
384\r
385 file = new File(fpdFilePath);\r
386\r
387 if(!file.exists()) {\r
8b7bd455 388 throw new PlatformPcdPreprocessBuildException("FPD File " + fpdFilePath + " does not exist!");\r
af98370e 389 }\r
390 }\r
391\r
392 /**\r
393 Test case function\r
394\r
395 @param argv parameter from command line\r
396 **/\r
8b7bd455 397 public static void main(String argv[]) throws PlatformPcdPreprocessBuildException {\r
af98370e 398 PlatformPcdPreprocessActionForBuilding ca = new PlatformPcdPreprocessActionForBuilding();\r
399 String projectDir = "x:/edk2";\r
af98370e 400 ca.setFPDFilePath(projectDir + "/EdkNt32Pkg/Nt32.fpd");\r
401 ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);\r
402 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",\r
403 projectDir,\r
404 "tools_def.txt");\r
405 System.out.println("After initInfo!");\r
406 FpdParserTask fpt = new FpdParserTask();\r
407 fpt.parseFpdFile(new File(projectDir + "/EdkNt32Pkg/Nt32.fpd"));\r
408 ca.execute();\r
409 }\r
410}\r