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