]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java
changed the way to fetch file name list in spd file, per the schema changes
[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.util.ArrayList;
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.tools.ant.BuildException;
29 import org.apache.xmlbeans.XmlObject;
30 import org.tianocore.FilenameDocument;
31 import org.tianocore.FilenameDocument.Filename;
32 import org.tianocore.FrameworkDatabaseDocument;
33 import org.tianocore.MsaFilesDocument;
34 import org.tianocore.MsaFilesDocument.MsaFiles.MsaFile;
35 import org.tianocore.MsaHeaderDocument.MsaHeader;
36 import org.tianocore.MsaLibHeaderDocument.MsaLibHeader;
37 import org.tianocore.PackageListDocument;
38 import org.tianocore.PackageSurfaceAreaDocument;
39 import org.tianocore.build.autogen.CommonDefinition;
40 import org.tianocore.build.fpd.FpdParserTask;
41 import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
42
43 /**
44 GlobalData provide initializing, instoring, querying and update global data.
45 It is a bridge to intercommunicate between multiple component, such as AutoGen,
46 PCD and so on.
47
48 <p>Note that all global information are initialized incrementally. All data will
49 parse and record only it is necessary during build time. </p>
50
51 @since GenBuild 1.0
52 **/
53 public class GlobalData {
54
55 ///
56 /// means no surface area information for module
57 ///
58 public static final int NO_SA = 0;
59
60 ///
61 /// means only MSA
62 ///
63 public static final int ONLY_MSA = 1;
64
65 ///
66 /// means only Library MSA
67 ///
68 public static final int ONLY_LIBMSA = 2;
69
70 ///
71 /// means both MSA and MBD
72 ///
73 public static final int MSA_AND_MBD = 3;
74
75 ///
76 /// means both Library MSA and Library MBD
77 ///
78 public static final int LIBMSA_AND_LIBMBD = 4;
79
80 ///
81 /// Be used to ensure Global data will be initialized only once.
82 ///
83 public static boolean globalFlag = false;
84
85 ///
86 /// Record current WORKSPACE Directory
87 ///
88 private static String workspaceDir = "";
89
90 ///
91 /// Two columns: Package Name (Key), Package Path(ralative to WORKSPACE)
92 ///
93 private static final Map<String, String> packageInfo = new HashMap<String, String>();
94
95 ///
96 /// spdTable
97 /// Key: Package Name, Value: SPD detail info
98 ///
99 private static final Map<String, Spd> spdTable = new HashMap<String, Spd>();
100
101 ///
102 /// Three columns:
103 /// 1. Module Name | BaseName (Key)
104 /// 2. Module Path + Msa file name (relative to Package)
105 /// 3. Package Name (This module belong to which package)
106 ///
107 private static final Map<String, String[]> moduleInfo = new HashMap<String, String[]>();
108
109 ///
110 /// List all libraries for current build module
111 /// Key: Library BaseName, Value: output library path+name
112 ///
113 private static final Map<String, String> libraries = new HashMap<String, String>();
114
115 ///
116 /// Store every module's relative library instances BaseName
117 /// Key: Module BaseName, Value: All library instances module depends on.
118 ///
119 private static final Map<String, Set<String> > moduleLibraryMap = new HashMap<String, Set<String> >();
120
121 ///
122 /// Key: Module BaseName, Value: original MSA info
123 ///
124 private static final Map<String, Map<String, XmlObject> > nativeMsa = new HashMap<String, Map<String, XmlObject> >();
125
126 ///
127 /// Key: Module BaseName, Value: original MBD info
128 ///
129 private static final Map<String, Map<String, XmlObject> > nativeMbd = new HashMap<String, Map<String, XmlObject> >();
130
131 ///
132 /// Two columns: Module Name or Base Name as Key
133 /// Value is a HashMap with overridden data from MSA/MBD or/and Platform
134 ///
135 private static final Map<String, Map<String, XmlObject> > parsedModules = new HashMap<String, Map<String, XmlObject> >();
136
137 ///
138 /// List all built Module; Value is Module BaseName + Arch. TBD
139 ///
140 private static final Set<String> builtModules = new HashSet<String>();
141
142 ///
143 /// Library instance information table which recored the library and it's
144 /// constructor and distructor function
145 ///
146 private static final Map<String, String[]> libInstanceInfo = new HashMap<String, String[]>();
147
148 ///
149 /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.
150 ///
151 private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();
152
153 /**
154 Query the module's absolute path with module base name.
155
156 @param moduleName the base name of the module
157 @return the absolute module path
158 **/
159 public synchronized static String getModulePath(String moduleName) {
160 String[] info = moduleInfo.get(moduleName);
161 String packagePath = (String) packageInfo.get(info[1]);
162 File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);
163 return convertFile.getParent();
164 }
165
166 /**
167 Query the module's absolute MSA file path with module base name.
168
169 @param moduleName the base name of the module
170 @return the absolute MSA file name
171 @throws BuildException
172 Base name is not registered in any SPD files
173 **/
174 private synchronized static String getMsaFilename(String moduleName) throws BuildException {
175 String[] info = moduleInfo.get(moduleName);
176 if (info == null) {
177 throw new BuildException("Module base name [" + moduleName + "] can't found in all SPD.");
178 }
179 String packagePath = (String) packageInfo.get(info[1]);
180 File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);
181 return convertFile.getPath();
182 }
183
184 /**
185 Query the module's absolute MBD file path with module base name.
186
187 @param moduleName the base name of the module
188 @return the absolute MBD file name
189 @throws BuildException
190 Base name is not registered in any SPD files
191 **/
192 private synchronized static String getMbdFilename(String moduleName) throws BuildException {
193 String[] info = moduleInfo.get(moduleName);
194 if (info == null) {
195 throw new BuildException("Info: Module base name [" + moduleName + "] can't found in all SPD.");
196 }
197 String packagePath = (String) packageInfo.get(info[1]);
198 File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);
199 return convertFile.getPath().substring(0, convertFile.getPath().length() - 4) + ".mbd";
200 }
201
202 /**
203 Get the current WORKSPACE Directory.
204 @return current workspace directory
205 **/
206 public synchronized static String getWorkspacePath() {
207 return workspaceDir;
208 }
209
210 /**
211 Query package relative path to WORKSPACE_DIR with package name.
212
213 @param packageName the name of the package
214 @return the path relative to WORKSPACE_DIR
215 **/
216 public synchronized static String getPackagePath(String packageName) {
217 return (String) packageInfo.get(packageName);
218 }
219
220 /**
221 Query package (which the module belongs to) relative path to WORSPACE_DIR.
222
223 @param moduleName the base name of the module
224 @return the relative path to WORKSPACE_DIR of the package which the module belongs to
225 **/
226 public synchronized static String getPackagePathForModule(String moduleName) {
227 String[] info = moduleInfo.get(moduleName);
228 String packagePath = (String) packageInfo.get(info[1]);
229 return packagePath;
230 }
231
232 /**
233 Query the package name which the module belongs to with the module's base name.
234
235 @param moduleName the base name of the module
236 @return the package name which the module belongs to
237 **/
238 public synchronized static String getPackageNameForModule(String moduleName) {
239 return moduleInfo.get(moduleName)[1];
240 }
241
242 /**
243 Parse framework database (DB) and all SPD files listed in DB to initialize
244 the environment for next build. This method will only be executed only once
245 in the whole build process.
246
247 @param workspaceDatabaseFile the file name of framework database
248 @param workspaceDir current workspace directory path
249 @throws BuildException
250 Framework Dababase or SPD or MSA file is not valid
251 **/
252 public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir) throws BuildException {
253 if (globalFlag) {
254 return;
255 }
256 globalFlag = true;
257 GlobalData.workspaceDir = workspaceDir;
258 File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);
259 try {
260 FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);
261 List<PackageListDocument.PackageList.Package> packages = db.getFrameworkDatabase().getPackageList()
262 .getPackageList();
263 Iterator iter = packages.iterator();
264 while (iter.hasNext()) {
265 PackageListDocument.PackageList.Package packageItem = (PackageListDocument.PackageList.Package) iter
266 .next();
267 String name = packageItem.getPackageNameArray(0).getStringValue();
268 String path = packageItem.getPathArray(0).getStringValue();
269 packageInfo.put(name, path);
270 File spdFile = new File(workspaceDir + File.separatorChar + path + File.separatorChar + name + ".spd");
271 initPackageInfo(spdFile.getPath(), name);
272 //
273 // SPD Parse.
274 //
275 PackageSurfaceAreaDocument spdDoc = (PackageSurfaceAreaDocument) XmlObject.Factory.parse(spdFile);
276 Spd spd = new Spd(spdDoc, path);
277 spdTable.put(name, spd);
278
279 }
280 } catch (Exception e) {
281 throw new BuildException("Parse workspace Database [" + dbFile.getPath() + "] Error.\n" + e.getMessage());
282 }
283 }
284
285 /**
286 Parse every MSA files, get base name from MSA Header. And record those
287 values to ModuleInfo.
288
289 @param packageFilename the file name of the package
290 @param packageName the name of the package
291 @throws BuildException
292 SPD or MSA file is not valid
293 **/
294 private synchronized static void initPackageInfo(String packageFilename, String packageName) throws BuildException {
295 File packageFile = new File(packageFilename);
296 try {
297 PackageSurfaceAreaDocument spd = (PackageSurfaceAreaDocument) XmlObject.Factory.parse(packageFile);
298 List<String> msaFilenameList;
299
300 List<MsaFilesDocument.MsaFiles.MsaFile> msasList = spd.getPackageSurfaceArea().getMsaFiles()
301 .getMsaFileList();
302 if (msasList.size() == 0) {
303 msaFilenameList = spd.getPackageSurfaceArea().getMsaFiles().getFilenameList();
304 } else {
305 msaFilenameList = new ArrayList<String>(msasList.size());
306 Iterator msasIter = msasList.iterator();
307 while (msasIter.hasNext()) {
308 MsaFilesDocument.MsaFiles.MsaFile msaFile = (MsaFilesDocument.MsaFiles.MsaFile)msasIter.next();
309 msaFilenameList.add(msaFile.getFilename().getStringValue());
310 }
311 }
312
313 Iterator msaFilenameIter = msaFilenameList.iterator();
314 while (msaFilenameIter.hasNext()) {
315 String filename = (String)msaFilenameIter.next();
316 File msaFile = new File(workspaceDir + File.separatorChar + GlobalData.getPackagePath(packageName)
317 + File.separatorChar + filename);
318 SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();
319 Map<String, XmlObject> map = surfaceAreaParser.parseFile(msaFile);
320 String baseName = "";
321 XmlObject header = null;
322 if ((header = map.get("MsaHeader")) != null) {
323 if (((MsaHeader) header).isSetBaseName()) {
324 baseName = ((MsaHeader) header).getBaseName().getStringValue();
325 } else {
326 baseName = ((MsaHeader) header).getModuleName();
327 }
328 } else if ((header = map.get("MsaLibHeader")) != null) {
329 baseName = ((MsaLibHeader) header).getBaseName().getStringValue();
330 } else {
331 continue;
332 }
333 nativeMsa.put(baseName, map);
334 String[] info = { filename, packageName };
335 moduleInfo.put(baseName, info);
336 }
337 } catch (Exception e) {
338 throw new BuildException("Parse package description file [" + packageFile.getPath() + "] Error.\n"
339 + e.getMessage());
340 }
341 }
342
343 /**
344 Query the libraries which the module depends on.
345
346 @param moduleName the base name of the module
347 @return the libraries which the module depends on
348 **/
349 public synchronized static String[] getModuleLibrary(String moduleName, String arch) {
350 Set<String> set = moduleLibraryMap.get(moduleName + "-" + arch);
351 return set.toArray(new String[set.size()]);
352 }
353
354 /**
355 Register module's library list which it depends on for later use.
356
357 @param moduleName the base name of the module
358 @param libraryList the libraries which the module depends on
359 **/
360 public synchronized static void addModuleLibrary(String moduleName, String arch, Set<String> libraryList) {
361 moduleLibraryMap.put(moduleName + "-" + arch, libraryList);
362 }
363
364 /**
365 Query the library absolute file name with library name.
366
367 @param library the base name of the library
368 @return the library absolute file name
369 **/
370 public synchronized static String getLibrary(String library, String arch) {
371 return libraries.get(library + "-" + arch);
372 }
373
374 /**
375 Register library absolute file name for later use.
376
377 @param library the base name of the library
378 @param resultPath the library absolute file name
379 **/
380 public synchronized static void addLibrary(String library, String arch, String resultPath) {
381 libraries.put(library + "-" + arch, resultPath);
382 }
383
384 /**
385 Whether the module with ARCH has built in the previous build.
386
387 @param moduleName the base name of the module
388 @param arch current build ARCH
389 @return true if the module has built in previous, otherwise return false
390 **/
391 public synchronized static boolean isModuleBuilt(String moduleName, String arch) {
392 return builtModules.contains(moduleName + "-" + arch);
393 }
394
395 /**
396 Register the module with ARCH has built.
397
398 @param moduleName the base name of the module
399 @param arch current build ARCH
400 **/
401 public synchronized static void registerBuiltModule(String moduleName, String arch) {
402 builtModules.add(moduleName + "-" + arch);
403 }
404
405 /**
406 Whether the module's surface area has parsed in the previous build.
407
408 @param moduleName the base name of the module
409 @return true if the module's surface area has parsed in previous, otherwise
410 return false
411 **/
412 public synchronized static boolean isModuleParsed(String moduleName) {
413 return parsedModules.containsKey(moduleName);
414 }
415
416 /**
417 Query overrided module surface area information. If current is Package
418 or Platform build, also include the information from FPD file.
419
420 <p>Note that surface area parsing is incremental. That means the method will
421 only to parse the MSA and MBD files when never parsed before. </p>
422
423 @param moduleName the base name of the module
424 @return the overrided module surface area information
425 @throws BuildException
426 MSA or MBD is not valid
427 **/
428 public synchronized static Map<String, XmlObject> getDoc(String moduleName) throws BuildException {
429 if (parsedModules.containsKey(moduleName)) {
430 return parsedModules.get(moduleName);
431 }
432 Map<String, XmlObject> msaMap = getNativeMsa(moduleName);
433 Map<String, XmlObject> mbdMap = getNativeMbd(moduleName);
434 OverrideProcess op = new OverrideProcess();
435 Map<String, XmlObject> map = op.override(mbdMap, msaMap);
436 //
437 // IF IT IS A PALTFORM BUILD, OVERRIDE FROM PLATFORM
438 //
439 if (FpdParserTask.platformBuildOptions != null) {
440 Map<String, XmlObject> platformMap = new HashMap<String, XmlObject>();
441 platformMap.put("BuildOptions", FpdParserTask.platformBuildOptions);
442 Map<String, XmlObject> overrideMap = op.override(platformMap, OverrideProcess.deal(map));
443 GlobalData.registerModule(moduleName, overrideMap);
444 return overrideMap;
445 } else {
446 parsedModules.put(moduleName, map);
447 return map;
448 }
449 }
450
451 /**
452 Query the native MSA information with module base name.
453
454 <p>Note that MSA parsing is incremental. That means the method will
455 only to parse the MSA files when never parsed before. </p>
456
457 @param moduleName the base name of the module
458 @return the native MSA information
459 @throws BuildException
460 MSA file is not valid
461 **/
462 public synchronized static Map<String, XmlObject> getNativeMsa(String moduleName) throws BuildException {
463 if (nativeMsa.containsKey(moduleName)) {
464 return nativeMsa.get(moduleName);
465 }
466 String msaFilename = getMsaFilename(moduleName);
467 File msaFile = new File(msaFilename);
468 if (!msaFile.exists()) {
469 throw new BuildException("Info: Surface Area file [" + msaFile.getPath() + "] can't found.");
470 }
471 SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();
472 Map<String, XmlObject> map = surfaceAreaParser.parseFile(msaFile);
473 nativeMsa.put(moduleName, map);
474 return map;
475 }
476
477 /**
478 Query the native MBD information with module base name.
479
480 <p>Note that MBD parsing is incremental. That means the method will
481 only to parse the MBD files when never parsed before. </p>
482
483 @param moduleName the base name of the module
484 @return the native MBD information
485 @throws BuildException
486 MBD file is not valid
487 **/
488 public synchronized static Map<String, XmlObject> getNativeMbd(String moduleName) throws BuildException {
489 if (nativeMbd.containsKey(moduleName)) {
490 return nativeMbd.get(moduleName);
491 }
492 String mbdFilename = getMbdFilename(moduleName);
493 File mbdFile = new File(mbdFilename);
494 if (!mbdFile.exists()) {
495 return null;
496 //throw new BuildException("Info: Surface Area file [" + mbdFile.getPath() + "] can't found.");
497 }
498 SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();
499 Map<String, XmlObject> map = surfaceAreaParser.parseFile(mbdFile);
500 nativeMbd.put(moduleName, map);
501 return map;
502 }
503
504 /**
505 Register module overrided surface area information. If has existed, then update.
506
507 @param moduleName the base name of the module
508 @param map the overrided surface area information
509 **/
510 public synchronized static void registerModule(String moduleName, Map<String, XmlObject> map) {
511 parsedModules.put(moduleName, map);
512 }
513
514 /**
515 *
516 * @param protocolName
517 * @return
518 */
519 public synchronized static String[] getProtocolInfoGuid(String protocolName) {
520 Set set = spdTable.keySet();
521 Iterator iter = set.iterator();
522 String[] cNameGuid = null;
523
524 while (iter.hasNext()) {
525 Spd spd = (Spd) spdTable.get(iter.next());
526 cNameGuid = spd.getProtocolNameGuidArray(protocolName);
527 if (cNameGuid != null) {
528 break;
529 }
530 }
531 return cNameGuid;
532 }
533
534 public synchronized static String[] getPpiInfoGuid(String ppiName) {
535 Set set = spdTable.keySet();
536 Iterator iter = set.iterator();
537 String[] cNameGuid = null;
538
539 while (iter.hasNext()) {
540 Spd spd = (Spd) spdTable.get(iter.next());
541 cNameGuid = spd.getPpiCnameGuidArray(ppiName);
542
543 if (cNameGuid != null) {
544 break;
545 }
546 }
547 return cNameGuid;
548 }
549
550 /**
551 *
552 * @param guidName
553 * @return
554 */
555 public synchronized static String[] getGuidInfoGuid(String guidName) {
556 String[] cNameGuid = null;
557 Set set = spdTable.keySet();
558 Iterator iter = set.iterator();
559
560 while (iter.hasNext()) {
561 Spd spd = (Spd) spdTable.get(iter.next());
562 cNameGuid = spd.getGuidNameArray(guidName);
563 if (cNameGuid != null) {
564 break;
565 }
566 }
567 return cNameGuid;
568 }
569
570 public synchronized static String getLibClassIncluder(String libName) {
571 String libIncluder = null;
572 Set set = spdTable.keySet();
573 Iterator iter = set.iterator();
574
575 while (iter.hasNext()) {
576 String packageName = (String) iter.next();
577 Spd spd = (Spd) spdTable.get(packageName);
578 libIncluder = spd.getLibClassIncluder(libName);
579 String packagePath = spd.packagePath;
580 if (packagePath != null) {
581 packagePath = packagePath.replace('\\', File.separatorChar);
582 packagePath = packagePath.replace('/', File.separatorChar);
583 } else {
584 packagePath = packageName;
585 }
586 if (libIncluder != null) {
587 libIncluder = libIncluder.replace('\\', File.separatorChar);
588 libIncluder = libIncluder.replace('/', File.separatorChar);
589 libIncluder = packageName + File.separatorChar + libIncluder;
590 break;
591 }
592 }
593 return libIncluder;
594 }
595
596 public synchronized static String getModuleInfoByPackageName(String packageName, String moduleType) {
597 Spd spd;
598 String includeFile = null;
599 String includeStr = "";
600 String cleanPath = "";
601
602 spd = (Spd) spdTable.get(packageName);
603 includeFile = spd.getModuleTypeIncluder(moduleType);
604 if (includeFile != null) {
605 includeFile = includeFile.replace('\\', File.separatorChar);
606 includeFile = includeFile.replace('/', File.separatorChar);
607 includeStr = CommonDefinition.include + " <" + includeStr;
608 cleanPath = spd.packagePath;
609 cleanPath = cleanPath.replace('\\', File.separatorChar);
610 cleanPath = cleanPath.replace('/', File.separatorChar);
611
612 if (cleanPath.charAt(spd.packagePath.length() - 1) != File.separatorChar) {
613 cleanPath = cleanPath + File.separatorChar;
614 }
615 includeStr = includeStr + cleanPath;
616 includeStr = includeStr + includeFile;
617 includeStr = includeStr + ">\r\n";
618 }
619
620 return includeStr;
621 }
622
623 public synchronized static void setLibInstanceInfo(String libName, String libConstructor, String libDesturctor) {
624 String[] libConsDes = new String[2];
625 libConsDes[0] = libConstructor;
626 libConsDes[1] = libDesturctor;
627
628 libInstanceInfo.put(libName, libConsDes);
629 }
630
631 public synchronized static boolean isHaveLibInstance(String libName) {
632 return libInstanceInfo.containsKey(libName);
633 }
634
635 public synchronized static String getLibInstanceConstructor(String libName) {
636 String[] libInstanceValue;
637 libInstanceValue = libInstanceInfo.get(libName);
638 if (libInstanceValue != null) {
639 return libInstanceValue[0];
640 } else {
641 return null;
642 }
643 }
644
645 public synchronized static String getLibInstanceDestructor(String libName) {
646 String[] libInstanceValue;
647 libInstanceValue = libInstanceInfo.get(libName);
648 if (libInstanceValue != null) {
649 return libInstanceValue[1];
650 } else {
651 return null;
652 }
653 }
654
655 public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {
656 return pcdDbManager;
657 }
658 }