]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Java/Source/GenBuild/org/tianocore/build/global/GlobalData.java
Added support for macro/property in tools_def.txt. Now you can define a property...
[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
305 packageId = (PackageIdentification)iter.next();\r
306 moduleId.setPackage(packageId);\r
307 Spd spd = spdTable.get(packageId);\r
89e1408f 308 File tempMsaFile = null;\r
309 if ((tempMsaFile = spd.getModuleFile(moduleId)) != null ) {\r
310 if (tempMsaFile.getParent().equalsIgnoreCase(moduleId.getMsaFile().getParent())) {\r
311 break ;\r
312 }\r
313 tempMsaFile = null;\r
a29c47e0 314 }\r
315 }\r
316 if (packageId == null){\r
892b0e7a 317 throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!");\r
82516887 318 } else {\r
a29c47e0 319 return packageId;\r
320 }\r
321 }\r
ff225cbb 322\r
878ddf1f 323 /**\r
a29c47e0 324 Difference between build and parse: ToolChain and Target\r
878ddf1f 325 **/\r
a29c47e0 326 public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) {\r
327 return builtModules.contains(moduleId);\r
878ddf1f 328 }\r
ff225cbb 329\r
a29c47e0 330 public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) {\r
331 builtModules.add(fpdModuleId);\r
878ddf1f 332 }\r
333\r
ff225cbb 334\r
892b0e7a 335 public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map<String, XmlObject> doc) throws EdkException{\r
a29c47e0 336 Map<String, XmlObject> result = new HashMap<String, XmlObject>();\r
337 Set keySet = doc.keySet();\r
338 Iterator iter = keySet.iterator();\r
339 while (iter.hasNext()){\r
340 String key = (String)iter.next();\r
341 XmlObject item = cloneXmlObject(doc.get(key), true);\r
342 result.put(key, item);\r
343 }\r
344 fpdModuleSA.put(fpdModuleId, result);\r
878ddf1f 345 }\r
57cc2ee7 346\r
347 public synchronized static boolean hasFpdModuleSA(FpdModuleIdentification fpdModuleId) {\r
348 return fpdModuleSA.containsKey(fpdModuleId);\r
349 }\r
350\r
878ddf1f 351 /**\r
82516887 352 Query module surface area information.\r
ff225cbb 353\r
354 <p>Note that surface area parsing is incremental. That means the method will\r
82516887 355 only parse the MSA files if necessary. </p>\r
356 \r
357 @param fpdModuleId Module ID with arch\r
358 @return ModuleSA info and MSA info for fpdModuleId\r
359 @throws BuildException Can't find MSA\r
878ddf1f 360 **/\r
892b0e7a 361 public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws EdkException{\r
a29c47e0 362 if (parsedModules.containsKey(fpdModuleId)) {\r
363 return parsedModules.get(fpdModuleId);\r
364 }\r
365 Map<String, XmlObject> doc = new HashMap<String, XmlObject>();\r
366 ModuleIdentification moduleId = fpdModuleId.getModule();\r
878ddf1f 367 //\r
a29c47e0 368 // First part: get the MSA files info\r
878ddf1f 369 //\r
136adffc 370 doc.putAll(getNativeMsa(moduleId));\r
ff225cbb 371\r
a29c47e0 372 //\r
373 // Second part: put build options\r
374 //\r
375 doc.put("BuildOptions", fpdBuildOptions);\r
ff225cbb 376\r
a29c47e0 377 //\r
378 // Third part: get Module info from FPD, such as Library instances, PCDs\r
379 //\r
380 if (fpdModuleSA.containsKey(fpdModuleId)){\r
381 //\r
382 // merge module info in FPD to final Doc\r
383 // For Library Module, do nothing here\r
384 //\r
385 doc.putAll(fpdModuleSA.get(fpdModuleId));\r
878ddf1f 386 }\r
a29c47e0 387 parsedModules.put(fpdModuleId, doc);\r
388 return doc;\r
878ddf1f 389 }\r
390\r
892b0e7a 391 public synchronized static Map<String, XmlObject> getDoc(ModuleIdentification moduleId, String arch) throws EdkException{\r
a29c47e0 392 FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);\r
393 return getDoc(fpdModuleId);\r
394 }\r
892b0e7a 395 \r
878ddf1f 396 /**\r
ff225cbb 397 Query the native MSA information with module base name.\r
398\r
399 <p>Note that MSA parsing is incremental. That means the method will\r
878ddf1f 400 only to parse the MSA files when never parsed before. </p>\r
ff225cbb 401\r
878ddf1f 402 @param moduleName the base name of the module\r
403 @return the native MSA information\r
404 @throws BuildException\r
405 MSA file is not valid\r
406 **/\r
892b0e7a 407 public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws EdkException {\r
a29c47e0 408 if (nativeMsa.containsKey(moduleId)) {\r
409 return nativeMsa.get(moduleId);\r
410 }\r
411 File msaFile = getMsaFile(moduleId);\r
412 Map<String, XmlObject> msaMap = getNativeMsa(msaFile);\r
413 nativeMsa.put(moduleId, msaMap);\r
414 return msaMap;\r
415 }\r
ff225cbb 416\r
892b0e7a 417 public synchronized static Map<String, XmlObject> getNativeMsa(File msaFile) throws EdkException {\r
82516887 418 if (!msaFile.exists()) {\r
892b0e7a 419 throw new EdkException("Module Surface Area file [" + msaFile.getPath() + "] can't be found!");\r
a29c47e0 420 }\r
421 try {\r
fe6d0f74 422 ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)parseXmlFile(msaFile);\r
a29c47e0 423 //\r
424 // parse MSA file\r
425 //\r
426 ModuleSurfaceArea msa= doc.getModuleSurfaceArea();\r
427 Map<String, XmlObject> msaMap = new HashMap<String, XmlObject>();\r
428 msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true));\r
429 msaMap.put("ModuleDefinitions", cloneXmlObject(msa.getModuleDefinitions(), true));\r
430 msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true));\r
431 msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true));\r
432 msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true));\r
433 msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true));\r
434 msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true));\r
435 msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true));\r
436 msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true));\r
136adffc 437 msaMap.put("PcdCoded", cloneXmlObject(msa.getPcdCoded(), true));\r
b69bb9ba 438 msaMap.put("ModuleBuildOptions", cloneXmlObject(msa.getModuleBuildOptions(), true));\r
a29c47e0 439 return msaMap;\r
892b0e7a 440 } catch(IOException ex) {\r
fe6d0f74 441 EdkException edkException = new EdkException("Parse of MSA file [" + msaFile.getPath() + "] failed!\n" + ex.getMessage());\r
892b0e7a 442 edkException.setStackTrace(ex.getStackTrace());\r
443 throw edkException;\r
444 } catch(XmlException ex) {\r
fe6d0f74 445 EdkException edkException = new EdkException("Parse of MSA file [" + msaFile.getPath() + "] failed!\n" + ex.getMessage());\r
892b0e7a 446 edkException.setStackTrace(ex.getStackTrace());\r
447 throw edkException;\r
a29c47e0 448 }\r
449 }\r
ff225cbb 450\r
19bf6b15 451 public static Map<String, XmlObject> getFpdBuildOptionsMap() {\r
452 return fpdBuildOptionsMap;\r
878ddf1f 453 }\r
ff225cbb 454\r
892b0e7a 455 public static void setFpdBuildOptions(XmlObject fpdBuildOptions) throws EdkException {\r
a29c47e0 456 GlobalData.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true);\r
19bf6b15 457 fpdBuildOptionsMap.put("BuildOptions", GlobalData.fpdBuildOptions);\r
a29c47e0 458 }\r
459\r
460 public static XmlObject getFpdDynamicPcds() {\r
461 return fpdDynamicPcds;\r
462 }\r
463\r
464 public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) {\r
465 GlobalData.fpdDynamicPcds = fpdDynamicPcds;\r
466 }\r
467\r
a29c47e0 468 public static Set<ModuleIdentification> getModules(PackageIdentification packageId){\r
469 Spd spd = spdTable.get(packageId);\r
470 if (spd == null ) {\r
471 Set<ModuleIdentification> dummy = new HashSet<ModuleIdentification>();\r
472 return dummy;\r
82516887 473 } else {\r
a29c47e0 474 return spd.getModules();\r
878ddf1f 475 }\r
878ddf1f 476 }\r
477\r
478 /**\r
a29c47e0 479 * The header file path is relative to workspace dir\r
480 */\r
481 public static String[] getLibraryClassHeaderFiles(\r
892b0e7a 482 PackageIdentification[] packages, String name) throws EdkException{\r
a29c47e0 483 if (packages == null) {\r
484 // throw Exception or not????\r
485 return new String[0];\r
486 }\r
487 String[] result = null;\r
488 for (int i = 0; i < packages.length; i++) {\r
489 Spd spd = spdTable.get(packages[i]);\r
490 //\r
491 // If find one package defined the library class\r
492 //\r
493 if ((result = spd.getLibClassIncluder(name)) != null) {\r
494 return result;\r
495 }\r
496 }\r
497 //\r
498 // If can't find library class declaration in every package\r
499 //\r
892b0e7a 500 throw new EdkException("Can not find library class [" + name\r
391dbbb1 501 + "] declaration in any SPD package!");\r
878ddf1f 502 }\r
503\r
504 /**\r
a29c47e0 505 * The header file path is relative to workspace dir\r
878ddf1f 506 */\r
a29c47e0 507 public static String getPackageHeaderFiles(PackageIdentification packages,\r
892b0e7a 508 String moduleType) {\r
a29c47e0 509 if (packages == null) {\r
510 return new String("");\r
511 }\r
512 Spd spd = spdTable.get(packages);\r
513 //\r
514 // If can't find package header file, skip it\r
515 //\r
516 String temp = null;\r
517 if (spd != null) {\r
518 if ((temp = spd.getPackageIncluder(moduleType)) != null) {\r
519 return temp;\r
520 } else {\r
521 temp = "";\r
522 return temp;\r
878ddf1f 523 }\r
a29c47e0 524 } else {\r
525 return null;\r
878ddf1f 526 }\r
878ddf1f 527 }\r
528\r
a29c47e0 529 /**\r
530 * return two values: {cName, GuidValue}\r
531 */\r
892b0e7a 532 public static String[] getGuid(List<PackageIdentification> packages, String name) {\r
a29c47e0 533 if (packages == null) {\r
534 // throw Exception or not????\r
535 return new String[0];\r
536 }\r
537 String[] result = null;\r
136adffc 538 Iterator item = packages.iterator();\r
539 while (item.hasNext()){\r
540 Spd spd = spdTable.get(item.next());\r
a29c47e0 541 //\r
542 // If find one package defined the GUID\r
543 //\r
544 if ((result = spd.getGuid(name)) != null) {\r
545 return result;\r
878ddf1f 546 }\r
547 }\r
136adffc 548\r
a29c47e0 549 return null;\r
878ddf1f 550 }\r
551\r
552 /**\r
a29c47e0 553 * return two values: {cName, GuidValue}\r
878ddf1f 554 */\r
136adffc 555 public static String[] getPpiGuid(List<PackageIdentification> packages,\r
892b0e7a 556 String name) {\r
a29c47e0 557 if (packages == null) {\r
558 return new String[0];\r
559 }\r
560 String[] result = null;\r
136adffc 561 Iterator item = packages.iterator();\r
562 while (item.hasNext()){\r
563 Spd spd = spdTable.get(item.next());\r
a29c47e0 564 //\r
565 // If find one package defined the Ppi GUID\r
566 //\r
567 if ((result = spd.getPpi(name)) != null) {\r
568 return result;\r
878ddf1f 569 }\r
570 }\r
a29c47e0 571 return null;\r
878ddf1f 572 }\r
573\r
a29c47e0 574 /**\r
575 * return two values: {cName, GuidValue}\r
576 */\r
136adffc 577 public static String[] getProtocolGuid(List<PackageIdentification> packages,\r
892b0e7a 578 String name) {\r
a29c47e0 579 if (packages == null) {\r
580 return new String[0];\r
581 }\r
582 String[] result = null;\r
136adffc 583 Iterator item = packages.iterator();\r
584 while (item.hasNext()){\r
585 Spd spd = spdTable.get(item.next());\r
a29c47e0 586 //\r
587 // If find one package defined the protocol GUID\r
588 //\r
136adffc 589 if ((result = spd.getProtocol(name))!= null){\r
a29c47e0 590 return result;\r
591 }\r
592 }\r
593 return null;\r
878ddf1f 594\r
a29c47e0 595 }\r
ff225cbb 596\r
892b0e7a 597 public synchronized static PlatformIdentification getPlatformByName(String name) throws EdkException {\r
a29c47e0 598 Iterator iter = platformList.iterator();\r
599 while(iter.hasNext()){\r
600 PlatformIdentification platformId = (PlatformIdentification)iter.next();\r
601 if (platformId.getName().equalsIgnoreCase(name)) {\r
a29c47e0 602 return platformId;\r
878ddf1f 603 }\r
a29c47e0 604 }\r
892b0e7a 605 throw new EdkException("Can't find platform [" + name + "] in the current WORKSPACE database!");\r
de4bb9f6 606 }\r
ff225cbb 607\r
892b0e7a 608 public synchronized static PlatformIdentification getPlatform(String filename) throws EdkException {\r
de4bb9f6 609 File file = new File(workspaceDir + File.separatorChar + filename);\r
610 Iterator iter = platformList.iterator();\r
611 while(iter.hasNext()){\r
612 PlatformIdentification platformId = (PlatformIdentification)iter.next();\r
613 if (platformId.getFpdFile().getPath().equalsIgnoreCase(file.getPath())) {\r
614 return platformId;\r
615 }\r
616 }\r
892b0e7a 617 throw new EdkException("Can't find platform file [" + filename + "] in the current WORKSPACE database!");\r
a29c47e0 618 }\r
ff225cbb 619\r
892b0e7a 620 public synchronized static PackageIdentification refreshPackageIdentification(PackageIdentification packageId) throws EdkException {\r
a29c47e0 621 Iterator iter = packageList.iterator();\r
622 while(iter.hasNext()){\r
623 PackageIdentification packageItem = (PackageIdentification)iter.next();\r
624 if (packageItem.equals(packageId)) {\r
625 packageId.setName(packageItem.getName());\r
626 packageId.setSpdFile(packageItem.getSpdFile());\r
627 return packageId;\r
878ddf1f 628 }\r
629 }\r
892b0e7a 630 throw new EdkException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!");\r
a29c47e0 631 }\r
ff225cbb 632\r
892b0e7a 633 public synchronized static ModuleIdentification refreshModuleIdentification(ModuleIdentification moduleId) throws EdkException {\r
a29c47e0 634 PackageIdentification packageId = getPackageForModule(moduleId);\r
a29c47e0 635 moduleId.setPackage(packageId);\r
636 Spd spd = spdTable.get(packageId);\r
637 if (spd == null) {\r
892b0e7a 638 throw new EdkException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!");\r
a29c47e0 639 }\r
640 Set<ModuleIdentification> modules = spd.getModules();\r
641 Iterator<ModuleIdentification> iter = modules.iterator();\r
642 while (iter.hasNext()) {\r
643 ModuleIdentification item = iter.next();\r
644 if (item.equals(moduleId)) {\r
645 moduleId.setName(item.getName());\r
646 moduleId.setModuleType(item.getModuleType());\r
647 moduleId.setMsaFile(item.getMsaFile());\r
648 return moduleId;\r
649 }\r
650 }\r
892b0e7a 651 throw new EdkException("Can't find module GUID value " + moduleId.toGuidString() + " in " + packageId + " under the current workspace!");\r
a29c47e0 652 }\r
ff225cbb 653\r
a29c47e0 654 public synchronized static Set<PackageIdentification> getPackageList(){\r
655 return packageList;\r
656 }\r
82516887 657\r
658 /**\r
659 BUGBUG: It is a walk around method. If do not clone, can't query info with\r
660 XPath correctly. \r
661 \r
662 @param object XmlObject\r
663 @param deep flag for deep clone\r
664 @return XmlObject after clone\r
665 @throws BuildException parse original XmlObject error. \r
666 **/\r
892b0e7a 667 private static XmlObject cloneXmlObject(XmlObject object, boolean deep) throws EdkException {\r
a29c47e0 668 if ( object == null) {\r
669 return null;\r
670 }\r
671 XmlObject result = null;\r
672 try {\r
673 result = XmlObject.Factory.parse(object.getDomNode()\r
674 .cloneNode(deep));\r
892b0e7a 675 } catch (XmlException ex) {\r
676 EdkException edkException = new EdkException(ex.getMessage());\r
677 edkException.setStackTrace(ex.getStackTrace());\r
678 throw edkException;\r
a29c47e0 679 }\r
680 return result;\r
878ddf1f 681 }\r
682\r
4b5f5549 683 ///\r
684 /// Tool Chain Related, try to refine and put some logic process to ToolChainFactory\r
685 ///\r
05b52e96 686 public synchronized static ToolChainInfo getToolChainInfo() {\r
a29c47e0 687 if (toolChainInfo == null) {\r
688 toolChainInfo = toolsDef.getConfigInfo().intersection(toolChainEnvInfo);\r
689 if (toolChainPlatformInfo != null) {\r
690 toolChainInfo = toolChainInfo.intersection(toolChainPlatformInfo);\r
878ddf1f 691 }\r
a29c47e0 692 toolChainInfo.addCommands(toolsDef.getConfigInfo().getCommands());\r
693 toolChainInfo.normalize();\r
2b0fe8b4 694\r
2eb7d78d 695 EdkLog.log("Init", EdkLog.EDK_ALWAYS, "Current build tool chain information summary: ");\r
696 EdkLog.log("Init", EdkLog.EDK_ALWAYS, toolChainInfo + "");\r
878ddf1f 697 }\r
a29c47e0 698 return toolChainInfo;\r
699 }\r
700\r
a29c47e0 701 public static void setPlatformToolChainFamilyOption(ToolChainMap map) {\r
702 platformToolChainFamilyOption = map;\r
878ddf1f 703 }\r
704\r
a29c47e0 705 public static void setPlatformToolChainOption(ToolChainMap map) {\r
706 platformToolChainOption = map;\r
707 }\r
878ddf1f 708\r
a29c47e0 709 public static void addModuleToolChainOption(FpdModuleIdentification fpdModuleId,\r
710 ToolChainMap toolChainOption) {\r
711 moduleToolChainOption.put(fpdModuleId, toolChainOption);\r
878ddf1f 712 }\r
713\r
a29c47e0 714 public static void addModuleToolChainFamilyOption(FpdModuleIdentification fpdModuleId,\r
715 ToolChainMap toolChainOption) {\r
716 moduleToolChainFamilyOption.put(fpdModuleId, toolChainOption);\r
878ddf1f 717 }\r
b69bb9ba 718 \r
719 public static void addMsaBuildOption(ModuleIdentification moduleId,\r
720 ToolChainMap toolChainOption) {\r
721 msaBuildOption.put(moduleId, toolChainOption);\r
722 }\r
723 \r
724 public static void addMsaFamilyBuildOption(ModuleIdentification moduleId,\r
725 ToolChainMap toolChainOption) {\r
726 msaFamilyBuildOption.put(moduleId, toolChainOption);\r
727 }\r
728 \r
2b0fe8b4 729 public static boolean isCommandSet(String target, String toolchain, String arch) throws EdkException {\r
c773bec0 730 String[] commands = getToolChainInfo().getCommands();\r
731\r
732 for (int i = 0; i < commands.length; ++i) {\r
b0a80562 733 String cmdName = toolsDef.getConfig().get(new String[] {target, toolchain, arch, commands[i], ToolDefinitions.TOOLS_DEF_ATTRIBUTE_NAME});\r
a10c0400 734 if (cmdName != null && cmdName.length() != 0) {\r
c773bec0 735 return true;\r
736 }\r
737 }\r
738\r
739 return false;\r
740 }\r
741\r
b69bb9ba 742 /**\r
743 Except FLAGS, all attribute are from TOOLS_DEF file. \r
744 \r
745 For FLAGS, information from four places, they are: \r
746 <pre>\r
747 1. tools_def.txt\r
748 2. MSA &lt;BuildOptions&gt;/&lt;Options&gt;\r
749 3. FPD &lt;BuildOptions&gt;/&lt;Options&gt;\r
750 4. FPD &lt;FrameworkModules&gt;/&lt;ModuleSaBuildOptions&gt;/&lt;Options&gt;\r
751 </pre>\r
752 \r
753 @param commandDescription Key: TARGET, TAGNAME, ARCH, COMMANDTYPE, ATTRIBUTE\r
754 @param fpdModuleId Module Identification with Arch\r
755 @return The corresponding String\r
756 @throws EdkException If build option definition error\r
757 **/\r
2f2c367a 758 public synchronized static String getCommandSetting(String[] commandDescription, FpdModuleIdentification fpdModuleId) throws EdkException {\r
a29c47e0 759 ToolChainKey toolChainKey = new ToolChainKey(commandDescription);\r
ff225cbb 760 ToolChainMap toolChainConfig = toolsDef.getConfig();\r
a29c47e0 761 String setting = null;\r
762\r
8c84e1b1 763 //\r
764 // Default in tools_def.txt\r
765 // \r
0923e8b3 766 setting = toolChainConfig.get(toolChainKey);\r
767 if (setting == null) {\r
8c84e1b1 768 setting = "";\r
0923e8b3 769 }\r
b0a80562 770 if (!commandDescription[ToolChainElement.ATTRIBUTE.value].equals(ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS)) {\r
a29c47e0 771 return setting;\r
878ddf1f 772 }\r
878ddf1f 773\r
92cfaeee 774 Set<String> flagSet = new LinkedHashSet<String>();\r
775 flagSet.add(setting);\r
776 \r
a29c47e0 777 //\r
b69bb9ba 778 // Tool's option can be in .fpd and/or .msa file\r
8c84e1b1 779 //\r
780 String optionString;\r
781 ToolChainMap option = null;\r
782 ToolChainKey toolChainFamilyKey = new ToolChainKey(commandDescription);\r
0923e8b3 783\r
b0a80562 784 toolChainFamilyKey.setKey(ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FAMILY, ToolChainElement.ATTRIBUTE.value);\r
8c84e1b1 785 String family = toolChainConfig.get(toolChainFamilyKey);\r
786 toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);\r
b0a80562 787 toolChainFamilyKey.setKey(ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS, ToolChainElement.ATTRIBUTE.value);\r
0923e8b3 788\r
b69bb9ba 789 //\r
790 // MSA's tool chain family option\r
791 //\r
792 option = msaFamilyBuildOption.get(fpdModuleId.getModule());\r
793 if (option != null && (optionString = option.get(toolChainFamilyKey)) != null) {\r
92cfaeee 794 flagSet.add(optionString);\r
b69bb9ba 795 }\r
796 \r
797 //\r
798 // MSA's tool chain option\r
799 //\r
800 option = msaBuildOption.get(fpdModuleId.getModule());\r
801 if (option != null && (optionString = option.get(toolChainKey)) != null) {\r
92cfaeee 802 flagSet.add(optionString);\r
b69bb9ba 803 }\r
804 \r
0923e8b3 805 //\r
8c84e1b1 806 // Platform's tool chain family option\r
0923e8b3 807 //\r
8c84e1b1 808 optionString = platformToolChainFamilyOption.get(toolChainFamilyKey);\r
809 if (optionString != null) {\r
92cfaeee 810 flagSet.add(optionString);\r
878ddf1f 811 }\r
878ddf1f 812\r
a29c47e0 813 //\r
8c84e1b1 814 // Platform's tool chain tag option\r
a29c47e0 815 //\r
8c84e1b1 816 optionString = platformToolChainOption.get(toolChainKey);\r
817 if (optionString != null) {\r
92cfaeee 818 flagSet.add(optionString);\r
8c84e1b1 819 }\r
a29c47e0 820\r
8c84e1b1 821 //\r
822 // Module's tool chain family option\r
823 //\r
824 option = moduleToolChainFamilyOption.get(fpdModuleId);\r
825 if (option != null && (optionString = option.get(toolChainFamilyKey)) != null) {\r
92cfaeee 826 flagSet.add(optionString);\r
a29c47e0 827 }\r
828\r
8c84e1b1 829 //\r
830 // Module's tool chain tag option\r
831 //\r
832 option = moduleToolChainOption.get(fpdModuleId);\r
833 if (option != null && (optionString = option.get(toolChainKey)) != null) {\r
92cfaeee 834 flagSet.add(optionString);\r
835 }\r
836 \r
837 setting = "";\r
838 for(Iterator<String> iter = flagSet.iterator(); iter.hasNext();) {\r
839 setting += iter.next() +" ";\r
a29c47e0 840 }\r
a29c47e0 841 return setting;\r
842 }\r
ff225cbb 843\r
a29c47e0 844 public static void setToolChainEnvInfo(ToolChainInfo envInfo) {\r
845 toolChainEnvInfo = envInfo;\r
846 }\r
847 public static void setToolChainPlatformInfo(ToolChainInfo platformInfo) {\r
848 toolChainPlatformInfo = platformInfo;\r
878ddf1f 849 }\r
a29c47e0 850\r
851 //\r
852 // for PCD\r
853 //\r
136adffc 854 public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {\r
855 return pcdDbManager;\r
856 }\r
a29c47e0 857\r
858 //\r
136adffc 859 // For PCD get tokenSpaceGUid\r
a29c47e0 860 //\r
20c5c53f 861 public synchronized static String getGuidInfoFromCname(String cName){\r
862 String cNameGuid = null;\r
136adffc 863 String guid = null;\r
864 Set set = spdTable.keySet();\r
865 Iterator iter = set.iterator();\r
548ce97a 866\r
867 if (iter == null) {\r
868 return null;\r
869 }\r
870\r
136adffc 871 while (iter.hasNext()){\r
872 Spd spd = (Spd) spdTable.get(iter.next());\r
873 guid = spd.getGuidFromCname(cName);\r
874 if (guid != null){\r
20c5c53f 875 cNameGuid = guid;\r
136adffc 876 break;\r
877 }\r
878 }\r
879 return cNameGuid;\r
880 }\r
a29c47e0 881\r
882 //\r
883 // For PCD\r
884 //\r
ff225cbb 885 public synchronized static Map<FpdModuleIdentification, XmlObject>\r
eece174a 886 getFpdModuleSaXmlObject(String xmlObjectName) {\r
136adffc 887 Set<FpdModuleIdentification> fpdModuleSASet = fpdModuleSA.keySet();\r
888 Iterator item = fpdModuleSASet.iterator();\r
ff225cbb 889\r
136adffc 890\r
891 Map<FpdModuleIdentification, XmlObject> SAPcdBuildDef = new HashMap<FpdModuleIdentification, XmlObject>();\r
892 Map<String, XmlObject> SANode = new HashMap<String, XmlObject>();\r
893 FpdModuleIdentification moduleId;\r
894 while (item.hasNext()) {\r
ff225cbb 895\r
136adffc 896 moduleId = (FpdModuleIdentification) item.next();\r
897 SANode = fpdModuleSA.get(moduleId);\r
898 try{\r
899 if (SANode.get(xmlObjectName)!= null){\r
900 SAPcdBuildDef.put(moduleId,\r
eece174a 901 (XmlObject) SANode.get(xmlObjectName));\r
136adffc 902\r
903 }\r
136adffc 904 } catch (Exception e){\r
905 EdkLog.log(EdkLog.EDK_INFO, e.getMessage());\r
906 }\r
eece174a 907 }\r
136adffc 908 return SAPcdBuildDef;\r
909 }\r
eece174a 910\r
911 public synchronized static Map<FpdModuleIdentification,XmlObject> getFpdPcdBuildDefinitions() {\r
912 Map<FpdModuleIdentification,XmlObject> pcdBuildDef = getFpdModuleSaXmlObject ("PcdBuildDefinition");\r
913\r
914 return pcdBuildDef;\r
915 }\r
fe6d0f74 916\r
917 public static XmlObject parseXmlFile(File xmlFile) throws IOException, XmlException {\r
918 Collection errors = new ArrayList(); \r
919 XmlOptions opt = new XmlOptions();\r
920\r
921 opt.setLoadLineNumbers();\r
922 opt.setLoadMessageDigest();\r
923 opt.setErrorListener(errors);\r
924\r
925 XmlObject doc = XmlObject.Factory.parse(xmlFile, opt);\r
926 //\r
927 // Validate File if they accord with XML Schema\r
928 //\r
929 if (!doc.validate(opt)){\r
930 StringBuilder errorMessage = new StringBuilder(1024);\r
931 for (Iterator it = errors.iterator(); it.hasNext(); ) {\r
932 errorMessage.append(it.next());\r
933 errorMessage.append("\n");\r
934 }\r
935 throw new XmlException(errorMessage.toString());\r
936 }\r
937\r
938 return doc;\r
939 }\r
878ddf1f 940}\r
a29c47e0 941\r