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