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