]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Java/Source/GenBuild/org/tianocore/build/global/GlobalData.java
Fixed EDKT532 and EDKT533
[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("Events", cloneXmlObject(msa.getEvents(), true));
438 msaMap.put("Hobs", cloneXmlObject(msa.getHobs(), true));
439 msaMap.put("Variables", cloneXmlObject(msa.getVariables(), true));
440 msaMap.put("SystemTables", cloneXmlObject(msa.getSystemTables(), true));
441 msaMap.put("DataHubs", cloneXmlObject(msa.getDataHubs(), true));
442 msaMap.put("HiiPackages", cloneXmlObject(msa.getHiiPackages(), true));
443 msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true));
444 msaMap.put("PcdCoded", cloneXmlObject(msa.getPcdCoded(), true));
445 msaMap.put("ModuleBuildOptions", cloneXmlObject(msa.getModuleBuildOptions(), true));
446 return msaMap;
447 } catch(IOException ex) {
448 EdkException edkException = new EdkException("Parse of MSA file [" + msaFile.getPath() + "] failed!\n" + ex.getMessage());
449 edkException.setStackTrace(ex.getStackTrace());
450 throw edkException;
451 } catch(XmlException ex) {
452 EdkException edkException = new EdkException("Parse of MSA file [" + msaFile.getPath() + "] failed!\n" + ex.getMessage());
453 edkException.setStackTrace(ex.getStackTrace());
454 throw edkException;
455 }
456 }
457
458 public static Map<String, XmlObject> getFpdBuildOptionsMap() {
459 return fpdBuildOptionsMap;
460 }
461
462 public static void setFpdBuildOptions(XmlObject fpdBuildOptions) throws EdkException {
463 GlobalData.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true);
464 fpdBuildOptionsMap.put("BuildOptions", GlobalData.fpdBuildOptions);
465 }
466
467 public static XmlObject getFpdDynamicPcds() {
468 return fpdDynamicPcds;
469 }
470
471 public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) {
472 GlobalData.fpdDynamicPcds = fpdDynamicPcds;
473 }
474
475 public static Set<ModuleIdentification> getModules(PackageIdentification packageId){
476 Spd spd = spdTable.get(packageId);
477 if (spd == null ) {
478 Set<ModuleIdentification> dummy = new HashSet<ModuleIdentification>();
479 return dummy;
480 } else {
481 return spd.getModules();
482 }
483 }
484
485 /**
486 * The header file path is relative to workspace dir
487 */
488 public static String[] getLibraryClassHeaderFiles(
489 PackageIdentification[] packages, String name) throws EdkException{
490 if (packages == null) {
491 // throw Exception or not????
492 return new String[0];
493 }
494 String[] result = null;
495 for (int i = 0; i < packages.length; i++) {
496 Spd spd = spdTable.get(packages[i]);
497 //
498 // If find one package defined the library class
499 //
500 if ((result = spd.getLibClassIncluder(name)) != null) {
501 return result;
502 }
503 }
504 //
505 // If can't find library class declaration in every package
506 //
507 throw new EdkException("Can not find library class [" + name
508 + "] declaration in any SPD package!");
509 }
510
511 /**
512 * The header file path is relative to workspace dir
513 */
514 public static String getPackageHeaderFiles(PackageIdentification packages,
515 String moduleType) {
516 if (packages == null) {
517 return new String("");
518 }
519 Spd spd = spdTable.get(packages);
520 //
521 // If can't find package header file, skip it
522 //
523 String temp = null;
524 if (spd != null) {
525 if ((temp = spd.getPackageIncluder(moduleType)) != null) {
526 return temp;
527 } else {
528 temp = "";
529 return temp;
530 }
531 } else {
532 return null;
533 }
534 }
535
536 /**
537 * return two values: {cName, GuidValue}
538 */
539 public static String[] getGuid(List<PackageIdentification> packages, String name) {
540 if (packages == null) {
541 // throw Exception or not????
542 return new String[0];
543 }
544 String[] result = null;
545 Iterator item = packages.iterator();
546 while (item.hasNext()){
547 Spd spd = spdTable.get(item.next());
548 //
549 // If find one package defined the GUID
550 //
551 if ((result = spd.getGuid(name)) != null) {
552 return result;
553 }
554 }
555
556 return null;
557 }
558
559 /**
560 * return two values: {cName, GuidValue}
561 */
562 public static String[] getPpiGuid(List<PackageIdentification> packages,
563 String name) {
564 if (packages == null) {
565 return new String[0];
566 }
567 String[] result = null;
568 Iterator item = packages.iterator();
569 while (item.hasNext()){
570 Spd spd = spdTable.get(item.next());
571 //
572 // If find one package defined the Ppi GUID
573 //
574 if ((result = spd.getPpi(name)) != null) {
575 return result;
576 }
577 }
578 return null;
579 }
580
581 /**
582 * return two values: {cName, GuidValue}
583 */
584 public static String[] getProtocolGuid(List<PackageIdentification> packages,
585 String name) {
586 if (packages == null) {
587 return new String[0];
588 }
589 String[] result = null;
590 Iterator item = packages.iterator();
591 while (item.hasNext()){
592 Spd spd = spdTable.get(item.next());
593 //
594 // If find one package defined the protocol GUID
595 //
596 if ((result = spd.getProtocol(name))!= null){
597 return result;
598 }
599 }
600 return null;
601
602 }
603
604 public synchronized static PlatformIdentification getPlatformByName(String name) throws EdkException {
605 Iterator iter = platformList.iterator();
606 while(iter.hasNext()){
607 PlatformIdentification platformId = (PlatformIdentification)iter.next();
608 if (platformId.getName().equalsIgnoreCase(name)) {
609 return platformId;
610 }
611 }
612 throw new EdkException("Can't find platform [" + name + "] in the current WORKSPACE database!");
613 }
614
615 public synchronized static PlatformIdentification getPlatform(String filename) throws EdkException {
616 File file = new File(workspaceDir + File.separatorChar + filename);
617 Iterator iter = platformList.iterator();
618 while(iter.hasNext()){
619 PlatformIdentification platformId = (PlatformIdentification)iter.next();
620 if (platformId.getFpdFile().getPath().equalsIgnoreCase(file.getPath())) {
621 return platformId;
622 }
623 }
624 throw new EdkException("Can't find platform file [" + filename + "] in the current WORKSPACE database!");
625 }
626
627 public synchronized static PackageIdentification refreshPackageIdentification(PackageIdentification packageId) throws EdkException {
628 Iterator iter = packageList.iterator();
629 while(iter.hasNext()){
630 PackageIdentification packageItem = (PackageIdentification)iter.next();
631 if (packageItem.equals(packageId)) {
632 packageId.setName(packageItem.getName());
633 packageId.setSpdFile(packageItem.getSpdFile());
634 return packageId;
635 }
636 }
637 throw new EdkException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!");
638 }
639
640 public synchronized static ModuleIdentification refreshModuleIdentification(ModuleIdentification moduleId) throws EdkException {
641 PackageIdentification packageId = getPackageForModule(moduleId);
642 moduleId.setPackage(packageId);
643 Spd spd = spdTable.get(packageId);
644 if (spd == null) {
645 throw new EdkException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!");
646 }
647 Set<ModuleIdentification> modules = spd.getModules();
648 Iterator<ModuleIdentification> iter = modules.iterator();
649 while (iter.hasNext()) {
650 ModuleIdentification item = iter.next();
651 if (item.equals(moduleId)) {
652 moduleId.setName(item.getName());
653 moduleId.setModuleType(item.getModuleType());
654 moduleId.setMsaFile(item.getMsaFile());
655 return moduleId;
656 }
657 }
658 throw new EdkException("Can't find " + moduleId + " under the current workspace!");
659 }
660
661 public synchronized static Set<PackageIdentification> getPackageList(){
662 return packageList;
663 }
664
665 /**
666 BUGBUG: It is a walk around method. If do not clone, can't query info with
667 XPath correctly.
668
669 @param object XmlObject
670 @param deep flag for deep clone
671 @return XmlObject after clone
672 @throws BuildException parse original XmlObject error.
673 **/
674 private static XmlObject cloneXmlObject(XmlObject object, boolean deep) throws EdkException {
675 if ( object == null) {
676 return null;
677 }
678 XmlObject result = null;
679 try {
680 result = XmlObject.Factory.parse(object.getDomNode()
681 .cloneNode(deep));
682 } catch (XmlException ex) {
683 EdkException edkException = new EdkException(ex.getMessage());
684 edkException.setStackTrace(ex.getStackTrace());
685 throw edkException;
686 }
687 return result;
688 }
689
690 ///
691 /// Tool Chain Related, try to refine and put some logic process to ToolChainFactory
692 ///
693 public synchronized static ToolChainInfo getToolChainInfo() {
694 if (toolChainInfo == null) {
695 toolChainInfo = toolsDef.getConfigInfo().intersection(toolChainEnvInfo);
696 if (toolChainPlatformInfo != null) {
697 toolChainInfo = toolChainInfo.intersection(toolChainPlatformInfo);
698 }
699 toolChainInfo.addCommands(toolsDef.getConfigInfo().getCommands());
700 toolChainInfo.normalize();
701
702 EdkLog.log("Init", EdkLog.EDK_ALWAYS, "Current build tool chain information summary: ");
703 EdkLog.log("Init", EdkLog.EDK_ALWAYS, toolChainInfo + "");
704 }
705 return toolChainInfo;
706 }
707
708 public static void setPlatformToolChainFamilyOption(ToolChainMap map) {
709 platformToolChainFamilyOption = map;
710 }
711
712 public static void setPlatformToolChainOption(ToolChainMap map) {
713 platformToolChainOption = map;
714 }
715
716 public static void addModuleToolChainOption(FpdModuleIdentification fpdModuleId,
717 ToolChainMap toolChainOption) {
718 moduleToolChainOption.put(fpdModuleId, toolChainOption);
719 }
720
721 public static void addModuleToolChainFamilyOption(FpdModuleIdentification fpdModuleId,
722 ToolChainMap toolChainOption) {
723 moduleToolChainFamilyOption.put(fpdModuleId, toolChainOption);
724 }
725
726 public static void addMsaBuildOption(ModuleIdentification moduleId,
727 ToolChainMap toolChainOption) {
728 msaBuildOption.put(moduleId, toolChainOption);
729 }
730
731 public static void addMsaFamilyBuildOption(ModuleIdentification moduleId,
732 ToolChainMap toolChainOption) {
733 msaFamilyBuildOption.put(moduleId, toolChainOption);
734 }
735
736 public static boolean isCommandSet(String target, String toolchain, String arch) throws EdkException {
737 String[] commands = getToolChainInfo().getCommands();
738
739 for (int i = 0; i < commands.length; ++i) {
740 String cmdName = toolsDef.getConfig().get(new String[] {target, toolchain, arch, commands[i], ToolDefinitions.TOOLS_DEF_ATTRIBUTE_NAME});
741 if (cmdName != null && cmdName.length() != 0) {
742 return true;
743 }
744 }
745
746 return false;
747 }
748
749 /**
750 Except FLAGS, all attribute are from TOOLS_DEF file.
751
752 For FLAGS, information from four places, they are:
753 <pre>
754 1. tools_def.txt
755 2. MSA &lt;BuildOptions&gt;/&lt;Options&gt;
756 3. FPD &lt;BuildOptions&gt;/&lt;Options&gt;
757 4. FPD &lt;FrameworkModules&gt;/&lt;ModuleSaBuildOptions&gt;/&lt;Options&gt;
758 </pre>
759
760 @param commandDescription Key: TARGET, TAGNAME, ARCH, COMMANDTYPE, ATTRIBUTE
761 @param fpdModuleId Module Identification with Arch
762 @return The corresponding String
763 @throws EdkException If build option definition error
764 **/
765 public synchronized static String getCommandSetting(String[] commandDescription, FpdModuleIdentification fpdModuleId) throws EdkException {
766 ToolChainKey toolChainKey = new ToolChainKey(commandDescription);
767 ToolChainMap toolChainConfig = toolsDef.getConfig();
768 String setting = null;
769
770 //
771 // Default in tools_def.txt
772 //
773 setting = toolChainConfig.get(toolChainKey);
774 if (setting == null) {
775 setting = "";
776 }
777 if (!commandDescription[ToolChainElement.ATTRIBUTE.value].equals(ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS)) {
778 return setting;
779 }
780
781 Set<String> flagSet = new LinkedHashSet<String>();
782 flagSet.add(setting);
783
784 //
785 // Tool's option can be in .fpd and/or .msa file
786 //
787 String optionString;
788 ToolChainMap option = null;
789 ToolChainKey toolChainFamilyKey = new ToolChainKey(commandDescription);
790
791 toolChainFamilyKey.setKey(ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FAMILY, ToolChainElement.ATTRIBUTE.value);
792 String family = toolChainConfig.get(toolChainFamilyKey);
793 toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);
794 toolChainFamilyKey.setKey(ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS, ToolChainElement.ATTRIBUTE.value);
795
796 //
797 // MSA's tool chain family option
798 //
799 option = msaFamilyBuildOption.get(fpdModuleId.getModule());
800 if (option != null && (optionString = option.get(toolChainFamilyKey)) != null) {
801 flagSet.add(optionString);
802 }
803
804 //
805 // MSA's tool chain option
806 //
807 option = msaBuildOption.get(fpdModuleId.getModule());
808 if (option != null && (optionString = option.get(toolChainKey)) != null) {
809 flagSet.add(optionString);
810 }
811
812 //
813 // Platform's tool chain family option
814 //
815 optionString = platformToolChainFamilyOption.get(toolChainFamilyKey);
816 if (optionString != null) {
817 flagSet.add(optionString);
818 }
819
820 //
821 // Platform's tool chain tag option
822 //
823 optionString = platformToolChainOption.get(toolChainKey);
824 if (optionString != null) {
825 flagSet.add(optionString);
826 }
827
828 //
829 // Module's tool chain family option
830 //
831 option = moduleToolChainFamilyOption.get(fpdModuleId);
832 if (option != null && (optionString = option.get(toolChainFamilyKey)) != null) {
833 flagSet.add(optionString);
834 }
835
836 //
837 // Module's tool chain tag option
838 //
839 option = moduleToolChainOption.get(fpdModuleId);
840 if (option != null && (optionString = option.get(toolChainKey)) != null) {
841 flagSet.add(optionString);
842 }
843
844 setting = "";
845 for(Iterator<String> iter = flagSet.iterator(); iter.hasNext();) {
846 setting += iter.next() +" ";
847 }
848 return setting;
849 }
850
851 public static void setToolChainEnvInfo(ToolChainInfo envInfo) {
852 toolChainEnvInfo = envInfo;
853 }
854 public static void setToolChainPlatformInfo(ToolChainInfo platformInfo) {
855 toolChainPlatformInfo = platformInfo;
856 }
857
858 //
859 // for PCD
860 //
861 public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {
862 return pcdDbManager;
863 }
864
865 //
866 // For PCD get tokenSpaceGUid
867 //
868 public synchronized static String getGuidInfoFromCname(String cName){
869 String cNameGuid = null;
870 String guid = null;
871 Set set = spdTable.keySet();
872 Iterator iter = set.iterator();
873
874 if (iter == null) {
875 return null;
876 }
877
878 while (iter.hasNext()){
879 Spd spd = (Spd) spdTable.get(iter.next());
880 guid = spd.getGuidFromCname(cName);
881 if (guid != null){
882 cNameGuid = guid;
883 break;
884 }
885 }
886 return cNameGuid;
887 }
888
889 //
890 // For PCD
891 //
892 public synchronized static Map<FpdModuleIdentification, XmlObject>
893 getFpdModuleSaXmlObject(String xmlObjectName) {
894 Set<FpdModuleIdentification> fpdModuleSASet = fpdModuleSA.keySet();
895 Iterator item = fpdModuleSASet.iterator();
896
897
898 Map<FpdModuleIdentification, XmlObject> SAPcdBuildDef = new HashMap<FpdModuleIdentification, XmlObject>();
899 Map<String, XmlObject> SANode = new HashMap<String, XmlObject>();
900 FpdModuleIdentification moduleId;
901 while (item.hasNext()) {
902
903 moduleId = (FpdModuleIdentification) item.next();
904 SANode = fpdModuleSA.get(moduleId);
905 try{
906 if (SANode.get(xmlObjectName)!= null){
907 SAPcdBuildDef.put(moduleId,
908 (XmlObject) SANode.get(xmlObjectName));
909
910 }
911 } catch (Exception e){
912 EdkLog.log(EdkLog.EDK_INFO, e.getMessage());
913 }
914 }
915 return SAPcdBuildDef;
916 }
917
918 public synchronized static Map<FpdModuleIdentification,XmlObject> getFpdPcdBuildDefinitions() {
919 Map<FpdModuleIdentification,XmlObject> pcdBuildDef = getFpdModuleSaXmlObject ("PcdBuildDefinition");
920
921 return pcdBuildDef;
922 }
923
924 public static XmlObject parseXmlFile(File xmlFile) throws IOException, XmlException {
925 Collection errors = new ArrayList();
926 XmlOptions opt = new XmlOptions();
927
928 opt.setLoadLineNumbers();
929 opt.setLoadMessageDigest();
930 opt.setErrorListener(errors);
931
932 XmlObject doc = XmlObject.Factory.parse(xmlFile, opt);
933 //
934 // Validate File if they accord with XML Schema
935 //
936 if (!doc.validate(opt)){
937 StringBuilder errorMessage = new StringBuilder(1024);
938 for (Iterator it = errors.iterator(); it.hasNext(); ) {
939 errorMessage.append(it.next());
940 errorMessage.append("\n");
941 }
942 throw new XmlException(errorMessage.toString());
943 }
944
945 return doc;
946 }
947 }
948