X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=Tools%2FSource%2FGenBuild%2Forg%2Ftianocore%2Fbuild%2Fglobal%2FGlobalData.java;h=ceb19d91db7d78c9400a26f819255e43feec0f1b;hp=e457d6dbe97598daa78ec276d0511585bce34805;hb=0923e8b3b22a10416d9c8e0a192f0e88758a1b90;hpb=61746a87be58d12489f9c82e2e6e2fd5837626fc diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java b/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java index e457d6dbe9..ceb19d91db 100644 --- a/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java +++ b/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java @@ -1,10 +1,10 @@ /** @file - GlobalData class. - + GlobalData class. + GlobalData provide initializing, instoring, querying and update global data. It is a bridge to intercommunicate between multiple component, such as AutoGen, - PCD and so on. - + PCD and so on. + Copyright (c) 2006, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -17,621 +17,942 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. package org.tianocore.build.global; import java.io.File; +import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; -import org.apache.tools.ant.BuildException; +import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; + +import org.tianocore.common.exception.EdkException; +import org.tianocore.common.logger.EdkLog; +import org.tianocore.pcd.entity.MemoryDatabaseManager; +import org.tianocore.DbPathAndFilename; import org.tianocore.FrameworkDatabaseDocument; -import org.tianocore.MsaFilesDocument; -import org.tianocore.PackageListDocument; -import org.tianocore.PackageSurfaceAreaDocument; -import org.tianocore.MsaHeaderDocument.MsaHeader; -import org.tianocore.MsaLibHeaderDocument.MsaLibHeader; -import org.tianocore.build.pcd.entity.MemoryDatabaseManager; -import org.tianocore.build.autogen.CommonDefinition; -import org.tianocore.build.fpd.FpdParserTask; +import org.tianocore.ModuleSurfaceAreaDocument; +import org.tianocore.ModuleSurfaceAreaDocument.ModuleSurfaceArea; +import org.tianocore.build.id.FpdModuleIdentification; +import org.tianocore.build.id.ModuleIdentification; +import org.tianocore.build.id.PackageIdentification; +import org.tianocore.build.id.PlatformIdentification; +import org.tianocore.build.toolchain.ToolChainAttribute; +import org.tianocore.build.toolchain.ToolChainConfig; +import org.tianocore.build.toolchain.ToolChainElement; +import org.tianocore.build.toolchain.ToolChainInfo; +import org.tianocore.build.toolchain.ToolChainKey; +import org.tianocore.build.toolchain.ToolChainMap; /** GlobalData provide initializing, instoring, querying and update global data. It is a bridge to intercommunicate between multiple component, such as AutoGen, - PCD and so on. - -

Note that all global information are initialized incrementally. All data will - parse and record only it is necessary during build time.

- + PCD and so on. + +

Note that all global information are initialized incrementally. All data will + parse and record only of necessary during build time.

+ @since GenBuild 1.0 **/ public class GlobalData { - /// - /// means no surface area information for module - /// - public static final int NO_SA = 0; - - /// - /// means only MSA + /// Record current WORKSPACE Directory /// - public static final int ONLY_MSA = 1; + private static String workspaceDir = ""; /// - /// means only Library MSA + /// Be used to ensure Global data will be initialized only once. /// - public static final int ONLY_LIBMSA = 2; + private static boolean globalFlag = false; /// - /// means both MSA and MBD + /// Framework Database information: package list and platform list /// - public static final int MSA_AND_MBD = 3; + private static Set packageList = new HashSet(); - /// - /// means both Library MSA and Library MBD - /// - public static final int LIBMSA_AND_LIBMBD = 4; + private static Set platformList = new HashSet(); /// - /// Be used to ensure Global data will be initialized only once. + /// Every detail SPD informations: Module list, Library class definition, + /// Package header file, GUID/PPI/Protocol definitions /// - public static boolean globalFlag = false; + private static final Map spdTable = new HashMap(); /// - /// Record current WORKSPACE Directory + /// Build informations are divided into three parts: + /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA /// - private static String workspaceDir = ""; + private static Map> nativeMsa = new HashMap>(); - /// - /// Two columns: Package Name (Key), Package Path(ralative to WORKSPACE) - /// - private static final Map packageInfo = new HashMap(); + private static Map> fpdModuleSA= new HashMap>(); - /// - /// spdTable - /// Key: Package Name, Value: SPD detail info - /// - private static final Map spdTable = new HashMap(); + private static Map fpdBuildOptionsMap = new HashMap(); + + private static XmlObject fpdBuildOptions; - /// - /// Three columns: - /// 1. Module Name | BaseName (Key) - /// 2. Module Path + Msa file name (relative to Package) - /// 3. Package Name (This module belong to which package) - /// - private static final Map moduleInfo = new HashMap(); + private static XmlObject fpdDynamicPcds; /// - /// List all libraries for current build module - /// Key: Library BaseName, Value: output library path+name + /// Parsed modules list /// - private static final Map libraries = new HashMap(); + private static Map> parsedModules = new HashMap>(); /// - /// Store every module's relative library instances BaseName - /// Key: Module BaseName, Value: All library instances module depends on. + /// built modules list with ARCH, TARGET, TOOLCHAIN /// - private static final Map > moduleLibraryMap = new HashMap >(); + private static Set builtModules = new HashSet(); /// - /// Key: Module BaseName, Value: original MSA info + /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD. /// - private static final Map > nativeMsa = new HashMap >(); + private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager(); /// - /// Key: Module BaseName, Value: original MBD info + /// build target + tool chain family/tag name + arch + command types + command options /// - private static final Map > nativeMbd = new HashMap >(); - /// - /// Two columns: Module Name or Base Name as Key - /// Value is a HashMap with overridden data from MSA/MBD or/and Platform + /// Tool Chain Data + /// toolsDef - build tool program information + /// fpdBuildOption - all modules's build options for tool tag or tool chain families + /// moduleSaBuildOption - build options for a specific module /// - private static final Map > parsedModules = new HashMap >(); + private static ToolChainConfig toolsDef; - /// - /// List all built Module; Value is Module BaseName + Arch. TBD - /// - private static final Set builtModules = new HashSet(); + private static ToolChainInfo toolChainInfo; + private static ToolChainInfo toolChainEnvInfo; + private static ToolChainInfo toolChainPlatformInfo; - /// - /// Library instance information table which recored the library and it's - /// constructor and distructor function - /// - private static final Map libInstanceInfo = new HashMap(); + private static ToolChainMap platformToolChainOption; + private static ToolChainMap platformToolChainFamilyOption; - /// - /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD. - /// - private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager(); + private static Map moduleToolChainOption = new HashMap(); + private static Map moduleToolChainFamilyOption = new HashMap(); /** - Query the module's absolute path with module base name. - - @param moduleName the base name of the module - @return the absolute module path - **/ - public synchronized static String getModulePath(String moduleName) { - String[] info = moduleInfo.get(moduleName); - String packagePath = (String) packageInfo.get(info[1]); - File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]); - return convertFile.getParent(); - } + Parse framework database (DB) and all SPD files listed in DB to initialize + the environment for next build. This method will only be executed only once + in the whole build process. - /** - Query the module's absolute MSA file path with module base name. - - @param moduleName the base name of the module - @return the absolute MSA file name + @param workspaceDatabaseFile the file name of framework database + @param workspaceDir current workspace directory path @throws BuildException - Base name is not registered in any SPD files + Framework Dababase or SPD or MSA file is not valid **/ - private synchronized static String getMsaFilename(String moduleName) throws BuildException { - String[] info = moduleInfo.get(moduleName); - if (info == null) { - throw new BuildException("Module base name [" + moduleName + "] can't found in all SPD."); + public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir, String toolsDefFilename ) throws EdkException { + // + // ensure this method will be revoked only once + // + if (globalFlag) { + return; } - String packagePath = (String) packageInfo.get(info[1]); - File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]); - return convertFile.getPath(); - } + globalFlag = true; - /** - Query the module's absolute MBD file path with module base name. - - @param moduleName the base name of the module - @return the absolute MBD file name - @throws BuildException - Base name is not registered in any SPD files - **/ - private synchronized static String getMbdFilename(String moduleName) throws BuildException { - String[] info = moduleInfo.get(moduleName); - if (info == null) { - throw new BuildException("Info: Module base name [" + moduleName + "] can't found in all SPD."); + // + // Backup workspace directory. It will be used by other method + // + GlobalData.workspaceDir = workspaceDir.replaceAll("(\\\\)", "/"); + + // + // Parse tools definition file + // + // + // If ToolChain has been set up before, do nothing. + // CONF dir + tools definition file name + // + File toolsDefFile = new File(workspaceDir + File.separatorChar + toolsDefFilename); + EdkLog.log("Init", EdkLog.EDK_ALWAYS, "Using tool definition file [" + toolsDefFile.getPath() + "]."); + toolsDef = new ToolChainConfig(toolsDefFile); + + // + // Parse Framework Database + // + File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile); + try { + FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile); + // + // validate FrameworkDatabaseFile + // + if (!db.validate()) { + throw new EdkException("Framework Database file [" + dbFile.getPath() + "] format is invalid!"); + } + // + // Get package list + // + if (db.getFrameworkDatabase().getPackageList() != null ) { + List packages = db.getFrameworkDatabase().getPackageList().getFilenameList(); + Iterator iter = packages.iterator(); + while (iter.hasNext()) { + String fileName = iter.next().getStringValue().trim(); + Spd spd = new Spd(new File(workspaceDir + File.separatorChar + fileName)); + packageList.add(spd.getPackageId()); + // + // Report warning if existing two packages with same GUID and Version + // + if (spdTable.containsKey(spd.getPackageId())) { + // + // BUGBUG + // + EdkLog.log("Init", EdkLog.EDK_WARNING, "Warning: Existing two packages with same GUID and Version. They are ... " + spd.getPackageId().getSpdFile().getPath()); + } + spdTable.put(spd.getPackageId(), spd); + } + } + + // + // Get platform list + // + if (db.getFrameworkDatabase().getPlatformList() != null) { + List platforms = db.getFrameworkDatabase().getPlatformList().getFilenameList(); + Iterator iter = platforms.iterator(); + while (iter.hasNext()) { + String fileName = iter.next().getStringValue().trim(); + File fpdFile = new File(workspaceDir + File.separatorChar + fileName); + if ( !fpdFile.exists() ) { + throw new EdkException("Platform file [" + fpdFile.getPath() + "] not exists. "); + } + XmlObject fpdDoc = XmlObject.Factory.parse(fpdFile); + // + // Verify FPD file, if is invalid, throw Exception + // + if (!fpdDoc.validate()) { + throw new EdkException("Framework Platform Surface Area file [" + fpdFile.getPath() + "] format is invalid!"); + } + // + // We can change Map to XmlObject + // + Map fpdDocMap = new HashMap(); + fpdDocMap.put("PlatformSurfaceArea", fpdDoc); + SurfaceAreaQuery saq = new SurfaceAreaQuery(fpdDocMap); + PlatformIdentification platformId = saq.getFpdHeader(); + platformId.setFpdFile(fpdFile); + // + // Report warning if existing two platfrom with same GUID and Version + // + if (platformList.contains(platformId)) { + // + // BUGBUG + // + EdkLog.log("Init", EdkLog.EDK_WARNING, "Warning: Existing two platforms with same GUID and Version. They are ... " + fpdFile.getPath()); + } + platformList.add(platformId); + } + } + } catch(IOException ex) { + EdkException edkException = new EdkException("Parse WORKSPACE Database file [" + dbFile.getPath() + "] Error.\n" + ex.getMessage()); + edkException.setStackTrace(ex.getStackTrace()); + throw edkException; + } catch(XmlException ex) { + EdkException edkException = new EdkException("Parse WORKSPACE Database file [" + dbFile.getPath() + "] Error.\n" + ex.getMessage()); + edkException.setStackTrace(ex.getStackTrace()); + throw edkException; } - String packagePath = (String) packageInfo.get(info[1]); - File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]); - return convertFile.getPath().substring(0, convertFile.getPath().length() - 4) + ".mbd"; } /** - Get the current WORKSPACE Directory. + Get the current WORKSPACE Directory. + @return current workspace directory **/ public synchronized static String getWorkspacePath() { return workspaceDir; } + /** - Query package relative path to WORKSPACE_DIR with package name. - - @param packageName the name of the package - @return the path relative to WORKSPACE_DIR - **/ - public synchronized static String getPackagePath(String packageName) { - return (String) packageInfo.get(packageName); + Get the MSA file name with absolute path + */ + public synchronized static File getMsaFile(ModuleIdentification moduleId) throws EdkException { + File msaFile = null; + // + // TBD. Do only when package is null. + // + Iterator iter = packageList.iterator(); + while (iter.hasNext()) { + PackageIdentification packageId = (PackageIdentification)iter.next(); + Spd spd = spdTable.get(packageId); + msaFile = spd.getModuleFile(moduleId); + if (msaFile != null ) { + break ; + } + } + if (msaFile == null){ + throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!"); + } else { + return msaFile; + } } - /** - Query package (which the module belongs to) relative path to WORSPACE_DIR. - - @param moduleName the base name of the module - @return the relative path to WORKSPACE_DIR of the package which the module belongs to - **/ - public synchronized static String getPackagePathForModule(String moduleName) { - String[] info = moduleInfo.get(moduleName); - String packagePath = (String) packageInfo.get(info[1]); - return packagePath; + public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) throws EdkException { + // + // If package already defined in module + // + if (moduleId.getPackage() != null) { + return moduleId.getPackage(); + } + + PackageIdentification packageId = null; + Iterator iter = packageList.iterator(); + while (iter.hasNext()) { + packageId = (PackageIdentification)iter.next(); + moduleId.setPackage(packageId); + Spd spd = spdTable.get(packageId); + File tempMsaFile = null; + if ((tempMsaFile = spd.getModuleFile(moduleId)) != null ) { + if (tempMsaFile.getParent().equalsIgnoreCase(moduleId.getMsaFile().getParent())) { + break ; + } + tempMsaFile = null; + } + } + if (packageId == null){ + throw new EdkException("Can't find Module [" + moduleId.getName() + "] in any SPD package!"); + } else { + return packageId; + } } /** - Query the package name which the module belongs to with the module's base name. - - @param moduleName the base name of the module - @return the package name which the module belongs to + Difference between build and parse: ToolChain and Target **/ - public synchronized static String getPackageNameForModule(String moduleName) { - return moduleInfo.get(moduleName)[1]; + public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) { + return builtModules.contains(moduleId); + } + + public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) { + builtModules.add(fpdModuleId); + } + + + public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map doc) throws EdkException{ + Map result = new HashMap(); + Set keySet = doc.keySet(); + Iterator iter = keySet.iterator(); + while (iter.hasNext()){ + String key = (String)iter.next(); + XmlObject item = cloneXmlObject(doc.get(key), true); + result.put(key, item); + } + fpdModuleSA.put(fpdModuleId, result); + } + + public synchronized static boolean hasFpdModuleSA(FpdModuleIdentification fpdModuleId) { + return fpdModuleSA.containsKey(fpdModuleId); } /** - Parse framework database (DB) and all SPD files listed in DB to initialize - the environment for next build. This method will only be executed only once - in the whole build process. - - @param workspaceDatabaseFile the file name of framework database - @param workspaceDir current workspace directory path - @throws BuildException - Framework Dababase or SPD or MSA file is not valid + Query module surface area information. + +

Note that surface area parsing is incremental. That means the method will + only parse the MSA files if necessary.

+ + @param fpdModuleId Module ID with arch + @return ModuleSA info and MSA info for fpdModuleId + @throws BuildException Can't find MSA **/ - public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir) throws BuildException { - if (globalFlag) { - return; + public synchronized static Map getDoc(FpdModuleIdentification fpdModuleId) throws EdkException{ + if (parsedModules.containsKey(fpdModuleId)) { + return parsedModules.get(fpdModuleId); } - globalFlag = true; - GlobalData.workspaceDir = workspaceDir; - File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile); - try { - FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile); - List packages = db.getFrameworkDatabase().getPackageList() - .getPackageList(); - Iterator iter = packages.iterator(); - while (iter.hasNext()) { - PackageListDocument.PackageList.Package packageItem = (PackageListDocument.PackageList.Package) iter - .next(); - String name = packageItem.getPackageNameArray(0).getStringValue(); - String path = packageItem.getPathArray(0).getStringValue(); - packageInfo.put(name, path); - File spdFile = new File(workspaceDir + File.separatorChar + path + File.separatorChar + name + ".spd"); - initPackageInfo(spdFile.getPath(), name); - // - // SPD Parse. - // - PackageSurfaceAreaDocument spdDoc = (PackageSurfaceAreaDocument) XmlObject.Factory.parse(spdFile); - Spd spd = new Spd(spdDoc, path); - spdTable.put(name, spd); + Map doc = new HashMap(); + ModuleIdentification moduleId = fpdModuleId.getModule(); + // + // First part: get the MSA files info + // + doc.putAll(getNativeMsa(moduleId)); - } - } catch (Exception e) { - throw new BuildException("Parse workspace Database [" + dbFile.getPath() + "] Error.\n" + e.getMessage()); + // + // Second part: put build options + // + doc.put("BuildOptions", fpdBuildOptions); + + // + // Third part: get Module info from FPD, such as Library instances, PCDs + // + if (fpdModuleSA.containsKey(fpdModuleId)){ + // + // merge module info in FPD to final Doc + // For Library Module, do nothing here + // + doc.putAll(fpdModuleSA.get(fpdModuleId)); } + parsedModules.put(fpdModuleId, doc); + return doc; } + public synchronized static Map getDoc(ModuleIdentification moduleId, String arch) throws EdkException{ + FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch); + return getDoc(fpdModuleId); + } + /** - Parse every MSA files, get base name from MSA Header. And record those - values to ModuleInfo. - - @param packageFilename the file name of the package - @param packageName the name of the package + Query the native MSA information with module base name. + +

Note that MSA parsing is incremental. That means the method will + only to parse the MSA files when never parsed before.

+ + @param moduleName the base name of the module + @return the native MSA information @throws BuildException - SPD or MSA file is not valid + MSA file is not valid **/ - private synchronized static void initPackageInfo(String packageFilename, String packageName) throws BuildException { - File packageFile = new File(packageFilename); + public synchronized static Map getNativeMsa(ModuleIdentification moduleId) throws EdkException { + if (nativeMsa.containsKey(moduleId)) { + return nativeMsa.get(moduleId); + } + File msaFile = getMsaFile(moduleId); + Map msaMap = getNativeMsa(msaFile); + nativeMsa.put(moduleId, msaMap); + return msaMap; + } + + public synchronized static Map getNativeMsa(File msaFile) throws EdkException { + if (!msaFile.exists()) { + throw new EdkException("Module Surface Area file [" + msaFile.getPath() + "] can't be found!"); + } try { - PackageSurfaceAreaDocument spd = (PackageSurfaceAreaDocument) XmlObject.Factory.parse(packageFile); - List msasList = spd.getPackageSurfaceArea().getMsaFiles() - .getMsaFileList(); - Iterator msasIter = msasList.iterator(); - while (msasIter.hasNext()) { - MsaFilesDocument.MsaFiles.MsaFile msas = (MsaFilesDocument.MsaFiles.MsaFile) msasIter.next(); - String msaFilename = msas.getFilename().getStringValue(); - File msaFile = new File(workspaceDir + File.separatorChar + GlobalData.getPackagePath(packageName) - + File.separatorChar + msaFilename); - SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser(); - Map map = surfaceAreaParser.parseFile(msaFile); - String baseName = ""; - XmlObject header = null; - if ((header = map.get("MsaHeader")) != null) { - baseName = ((MsaHeader) header).getBaseName().getStringValue(); - } else if ((header = map.get("MsaLibHeader")) != null) { - baseName = ((MsaLibHeader) header).getBaseName().getStringValue(); - } else { - continue; - } - nativeMsa.put(baseName, map); - String[] info = { msaFilename, packageName }; - moduleInfo.put(baseName, info); + ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)XmlObject.Factory.parse(msaFile); + // + // Validate File if they accord with XML Schema + // + if ( !doc.validate()){ + throw new EdkException("Module Surface Area file [" + msaFile.getPath() + "] format is invalid!"); } - } catch (Exception e) { - throw new BuildException("Parse package description file [" + packageFile.getPath() + "] Error.\n" - + e.getMessage()); + // + // parse MSA file + // + ModuleSurfaceArea msa= doc.getModuleSurfaceArea(); + Map msaMap = new HashMap(); + msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true)); + msaMap.put("ModuleDefinitions", cloneXmlObject(msa.getModuleDefinitions(), true)); + msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true)); + msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true)); + msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true)); + msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true)); + msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true)); + msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true)); + msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true)); + msaMap.put("PcdCoded", cloneXmlObject(msa.getPcdCoded(), true)); + return msaMap; + } catch(IOException ex) { + EdkException edkException = new EdkException("Parsing MSA file [" + msaFile.getPath() + "] error. \n" + ex.getMessage()); + edkException.setStackTrace(ex.getStackTrace()); + throw edkException; + } catch(XmlException ex) { + EdkException edkException = new EdkException("Parsing MSA file [" + msaFile.getPath() + "] error. \n" + ex.getMessage()); + edkException.setStackTrace(ex.getStackTrace()); + throw edkException; } } - /** - Query the libraries which the module depends on. - - @param moduleName the base name of the module - @return the libraries which the module depends on - **/ - public synchronized static String[] getModuleLibrary(String moduleName, String arch) { - Set set = moduleLibraryMap.get(moduleName + "-" + arch); - return set.toArray(new String[set.size()]); + public static Map getFpdBuildOptionsMap() { + return fpdBuildOptionsMap; } - /** - Register module's library list which it depends on for later use. - - @param moduleName the base name of the module - @param libraryList the libraries which the module depends on - **/ - public synchronized static void addModuleLibrary(String moduleName, String arch, Set libraryList) { - moduleLibraryMap.put(moduleName + "-" + arch, libraryList); + public static void setFpdBuildOptions(XmlObject fpdBuildOptions) throws EdkException { + GlobalData.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true); + fpdBuildOptionsMap.put("BuildOptions", GlobalData.fpdBuildOptions); } - /** - Query the library absolute file name with library name. - - @param library the base name of the library - @return the library absolute file name - **/ - public synchronized static String getLibrary(String library, String arch) { - return libraries.get(library + "-" + arch); + public static XmlObject getFpdDynamicPcds() { + return fpdDynamicPcds; } - /** - Register library absolute file name for later use. - - @param library the base name of the library - @param resultPath the library absolute file name - **/ - public synchronized static void addLibrary(String library, String arch, String resultPath) { - libraries.put(library + "-" + arch, resultPath); - } - - /** - Whether the module with ARCH has built in the previous build. - - @param moduleName the base name of the module - @param arch current build ARCH - @return true if the module has built in previous, otherwise return false - **/ - public synchronized static boolean isModuleBuilt(String moduleName, String arch) { - return builtModules.contains(moduleName + "-" + arch); + public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) { + GlobalData.fpdDynamicPcds = fpdDynamicPcds; } - /** - Register the module with ARCH has built. - - @param moduleName the base name of the module - @param arch current build ARCH - **/ - public synchronized static void registerBuiltModule(String moduleName, String arch) { - builtModules.add(moduleName + "-" + arch); + public static Set getModules(PackageIdentification packageId){ + Spd spd = spdTable.get(packageId); + if (spd == null ) { + Set dummy = new HashSet(); + return dummy; + } else { + return spd.getModules(); + } } /** - Whether the module's surface area has parsed in the previous build. - - @param moduleName the base name of the module - @return true if the module's surface area has parsed in previous, otherwise - return false - **/ - public synchronized static boolean isModuleParsed(String moduleName) { - return parsedModules.containsKey(moduleName); + * The header file path is relative to workspace dir + */ + public static String[] getLibraryClassHeaderFiles( + PackageIdentification[] packages, String name) throws EdkException{ + if (packages == null) { + // throw Exception or not???? + return new String[0]; + } + String[] result = null; + for (int i = 0; i < packages.length; i++) { + Spd spd = spdTable.get(packages[i]); + // + // If find one package defined the library class + // + if ((result = spd.getLibClassIncluder(name)) != null) { + return result; + } + } + // + // If can't find library class declaration in every package + // + throw new EdkException("Can not find library class [" + name + + "] declaration in any SPD package!"); } /** - Query overrided module surface area information. If current is Package - or Platform build, also include the information from FPD file. - -

Note that surface area parsing is incremental. That means the method will - only to parse the MSA and MBD files when never parsed before.

- - @param moduleName the base name of the module - @return the overrided module surface area information - @throws BuildException - MSA or MBD is not valid - **/ - public synchronized static Map getDoc(String moduleName) throws BuildException { - if (parsedModules.containsKey(moduleName)) { - return parsedModules.get(moduleName); - } - Map msaMap = getNativeMsa(moduleName); - Map mbdMap = getNativeMbd(moduleName); - OverrideProcess op = new OverrideProcess(); - Map map = op.override(mbdMap, msaMap); + * The header file path is relative to workspace dir + */ + public static String getPackageHeaderFiles(PackageIdentification packages, + String moduleType) { + if (packages == null) { + return new String(""); + } + Spd spd = spdTable.get(packages); // - // IF IT IS A PALTFORM BUILD, OVERRIDE FROM PLATFORM + // If can't find package header file, skip it // - if (FpdParserTask.platformBuildOptions != null) { - Map platformMap = new HashMap(); - platformMap.put("BuildOptions", FpdParserTask.platformBuildOptions); - Map overrideMap = op.override(platformMap, OverrideProcess.deal(map)); - GlobalData.registerModule(moduleName, overrideMap); - return overrideMap; + String temp = null; + if (spd != null) { + if ((temp = spd.getPackageIncluder(moduleType)) != null) { + return temp; + } else { + temp = ""; + return temp; + } } else { - parsedModules.put(moduleName, map); - return map; + return null; } } /** - Query the native MSA information with module base name. - -

Note that MSA parsing is incremental. That means the method will - only to parse the MSA files when never parsed before.

- - @param moduleName the base name of the module - @return the native MSA information - @throws BuildException - MSA file is not valid - **/ - public synchronized static Map getNativeMsa(String moduleName) throws BuildException { - if (nativeMsa.containsKey(moduleName)) { - return nativeMsa.get(moduleName); + * return two values: {cName, GuidValue} + */ + public static String[] getGuid(List packages, String name) { + if (packages == null) { + // throw Exception or not???? + return new String[0]; } - String msaFilename = getMsaFilename(moduleName); - File msaFile = new File(msaFilename); - if (!msaFile.exists()) { - throw new BuildException("Info: Surface Area file [" + msaFile.getPath() + "] can't found."); + String[] result = null; + Iterator item = packages.iterator(); + while (item.hasNext()){ + Spd spd = spdTable.get(item.next()); + // + // If find one package defined the GUID + // + if ((result = spd.getGuid(name)) != null) { + return result; + } } - SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser(); - Map map = surfaceAreaParser.parseFile(msaFile); - nativeMsa.put(moduleName, map); - return map; + + return null; } - + /** - Query the native MBD information with module base name. - -

Note that MBD parsing is incremental. That means the method will - only to parse the MBD files when never parsed before.

- - @param moduleName the base name of the module - @return the native MBD information - @throws BuildException - MBD file is not valid - **/ - public synchronized static Map getNativeMbd(String moduleName) throws BuildException { - if (nativeMbd.containsKey(moduleName)) { - return nativeMbd.get(moduleName); + * return two values: {cName, GuidValue} + */ + public static String[] getPpiGuid(List packages, + String name) { + if (packages == null) { + return new String[0]; } - String mbdFilename = getMbdFilename(moduleName); - File mbdFile = new File(mbdFilename); - if (!mbdFile.exists()) { - throw new BuildException("Info: Surface Area file [" + mbdFile.getPath() + "] can't found."); + String[] result = null; + Iterator item = packages.iterator(); + while (item.hasNext()){ + Spd spd = spdTable.get(item.next()); + // + // If find one package defined the Ppi GUID + // + if ((result = spd.getPpi(name)) != null) { + return result; + } } - SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser(); - Map map = surfaceAreaParser.parseFile(mbdFile); - nativeMbd.put(moduleName, map); - return map; + return null; } /** - Register module overrided surface area information. If has existed, then update. - - @param moduleName the base name of the module - @param map the overrided surface area information - **/ - public synchronized static void registerModule(String moduleName, Map map) { - parsedModules.put(moduleName, map); + * return two values: {cName, GuidValue} + */ + public static String[] getProtocolGuid(List packages, + String name) { + if (packages == null) { + return new String[0]; + } + String[] result = null; + Iterator item = packages.iterator(); + while (item.hasNext()){ + Spd spd = spdTable.get(item.next()); + // + // If find one package defined the protocol GUID + // + if ((result = spd.getProtocol(name))!= null){ + return result; + } + } + return null; + } - /** - * - * @param protocolName - * @return - */ - public synchronized static String[] getProtocolInfoGuid(String protocolName) { - Set set = spdTable.keySet(); - Iterator iter = set.iterator(); - String[] cNameGuid = null; + public synchronized static PlatformIdentification getPlatformByName(String name) throws EdkException { + Iterator iter = platformList.iterator(); + while(iter.hasNext()){ + PlatformIdentification platformId = (PlatformIdentification)iter.next(); + if (platformId.getName().equalsIgnoreCase(name)) { + return platformId; + } + } + throw new EdkException("Can't find platform [" + name + "] in the current WORKSPACE database!"); + } - while (iter.hasNext()) { - Spd spd = (Spd) spdTable.get(iter.next()); - cNameGuid = spd.getProtocolNameGuidArray(protocolName); - if (cNameGuid != null) { - break; + public synchronized static PlatformIdentification getPlatform(String filename) throws EdkException { + File file = new File(workspaceDir + File.separatorChar + filename); + Iterator iter = platformList.iterator(); + while(iter.hasNext()){ + PlatformIdentification platformId = (PlatformIdentification)iter.next(); + if (platformId.getFpdFile().getPath().equalsIgnoreCase(file.getPath())) { + return platformId; } } - return cNameGuid; + throw new EdkException("Can't find platform file [" + filename + "] in the current WORKSPACE database!"); } - public synchronized static String[] getPpiInfoGuid(String ppiName) { - Set set = spdTable.keySet(); - Iterator iter = set.iterator(); - String[] cNameGuid = null; + public synchronized static PackageIdentification refreshPackageIdentification(PackageIdentification packageId) throws EdkException { + Iterator iter = packageList.iterator(); + while(iter.hasNext()){ + PackageIdentification packageItem = (PackageIdentification)iter.next(); + if (packageItem.equals(packageId)) { + packageId.setName(packageItem.getName()); + packageId.setSpdFile(packageItem.getSpdFile()); + return packageId; + } + } + throw new EdkException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!"); + } + public synchronized static ModuleIdentification refreshModuleIdentification(ModuleIdentification moduleId) throws EdkException { + PackageIdentification packageId = getPackageForModule(moduleId); + moduleId.setPackage(packageId); + Spd spd = spdTable.get(packageId); + if (spd == null) { + throw new EdkException("Can't find package GUID value " + packageId.toGuidString() + " in the current workspace!"); + } + Set modules = spd.getModules(); + Iterator iter = modules.iterator(); while (iter.hasNext()) { - Spd spd = (Spd) spdTable.get(iter.next()); - cNameGuid = spd.getPpiCnameGuidArray(ppiName); - - if (cNameGuid != null) { - break; + ModuleIdentification item = iter.next(); + if (item.equals(moduleId)) { + moduleId.setName(item.getName()); + moduleId.setModuleType(item.getModuleType()); + moduleId.setMsaFile(item.getMsaFile()); + return moduleId; } } - return cNameGuid; + throw new EdkException("Can't find module GUID value " + moduleId.toGuidString() + " in " + packageId + " under the current workspace!"); + } + + public synchronized static Set getPackageList(){ + return packageList; } /** - * - * @param guidName - * @return - */ - public synchronized static String[] getGuidInfoGuid(String guidName) { - String[] cNameGuid = null; - Set set = spdTable.keySet(); - Iterator iter = set.iterator(); + BUGBUG: It is a walk around method. If do not clone, can't query info with + XPath correctly. + + @param object XmlObject + @param deep flag for deep clone + @return XmlObject after clone + @throws BuildException parse original XmlObject error. + **/ + private static XmlObject cloneXmlObject(XmlObject object, boolean deep) throws EdkException { + if ( object == null) { + return null; + } + XmlObject result = null; + try { + result = XmlObject.Factory.parse(object.getDomNode() + .cloneNode(deep)); + } catch (XmlException ex) { + EdkException edkException = new EdkException(ex.getMessage()); + edkException.setStackTrace(ex.getStackTrace()); + throw edkException; + } + return result; + } - while (iter.hasNext()) { - Spd spd = (Spd) spdTable.get(iter.next()); - cNameGuid = spd.getGuidNameArray(guidName); - if (cNameGuid != null) { - break; + /// + /// Tool Chain Related, try to refine and put some logic process to ToolChainFactory + /// + public synchronized static ToolChainInfo getToolChainInfo() { + if (toolChainInfo == null) { + toolChainInfo = toolsDef.getConfigInfo().intersection(toolChainEnvInfo); + if (toolChainPlatformInfo != null) { + toolChainInfo = toolChainInfo.intersection(toolChainPlatformInfo); } + toolChainInfo.addCommands(toolsDef.getConfigInfo().getCommands()); + toolChainInfo.normalize(); + EdkLog.log("Init", EdkLog.EDK_ALWAYS, "Current build tool chain information summary: "); + EdkLog.log("Init", EdkLog.EDK_ALWAYS, toolChainInfo + ""); } - return cNameGuid; + return toolChainInfo; } - public synchronized static String getLibClassIncluder(String libName) { - String libIncluder = null; - Set set = spdTable.keySet(); - Iterator iter = set.iterator(); + public static void setPlatformToolChainFamilyOption(ToolChainMap map) { + platformToolChainFamilyOption = map; + } - while (iter.hasNext()) { - String packageName = (String) iter.next(); - Spd spd = (Spd) spdTable.get(packageName); - libIncluder = spd.getLibClassIncluder(libName); - String packagePath = spd.packagePath; - if (packagePath != null) { - packagePath = packagePath.replace('\\', File.separatorChar); - packagePath = packagePath.replace('/', File.separatorChar); - } else { - packagePath = packageName; - } - if (libIncluder != null) { - libIncluder = libIncluder.replace('\\', File.separatorChar); - libIncluder = libIncluder.replace('/', File.separatorChar); - libIncluder = packageName + File.separatorChar + libIncluder; - break; + public static void setPlatformToolChainOption(ToolChainMap map) { + platformToolChainOption = map; + } + + public static void addModuleToolChainOption(FpdModuleIdentification fpdModuleId, + ToolChainMap toolChainOption) { + moduleToolChainOption.put(fpdModuleId, toolChainOption); + } + + public static void addModuleToolChainFamilyOption(FpdModuleIdentification fpdModuleId, + ToolChainMap toolChainOption) { + moduleToolChainFamilyOption.put(fpdModuleId, toolChainOption); + } + + public static boolean isCommandSet(String target, String toolchain, String arch) { + String[] commands = getToolChainInfo().getCommands(); + + for (int i = 0; i < commands.length; ++i) { + String cmdName = toolsDef.getConfig().get(new String[] {target, toolchain, arch, commands[i], ToolChainAttribute.NAME.toString()}); + if (cmdName != null && cmdName.length() != 0) { + return true; } } - return libIncluder; + + return false; } - public synchronized static String getModuleInfoByPackageName(String packageName, String moduleType) { - Spd spd; - String includeFile = null; - String includeStr = ""; - String cleanPath = ""; + public synchronized static String getCommandSetting(String[] commandDescription, FpdModuleIdentification fpdModuleId) throws EdkException { + ToolChainKey toolChainKey = new ToolChainKey(commandDescription); + ToolChainMap toolChainConfig = toolsDef.getConfig(); + String setting = null; + + setting = toolChainConfig.get(toolChainKey); + if (setting == null) { + setting = ""; + } + if (!commandDescription[ToolChainElement.ATTRIBUTE.value].equals(ToolChainAttribute.FLAGS.toString())) { + return setting; + } + + // + // get module specific options, if any + // + // tool tag first + ToolChainMap option = moduleToolChainOption.get(fpdModuleId); + ToolChainKey toolChainFamilyKey = null; + + if (option != null && option.get(toolChainKey) != null) + { + String str = option.get(toolChainKey); + + Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+"); + Matcher matcher = myPattern.matcher(str + " "); + while (matcher.find()) + { + setting = setting + " " + str.substring(matcher.start(1), matcher.end(1)); + } + } +// else +// { + if (toolChainFamilyKey == null) + { + toolChainFamilyKey = new ToolChainKey(commandDescription); + toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value); + String family = toolChainConfig.get(toolChainFamilyKey); + toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value); + toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value); + } + + option = moduleToolChainFamilyOption.get(fpdModuleId); + if (option != null && option.get(toolChainFamilyKey) != null) + { + String str = option.get(toolChainFamilyKey); + + Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+"); + Matcher matcher = myPattern.matcher(str + " "); + while (matcher.find()) + { + setting = setting + " " + str.substring(matcher.start(1), matcher.end(1)); + } + } +// } + + // + // get platform options, if any + // + // tool tag first +// if (platformToolChainOption != null && platformToolChainOption.get(toolChainKey) != null) + if (platformToolChainOption.get(toolChainKey) != null) + { + String str = platformToolChainOption.get(toolChainKey); + + Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+"); + Matcher matcher = myPattern.matcher(str + " "); + while (matcher.find()) + { + setting = setting + " " + str.substring(matcher.start(1), matcher.end(1)); + } + } +// else +// { + // then tool chain family + if (toolChainFamilyKey == null) + { + toolChainFamilyKey = new ToolChainKey(commandDescription); + toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value); + String family = toolChainConfig.get(toolChainFamilyKey); + toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value); + toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value); + } + +// if (platformToolChainFamilyOption != null && platformToolChainFamilyOption.get(toolChainFamilyKey) != null) + if (platformToolChainFamilyOption.get(toolChainFamilyKey) != null) + { + String str = platformToolChainFamilyOption.get(toolChainFamilyKey); + + setting = setting + " " + str; + +// Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+"); +// Matcher matcher = myPattern.matcher(str + " "); +// while (matcher.find()) +// { +// setting = setting + " " + str.substring(matcher.start(1), matcher.end(1)); +// } + } +// } + + return setting; + +/* + // + // get module specific options, if any + // + // tool tag first + ToolChainMap option = moduleToolChainOption.get(fpdModuleId); + ToolChainKey toolChainFamilyKey = null; + + if ((option == null) || (option != null && (setting = option.get(toolChainKey)) == null)) + { + // + // then tool chain family + // + toolChainFamilyKey = new ToolChainKey(commandDescription); + toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value); + String family = toolChainConfig.get(toolChainFamilyKey); + toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value); + toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value); + + option = moduleToolChainFamilyOption.get(fpdModuleId); + if (option != null) { + setting = option.get(toolChainFamilyKey); + } + } - spd = (Spd) spdTable.get(packageName); - includeFile = spd.getModuleTypeIncluder(moduleType); - if (includeFile != null) { - includeFile = includeFile.replace('\\', File.separatorChar); - includeFile = includeFile.replace('/', File.separatorChar); - includeStr = CommonDefinition.include + " <" + includeStr; - cleanPath = spd.packagePath; - cleanPath = cleanPath.replace('\\', File.separatorChar); - cleanPath = cleanPath.replace('/', File.separatorChar); + // + // get platform options, if any + // + if (setting == null) { + // tool tag first + if (platformToolChainOption == null || (setting = platformToolChainOption.get(toolChainKey)) == null) { + // then tool chain family + if (toolChainFamilyKey == null) { + toolChainFamilyKey = new ToolChainKey(commandDescription); + toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value); + String family = toolChainConfig.get(toolChainFamilyKey); + toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value); + toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value); + } - if (cleanPath.charAt(spd.packagePath.length() - 1) != File.separatorChar) { - cleanPath = cleanPath + File.separatorChar; + setting = platformToolChainFamilyOption.get(toolChainFamilyKey); } - includeStr = includeStr + cleanPath; - includeStr = includeStr + includeFile; - includeStr = includeStr + ">\r\n"; } - return includeStr; - } + if (setting == null) { + setting = ""; + } - public synchronized static void setLibInstanceInfo(String libName, String libConstructor, String libDesturctor) { - String[] libConsDes = new String[2]; - libConsDes[0] = libConstructor; - libConsDes[1] = libDesturctor; + return setting; +*/ + } - libInstanceInfo.put(libName, libConsDes); + public static void setToolChainEnvInfo(ToolChainInfo envInfo) { + toolChainEnvInfo = envInfo; + } + public static void setToolChainPlatformInfo(ToolChainInfo platformInfo) { + toolChainPlatformInfo = platformInfo; } - public synchronized static boolean isHaveLibInstance(String libName) { - return libInstanceInfo.containsKey(libName); + // + // for PCD + // + public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() { + return pcdDbManager; } - public synchronized static String getLibInstanceConstructor(String libName) { - String[] libInstanceValue; - libInstanceValue = libInstanceInfo.get(libName); - if (libInstanceValue != null) { - return libInstanceValue[0]; - } else { + // + // For PCD get tokenSpaceGUid + // + public synchronized static String getGuidInfoFromCname(String cName){ + String cNameGuid = null; + String guid = null; + Set set = spdTable.keySet(); + Iterator iter = set.iterator(); + + if (iter == null) { return null; } + + while (iter.hasNext()){ + Spd spd = (Spd) spdTable.get(iter.next()); + guid = spd.getGuidFromCname(cName); + if (guid != null){ + cNameGuid = guid; + break; + } + } + return cNameGuid; } - public synchronized static String getLibInstanceDestructor(String libName) { - String[] libInstanceValue; - libInstanceValue = libInstanceInfo.get(libName); - if (libInstanceValue != null) { - return libInstanceValue[1]; - } else { - return null; + // + // For PCD + // + public synchronized static Map + getFpdModuleSaXmlObject(String xmlObjectName) { + Set fpdModuleSASet = fpdModuleSA.keySet(); + Iterator item = fpdModuleSASet.iterator(); + + + Map SAPcdBuildDef = new HashMap(); + Map SANode = new HashMap(); + FpdModuleIdentification moduleId; + while (item.hasNext()) { + + moduleId = (FpdModuleIdentification) item.next(); + SANode = fpdModuleSA.get(moduleId); + try{ + if (SANode.get(xmlObjectName)!= null){ + SAPcdBuildDef.put(moduleId, + (XmlObject) SANode.get(xmlObjectName)); + + } + } catch (Exception e){ + EdkLog.log(EdkLog.EDK_INFO, e.getMessage()); + } } + return SAPcdBuildDef; } - public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() { - return pcdDbManager; + public synchronized static Map getFpdPcdBuildDefinitions() { + Map pcdBuildDef = getFpdModuleSaXmlObject ("PcdBuildDefinition"); + + return pcdBuildDef; } } +