]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java
To locate module precisely in stand-alone module build. Except Module Guid, add MSA...
[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 //
170 // Parse Framework Database
171 //
172 File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);
173 try {
174 FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);
175 //
176 // validate FrameworkDatabaseFile
177 //
178 if (!db.validate()) {
179 throw new EdkException("Framework Database file [" + dbFile.getPath() + "] format is invalid!");
180 }
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
204 //
205 // Get platform list
206 //
207 if (db.getFrameworkDatabase().getPlatformList() != null) {
208 List<DbPathAndFilename> platforms = db.getFrameworkDatabase().getPlatformList().getFilenameList();
209 Iterator<DbPathAndFilename> iter = platforms.iterator();
210 while (iter.hasNext()) {
211 String fileName = iter.next().getStringValue().trim();
212 File fpdFile = new File(workspaceDir + File.separatorChar + fileName);
213 if ( !fpdFile.exists() ) {
214 throw new EdkException("Platform file [" + fpdFile.getPath() + "] not exists. ");
215 }
216 XmlObject fpdDoc = XmlObject.Factory.parse(fpdFile);
217 //
218 // Verify FPD file, if is invalid, throw Exception
219 //
220 if (!fpdDoc.validate()) {
221 throw new EdkException("Framework Platform Surface Area file [" + fpdFile.getPath() + "] format is invalid!");
222 }
223 //
224 // We can change Map to XmlObject
225 //
226 Map<String, XmlObject> fpdDocMap = new HashMap<String, XmlObject>();
227 fpdDocMap.put("PlatformSurfaceArea", fpdDoc);
228 SurfaceAreaQuery saq = new SurfaceAreaQuery(fpdDocMap);
229 PlatformIdentification platformId = saq.getFpdHeader();
230 platformId.setFpdFile(fpdFile);
231 //
232 // Report warning if existing two platfrom with same GUID and Version
233 //
234 if (platformList.contains(platformId)) {
235 //
236 // BUGBUG
237 //
238 EdkLog.log("Init", EdkLog.EDK_WARNING, "Warning: Existing two platforms with same GUID and Version. They are ... " + fpdFile.getPath());
239 }
240 platformList.add(platformId);
241 }
242 }
243 } catch(IOException ex) {
244 EdkException edkException = new EdkException("Parse WORKSPACE Database file [" + dbFile.getPath() + "] Error.\n" + ex.getMessage());
245 edkException.setStackTrace(ex.getStackTrace());
246 throw edkException;
247 } catch(XmlException ex) {
248 EdkException edkException = new EdkException("Parse WORKSPACE Database file [" + dbFile.getPath() + "] Error.\n" + ex.getMessage());
249 edkException.setStackTrace(ex.getStackTrace());
250 throw edkException;
251 }
252 }
253
254 /**
255 Get the current WORKSPACE Directory.
256
257 @return current workspace directory
258 **/
259 public synchronized static String getWorkspacePath() {
260 return workspaceDir;
261 }
262
263
264 /**
265 Get the MSA file name with absolute path
266 */
267 public synchronized static File getMsaFile(ModuleIdentification moduleId) throws EdkException {
268 File msaFile = null;
269 //
270 // TBD. Do only when package is null.
271 //
272 Iterator iter = packageList.iterator();
273 while (iter.hasNext()) {
274 PackageIdentification packageId = (PackageIdentification)iter.next();
275 Spd spd = spdTable.get(packageId);
276 msaFile = spd.getModuleFile(moduleId);
277 if (msaFile != null ) {
278 break ;
279 }
280 }
281 if (msaFile == null){
282 throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!");
283 } else {
284 return msaFile;
285 }
286 }
287
288 public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) throws EdkException {
289 //
290 // If package already defined in module
291 //
292 if (moduleId.getPackage() != null) {
293 return moduleId.getPackage();
294 }
295
296 PackageIdentification packageId = null;
297 Iterator iter = packageList.iterator();
298 while (iter.hasNext()) {
299 packageId = (PackageIdentification)iter.next();
300 moduleId.setPackage(packageId);
301 Spd spd = spdTable.get(packageId);
302 File tempMsaFile = null;
303 if ((tempMsaFile = spd.getModuleFile(moduleId)) != null ) {
304 if (tempMsaFile.getParent().equalsIgnoreCase(moduleId.getMsaFile().getParent())) {
305 break ;
306 }
307 tempMsaFile = null;
308 }
309 }
310 if (packageId == null){
311 throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!");
312 } else {
313 return packageId;
314 }
315 }
316
317 /**
318 Difference between build and parse: ToolChain and Target
319 **/
320 public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) {
321 return builtModules.contains(moduleId);
322 }
323
324 public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) {
325 builtModules.add(fpdModuleId);
326 }
327
328
329 public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map<String, XmlObject> doc) throws EdkException{
330 Map<String, XmlObject> result = new HashMap<String, XmlObject>();
331 Set keySet = doc.keySet();
332 Iterator iter = keySet.iterator();
333 while (iter.hasNext()){
334 String key = (String)iter.next();
335 XmlObject item = cloneXmlObject(doc.get(key), true);
336 result.put(key, item);
337 }
338 fpdModuleSA.put(fpdModuleId, result);
339 }
340
341 public synchronized static boolean hasFpdModuleSA(FpdModuleIdentification fpdModuleId) {
342 return fpdModuleSA.containsKey(fpdModuleId);
343 }
344
345 /**
346 Query module surface area information.
347
348 <p>Note that surface area parsing is incremental. That means the method will
349 only parse the MSA files if necessary. </p>
350
351 @param fpdModuleId Module ID with arch
352 @return ModuleSA info and MSA info for fpdModuleId
353 @throws BuildException Can't find MSA
354 **/
355 public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws EdkException{
356 if (parsedModules.containsKey(fpdModuleId)) {
357 return parsedModules.get(fpdModuleId);
358 }
359 Map<String, XmlObject> doc = new HashMap<String, XmlObject>();
360 ModuleIdentification moduleId = fpdModuleId.getModule();
361 //
362 // First part: get the MSA files info
363 //
364 doc.putAll(getNativeMsa(moduleId));
365
366 //
367 // Second part: put build options
368 //
369 doc.put("BuildOptions", fpdBuildOptions);
370
371 //
372 // Third part: get Module info from FPD, such as Library instances, PCDs
373 //
374 if (fpdModuleSA.containsKey(fpdModuleId)){
375 //
376 // merge module info in FPD to final Doc
377 // For Library Module, do nothing here
378 //
379 doc.putAll(fpdModuleSA.get(fpdModuleId));
380 }
381 parsedModules.put(fpdModuleId, doc);
382 return doc;
383 }
384
385 public synchronized static Map<String, XmlObject> getDoc(ModuleIdentification moduleId, String arch) throws EdkException{
386 FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);
387 return getDoc(fpdModuleId);
388 }
389
390 /**
391 Query the native MSA information with module base name.
392
393 <p>Note that MSA parsing is incremental. That means the method will
394 only to parse the MSA files when never parsed before. </p>
395
396 @param moduleName the base name of the module
397 @return the native MSA information
398 @throws BuildException
399 MSA file is not valid
400 **/
401 public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws EdkException {
402 if (nativeMsa.containsKey(moduleId)) {
403 return nativeMsa.get(moduleId);
404 }
405 File msaFile = getMsaFile(moduleId);
406 Map<String, XmlObject> msaMap = getNativeMsa(msaFile);
407 nativeMsa.put(moduleId, msaMap);
408 return msaMap;
409 }
410
411 public synchronized static Map<String, XmlObject> getNativeMsa(File msaFile) throws EdkException {
412 if (!msaFile.exists()) {
413 throw new EdkException("Module Surface Area file [" + msaFile.getPath() + "] can't be found!");
414 }
415 try {
416 ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)XmlObject.Factory.parse(msaFile);
417 //
418 // Validate File if they accord with XML Schema
419 //
420 if ( !doc.validate()){
421 throw new EdkException("Module Surface Area file [" + msaFile.getPath() + "] format is invalid!");
422 }
423 //
424 // parse MSA file
425 //
426 ModuleSurfaceArea msa= doc.getModuleSurfaceArea();
427 Map<String, XmlObject> msaMap = new HashMap<String, XmlObject>();
428 msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true));
429 msaMap.put("ModuleDefinitions", cloneXmlObject(msa.getModuleDefinitions(), true));
430 msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true));
431 msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true));
432 msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true));
433 msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true));
434 msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true));
435 msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true));
436 msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true));
437 msaMap.put("PcdCoded", cloneXmlObject(msa.getPcdCoded(), true));
438 return msaMap;
439 } catch(IOException ex) {
440 EdkException edkException = new EdkException("Parsing MSA file [" + msaFile.getPath() + "] error. \n" + ex.getMessage());
441 edkException.setStackTrace(ex.getStackTrace());
442 throw edkException;
443 } catch(XmlException ex) {
444 EdkException edkException = new EdkException("Parsing MSA file [" + msaFile.getPath() + "] error. \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 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 boolean isCommandSet(String target, String toolchain, String arch) {
718 String[] commands = getToolChainInfo().getCommands();
719
720 for (int i = 0; i < commands.length; ++i) {
721 String cmdName = toolsDef.getConfig().get(new String[] {target, toolchain, arch, commands[i], ToolChainAttribute.NAME.toString()});
722 if (cmdName != null && cmdName.length() != 0) {
723 return true;
724 }
725 }
726
727 return false;
728 }
729
730 public static String getCommandSetting(String[] commandDescription, FpdModuleIdentification fpdModuleId) throws EdkException {
731 ToolChainKey toolChainKey = new ToolChainKey(commandDescription);
732 ToolChainMap toolChainConfig = toolsDef.getConfig();
733 String setting = null;
734
735 if (!commandDescription[ToolChainElement.ATTRIBUTE.value].equals(ToolChainAttribute.FLAGS.toString())) {
736 setting = toolChainConfig.get(toolChainKey);
737 if (setting == null) {
738 setting = "";
739 }
740 return setting;
741 }
742
743 //
744 // get module specific options, if any
745 //
746 // tool tag first
747 ToolChainMap option = moduleToolChainOption.get(fpdModuleId);
748 ToolChainKey toolChainFamilyKey = null;
749
750 if ((option == null) || (option != null && (setting = option.get(toolChainKey)) == null)) {
751 //
752 // then tool chain family
753 //
754 toolChainFamilyKey = new ToolChainKey(commandDescription);
755 toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value);
756 String family = toolChainConfig.get(toolChainFamilyKey);
757 toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);
758 toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value);
759
760 option = moduleToolChainFamilyOption.get(fpdModuleId);
761 if (option != null) {
762 setting = option.get(toolChainFamilyKey);
763 }
764 }
765
766 //
767 // get platform options, if any
768 //
769 if (setting == null) {
770 // tool tag first
771 if (platformToolChainOption == null || (setting = platformToolChainOption.get(toolChainKey)) == null) {
772 // then tool chain family
773 if (toolChainFamilyKey == null) {
774 toolChainFamilyKey = new ToolChainKey(commandDescription);
775 toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value);
776 String family = toolChainConfig.get(toolChainFamilyKey);
777 toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);
778 toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value);
779 }
780
781 setting = platformToolChainFamilyOption.get(toolChainFamilyKey);
782 }
783 }
784
785 if (setting == null) {
786 setting = "";
787 }
788
789 return setting;
790 }
791
792 public static void setToolChainEnvInfo(ToolChainInfo envInfo) {
793 toolChainEnvInfo = envInfo;
794 }
795 public static void setToolChainPlatformInfo(ToolChainInfo platformInfo) {
796 toolChainPlatformInfo = platformInfo;
797 }
798
799 //
800 // for PCD
801 //
802 public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {
803 return pcdDbManager;
804 }
805
806 //
807 // For PCD get tokenSpaceGUid
808 //
809 public synchronized static String getGuidInfoFromCname(String cName){
810 String cNameGuid = null;
811 String guid = null;
812 Set set = spdTable.keySet();
813 Iterator iter = set.iterator();
814
815 if (iter == null) {
816 return null;
817 }
818
819 while (iter.hasNext()){
820 Spd spd = (Spd) spdTable.get(iter.next());
821 guid = spd.getGuidFromCname(cName);
822 if (guid != null){
823 cNameGuid = guid;
824 break;
825 }
826 }
827 return cNameGuid;
828 }
829
830 //
831 // For PCD
832 //
833 public synchronized static Map<FpdModuleIdentification, XmlObject>
834 getFpdModuleSaXmlObject(String xmlObjectName) {
835 Set<FpdModuleIdentification> fpdModuleSASet = fpdModuleSA.keySet();
836 Iterator item = fpdModuleSASet.iterator();
837
838
839 Map<FpdModuleIdentification, XmlObject> SAPcdBuildDef = new HashMap<FpdModuleIdentification, XmlObject>();
840 Map<String, XmlObject> SANode = new HashMap<String, XmlObject>();
841 FpdModuleIdentification moduleId;
842 while (item.hasNext()) {
843
844 moduleId = (FpdModuleIdentification) item.next();
845 SANode = fpdModuleSA.get(moduleId);
846 try{
847 if (SANode.get(xmlObjectName)!= null){
848 SAPcdBuildDef.put(moduleId,
849 (XmlObject) SANode.get(xmlObjectName));
850
851 }
852 } catch (Exception e){
853 EdkLog.log(EdkLog.EDK_INFO, e.getMessage());
854 }
855 }
856 return SAPcdBuildDef;
857 }
858
859 public synchronized static Map<FpdModuleIdentification,XmlObject> getFpdPcdBuildDefinitions() {
860 Map<FpdModuleIdentification,XmlObject> pcdBuildDef = getFpdModuleSaXmlObject ("PcdBuildDefinition");
861
862 return pcdBuildDef;
863 }
864 }
865