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