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