c736952377c71f6c808815eabb1b696cb6c89943
[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.List;
27 import java.util.Map;
28 import java.util.Set;
29
30 import org.apache.xmlbeans.XmlException;
31 import org.apache.xmlbeans.XmlObject;
32 import org.apache.xmlbeans.XmlOptions;
33 import org.tianocore.DbPathAndFilename;
34 import org.tianocore.FrameworkDatabaseDocument;
35 import org.tianocore.ModuleSurfaceAreaDocument;
36 import org.tianocore.ModuleSurfaceAreaDocument.ModuleSurfaceArea;
37 import org.tianocore.build.id.FpdModuleIdentification;
38 import org.tianocore.build.id.ModuleIdentification;
39 import org.tianocore.build.id.PackageIdentification;
40 import org.tianocore.build.id.PlatformIdentification;
41 import org.tianocore.build.toolchain.ToolChainConfig;
42 import org.tianocore.build.toolchain.ToolChainElement;
43 import org.tianocore.build.toolchain.ToolChainInfo;
44 import org.tianocore.build.toolchain.ToolChainKey;
45 import org.tianocore.build.toolchain.ToolChainMap;
46 import org.tianocore.common.definitions.ToolDefinitions;
47 import org.tianocore.common.exception.EdkException;
48 import org.tianocore.common.logger.EdkLog;
49 import org.tianocore.pcd.entity.MemoryDatabaseManager;
50
51 /**
52 GlobalData provide initializing, instoring, querying and update global data.
53 It is a bridge to intercommunicate between multiple component, such as AutoGen,
54 PCD and so on.
55
56 <p>Note that all global information are initialized incrementally. All data will
57 parse and record only of necessary during build time. </p>
58
59 @since GenBuild 1.0
60 **/
61 public class GlobalData {
62 ///
63 /// Record current WORKSPACE Directory
64 ///
65 private static String workspaceDir = "";
66
67 ///
68 /// Be used to ensure Global data will be initialized only once.
69 ///
70 private static boolean globalFlag = false;
71
72 ///
73 /// Framework Database information: package list and platform list
74 ///
75 private static Set<PackageIdentification> packageList = new HashSet<PackageIdentification>();
76
77 private static Set<PlatformIdentification> platformList = new HashSet<PlatformIdentification>();
78
79 ///
80 /// Every detail SPD informations: Module list, Library class definition,
81 /// Package header file, GUID/PPI/Protocol definitions
82 ///
83 private static final Map<PackageIdentification, Spd> spdTable = new HashMap<PackageIdentification, Spd>();
84
85 ///
86 /// Build informations are divided into three parts:
87 /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA
88 ///
89 private static Map<ModuleIdentification, Map<String, XmlObject>> nativeMsa = new HashMap<ModuleIdentification, Map<String, XmlObject>>();
90
91 private static Map<FpdModuleIdentification, Map<String, XmlObject>> fpdModuleSA= new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
92
93 private static Map<String, XmlObject> fpdBuildOptionsMap = new HashMap<String, XmlObject>();
94
95 private static XmlObject fpdBuildOptions;
96
97 private static XmlObject fpdDynamicPcds;
98
99 ///
100 /// Parsed modules list
101 ///
102 private static Map<FpdModuleIdentification, Map<String, XmlObject>> parsedModules = new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
103
104 ///
105 /// built modules list with ARCH, TARGET, TOOLCHAIN
106 ///
107 private static Set<FpdModuleIdentification> builtModules = new HashSet<FpdModuleIdentification>();
108
109 ///
110 /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.
111 ///
112 private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();
113
114 ///
115 /// build target + tool chain family/tag name + arch + command types + command options
116 ///
117 ///
118 /// Tool Chain Data
119 /// toolsDef - build tool program information
120 /// fpdBuildOption - all modules's build options for tool tag or tool chain families
121 /// moduleSaBuildOption - build options for a specific module
122 ///
123 private static ToolChainConfig toolsDef;
124
125 private static ToolChainInfo toolChainInfo;
126 private static ToolChainInfo toolChainEnvInfo;
127 private static ToolChainInfo toolChainPlatformInfo;
128
129 private static ToolChainMap platformToolChainOption;
130 private static ToolChainMap platformToolChainFamilyOption;
131
132 private static Map<FpdModuleIdentification, ToolChainMap> moduleToolChainOption = new HashMap<FpdModuleIdentification, ToolChainMap>();
133 private static Map<FpdModuleIdentification, ToolChainMap> moduleToolChainFamilyOption = new HashMap<FpdModuleIdentification, ToolChainMap>();
134
135 private static Map<ModuleIdentification, ToolChainMap> msaBuildOption = new HashMap<ModuleIdentification, ToolChainMap>();
136 private static Map<ModuleIdentification, ToolChainMap> msaFamilyBuildOption = new HashMap<ModuleIdentification, ToolChainMap>();
137
138 /**
139 Parse framework database (DB) and all SPD files listed in DB to initialize
140 the environment for next build. This method will only be executed only once
141 in the whole build process.
142
143 @param workspaceDatabaseFile the file name of framework database
144 @param workspaceDir current workspace directory path
145 @throws BuildException
146 Framework Dababase or SPD or MSA file is not valid
147 **/
148 public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir, String toolsDefFilename ) throws EdkException {
149 //
150 // ensure this method will be revoked only once
151 //
152 if (globalFlag) {
153 return;
154 }
155 globalFlag = true;
156
157 //
158 // Backup workspace directory. It will be used by other method
159 //
160 GlobalData.workspaceDir = workspaceDir.replaceAll("(\\\\)", "/");
161
162 //
163 // Parse tools definition file
164 //
165 //
166 // If ToolChain has been set up before, do nothing.
167 // CONF dir + tools definition file name
168 //
169 File toolsDefFile = new File(workspaceDir + File.separatorChar + toolsDefFilename);
170 EdkLog.log("Init", EdkLog.EDK_ALWAYS, "Using tool definition file [" + toolsDefFile.getPath() + "].");
171 toolsDef = new ToolChainConfig(toolsDefFile);
172
173 //
174 // Parse Framework Database
175 //
176 File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);
177 FrameworkDatabaseDocument db = null;
178 try {
179 db = (FrameworkDatabaseDocument)parseXmlFile(dbFile);
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 } catch(IOException ex) {
203 EdkException edkException = new EdkException("Parse of WORKSPACE Database file [" + dbFile.getPath() + "] failed!\n" + ex.getMessage());
204 edkException.setStackTrace(ex.getStackTrace());
205 throw edkException;
206 } catch(XmlException ex) {
207 EdkException edkException = new EdkException("Parse of WORKSPACE Database file [" + dbFile.getPath() + "] failed!\n" + ex.getMessage());
208 edkException.setStackTrace(ex.getStackTrace());
209 throw edkException;
210 }
211
212 File fpdFile = null;
213 try {
214 //
215 // Get platform list
216 //
217 if (db.getFrameworkDatabase().getPlatformList() != null) {
218 List<DbPathAndFilename> platforms = db.getFrameworkDatabase().getPlatformList().getFilenameList();
219 Iterator<DbPathAndFilename> iter = platforms.iterator();
220 while (iter.hasNext()) {
221 String fileName = iter.next().getStringValue().trim();
222 fpdFile = new File(workspaceDir + File.separatorChar + fileName);
223 if ( !fpdFile.exists() ) {
224 throw new EdkException("Platform file [" + fpdFile.getPath() + "] not exists. ");
225 }
226 XmlObject fpdDoc = parseXmlFile(fpdFile);
227 //
228 // We can change Map to XmlObject
229 //
230 Map<String, XmlObject> fpdDocMap = new HashMap<String, XmlObject>();
231 fpdDocMap.put("PlatformSurfaceArea", fpdDoc);
232 SurfaceAreaQuery saq = new SurfaceAreaQuery(fpdDocMap);
233 PlatformIdentification platformId = saq.getFpdHeader();
234 platformId.setFpdFile(fpdFile);
235 //
236 // Report warning if existing two platfrom with same GUID and Version
237 //
238 if (platformList.contains(platformId)) {
239 //
240 // BUGBUG
241 //
242 EdkLog.log("Init", EdkLog.EDK_WARNING, "Warning: Existing two platforms with same GUID and Version. They are ... " + fpdFile.getPath());
243 }
244 platformList.add(platformId);
245 }
246 }
247 } catch(IOException ex) {
248 EdkException edkException = new EdkException("Parse of platform definition file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage());
249 edkException.setStackTrace(ex.getStackTrace());
250 throw edkException;
251 } catch(XmlException ex) {
252 EdkException edkException = new EdkException("Parse of platform definition file [" + fpdFile.getPath() + "] failed!\n" + ex.getMessage());
253 edkException.setStackTrace(ex.getStackTrace());
254 throw edkException;
255 }
256 }
257
258 /**
259 Get the current WORKSPACE Directory.
260
261 @return current workspace directory
262 **/
263 public synchronized static String getWorkspacePath() {
264 return workspaceDir;
265 }
266
267
268 /**
269 Get the MSA file name with absolute path
270 */
271 public synchronized static File getMsaFile(ModuleIdentification moduleId) throws EdkException {
272 File msaFile = null;
273 //
274 // TBD. Do only when package is null.
275 //
276 Iterator iter = packageList.iterator();
277 while (iter.hasNext()) {
278 PackageIdentification packageId = (PackageIdentification)iter.next();
279 Spd spd = spdTable.get(packageId);
280 msaFile = spd.getModuleFile(moduleId);
281 if (msaFile != null ) {
282 break ;
283 }
284 }
285 if (msaFile == null){
286 throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!");
287 } else {
288 return msaFile;
289 }
290 }
291
292 public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) throws EdkException {
293 //
294 // If package already defined in module
295 //
296 if (moduleId.getPackage() != null) {
297 return moduleId.getPackage();
298 }
299
300 PackageIdentification packageId = null;
301 Iterator iter = packageList.iterator();
302 while (iter.hasNext()) {
303 packageId = (PackageIdentification)iter.next();
304 moduleId.setPackage(packageId);
305 Spd spd = spdTable.get(packageId);
306 File tempMsaFile = null;
307 if ((tempMsaFile = spd.getModuleFile(moduleId)) != null ) {
308 if (tempMsaFile.getParent().equalsIgnoreCase(moduleId.getMsaFile().getParent())) {
309 break ;
310 }
311 tempMsaFile = null;
312 }
313 }
314 if (packageId == null){
315 throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!");
316 } else {
317 return packageId;
318 }
319 }
320
321 /**
322 Difference between build and parse: ToolChain and Target
323 **/
324 public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) {
325 return builtModules.contains(moduleId);
326 }
327
328 public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) {
329 builtModules.add(fpdModuleId);
330 }
331
332
333 public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map<String, XmlObject> doc) throws EdkException{
334 Map<String, XmlObject> result = new HashMap<String, XmlObject>();
335 Set keySet = doc.keySet();
336 Iterator iter = keySet.iterator();
337 while (iter.hasNext()){
338 String key = (String)iter.next();
339 XmlObject item = cloneXmlObject(doc.get(key), true);
340 result.put(key, item);
341 }
342 fpdModuleSA.put(fpdModuleId, result);
343 }
344
345 public synchronized static boolean hasFpdModuleSA(FpdModuleIdentification fpdModuleId) {
346 return fpdModuleSA.containsKey(fpdModuleId);
347 }
348
349 /**
350 Query module surface area information.
351
352 <p>Note that surface area parsing is incremental. That means the method will
353 only parse the MSA files if necessary. </p>
354
355 @param fpdModuleId Module ID with arch
356 @return ModuleSA info and MSA info for fpdModuleId
357 @throws BuildException Can't find MSA
358 **/
359 public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws EdkException{
360 if (parsedModules.containsKey(fpdModuleId)) {
361 return parsedModules.get(fpdModuleId);
362 }
363 Map<String, XmlObject> doc = new HashMap<String, XmlObject>();
364 ModuleIdentification moduleId = fpdModuleId.getModule();
365 //
366 // First part: get the MSA files info
367 //
368 doc.putAll(getNativeMsa(moduleId));
369
370 //
371 // Second part: put build options
372 //
373 doc.put("BuildOptions", fpdBuildOptions);
374
375 //
376 // Third part: get Module info from FPD, such as Library instances, PCDs
377 //
378 if (fpdModuleSA.containsKey(fpdModuleId)){
379 //
380 // merge module info in FPD to final Doc
381 // For Library Module, do nothing here
382 //
383 doc.putAll(fpdModuleSA.get(fpdModuleId));
384 }
385 parsedModules.put(fpdModuleId, doc);
386 return doc;
387 }
388
389 public synchronized static Map<String, XmlObject> getDoc(ModuleIdentification moduleId, String arch) throws EdkException{
390 FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);
391 return getDoc(fpdModuleId);
392 }
393
394 /**
395 Query the native MSA information with module base name.
396
397 <p>Note that MSA parsing is incremental. That means the method will
398 only to parse the MSA files when never parsed before. </p>
399
400 @param moduleName the base name of the module
401 @return the native MSA information
402 @throws BuildException
403 MSA file is not valid
404 **/
405 public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws EdkException {
406 if (nativeMsa.containsKey(moduleId)) {
407 return nativeMsa.get(moduleId);
408 }
409 File msaFile = getMsaFile(moduleId);
410 Map<String, XmlObject> msaMap = getNativeMsa(msaFile);
411 nativeMsa.put(moduleId, msaMap);
412 return msaMap;
413 }
414
415 public synchronized static Map<String, XmlObject> getNativeMsa(File msaFile) throws EdkException {
416 if (!msaFile.exists()) {
417 throw new EdkException("Module Surface Area file [" + msaFile.getPath() + "] can't be found!");
418 }
419 try {
420 ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)parseXmlFile(msaFile);
421 //
422 // parse MSA file
423 //
424 ModuleSurfaceArea msa= doc.getModuleSurfaceArea();
425 Map<String, XmlObject> msaMap = new HashMap<String, XmlObject>();
426 msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true));
427 msaMap.put("ModuleDefinitions", cloneXmlObject(msa.getModuleDefinitions(), true));
428 msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true));
429 msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true));
430 msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true));
431 msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true));
432 msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true));
433 msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true));
434 msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true));
435 msaMap.put("PcdCoded", cloneXmlObject(msa.getPcdCoded(), true));
436 msaMap.put("ModuleBuildOptions", cloneXmlObject(msa.getModuleBuildOptions(), true));
437 return msaMap;
438 } catch(IOException ex) {
439 EdkException edkException = new EdkException("Parse of MSA file [" + msaFile.getPath() + "] failed!\n" + ex.getMessage());
440 edkException.setStackTrace(ex.getStackTrace());
441 throw edkException;
442 } catch(XmlException ex) {
443 EdkException edkException = new EdkException("Parse of MSA file [" + msaFile.getPath() + "] failed!\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 void addMsaBuildOption(ModuleIdentification moduleId,
717 ToolChainMap toolChainOption) {
718 msaBuildOption.put(moduleId, toolChainOption);
719 }
720
721 public static void addMsaFamilyBuildOption(ModuleIdentification moduleId,
722 ToolChainMap toolChainOption) {
723 msaFamilyBuildOption.put(moduleId, toolChainOption);
724 }
725
726 public static boolean isCommandSet(String target, String toolchain, String arch) {
727 String[] commands = getToolChainInfo().getCommands();
728
729 for (int i = 0; i < commands.length; ++i) {
730 String cmdName = toolsDef.getConfig().get(new String[] {target, toolchain, arch, commands[i], ToolDefinitions.TOOLS_DEF_ATTRIBUTE_NAME});
731 if (cmdName != null && cmdName.length() != 0) {
732 return true;
733 }
734 }
735
736 return false;
737 }
738
739 /**
740 Except FLAGS, all attribute are from TOOLS_DEF file.
741
742 For FLAGS, information from four places, they are:
743 <pre>
744 1. tools_def.txt
745 2. MSA &lt;BuildOptions&gt;/&lt;Options&gt;
746 3. FPD &lt;BuildOptions&gt;/&lt;Options&gt;
747 4. FPD &lt;FrameworkModules&gt;/&lt;ModuleSaBuildOptions&gt;/&lt;Options&gt;
748 </pre>
749
750 @param commandDescription Key: TARGET, TAGNAME, ARCH, COMMANDTYPE, ATTRIBUTE
751 @param fpdModuleId Module Identification with Arch
752 @return The corresponding String
753 @throws EdkException If build option definition error
754 **/
755 public synchronized static String getCommandSetting(String[] commandDescription, FpdModuleIdentification fpdModuleId) throws EdkException {
756 ToolChainKey toolChainKey = new ToolChainKey(commandDescription);
757 ToolChainMap toolChainConfig = toolsDef.getConfig();
758 String setting = null;
759
760 //
761 // Default in tools_def.txt
762 //
763 setting = toolChainConfig.get(toolChainKey);
764 if (setting == null) {
765 setting = "";
766 }
767 if (!commandDescription[ToolChainElement.ATTRIBUTE.value].equals(ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS)) {
768 return setting;
769 }
770
771 //
772 // Tool's option can be in .fpd and/or .msa file
773 //
774 String optionString;
775 ToolChainMap option = null;
776 ToolChainKey toolChainFamilyKey = new ToolChainKey(commandDescription);
777
778 toolChainFamilyKey.setKey(ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FAMILY, ToolChainElement.ATTRIBUTE.value);
779 String family = toolChainConfig.get(toolChainFamilyKey);
780 toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);
781 toolChainFamilyKey.setKey(ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS, ToolChainElement.ATTRIBUTE.value);
782
783 //
784 // MSA's tool chain family option
785 //
786 option = msaFamilyBuildOption.get(fpdModuleId.getModule());
787 if (option != null && (optionString = option.get(toolChainFamilyKey)) != null) {
788 setting += (" " + optionString);
789 }
790
791 //
792 // MSA's tool chain option
793 //
794 option = msaBuildOption.get(fpdModuleId.getModule());
795 if (option != null && (optionString = option.get(toolChainKey)) != null) {
796 setting += (" " + optionString);
797 }
798
799 //
800 // Platform's tool chain family option
801 //
802 optionString = platformToolChainFamilyOption.get(toolChainFamilyKey);
803 if (optionString != null) {
804 setting += (" " + optionString);
805 }
806
807 //
808 // Platform's tool chain tag option
809 //
810 optionString = platformToolChainOption.get(toolChainKey);
811 if (optionString != null) {
812 setting += (" " + optionString);
813 }
814
815 //
816 // Module's tool chain family option
817 //
818 option = moduleToolChainFamilyOption.get(fpdModuleId);
819 if (option != null && (optionString = option.get(toolChainFamilyKey)) != null) {
820 setting += (" " + optionString);
821 }
822
823 //
824 // Module's tool chain tag option
825 //
826 option = moduleToolChainOption.get(fpdModuleId);
827 if (option != null && (optionString = option.get(toolChainKey)) != null) {
828 setting += (" " + optionString);
829 }
830
831 return setting;
832 }
833
834 public static void setToolChainEnvInfo(ToolChainInfo envInfo) {
835 toolChainEnvInfo = envInfo;
836 }
837 public static void setToolChainPlatformInfo(ToolChainInfo platformInfo) {
838 toolChainPlatformInfo = platformInfo;
839 }
840
841 //
842 // for PCD
843 //
844 public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {
845 return pcdDbManager;
846 }
847
848 //
849 // For PCD get tokenSpaceGUid
850 //
851 public synchronized static String getGuidInfoFromCname(String cName){
852 String cNameGuid = null;
853 String guid = null;
854 Set set = spdTable.keySet();
855 Iterator iter = set.iterator();
856
857 if (iter == null) {
858 return null;
859 }
860
861 while (iter.hasNext()){
862 Spd spd = (Spd) spdTable.get(iter.next());
863 guid = spd.getGuidFromCname(cName);
864 if (guid != null){
865 cNameGuid = guid;
866 break;
867 }
868 }
869 return cNameGuid;
870 }
871
872 //
873 // For PCD
874 //
875 public synchronized static Map<FpdModuleIdentification, XmlObject>
876 getFpdModuleSaXmlObject(String xmlObjectName) {
877 Set<FpdModuleIdentification> fpdModuleSASet = fpdModuleSA.keySet();
878 Iterator item = fpdModuleSASet.iterator();
879
880
881 Map<FpdModuleIdentification, XmlObject> SAPcdBuildDef = new HashMap<FpdModuleIdentification, XmlObject>();
882 Map<String, XmlObject> SANode = new HashMap<String, XmlObject>();
883 FpdModuleIdentification moduleId;
884 while (item.hasNext()) {
885
886 moduleId = (FpdModuleIdentification) item.next();
887 SANode = fpdModuleSA.get(moduleId);
888 try{
889 if (SANode.get(xmlObjectName)!= null){
890 SAPcdBuildDef.put(moduleId,
891 (XmlObject) SANode.get(xmlObjectName));
892
893 }
894 } catch (Exception e){
895 EdkLog.log(EdkLog.EDK_INFO, e.getMessage());
896 }
897 }
898 return SAPcdBuildDef;
899 }
900
901 public synchronized static Map<FpdModuleIdentification,XmlObject> getFpdPcdBuildDefinitions() {
902 Map<FpdModuleIdentification,XmlObject> pcdBuildDef = getFpdModuleSaXmlObject ("PcdBuildDefinition");
903
904 return pcdBuildDef;
905 }
906
907 public static XmlObject parseXmlFile(File xmlFile) throws IOException, XmlException {
908 Collection errors = new ArrayList();
909 XmlOptions opt = new XmlOptions();
910
911 opt.setLoadLineNumbers();
912 opt.setLoadMessageDigest();
913 opt.setErrorListener(errors);
914
915 XmlObject doc = XmlObject.Factory.parse(xmlFile, opt);
916 //
917 // Validate File if they accord with XML Schema
918 //
919 if (!doc.validate(opt)){
920 StringBuilder errorMessage = new StringBuilder(1024);
921 for (Iterator it = errors.iterator(); it.hasNext(); ) {
922 errorMessage.append(it.next());
923 errorMessage.append("\n");
924 }
925 throw new XmlException(errorMessage.toString());
926 }
927
928 return doc;
929 }
930 }
931