To fix bug EDKT432. Add judge to avoid include flags twice.
[mirror_edk2.git] / Tools / Java / Source / GenBuild / org / tianocore / build / global / GlobalData.java
1 /** @file
2 GlobalData class.
3
4 GlobalData provide initializing, instoring, querying and update global data.
5 It is a bridge to intercommunicate between multiple component, such as AutoGen,
6 PCD and so on.
7
8 Copyright (c) 2006, Intel Corporation
9 All rights reserved. This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
13
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 **/
17 package org.tianocore.build.global;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.Iterator;
26 import java.util.LinkedHashSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30
31 import org.apache.xmlbeans.XmlException;
32 import org.apache.xmlbeans.XmlObject;
33 import org.apache.xmlbeans.XmlOptions;
34 import org.tianocore.DbPathAndFilename;
35 import org.tianocore.FrameworkDatabaseDocument;
36 import org.tianocore.ModuleSurfaceAreaDocument;
37 import org.tianocore.ModuleSurfaceAreaDocument.ModuleSurfaceArea;
38 import org.tianocore.build.id.FpdModuleIdentification;
39 import org.tianocore.build.id.ModuleIdentification;
40 import org.tianocore.build.id.PackageIdentification;
41 import org.tianocore.build.id.PlatformIdentification;
42 import org.tianocore.build.toolchain.ToolChainConfig;
43 import org.tianocore.build.toolchain.ToolChainElement;
44 import org.tianocore.build.toolchain.ToolChainInfo;
45 import org.tianocore.build.toolchain.ToolChainKey;
46 import org.tianocore.build.toolchain.ToolChainMap;
47 import org.tianocore.common.definitions.ToolDefinitions;
48 import org.tianocore.common.exception.EdkException;
49 import org.tianocore.common.logger.EdkLog;
50 import org.tianocore.pcd.entity.MemoryDatabaseManager;
51
52 /**
53 GlobalData provide initializing, instoring, querying and update global data.
54 It is a bridge to intercommunicate between multiple component, such as AutoGen,
55 PCD and so on.
56
57 <p>Note that all global information are initialized incrementally. All data will
58 parse and record only of necessary during build time. </p>
59
60 @since GenBuild 1.0
61 **/
62 public class GlobalData {
63 ///
64 /// Record current WORKSPACE Directory
65 ///
66 private static String workspaceDir = "";
67
68 ///
69 /// Be used to ensure Global data will be initialized only once.
70 ///
71 private static boolean globalFlag = false;
72
73 ///
74 /// Framework Database information: package list and platform list
75 ///
76 private static Set<PackageIdentification> packageList = new HashSet<PackageIdentification>();
77
78 private static Set<PlatformIdentification> platformList = new HashSet<PlatformIdentification>();
79
80 ///
81 /// Every detail SPD informations: Module list, Library class definition,
82 /// Package header file, GUID/PPI/Protocol definitions
83 ///
84 private static final Map<PackageIdentification, Spd> spdTable = new HashMap<PackageIdentification, Spd>();
85
86 ///
87 /// Build informations are divided into three parts:
88 /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA
89 ///
90 private static Map<ModuleIdentification, Map<String, XmlObject>> nativeMsa = new HashMap<ModuleIdentification, Map<String, XmlObject>>();
91
92 private static Map<FpdModuleIdentification, Map<String, XmlObject>> fpdModuleSA= new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
93
94 private static Map<String, XmlObject> fpdBuildOptionsMap = new HashMap<String, XmlObject>();
95
96 private static XmlObject fpdBuildOptions;
97
98 private static XmlObject fpdDynamicPcds;
99
100 ///
101 /// Parsed modules list
102 ///
103 private static Map<FpdModuleIdentification, Map<String, XmlObject>> parsedModules = new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
104
105 ///
106 /// built modules list with ARCH, TARGET, TOOLCHAIN
107 ///
108 private static Set<FpdModuleIdentification> builtModules = new HashSet<FpdModuleIdentification>();
109
110 ///
111 /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.
112 ///
113 private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();
114
115 ///
116 /// build target + tool chain family/tag name + arch + command types + command options
117 ///
118 ///
119 /// Tool Chain Data
120 /// toolsDef - build tool program information
121 /// fpdBuildOption - all modules's build options for tool tag or tool chain families
122 /// moduleSaBuildOption - build options for a specific module
123 ///
124 private static ToolChainConfig toolsDef;
125
126 private static ToolChainInfo toolChainInfo;
127 private static ToolChainInfo toolChainEnvInfo;
128 private static ToolChainInfo toolChainPlatformInfo;
129
130 private static ToolChainMap platformToolChainOption;
131 private static ToolChainMap platformToolChainFamilyOption;
132
133 private static Map<FpdModuleIdentification, ToolChainMap> moduleToolChainOption = new HashMap<FpdModuleIdentification, ToolChainMap>();
134 private static Map<FpdModuleIdentification, ToolChainMap> moduleToolChainFamilyOption = new HashMap<FpdModuleIdentification, ToolChainMap>();
135
136 private static Map<ModuleIdentification, ToolChainMap> msaBuildOption = new HashMap<ModuleIdentification, ToolChainMap>();
137 private static Map<ModuleIdentification, ToolChainMap> msaFamilyBuildOption = new HashMap<ModuleIdentification, ToolChainMap>();
138
139 /**
140 Parse framework database (DB) and all SPD files listed in DB to initialize
141 the environment for next build. This method will only be executed only once
142 in the whole build process.
143
144 @param workspaceDatabaseFile the file name of framework database
145 @param workspaceDir current workspace directory path
146 @throws BuildException
147 Framework Dababase or SPD or MSA file is not valid
148 **/
149 public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir, String toolsDefFilename ) throws EdkException {
150 //
151 // ensure this method will be revoked only once
152 //
153 if (globalFlag) {
154 return;
155 }
156 globalFlag = true;
157
158 //
159 // Backup workspace directory. It will be used by other method
160 //
161 GlobalData.workspaceDir = workspaceDir.replaceAll("(\\\\)", "/");
162
163 //
164 // Parse tools definition file
165 //
166 //
167 // If ToolChain has been set up before, do nothing.
168 // CONF dir + tools definition file name
169 //
170 File toolsDefFile = new File(workspaceDir + File.separatorChar + toolsDefFilename);
171 EdkLog.log("Init", EdkLog.EDK_ALWAYS, "Using tool definition file [" + toolsDefFile.getPath() + "].");
172 toolsDef = new ToolChainConfig(toolsDefFile);
173
174 //
175 // Parse Framework Database
176 //
177 File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);
178 FrameworkDatabaseDocument db = null;
179 try {
180 db = (FrameworkDatabaseDocument)parseXmlFile(dbFile);
181 //
182 // Get package list
183 //
184 if (db.getFrameworkDatabase().getPackageList() != null ) {
185 List<DbPathAndFilename> packages = db.getFrameworkDatabase().getPackageList().getFilenameList();
186 Iterator<DbPathAndFilename> iter = packages.iterator();
187 while (iter.hasNext()) {
188 String fileName = iter.next().getStringValue().trim();
189 Spd spd = new Spd(new File(workspaceDir + File.separatorChar + fileName));
190 packageList.add(spd.getPackageId());
191 //
192 // Report warning if existing two packages with same GUID and Version
193 //
194 if (spdTable.containsKey(spd.getPackageId())) {
195 //
196 // BUGBUG
197 //
198 EdkLog.log("Init", EdkLog.EDK_WARNING, "Warning: Existing two packages with same GUID and Version. They are ... " + spd.getPackageId().getSpdFile().getPath());
199 }
200 spdTable.put(spd.getPackageId(), spd);
201 }
202 }
203 } catch(IOException ex) {
204 EdkException edkException = new EdkException("Parse of WORKSPACE Database file [" + dbFile.getPath() + "] failed!\n" + ex.getMessage());
205 edkException.setStackTrace(ex.getStackTrace());
206 throw edkException;
207 } catch(XmlException ex) {
208 EdkException edkException = new EdkException("Parse of WORKSPACE Database file [" + dbFile.getPath() + "] failed!\n" + ex.getMessage());
209 edkException.setStackTrace(ex.getStackTrace());
210 throw edkException;
211 }
212
213 File fpdFile = null;
214 try {
215 //
216 // Get platform list
217 //
218 if (db.getFrameworkDatabase().getPlatformList() != null) {
219 List<DbPathAndFilename> platforms = db.getFrameworkDatabase().getPlatformList().getFilenameList();
220 Iterator<DbPathAndFilename> iter = platforms.iterator();
221 while (iter.hasNext()) {
222 String fileName = iter.next().getStringValue().trim();
223 fpdFile = new File(workspaceDir + File.separatorChar + fileName);
224 if ( !fpdFile.exists() ) {
225 throw new EdkException("Platform file [" + fpdFile.getPath() + "] not exists. ");
226 }
227 XmlObject fpdDoc = parseXmlFile(fpdFile);
228 //
229 // We can change Map to XmlObject
230 //
231 Map<String, XmlObject> fpdDocMap = new HashMap<String, XmlObject>();
232 fpdDocMap.put("PlatformSurfaceArea", fpdDoc);
233 SurfaceAreaQuery saq = new SurfaceAreaQuery(fpdDocMap);
234 PlatformIdentification platformId = saq.getFpdHeader();
235 platformId.setFpdFile(fpdFile);
236 //
237 // Report warning if existing two platfrom with same GUID and Version
238 //
239 if (platformList.contains(platformId)) {
240 //
241 // BUGBUG
242 //
243 EdkLog.log("Init", EdkLog.EDK_WARNING, "Warning: Existing two platforms with same GUID and Version. They are ... " + fpdFile.getPath());
244 }
245 platformList.add(platformId);
246 }
247 }
248 } catch(IOException ex) {
249 EdkException edkException = new EdkException("Parse of platform definition file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage());
250 edkException.setStackTrace(ex.getStackTrace());
251 throw edkException;
252 } catch(XmlException ex) {
253 EdkException edkException = new EdkException("Parse of platform definition file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage());
254 edkException.setStackTrace(ex.getStackTrace());
255 throw edkException;
256 }
257 }
258
259 /**
260 Get the current WORKSPACE Directory.
261
262 @return current workspace directory
263 **/
264 public synchronized static String getWorkspacePath() {
265 return workspaceDir;
266 }
267
268
269 /**
270 Get the MSA file name with absolute path
271 */
272 public synchronized static File getMsaFile(ModuleIdentification moduleId) throws EdkException {
273 File msaFile = null;
274 //
275 // TBD. Do only when package is null.
276 //
277 Iterator iter = packageList.iterator();
278 while (iter.hasNext()) {
279 PackageIdentification packageId = (PackageIdentification)iter.next();
280 Spd spd = spdTable.get(packageId);
281 msaFile = spd.getModuleFile(moduleId);
282 if (msaFile != null ) {
283 break ;
284 }
285 }
286 if (msaFile == null){
287 throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!");
288 } else {
289 return msaFile;
290 }
291 }
292
293 public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) throws EdkException {
294 //
295 // If package already defined in module
296 //
297 if (moduleId.getPackage() != null) {
298 return moduleId.getPackage();
299 }
300
301 PackageIdentification packageId = null;
302 Iterator iter = packageList.iterator();
303 while (iter.hasNext()) {
304 packageId = (PackageIdentification)iter.next();
305 moduleId.setPackage(packageId);
306 Spd spd = spdTable.get(packageId);
307 File tempMsaFile = null;
308 if ((tempMsaFile = spd.getModuleFile(moduleId)) != null ) {
309 if (tempMsaFile.getParent().equalsIgnoreCase(moduleId.getMsaFile().getParent())) {
310 break ;
311 }
312 tempMsaFile = null;
313 }
314 }
315 if (packageId == null){
316 throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!");
317 } else {
318 return packageId;
319 }
320 }
321
322 /**
323 Difference between build and parse: ToolChain and Target
324 **/
325 public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) {
326 return builtModules.contains(moduleId);
327 }
328
329 public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) {
330 builtModules.add(fpdModuleId);
331 }
332
333
334 public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map<String, XmlObject> doc) throws EdkException{
335 Map<String, XmlObject> result = new HashMap<String, XmlObject>();
336 Set keySet = doc.keySet();
337 Iterator iter = keySet.iterator();
338 while (iter.hasNext()){
339 String key = (String)iter.next();
340 XmlObject item = cloneXmlObject(doc.get(key), true);
341 result.put(key, item);
342 }
343 fpdModuleSA.put(fpdModuleId, result);
344 }
345
346 public synchronized static boolean hasFpdModuleSA(FpdModuleIdentification fpdModuleId) {
347 return fpdModuleSA.containsKey(fpdModuleId);
348 }
349
350 /**
351 Query module surface area information.
352
353 <p>Note that surface area parsing is incremental. That means the method will
354 only parse the MSA files if necessary. </p>
355
356 @param fpdModuleId Module ID with arch
357 @return ModuleSA info and MSA info for fpdModuleId
358 @throws BuildException Can't find MSA
359 **/
360 public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws EdkException{
361 if (parsedModules.containsKey(fpdModuleId)) {
362 return parsedModules.get(fpdModuleId);
363 }
364 Map<String, XmlObject> doc = new HashMap<String, XmlObject>();
365 ModuleIdentification moduleId = fpdModuleId.getModule();
366 //
367 // First part: get the MSA files info
368 //
369 doc.putAll(getNativeMsa(moduleId));
370
371 //
372 // Second part: put build options
373 //
374 doc.put("BuildOptions", fpdBuildOptions);
375
376 //
377 // Third part: get Module info from FPD, such as Library instances, PCDs
378 //
379 if (fpdModuleSA.containsKey(fpdModuleId)){
380 //
381 // merge module info in FPD to final Doc
382 // For Library Module, do nothing here
383 //
384 doc.putAll(fpdModuleSA.get(fpdModuleId));
385 }
386 parsedModules.put(fpdModuleId, doc);
387 return doc;
388 }
389
390 public synchronized static Map<String, XmlObject> getDoc(ModuleIdentification moduleId, String arch) throws EdkException{
391 FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);
392 return getDoc(fpdModuleId);
393 }
394
395 /**
396 Query the native MSA information with module base name.
397
398 <p>Note that MSA parsing is incremental. That means the method will
399 only to parse the MSA files when never parsed before. </p>
400
401 @param moduleName the base name of the module
402 @return the native MSA information
403 @throws BuildException
404 MSA file is not valid
405 **/
406 public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws EdkException {
407 if (nativeMsa.containsKey(moduleId)) {
408 return nativeMsa.get(moduleId);
409 }
410 File msaFile = getMsaFile(moduleId);
411 Map<String, XmlObject> msaMap = getNativeMsa(msaFile);
412 nativeMsa.put(moduleId, msaMap);
413 return msaMap;
414 }
415
416 public synchronized static Map<String, XmlObject> getNativeMsa(File msaFile) throws EdkException {
417 if (!msaFile.exists()) {
418 throw new EdkException("Module Surface Area file [" + msaFile.getPath() + "] can't be found!");
419 }
420 try {
421 ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)parseXmlFile(msaFile);
422 //
423 // parse MSA file
424 //
425 ModuleSurfaceArea msa= doc.getModuleSurfaceArea();
426 Map<String, XmlObject> msaMap = new HashMap<String, XmlObject>();
427 msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true));
428 msaMap.put("ModuleDefinitions", cloneXmlObject(msa.getModuleDefinitions(), true));
429 msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true));
430 msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true));
431 msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true));
432 msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true));
433 msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true));
434 msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true));
435 msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true));
436 msaMap.put("PcdCoded", cloneXmlObject(msa.getPcdCoded(), true));
437 msaMap.put("ModuleBuildOptions", cloneXmlObject(msa.getModuleBuildOptions(), true));
438 return msaMap;
439 } catch(IOException ex) {
440 EdkException edkException = new EdkException("Parse of MSA file [" + msaFile.getPath() + "] failed!\n" + ex.getMessage());
441 edkException.setStackTrace(ex.getStackTrace());
442 throw edkException;
443 } catch(XmlException ex) {
444 EdkException edkException = new EdkException("Parse of MSA file [" + msaFile.getPath() + "] failed!\n" + ex.getMessage());
445 edkException.setStackTrace(ex.getStackTrace());
446 throw edkException;
447 }
448 }
449
450 public static Map<String, XmlObject> getFpdBuildOptionsMap() {
451 return fpdBuildOptionsMap;
452 }
453
454 public static void setFpdBuildOptions(XmlObject fpdBuildOptions) throws EdkException {
455 GlobalData.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true);
456 fpdBuildOptionsMap.put("BuildOptions", GlobalData.fpdBuildOptions);
457 }
458
459 public static XmlObject getFpdDynamicPcds() {
460 return fpdDynamicPcds;
461 }
462
463 public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) {
464 GlobalData.fpdDynamicPcds = fpdDynamicPcds;
465 }
466
467 public static Set<ModuleIdentification> getModules(PackageIdentification packageId){
468 Spd spd = spdTable.get(packageId);
469 if (spd == null ) {
470 Set<ModuleIdentification> dummy = new HashSet<ModuleIdentification>();
471 return dummy;
472 } else {
473 return spd.getModules();
474 }
475 }
476
477 /**
478 * The header file path is relative to workspace dir
479 */
480 public static String[] getLibraryClassHeaderFiles(
481 PackageIdentification[] packages, String name) throws EdkException{
482 if (packages == null) {
483 // throw Exception or not????
484 return new String[0];
485 }
486 String[] result = null;
487 for (int i = 0; i < packages.length; i++) {
488 Spd spd = spdTable.get(packages[i]);
489 //
490 // If find one package defined the library class
491 //
492 if ((result = spd.getLibClassIncluder(name)) != null) {
493 return result;
494 }
495 }
496 //
497 // If can't find library class declaration in every package
498 //
499 throw new EdkException("Can not find library class [" + name
500 + "] declaration in any SPD package!");
501 }
502
503 /**
504 * The header file path is relative to workspace dir
505 */
506 public static String getPackageHeaderFiles(PackageIdentification packages,
507 String moduleType) {
508 if (packages == null) {
509 return new String("");
510 }
511 Spd spd = spdTable.get(packages);
512 //
513 // If can't find package header file, skip it
514 //
515 String temp = null;
516 if (spd != null) {
517 if ((temp = spd.getPackageIncluder(moduleType)) != null) {
518 return temp;
519 } else {
520 temp = "";
521 return temp;
522 }
523 } else {
524 return null;
525 }
526 }
527
528 /**
529 * return two values: {cName, GuidValue}
530 */
531 public static String[] getGuid(List<PackageIdentification> packages, String name) {
532 if (packages == null) {
533 // throw Exception or not????
534 return new String[0];
535 }
536 String[] result = null;
537 Iterator item = packages.iterator();
538 while (item.hasNext()){
539 Spd spd = spdTable.get(item.next());
540 //
541 // If find one package defined the GUID
542 //
543 if ((result = spd.getGuid(name)) != null) {
544 return result;
545 }
546 }
547
548 return null;
549 }
550
551 /**
552 * return two values: {cName, GuidValue}
553 */
554 public static String[] getPpiGuid(List<PackageIdentification> packages,
555 String name) {
556 if (packages == null) {
557 return new String[0];
558 }
559 String[] result = null;
560 Iterator item = packages.iterator();
561 while (item.hasNext()){
562 Spd spd = spdTable.get(item.next());
563 //
564 // If find one package defined the Ppi GUID
565 //
566 if ((result = spd.getPpi(name)) != null) {
567 return result;
568 }
569 }
570 return null;
571 }
572
573 /**
574 * return two values: {cName, GuidValue}
575 */
576 public static String[] getProtocolGuid(List<PackageIdentification> packages,
577 String name) {
578 if (packages == null) {
579 return new String[0];
580 }
581 String[] result = null;
582 Iterator item = packages.iterator();
583 while (item.hasNext()){
584 Spd spd = spdTable.get(item.next());
585 //
586 // If find one package defined the protocol GUID
587 //
588 if ((result = spd.getProtocol(name))!= null){
589 return result;
590 }
591 }
592 return null;
593
594 }
595
596 public synchronized static PlatformIdentification getPlatformByName(String name) throws EdkException {
597 Iterator iter = platformList.iterator();
598 while(iter.hasNext()){
599 PlatformIdentification platformId = (PlatformIdentification)iter.next();
600 if (platformId.getName().equalsIgnoreCase(name)) {
601 return platformId;
602 }
603 }
604 throw new EdkException("Can't find platform [" + name + "] in the current WORKSPACE database!");
605 }
606
607 public synchronized static PlatformIdentification getPlatform(String filename) throws EdkException {
608 File file = new File(workspaceDir + File.separatorChar + filename);
609 Iterator iter = platformList.iterator();
610 while(iter.hasNext()){
611 PlatformIdentification platformId = (PlatformIdentification)iter.next();
612 if (platformId.getFpdFile().getPath().equalsIgnoreCase(file.getPath())) {
613 return platformId;
614 }
615 }
616 throw new EdkException("Can't find platform file [" + filename + "] in the current WORKSPACE database!");
617 }
618
619 public synchronized static PackageIdentification refreshPackageIdentification(PackageIdentification packageId) throws EdkException {
620 Iterator iter = packageList.iterator();
621 while(iter.hasNext()){
622 PackageIdentification packageItem = (PackageIdentification)iter.next();
623 if (packageItem.equals(packageId)) {
624 packageId.setName(packageItem.getName());
625 packageId.setSpdFile(packageItem.getSpdFile());
626 return packageId;
627 }
628 }
629 throw new EdkException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!");
630 }
631
632 public synchronized static ModuleIdentification refreshModuleIdentification(ModuleIdentification moduleId) throws EdkException {
633 PackageIdentification packageId = getPackageForModule(moduleId);
634 moduleId.setPackage(packageId);
635 Spd spd = spdTable.get(packageId);
636 if (spd == null) {
637 throw new EdkException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!");
638 }
639 Set<ModuleIdentification> modules = spd.getModules();
640 Iterator<ModuleIdentification> iter = modules.iterator();
641 while (iter.hasNext()) {
642 ModuleIdentification item = iter.next();
643 if (item.equals(moduleId)) {
644 moduleId.setName(item.getName());
645 moduleId.setModuleType(item.getModuleType());
646 moduleId.setMsaFile(item.getMsaFile());
647 return moduleId;
648 }
649 }
650 throw new EdkException("Can't find module GUID value " + moduleId.toGuidString() + " in " + packageId + " under the current workspace!");
651 }
652
653 public synchronized static Set<PackageIdentification> getPackageList(){
654 return packageList;
655 }
656
657 /**
658 BUGBUG: It is a walk around method. If do not clone, can't query info with
659 XPath correctly.
660
661 @param object XmlObject
662 @param deep flag for deep clone
663 @return XmlObject after clone
664 @throws BuildException parse original XmlObject error.
665 **/
666 private static XmlObject cloneXmlObject(XmlObject object, boolean deep) throws EdkException {
667 if ( object == null) {
668 return null;
669 }
670 XmlObject result = null;
671 try {
672 result = XmlObject.Factory.parse(object.getDomNode()
673 .cloneNode(deep));
674 } catch (XmlException ex) {
675 EdkException edkException = new EdkException(ex.getMessage());
676 edkException.setStackTrace(ex.getStackTrace());
677 throw edkException;
678 }
679 return result;
680 }
681
682 ///
683 /// Tool Chain Related, try to refine and put some logic process to ToolChainFactory
684 ///
685 public synchronized static ToolChainInfo getToolChainInfo() {
686 if (toolChainInfo == null) {
687 toolChainInfo = toolsDef.getConfigInfo().intersection(toolChainEnvInfo);
688 if (toolChainPlatformInfo != null) {
689 toolChainInfo = toolChainInfo.intersection(toolChainPlatformInfo);
690 }
691 toolChainInfo.addCommands(toolsDef.getConfigInfo().getCommands());
692 toolChainInfo.normalize();
693 EdkLog.log("Init", EdkLog.EDK_ALWAYS, "Current build tool chain information summary: ");
694 EdkLog.log("Init", EdkLog.EDK_ALWAYS, toolChainInfo + "");
695 }
696 return toolChainInfo;
697 }
698
699 public static void setPlatformToolChainFamilyOption(ToolChainMap map) {
700 platformToolChainFamilyOption = map;
701 }
702
703 public static void setPlatformToolChainOption(ToolChainMap map) {
704 platformToolChainOption = map;
705 }
706
707 public static void addModuleToolChainOption(FpdModuleIdentification fpdModuleId,
708 ToolChainMap toolChainOption) {
709 moduleToolChainOption.put(fpdModuleId, toolChainOption);
710 }
711
712 public static void addModuleToolChainFamilyOption(FpdModuleIdentification fpdModuleId,
713 ToolChainMap toolChainOption) {
714 moduleToolChainFamilyOption.put(fpdModuleId, toolChainOption);
715 }
716
717 public static void addMsaBuildOption(ModuleIdentification moduleId,
718 ToolChainMap toolChainOption) {
719 msaBuildOption.put(moduleId, toolChainOption);
720 }
721
722 public static void addMsaFamilyBuildOption(ModuleIdentification moduleId,
723 ToolChainMap toolChainOption) {
724 msaFamilyBuildOption.put(moduleId, toolChainOption);
725 }
726
727 public static boolean isCommandSet(String target, String toolchain, String arch) {
728 String[] commands = getToolChainInfo().getCommands();
729
730 for (int i = 0; i < commands.length; ++i) {
731 String cmdName = toolsDef.getConfig().get(new String[] {target, toolchain, arch, commands[i], ToolDefinitions.TOOLS_DEF_ATTRIBUTE_NAME});
732 if (cmdName != null && cmdName.length() != 0) {
733 return true;
734 }
735 }
736
737 return false;
738 }
739
740 /**
741 Except FLAGS, all attribute are from TOOLS_DEF file.
742
743 For FLAGS, information from four places, they are:
744 <pre>
745 1. tools_def.txt
746 2. MSA &lt;BuildOptions&gt;/&lt;Options&gt;
747 3. FPD &lt;BuildOptions&gt;/&lt;Options&gt;
748 4. FPD &lt;FrameworkModules&gt;/&lt;ModuleSaBuildOptions&gt;/&lt;Options&gt;
749 </pre>
750
751 @param commandDescription Key: TARGET, TAGNAME, ARCH, COMMANDTYPE, ATTRIBUTE
752 @param fpdModuleId Module Identification with Arch
753 @return The corresponding String
754 @throws EdkException If build option definition error
755 **/
756 public synchronized static String getCommandSetting(String[] commandDescription, FpdModuleIdentification fpdModuleId) throws EdkException {
757 ToolChainKey toolChainKey = new ToolChainKey(commandDescription);
758 ToolChainMap toolChainConfig = toolsDef.getConfig();
759 String setting = null;
760
761 //
762 // Default in tools_def.txt
763 //
764 setting = toolChainConfig.get(toolChainKey);
765 if (setting == null) {
766 setting = "";
767 }
768 if (!commandDescription[ToolChainElement.ATTRIBUTE.value].equals(ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS)) {
769 return setting;
770 }
771
772 Set<String> flagSet = new LinkedHashSet<String>();
773 flagSet.add(setting);
774
775 //
776 // Tool's option can be in .fpd and/or .msa file
777 //
778 String optionString;
779 ToolChainMap option = null;
780 ToolChainKey toolChainFamilyKey = new ToolChainKey(commandDescription);
781
782 toolChainFamilyKey.setKey(ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FAMILY, ToolChainElement.ATTRIBUTE.value);
783 String family = toolChainConfig.get(toolChainFamilyKey);
784 toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);
785 toolChainFamilyKey.setKey(ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS, ToolChainElement.ATTRIBUTE.value);
786
787 //
788 // MSA's tool chain family option
789 //
790 option = msaFamilyBuildOption.get(fpdModuleId.getModule());
791 if (option != null && (optionString = option.get(toolChainFamilyKey)) != null) {
792 flagSet.add(optionString);
793 }
794
795 //
796 // MSA's tool chain option
797 //
798 option = msaBuildOption.get(fpdModuleId.getModule());
799 if (option != null && (optionString = option.get(toolChainKey)) != null) {
800 flagSet.add(optionString);
801 }
802
803 //
804 // Platform's tool chain family option
805 //
806 optionString = platformToolChainFamilyOption.get(toolChainFamilyKey);
807 if (optionString != null) {
808 flagSet.add(optionString);
809 }
810
811 //
812 // Platform's tool chain tag option
813 //
814 optionString = platformToolChainOption.get(toolChainKey);
815 if (optionString != null) {
816 flagSet.add(optionString);
817 }
818
819 //
820 // Module's tool chain family option
821 //
822 option = moduleToolChainFamilyOption.get(fpdModuleId);
823 if (option != null && (optionString = option.get(toolChainFamilyKey)) != null) {
824 flagSet.add(optionString);
825 }
826
827 //
828 // Module's tool chain tag option
829 //
830 option = moduleToolChainOption.get(fpdModuleId);
831 if (option != null && (optionString = option.get(toolChainKey)) != null) {
832 flagSet.add(optionString);
833 }
834
835 setting = "";
836 for(Iterator<String> iter = flagSet.iterator(); iter.hasNext();) {
837 setting += iter.next() +" ";
838 }
839 return setting;
840 }
841
842 public static void setToolChainEnvInfo(ToolChainInfo envInfo) {
843 toolChainEnvInfo = envInfo;
844 }
845 public static void setToolChainPlatformInfo(ToolChainInfo platformInfo) {
846 toolChainPlatformInfo = platformInfo;
847 }
848
849 //
850 // for PCD
851 //
852 public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {
853 return pcdDbManager;
854 }
855
856 //
857 // For PCD get tokenSpaceGUid
858 //
859 public synchronized static String getGuidInfoFromCname(String cName){
860 String cNameGuid = null;
861 String guid = null;
862 Set set = spdTable.keySet();
863 Iterator iter = set.iterator();
864
865 if (iter == null) {
866 return null;
867 }
868
869 while (iter.hasNext()){
870 Spd spd = (Spd) spdTable.get(iter.next());
871 guid = spd.getGuidFromCname(cName);
872 if (guid != null){
873 cNameGuid = guid;
874 break;
875 }
876 }
877 return cNameGuid;
878 }
879
880 //
881 // For PCD
882 //
883 public synchronized static Map<FpdModuleIdentification, XmlObject>
884 getFpdModuleSaXmlObject(String xmlObjectName) {
885 Set<FpdModuleIdentification> fpdModuleSASet = fpdModuleSA.keySet();
886 Iterator item = fpdModuleSASet.iterator();
887
888
889 Map<FpdModuleIdentification, XmlObject> SAPcdBuildDef = new HashMap<FpdModuleIdentification, XmlObject>();
890 Map<String, XmlObject> SANode = new HashMap<String, XmlObject>();
891 FpdModuleIdentification moduleId;
892 while (item.hasNext()) {
893
894 moduleId = (FpdModuleIdentification) item.next();
895 SANode = fpdModuleSA.get(moduleId);
896 try{
897 if (SANode.get(xmlObjectName)!= null){
898 SAPcdBuildDef.put(moduleId,
899 (XmlObject) SANode.get(xmlObjectName));
900
901 }
902 } catch (Exception e){
903 EdkLog.log(EdkLog.EDK_INFO, e.getMessage());
904 }
905 }
906 return SAPcdBuildDef;
907 }
908
909 public synchronized static Map<FpdModuleIdentification,XmlObject> getFpdPcdBuildDefinitions() {
910 Map<FpdModuleIdentification,XmlObject> pcdBuildDef = getFpdModuleSaXmlObject ("PcdBuildDefinition");
911
912 return pcdBuildDef;
913 }
914
915 public static XmlObject parseXmlFile(File xmlFile) throws IOException, XmlException {
916 Collection errors = new ArrayList();
917 XmlOptions opt = new XmlOptions();
918
919 opt.setLoadLineNumbers();
920 opt.setLoadMessageDigest();
921 opt.setErrorListener(errors);
922
923 XmlObject doc = XmlObject.Factory.parse(xmlFile, opt);
924 //
925 // Validate File if they accord with XML Schema
926 //
927 if (!doc.validate(opt)){
928 StringBuilder errorMessage = new StringBuilder(1024);
929 for (Iterator it = errors.iterator(); it.hasNext(); ) {
930 errorMessage.append(it.next());
931 errorMessage.append("\n");
932 }
933 throw new XmlException(errorMessage.toString());
934 }
935
936 return doc;
937 }
938 }
939