]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - Tools/Java/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java
Modify the way of pcd warning message reporting to be a total in the end.
[mirror_edk2.git] / Tools / Java / Source / GenBuild / org / tianocore / build / fpd / FpdParserTask.java
... / ...
CommitLineData
1/** @file\r
2 This file is ANT task FpdParserTask.\r
3\r
4 FpdParserTask is used to parse FPD (Framework Platform Description) and generate\r
5 build.out.xml. It is for Package or Platform build use.\r
6\r
7 Copyright (c) 2006, Intel Corporation\r
8 All rights reserved. This program and the accompanying materials\r
9 are licensed and made available under the terms and conditions of the BSD License\r
10 which accompanies this distribution. The full text of the license may be found at\r
11 http://opensource.org/licenses/bsd-license.php\r
12\r
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15 **/\r
16package org.tianocore.build.fpd;\r
17\r
18import java.io.BufferedWriter;\r
19import java.io.File;\r
20import java.io.FileWriter;\r
21import java.io.IOException;\r
22import java.util.HashMap;\r
23import java.util.Iterator;\r
24import java.util.LinkedHashMap;\r
25import java.util.LinkedHashSet;\r
26import java.util.Map;\r
27import java.util.Set;\r
28import java.util.Vector;\r
29\r
30import org.apache.tools.ant.BuildException;\r
31import org.apache.tools.ant.Task;\r
32import org.apache.tools.ant.taskdefs.Ant;\r
33import org.apache.tools.ant.taskdefs.Property;\r
34import org.apache.xmlbeans.XmlException;\r
35import org.apache.xmlbeans.XmlObject;\r
36\r
37import org.tianocore.common.definitions.EdkDefinitions;\r
38import org.tianocore.common.definitions.ToolDefinitions;\r
39import org.tianocore.common.exception.EdkException;\r
40import org.tianocore.common.logger.EdkLog;\r
41import org.tianocore.build.FrameworkBuildTask;\r
42import org.tianocore.build.global.GlobalData;\r
43import org.tianocore.build.global.OutputManager;\r
44import org.tianocore.build.global.SurfaceAreaQuery;\r
45import org.tianocore.build.id.FpdModuleIdentification;\r
46import org.tianocore.build.id.ModuleIdentification;\r
47import org.tianocore.build.id.PackageIdentification;\r
48import org.tianocore.build.id.PlatformIdentification;\r
49import org.tianocore.build.pcd.action.PlatformPcdPreprocessActionForBuilding;\r
50import org.tianocore.build.toolchain.ToolChainElement;\r
51import org.tianocore.build.toolchain.ToolChainMap;\r
52import org.tianocore.build.toolchain.ToolChainInfo;\r
53import org.w3c.dom.NamedNodeMap;\r
54import org.w3c.dom.Node;\r
55import org.w3c.dom.NodeList;\r
56\r
57/**\r
58 <code>FpdParserTask</code> is an ANT task. The main function is parsing Framework\r
59 Platform Descritpion (FPD) XML file and generating its ANT build script for\r
60 corresponding platform.\r
61\r
62 <p>The task sets global properties PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR\r
63 and BUILD_DIR. </p>\r
64\r
65 <p>The task generates ${PLATFORM}_build.xml file which will be called by top level\r
66 build.xml. The task also generate Fv.inf files (File is for Tool GenFvImage). </p>\r
67\r
68 <p>FpdParserTask task stores all FPD information to GlobalData. And parse\r
69 tools definition file to set up compiler options for different Target and\r
70 different ToolChainTag. </p>\r
71\r
72 <p>The method parseFpdFile is also prepared for single module build. </p>\r
73\r
74 @since GenBuild 1.0\r
75**/\r
76public class FpdParserTask extends Task {\r
77\r
78 private File fpdFile = null;\r
79\r
80 PlatformIdentification platformId;\r
81\r
82 private String type;\r
83\r
84 ///\r
85 /// Mapping from modules identification to out put file name\r
86 ///\r
87 Map<FpdModuleIdentification, String> outfiles = new LinkedHashMap<FpdModuleIdentification, String>();\r
88\r
89 ///\r
90 /// Mapping from FV name to its modules\r
91 ///\r
92 Map<String, Set<FpdModuleIdentification>> fvs = new HashMap<String, Set<FpdModuleIdentification>>();\r
93\r
94 ///\r
95 /// FpdParserTask can specify some ANT properties.\r
96 ///\r
97 private Vector<Property> properties = new Vector<Property>();\r
98\r
99 SurfaceAreaQuery saq = null;\r
100 \r
101 boolean isUnified = true;\r
102\r
103 /**\r
104 Public construct method. It is necessary for ANT task.\r
105 **/\r
106 public FpdParserTask() {\r
107 }\r
108\r
109 /**\r
110 ANT task's entry method. The main steps is described as following:\r
111\r
112 <ul>\r
113 <li>Initialize global information (Framework DB, SPD files and all MSA files\r
114 listed in SPD). This step will execute only once in whole build process;</li>\r
115 <li>Parse specified FPD file; </li>\r
116 <li>Generate FV.inf files; </li>\r
117 <li>Generate PlatformName_build.xml file for Flatform build; </li>\r
118 <li>Collect PCD information. </li>\r
119 </ul>\r
120\r
121 @throws BuildException\r
122 Surface area is not valid.\r
123 **/\r
124 public void execute() throws BuildException {\r
125 this.setTaskName("FpdParser");\r
126 \r
127 //\r
128 // Parse FPD file\r
129 //\r
130 parseFpdFile();\r
131\r
132 //\r
133 // Prepare BUILD_DIR\r
134 //\r
135 isUnified = OutputManager.getInstance().prepareBuildDir(getProject());\r
136\r
137 String buildDir = getProject().getProperty("BUILD_DIR");\r
138 //\r
139 // For every Target and ToolChain\r
140 //\r
141 String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
142 for (int i = 0; i < targetList.length; i++) {\r
143 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
144 for(int j = 0; j < toolchainList.length; j++) {\r
145 //\r
146 // Prepare FV_DIR\r
147 //\r
148 String ffsCommonDir = buildDir + File.separatorChar\r
149 + targetList[i] + "_"\r
150 + toolchainList[j];\r
151 File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");\r
152 fvDir.mkdirs();\r
153 getProject().setProperty("FV_DIR", fvDir.getPath().replaceAll("(\\\\)", "/"));\r
154\r
155 //\r
156 // Gen Fv.inf files\r
157 //\r
158 genFvInfFiles(ffsCommonDir);\r
159 }\r
160 }\r
161\r
162 //\r
163 // Gen build.xml\r
164 //\r
165 String platformBuildFile = buildDir + File.separatorChar + platformId.getName() + "_build.xml";\r
166 PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq, platformBuildFile);\r
167 fileGenerator.genBuildFile();\r
168\r
169 //\r
170 // Ant call ${PLATFORM}_build.xml\r
171 //\r
172 Ant ant = new Ant();\r
173 ant.setProject(getProject());\r
174 ant.setAntfile(platformBuildFile);\r
175 ant.setTarget(type);\r
176 ant.setInheritAll(true);\r
177 ant.init();\r
178 ant.execute();\r
179 }\r
180\r
181 /**\r
182 Generate Fv.inf files. The Fv.inf file is composed with four\r
183 parts: Options, Attributes, Components and Files. The Fv.inf files\r
184 will be under FV_DIR.\r
185\r
186 @throws BuildException\r
187 File write FV.inf files error.\r
188 **/\r
189 void genFvInfFiles(String ffsCommonDir) throws BuildException {\r
190 String[] validFv = saq.getFpdValidImageNames();\r
191 for (int i = 0; i < validFv.length; i++) {\r
192 //\r
193 // Get all global variables from FPD and set them to properties\r
194 //\r
195 String[][] globalVariables = saq.getFpdGlobalVariable();\r
196 for (int j = 0; j < globalVariables.length; j++) {\r
197 getProject().setProperty(globalVariables[j][0], globalVariables[j][1]);\r
198 }\r
199\r
200 getProject().setProperty("FV_FILENAME", validFv[i]);\r
201\r
202 File fvFile = new File(getProject().replaceProperties( getProject().getProperty("FV_DIR") + File.separatorChar + validFv[i] + ".inf"));\r
203 if (fvFile.exists() && (fvFile.lastModified() >= fpdFile.lastModified())) {\r
204 //\r
205 // don't re-generate FV.inf if fpd has not been changed\r
206 // \r
207 continue;\r
208 }\r
209 fvFile.getParentFile().mkdirs();\r
210\r
211 try {\r
212 FileWriter fw = new FileWriter(fvFile);\r
213 BufferedWriter bw = new BufferedWriter(fw);\r
214\r
215 //\r
216 // Options\r
217 //\r
218 String[][] options = saq.getFpdOptions(validFv[i]);\r
219 if (options.length > 0) {\r
220 bw.write("[options]");\r
221 bw.newLine();\r
222 for (int j = 0; j < options.length; j++) {\r
223 StringBuffer str = new StringBuffer(100);\r
224 str.append(options[j][0]);\r
225 while (str.length() < 40) {\r
226 str.append(' ');\r
227 }\r
228 str.append("= ");\r
229 str.append(options[j][1]);\r
230 bw.write(getProject().replaceProperties(str.toString()));\r
231 bw.newLine();\r
232 }\r
233 bw.newLine();\r
234 }\r
235\r
236 //\r
237 // Attributes;\r
238 //\r
239 String[][] attributes = saq.getFpdAttributes(validFv[i]);\r
240 if (attributes.length > 0) {\r
241 bw.write("[attributes]");\r
242 bw.newLine();\r
243 for (int j = 0; j < attributes.length; j++) {\r
244 StringBuffer str = new StringBuffer(100);\r
245 str.append(attributes[j][0]);\r
246 while (str.length() < 40) {\r
247 str.append(' ');\r
248 }\r
249 str.append("= ");\r
250 str.append(attributes[j][1]);\r
251 bw.write(getProject().replaceProperties(str.toString()));\r
252 bw.newLine();\r
253 }\r
254 bw.newLine();\r
255 }\r
256\r
257 //\r
258 // Components\r
259 //\r
260 String[][] components = saq.getFpdComponents(validFv[i]);\r
261 if (components.length > 0) {\r
262 bw.write("[components]");\r
263 bw.newLine();\r
264 for (int j = 0; j < components.length; j++) {\r
265 StringBuffer str = new StringBuffer(100);\r
266 str.append(components[j][0]);\r
267 while (str.length() < 40) {\r
268 str.append(' ');\r
269 }\r
270 str.append("= ");\r
271 str.append(components[j][1]);\r
272 bw.write(getProject().replaceProperties(str.toString()));\r
273 bw.newLine();\r
274 }\r
275 bw.newLine();\r
276 }\r
277 \r
278 //\r
279 // Files\r
280 //\r
281 Set<FpdModuleIdentification> moduleSeqSet = getModuleSequenceForFv(validFv[i]);\r
282 \r
283 Set<FpdModuleIdentification> filesSet = fvs.get(validFv[i]);\r
284 \r
285 FpdModuleIdentification[] files = null;\r
286 \r
287 if (moduleSeqSet == null) {\r
288 if (filesSet != null) {\r
289 files = filesSet.toArray(new FpdModuleIdentification[filesSet.size()]);\r
290 }\r
291 } else if (filesSet == null) {\r
292 if (moduleSeqSet.size() != 0) {\r
293 throw new BuildException("Can not find any modules belongs to FV[" + validFv[i] + "], but listed some in BuildOptions.UserExtensions[@UserID='IMAGES' @Identifier='1']");\r
294 }\r
295 } else {\r
296 //\r
297 // if moduleSeqSet and filesSet is inconsistent, report error\r
298 //\r
299 if(moduleSeqSet.size() != filesSet.size()){\r
300 throw new BuildException("Modules for FV[" + validFv[i] + "] defined in FrameworkModules and in BuildOptions.UserExtensions[@UserID='IMAGES' @Identifier='1'] are inconsistent. ");\r
301 } else {\r
302 //\r
303 // whether all modules in moduleSeqSet listed in filesSet\r
304 //\r
305 Iterator<FpdModuleIdentification> iter = moduleSeqSet.iterator();\r
306 while (iter.hasNext()) {\r
307 FpdModuleIdentification item = iter.next();\r
308 if (!filesSet.contains(item)) {\r
309 throw new BuildException("Can not find " + item + " belongs to FV[" + validFv[i] + "]");\r
310 }\r
311 }\r
312 }\r
313 \r
314 files = moduleSeqSet.toArray(new FpdModuleIdentification[moduleSeqSet.size()]);\r
315 }\r
316 \r
317 \r
318 if (files != null) {\r
319 bw.write("[files]");\r
320 bw.newLine();\r
321 for (int j = 0; j < files.length; j++) {\r
322 String str = ffsCommonDir + File.separatorChar + outfiles.get(files[j]);\r
323 bw.write(getProject().replaceProperties("EFI_FILE_NAME = " + str));\r
324 bw.newLine();\r
325 }\r
326 }\r
327 bw.flush();\r
328 bw.close();\r
329 fw.close();\r
330 } catch (IOException ex) {\r
331 BuildException buildException = new BuildException("Generation of the FV file [" + fvFile.getPath() + "] failed!\n" + ex.getMessage());\r
332 buildException.setStackTrace(ex.getStackTrace());\r
333 throw buildException;\r
334 } catch (EdkException ex) {\r
335 BuildException buildException = new BuildException("Generation of the FV file [" + fvFile.getPath() + "] failed!\n" + ex.getMessage());\r
336 buildException.setStackTrace(ex.getStackTrace());\r
337 throw buildException;\r
338 }\r
339 }\r
340 }\r
341 \r
342 /**\r
343 This method is used for Single Module Build.\r
344\r
345 @throws BuildException\r
346 FPD file is not valid.\r
347 **/\r
348 public void parseFpdFile(File fpdFile) throws BuildException, EdkException {\r
349 this.fpdFile = fpdFile;\r
350 parseFpdFile();\r
351 \r
352 //\r
353 // Call Platform_build.xml prebuild firstly in stand-alone build\r
354 // Prepare BUILD_DIR\r
355 //\r
356 isUnified = OutputManager.getInstance().prepareBuildDir(getProject());\r
357\r
358 String buildDir = getProject().getProperty("BUILD_DIR");\r
359 //\r
360 // For every Target and ToolChain\r
361 //\r
362 String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
363 for (int i = 0; i < targetList.length; i++) {\r
364 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
365 for(int j = 0; j < toolchainList.length; j++) {\r
366 //\r
367 // Prepare FV_DIR\r
368 //\r
369 String ffsCommonDir = buildDir + File.separatorChar\r
370 + targetList[i] + "_"\r
371 + toolchainList[j];\r
372 File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");\r
373 fvDir.mkdirs();\r
374 }\r
375 }\r
376\r
377 String platformBuildFile = buildDir + File.separatorChar + platformId.getName() + "_build.xml";\r
378 PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq, platformBuildFile);\r
379 fileGenerator.genBuildFile();\r
380 \r
381 Ant ant = new Ant();\r
382 ant.setProject(getProject());\r
383 ant.setAntfile(platformBuildFile);\r
384 ant.setTarget("prebuild");\r
385 ant.setInheritAll(true);\r
386 ant.init();\r
387 ant.execute();\r
388 }\r
389\r
390 /**\r
391 Parse FPD file.\r
392\r
393 @throws BuildException\r
394 FPD file is not valid.\r
395 **/\r
396 void parseFpdFile() throws BuildException {\r
397 try {\r
398 XmlObject doc = XmlObject.Factory.parse(fpdFile);\r
399\r
400 if (!doc.validate()) {\r
401 throw new BuildException("Platform Surface Area file [" + fpdFile.getPath() + "] format is invalid!");\r
402 }\r
403\r
404 Map<String, XmlObject> map = new HashMap<String, XmlObject>();\r
405 map.put("PlatformSurfaceArea", doc);\r
406 saq = new SurfaceAreaQuery(map);\r
407\r
408 //\r
409 // Initialize\r
410 //\r
411 platformId = saq.getFpdHeader();\r
412 platformId.setFpdFile(fpdFile);\r
413 getProject().setProperty("PLATFORM", platformId.getName());\r
414 getProject().setProperty("PLATFORM_FILE", platformId.getRelativeFpdFile().replaceAll("(\\\\)", "/"));\r
415 getProject().setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));\r
416 getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));\r
417 \r
418 if( !FrameworkBuildTask.multithread) {\r
419 FrameworkBuildTask.originalProperties.put("PLATFORM", platformId.getName());\r
420 FrameworkBuildTask.originalProperties.put("PLATFORM_FILE", platformId.getRelativeFpdFile().replaceAll("(\\\\)", "/"));\r
421 FrameworkBuildTask.originalProperties.put("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));\r
422 FrameworkBuildTask.originalProperties.put("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));\r
423 }\r
424\r
425 //\r
426 // Build mode. User-defined output dir.\r
427 //\r
428 String buildMode = saq.getFpdIntermediateDirectories();\r
429 String userDefinedOutputDir = saq.getFpdOutputDirectory();\r
430\r
431 OutputManager.getInstance().setup(userDefinedOutputDir, buildMode);\r
432\r
433 //\r
434 // TBD. Deal PCD and BuildOption related Info\r
435 //\r
436 GlobalData.setFpdBuildOptions(saq.getFpdBuildOptions());\r
437\r
438 GlobalData.setToolChainPlatformInfo(saq.getFpdToolChainInfo());\r
439\r
440 //\r
441 // Parse all list modules SA\r
442 //\r
443 parseModuleSAFiles();\r
444\r
445 //\r
446 // TBD. Deal PCD and BuildOption related Info\r
447 //\r
448 parseToolChainFamilyOptions();\r
449 parseToolChainOptions();\r
450\r
451 //\r
452 // check if the tool chain is valid or not\r
453 // \r
454 checkToolChain();\r
455\r
456 saq.push(map);\r
457\r
458 //\r
459 // Pcd Collection. Call CollectPCDAction to collect pcd info.\r
460 //\r
461 PlatformPcdPreprocessActionForBuilding ca = new PlatformPcdPreprocessActionForBuilding();\r
462 ca.perform(platformId.getFpdFile().getPath());\r
463 } catch (IOException ex) {\r
464 BuildException buildException = new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage());\r
465 buildException.setStackTrace(ex.getStackTrace());\r
466 throw buildException;\r
467 } catch (XmlException ex) {\r
468 BuildException buildException = new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage());\r
469 buildException.setStackTrace(ex.getStackTrace());\r
470 throw buildException;\r
471 } catch (EdkException ex) {\r
472 BuildException buildException = new BuildException("Parsing of the FPD file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage());\r
473 buildException.setStackTrace(ex.getStackTrace());\r
474 throw buildException;\r
475 }\r
476 }\r
477\r
478 /**\r
479 Parse all modules listed in FPD file.\r
480 **/\r
481 void parseModuleSAFiles() throws EdkException{\r
482 Map<FpdModuleIdentification, Map<String, XmlObject>> moduleSAs = saq.getFpdModules();\r
483\r
484 //\r
485 // For every Module lists in FPD file.\r
486 //\r
487 Set<FpdModuleIdentification> keys = moduleSAs.keySet();\r
488 Iterator iter = keys.iterator();\r
489 while (iter.hasNext()) {\r
490 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();\r
491\r
492 //\r
493 // Judge if Module is existed?\r
494 // TBD\r
495 GlobalData.registerFpdModuleSA(fpdModuleId, moduleSAs.get(fpdModuleId));\r
496\r
497 //\r
498 // Put fpdModuleId to the corresponding FV\r
499 //\r
500 saq.push(GlobalData.getDoc(fpdModuleId));\r
501 String fvBinding = saq.getModuleFvBindingKeyword();\r
502\r
503 fpdModuleId.setFvBinding(fvBinding);\r
504 updateFvs(fvBinding, fpdModuleId);\r
505\r
506 //\r
507 // Prepare for out put file name\r
508 //\r
509 ModuleIdentification moduleId = fpdModuleId.getModule();\r
510\r
511 String baseName = saq.getModuleOutputFileBasename();\r
512 \r
513 if (baseName == null) {\r
514 baseName = moduleId.getName();\r
515 }\r
516 outfiles.put(fpdModuleId, fpdModuleId.getArch() + File.separatorChar\r
517 + moduleId.getGuid() + "-" + baseName\r
518 + getSuffix(moduleId.getModuleType()));\r
519\r
520 //\r
521 // parse module build options, if any\r
522 //\r
523 GlobalData.addModuleToolChainOption(fpdModuleId, parseModuleBuildOptions(false));\r
524 GlobalData.addModuleToolChainFamilyOption(fpdModuleId, parseModuleBuildOptions(true));\r
525 \r
526 //\r
527 // parse MSA build options\r
528 //\r
529 GlobalData.addMsaBuildOption(moduleId, parseMsaBuildOptions(false));\r
530 GlobalData.addMsaFamilyBuildOption(moduleId, parseMsaBuildOptions(true));\r
531 \r
532 ModuleIdentification[] libraryInstances = saq.getLibraryInstance(null);\r
533 for (int i = 0; i < libraryInstances.length; i++) {\r
534 saq.push(GlobalData.getDoc(libraryInstances[i], fpdModuleId.getArch()));\r
535 GlobalData.addMsaBuildOption(libraryInstances[i], parseMsaBuildOptions(false));\r
536 GlobalData.addMsaFamilyBuildOption(libraryInstances[i], parseMsaBuildOptions(true));\r
537 saq.pop();\r
538 }\r
539 \r
540 saq.pop();\r
541 }\r
542 }\r
543\r
544 ToolChainMap parseModuleBuildOptions(boolean toolChainFamilyFlag) throws EdkException {\r
545 String[][] options = saq.getModuleBuildOptions(toolChainFamilyFlag);\r
546 if (options == null || options.length == 0) {\r
547 return new ToolChainMap();\r
548 }\r
549 return parseOptions(options);\r
550 }\r
551\r
552 private ToolChainMap parsePlatformBuildOptions(boolean toolChainFamilyFlag) throws EdkException {\r
553 String[][] options = saq.getPlatformBuildOptions(toolChainFamilyFlag);\r
554 if (options == null || options.length == 0) {\r
555 return new ToolChainMap();\r
556 }\r
557 return parseOptions(options);\r
558 }\r
559\r
560 ToolChainMap parseMsaBuildOptions(boolean toolChainFamilyFlag) throws EdkException {\r
561 String[][] options = saq.getMsaBuildOptions(toolChainFamilyFlag);\r
562 if (options == null || options.length == 0) {\r
563 return new ToolChainMap();\r
564 }\r
565 return parseOptions(options);\r
566 }\r
567 \r
568 private ToolChainMap parseOptions(String[][] options) throws EdkException {\r
569 ToolChainMap map = new ToolChainMap();\r
570 int flagIndex = ToolChainElement.ATTRIBUTE.value;\r
571\r
572 for (int i = 0; i < options.length; ++i) {\r
573 String flagString = options[i][flagIndex];\r
574 if (flagString == null) {\r
575 flagString = "";\r
576 }\r
577 options[i][flagIndex] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS;\r
578 map.put(options[i], flagString.trim());\r
579 }\r
580\r
581 return map;\r
582 }\r
583\r
584 private void parseToolChainFamilyOptions() throws EdkException {\r
585 GlobalData.setPlatformToolChainFamilyOption(parsePlatformBuildOptions(true));\r
586 }\r
587\r
588 private void parseToolChainOptions() throws EdkException {\r
589 GlobalData.setPlatformToolChainOption(parsePlatformBuildOptions(false));\r
590 }\r
591\r
592 /**\r
593 Add the current module to corresponding FV.\r
594\r
595 @param fvName current FV name\r
596 @param moduleName current module identification\r
597 **/\r
598 void updateFvs(String fvName, FpdModuleIdentification fpdModuleId) {\r
599 if (fvName == null || fvName.trim().length() == 0) {\r
600 fvName = "NULL";\r
601 }\r
602 String[] fvNameArray = fvName.split("[, \t]+");\r
603 for (int i = 0; i < fvNameArray.length; i++) {\r
604 //\r
605 // Put module to corresponding fvName\r
606 //\r
607 if (fvs.containsKey(fvNameArray[i])) {\r
608 Set<FpdModuleIdentification> set = fvs.get(fvNameArray[i]);\r
609 set.add(fpdModuleId);\r
610 } else {\r
611 Set<FpdModuleIdentification> set = new LinkedHashSet<FpdModuleIdentification>();\r
612 set.add(fpdModuleId);\r
613 fvs.put(fvNameArray[i], set);\r
614 }\r
615 }\r
616 }\r
617\r
618 /**\r
619 Get the suffix based on module type. Current relationship are listed:\r
620\r
621 <pre>\r
622 <b>ModuleType</b> <b>Suffix</b>\r
623 BASE .FFS\r
624 SEC .SEC\r
625 PEI_CORE .PEI\r
626 PEIM .PEI\r
627 DXE_CORE .DXE\r
628 DXE_DRIVER .DXE\r
629 DXE_RUNTIME_DRIVER .DXE\r
630 DXE_SAL_DRIVER .DXE\r
631 DXE_SMM_DRIVER .DXE\r
632 TOOL .FFS\r
633 UEFI_DRIVER .DXE\r
634 UEFI_APPLICATION .APP\r
635 USER_DEFINED .FFS\r
636 </pre>\r
637\r
638 @param moduleType module type\r
639 @return\r
640 @throws BuildException\r
641 If module type is null\r
642 **/\r
643 public static String getSuffix(String moduleType) throws BuildException {\r
644 if (moduleType == null) {\r
645 throw new BuildException("Module type is not specified.");\r
646 }\r
647\r
648 String[][] suffix = EdkDefinitions.ModuleTypeExtensions;\r
649\r
650 for (int i = 0; i < suffix.length; i++) {\r
651 if (suffix[i][0].equalsIgnoreCase(moduleType)) {\r
652 return suffix[i][1];\r
653 }\r
654 }\r
655 //\r
656 // Default is '.FFS'\r
657 //\r
658 return ".FFS";\r
659 }\r
660 /**\r
661 Add a property.\r
662\r
663 @param p property\r
664 **/\r
665 public void addProperty(Property p) {\r
666 properties.addElement(p);\r
667 }\r
668\r
669 public void setFpdFile(File fpdFile) {\r
670 this.fpdFile = fpdFile;\r
671 }\r
672\r
673 public void setType(String type) {\r
674 this.type = type;\r
675 }\r
676 \r
677 public String getAllArchForModule(ModuleIdentification moduleId) {\r
678 String archs = "";\r
679 Iterator<FpdModuleIdentification> iter = outfiles.keySet().iterator();\r
680 while (iter.hasNext()) {\r
681 FpdModuleIdentification fpdModuleId = iter.next();\r
682 \r
683 if (fpdModuleId.getModule().equals(moduleId)) {\r
684 archs += fpdModuleId.getArch() + " ";\r
685 }\r
686 }\r
687 \r
688 return archs;\r
689 }\r
690 \r
691 private Set<FpdModuleIdentification> getModuleSequenceForFv(String fvName) throws EdkException {\r
692 Node node = saq.getFpdModuleSequence(fvName);\r
693 Set<FpdModuleIdentification> result = new LinkedHashSet<FpdModuleIdentification>();\r
694 \r
695 if ( node == null) {\r
696 EdkLog.log(this, EdkLog.EDK_WARNING, "FV[" + fvName + "] does not specify module sequence in FPD. Assuming present sequence as default sequence in FV. ");\r
697 return null;\r
698 } else {\r
699 NodeList childNodes = node.getChildNodes();\r
700 for (int i = 0; i < childNodes.getLength(); i++) {\r
701 Node childItem = childNodes.item(i);\r
702 if (childItem.getNodeType() == Node.ELEMENT_NODE) {\r
703 //\r
704 // Find child elements "IncludeModules"\r
705 //\r
706 if (childItem.getNodeName().compareTo("IncludeModules") == 0) {\r
707 //\r
708 // result will be updated\r
709 //\r
710 processNodes(childItem, result);\r
711 } else if (childItem.getNodeName().compareTo("FvName") == 0) {\r
712 \r
713 } else if (childItem.getNodeName().compareTo("InfFileName") == 0) {\r
714 \r
715 } else {\r
716 //\r
717 // Report Warning\r
718 //\r
719 EdkLog.log(this, EdkLog.EDK_WARNING, "Unrecognised element " + childItem.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1']");\r
720 }\r
721 }\r
722 }\r
723 }\r
724 \r
725 return result;\r
726 }\r
727 \r
728 private void processNodes(Node node, Set<FpdModuleIdentification> result) throws EdkException {\r
729 //\r
730 // Found out all elements "Module"\r
731 //\r
732 NodeList childNodes = node.getChildNodes();\r
733 for (int j = 0; j < childNodes.getLength(); j++) {\r
734 Node childItem = childNodes.item(j);\r
735 if (childItem.getNodeType() == Node.ELEMENT_NODE) {\r
736 if (childItem.getNodeName().compareTo("Module") == 0) {\r
737 String moduleGuid = null;\r
738 String moduleVersion = null;\r
739 String packageGuid = null;\r
740 String packageVersion = null;\r
741 String arch = null;\r
742 \r
743 NamedNodeMap attr = childItem.getAttributes();\r
744 for (int i = 0; i < attr.getLength(); i++) {\r
745 Node attrItem = attr.item(i);\r
746 if (attrItem.getNodeName().compareTo("ModuleGuid") == 0) {\r
747 moduleGuid = attrItem.getNodeValue();\r
748 } else if (attrItem.getNodeName().compareTo("ModuleVersion") == 0) {\r
749 moduleVersion = attrItem.getNodeValue();\r
750 } else if (attrItem.getNodeName().compareTo("PackageGuid") == 0) {\r
751 packageGuid = attrItem.getNodeValue();\r
752 } else if (attrItem.getNodeName().compareTo("PackageVersion") == 0) {\r
753 packageVersion = attrItem.getNodeValue();\r
754 } else if (attrItem.getNodeName().compareTo("Arch") == 0) {\r
755 arch = attrItem.getNodeValue();\r
756 } else {\r
757 //\r
758 // Report warning\r
759 //\r
760 EdkLog.log(this, EdkLog.EDK_WARNING, "Unrecognised attribute " + attrItem.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules.Module");\r
761 }\r
762 }\r
763 \r
764 PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion);\r
765 GlobalData.refreshPackageIdentification(packageId);\r
766 \r
767 ModuleIdentification moduleId = new ModuleIdentification(moduleGuid, moduleVersion);\r
768 moduleId.setPackage(packageId);\r
769 GlobalData.refreshModuleIdentification(moduleId);\r
770 \r
771 if (arch == null) {\r
772 throw new EdkException("Attribute [Arch] is required for element FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules.Module. ");\r
773 }\r
774 \r
775 result.add(new FpdModuleIdentification(moduleId, arch));\r
776 } else {\r
777 //\r
778 // Report Warning\r
779 //\r
780 EdkLog.log(this, EdkLog.EDK_WARNING, "Unrecognised element " + childItem.getNodeName() + " under FPD.BuildOptions.UserExtensions[UserID='IMAGES' Identifier='1'].IncludeModules");\r
781 }\r
782 }\r
783 }\r
784 }\r
785\r
786\r
787 private void checkToolChain() throws EdkException {\r
788 ToolChainInfo toolChainInfo = GlobalData.getToolChainInfo();\r
789\r
790 if (toolChainInfo.getTargets().length == 0) {\r
791 throw new EdkException("No valid target found! "+\r
792 "Please check the TARGET definition in Tools/Conf/target.txt, "+\r
793 "or the <BuildTarget>, <BuildOptions> in the FPD file.");\r
794 }\r
795\r
796 if (toolChainInfo.getTagnames().length == 0) {\r
797 throw new EdkException("No valid tool chain found! "+\r
798 "Please check the TOOL_CHAIN_TAG definition in Tools/Conf/target.txt, "+\r
799 "or the <BuildOptions> in the FPD file.");\r
800 }\r
801\r
802 if (toolChainInfo.getArchs().length == 0) {\r
803 throw new EdkException("No valid architecture found! "+\r
804 "Please check the TARGET_ARCH definition in Tools/Conf/target.txt, "+\r
805 "or the <SupportedArchitectures>, <BuildOptions> in the FPD file.");\r
806 }\r
807\r
808 if (toolChainInfo.getCommands().length == 0) {\r
809 throw new EdkException("No valid COMMAND found! Please check the tool chain definitions "+\r
810 "in Tools/Conf/tools_def.txt.");\r
811 }\r
812 }\r
813}\r