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