package org.tianocore.build;\r
\r
import java.io.File;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
+import java.util.Hashtable;\r
import java.util.Iterator;\r
import java.util.LinkedHashSet;\r
import java.util.List;\r
import java.util.Map;\r
import java.util.Set;\r
+import java.util.Stack;\r
import java.util.Vector;\r
import java.util.regex.Matcher;\r
import java.util.regex.Pattern;\r
\r
-import javax.xml.parsers.DocumentBuilder;\r
-import javax.xml.parsers.DocumentBuilderFactory;\r
-import javax.xml.transform.OutputKeys;\r
-import javax.xml.transform.Result;\r
-import javax.xml.transform.Source;\r
-import javax.xml.transform.Transformer;\r
-import javax.xml.transform.TransformerFactory;\r
-import javax.xml.transform.dom.DOMSource;\r
-import javax.xml.transform.stream.StreamResult;\r
-\r
import org.apache.tools.ant.BuildException;\r
-import org.apache.tools.ant.Project;\r
-import org.apache.tools.ant.Task;\r
import org.apache.tools.ant.taskdefs.Ant;\r
+import org.apache.tools.ant.taskdefs.Property;\r
import org.apache.xmlbeans.XmlObject;\r
-import org.w3c.dom.Comment;\r
-import org.w3c.dom.Document;\r
-import org.w3c.dom.Element;\r
-import org.w3c.dom.Node;\r
\r
import org.tianocore.build.autogen.AutoGen;\r
-import org.tianocore.build.autogen.CommonDefinition;\r
import org.tianocore.build.fpd.FpdParserTask;\r
+import org.tianocore.build.global.GenBuildLogger;\r
import org.tianocore.build.global.GlobalData;\r
import org.tianocore.build.global.OutputManager;\r
import org.tianocore.build.global.SurfaceAreaQuery;\r
-import org.tianocore.build.toolchain.ToolChainFactory;\r
-import org.tianocore.FilenameDocument;\r
-import org.tianocore.MsaHeaderDocument;\r
-import org.tianocore.MsaLibHeaderDocument;\r
+import org.tianocore.build.id.FpdModuleIdentification;\r
+import org.tianocore.build.id.ModuleIdentification;\r
+import org.tianocore.build.id.PackageIdentification;\r
+import org.tianocore.build.id.PlatformIdentification;\r
+import org.tianocore.build.tools.ModuleItem;\r
+import org.tianocore.exception.EdkException;\r
+import org.tianocore.logger.EdkLog;\r
\r
/**\r
<p>\r
<code>GenBuildTask</code> is an ANT task that can be used in ANT build\r
system. The main function of this task is to parse module's surface area,\r
then generate the corresponding <em>BaseName_build.xml</em> (the real ANT\r
- build script) and call this to build the module.\r
+ build script) and call this to build the module. The whole process including:\r
+ 1. generate AutoGen.c and AutoGen.h; 2. build all dependent library instances; \r
+ 3. build all source files inlcude AutoGen.c; 4. generate sections;\r
+ 5. generate FFS file if it is driver module while LIB file if it is Library module. \r
</p>\r
\r
<p>\r
</p>\r
\r
<pre>\r
- <GenBuild baseName="HelloWorld" \r
- mbdFilename="${MODULE_DIR}/HelloWorld.mbd" \r
- msaFilename="${MODULE_DIR}/HelloWorld.msa"/>\r
+ <GenBuild \r
+ msaFilename="HelloWorld.msa"/> \r
+ processTo="ALL"/>\r
</pre>\r
\r
+ <p><code>processTo</code> provides a way to customize the whole build process. \r
+ processTo can be one value of ALL, AUTOGEN, FILES, LIBRARYINSTANCES, SECTIONS, NONE. \r
+ Default is ALL, means whole \r
+ </p>\r
+ \r
<p>\r
This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and\r
<em>AutoGen.h</em>. The task also parses the development environment\r
\r
@since GenBuild 1.0\r
**/\r
-public class GenBuildTask extends Task {\r
-\r
+public class GenBuildTask extends Ant {\r
+ \r
///\r
/// Module surface area file.\r
///\r
- File msaFilename;\r
-\r
- ///\r
- /// Module build description file.\r
- ///\r
- File mbdFilename;\r
-\r
- ///\r
- /// Module surface area information after overrided.\r
- ///\r
- public Map<String, XmlObject> map = new HashMap<String, XmlObject>();\r
-\r
- ///\r
- /// Module's base name.\r
- ///\r
- private String baseName;\r
-\r
- ///\r
- /// Current build Arch, such as IA32, X64, IPF and so on.\r
- ///\r
- private String arch;\r
-\r
- ///\r
- /// Module's GUID (Globally Unique Identifier).\r
- ///\r
- private String guid;\r
-\r
- ///\r
- /// Module's component type, such as SEC, LIBRARY, BS_DRIVER and so on.\r
- ///\r
- private String componentType;\r
-\r
- ///\r
- /// This value is used in build time. Override module's component type. When\r
- /// search FFS (Sections information) in common file, buildtype instead of\r
- /// component type.\r
- ///\r
- private String buildType;\r
-\r
- ///\r
- /// List all required includes for current build module.\r
- ///\r
- public Set<String> includes = new LinkedHashSet<String>();\r
-\r
- ///\r
- /// List all libraries for current build module.\r
- ///\r
- public Set<String> libraries = new LinkedHashSet<String>();\r
-\r
- ///\r
- /// List all source files for current build module.\r
- ///\r
- public Set<String> sourceFiles = new LinkedHashSet<String>();\r
+ File msaFile;\r
\r
///\r
- /// Flag to identify what surface area files are specified. Current value is\r
- /// <em>NO_SA</em>, <em>ONLY_MSA</em>, <em>ONLY_LIBMSA</em>,\r
- /// <em>MSA_AND_MBD</em> or <em>LIBMSA_AND_LIBMBD</em>.\r
/// \r
- /// @see org.tianocore.build.global.GlobaData\r
///\r
- private int flag = GlobalData.NO_SA;\r
-\r
+ private String type = "all"; // = "build";\r
+ \r
///\r
- /// The information at the header of <em>build.xml</em>.\r
+ /// Module's Identification.\r
///\r
- private String info = "====================================================================\n"\r
- + "DO NOT EDIT \n"\r
- + "File auto-generated by build utility\n"\r
- + "\n"\r
- + "Abstract:\n"\r
- + "Auto-generated ANT build file for building of EFI Modules/Platforms\n"\r
- + "=====================================================================";\r
+ private ModuleIdentification moduleId;\r
\r
+ private Vector<Property> properties = new Vector<Property>();\r
+\r
+ private static Stack<Hashtable> backupPropertiesStack = new Stack<Hashtable>();\r
+ \r
+ private boolean isSingleModuleBuild = false;\r
+ \r
/**\r
Public construct method. It is necessary for ANT task.\r
**/\r
}\r
\r
/**\r
- ANT task's entry point, will be called after init(). The main steps is described\r
- as following: \r
- <ul>\r
- <li> Judge current build mode (MODULE | PACKAGE | PLATFORM). This step will execute\r
- only once in whole build process; </li>\r
- <li> Initialize global information (Framework DB, SPD files and all MSA files \r
- listed in SPD). This step will execute only once in whole build process; </li>\r
- <li> Restore some important ANT property. If current build is single module \r
- build, here will set many default values; </li>\r
- <li> Get the current module's overridded surface area information from \r
- global data; </li> \r
- <li> Set up the output directories, including BIN_DIR, DEST_DIR_OUTPUT and\r
- DEST_DIR_DEBUG; </li>\r
- <li> Get module dependent library instances and include pathes; </li>\r
- <li> Judge whether current module is built. If yes, skip it; </li>\r
- <li> Call AutoGen and PCD to generate AutoGen.c & AutoGen.h </li>\r
- <li> Set up the compile flags; </li>\r
- <li> Generate BaseName_build.xml; </li>\r
- <li> Call to BaseName_build.xml, and build the current module. </li>\r
- </ul>\r
- \r
- <p>Build is dependent on BuildMacro.xml which define many macro. </p> \r
- \r
+ \r
@throws BuildException\r
From module build, exception from module surface area invalid.\r
**/\r
public void execute() throws BuildException {\r
- System.out.println("Module [" + baseName + "] start.");\r
- OutputManager.update(getProject());\r
- GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db",\r
- getProject().getProperty("WORKSPACE_DIR"));\r
- recallFixedProperties();\r
- arch = getProject().getProperty("ARCH");\r
- arch = arch.toUpperCase();\r
- map = GlobalData.getDoc(baseName);\r
- //\r
- // Initialize SurfaceAreaQuery\r
- //\r
- SurfaceAreaQuery.setDoc(map);\r
- //\r
- // Setup Output Management\r
- //\r
- String[] outdir = SurfaceAreaQuery.getOutputDirectory();\r
- OutputManager.update(getProject(), outdir[1], outdir[0]);\r
-\r
- updateIncludesAndLibraries();\r
-\r
- if (GlobalData.isModuleBuilt(baseName, arch)) {\r
- return;\r
- } else {\r
- GlobalData.registerBuiltModule(baseName, arch);\r
- }\r
- //\r
- // Call AutoGen\r
- //\r
- AutoGen autogen = new AutoGen(getProject().getProperty("DEST_DIR_DEBUG"), baseName, arch);\r
- autogen.genAutogen();\r
- //\r
- // Update parameters\r
- //\r
- updateParameters();\r
+ //\r
+ // set Logger\r
//\r
- // Update flags like CC_FLAGS, LIB_FLAGS etc.\r
- //\r
- flagsSetup();\r
- GlobalData.addLibrary(baseName, arch, getProject().getProperty("BIN_DIR") + File.separatorChar + baseName + ".lib");\r
- GlobalData.addModuleLibrary(baseName, arch, libraries);\r
+ GenBuildLogger logger = new GenBuildLogger(getProject());\r
+ EdkLog.setLogLevel(getProject().getProperty("env.LOGLEVEL"));\r
+ EdkLog.setLogger(logger);\r
+ // remove !!\r
+ try {\r
+ pushProperties();\r
//\r
- // If ComponentType is USER_DEFINED,\r
- // then call the exist BaseName_build.xml directly.\r
+ // Enable all specified properties\r
//\r
- if (buildType.equalsIgnoreCase("CUSTOM_BUILD")) {\r
- System.out.println("Call user-defined " + baseName + "_build.xml");\r
- Ant ant = new Ant();\r
- ant.setProject(getProject());\r
- ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + baseName + "_build.xml");\r
- ant.setInheritAll(true);\r
- ant.init();\r
- ant.execute();\r
- return;\r
+ Iterator<Property> iter = properties.iterator();\r
+ while (iter.hasNext()) {\r
+ Property item = iter.next();\r
+ getProject().setProperty(item.getName(), item.getValue());\r
}\r
+ \r
//\r
- // Generate ${BASE_NAME}_build.xml file\r
+ // GenBuild should specify either msaFile or moduleGuid & packageGuid\r
//\r
- System.out.println("Generate " + baseName + "_build.xml");\r
- genBuildFile();\r
- System.out.println("Call the " + baseName + "_build.xml");\r
- Ant ant = new Ant();\r
- ant.setProject(getProject());\r
- ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName + "_build.xml");\r
- ant.setInheritAll(true);\r
- ant.init();\r
- ant.execute();\r
- }\r
-\r
- /**\r
- Return the name of the directory that corresponds to the architecture.\r
- This is a translation from the XML Schema tag to a directory that\r
- corresponds to our directory name coding convention.\r
- \r
- **/\r
- private String archDir(String arch) {\r
- return arch.replaceFirst("X64", "x64")\r
- .replaceFirst("IPF", "Ipf")\r
- .replaceFirst("IA32", "Ia32")\r
- .replaceFirst("ARM", "Arm")\r
- .replaceFirst("EBC", "Ebc");\r
- }\r
-\r
- /**\r
- Get the dependent library instances and include package name from \r
- surface area, and initialize module include pathes. \r
- \r
- **/\r
- private void updateIncludesAndLibraries() {\r
- List<String> rawIncludes = SurfaceAreaQuery.getIncludePackageName(arch);\r
- if (rawIncludes != null) {\r
- Iterator iter = rawIncludes.iterator();\r
- while (iter.hasNext()) {\r
- String packageName = (String) iter.next();\r
- includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)\r
- + File.separatorChar + "Include");\r
- includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)\r
- + File.separatorChar + "Include" + File.separatorChar + archDir(arch));\r
+ if (msaFile == null ) {\r
+ String moduleGuid = getProject().getProperty("MODULE_GUID");\r
+ String moduleVersion = getProject().getProperty("MODULE_VERSION");\r
+ String packageGuid = getProject().getProperty("PACKAGE_GUID");\r
+ String packageVersion = getProject().getProperty("PACKAGE_VERSION");\r
+ if (moduleGuid == null || packageGuid == null) {\r
+ throw new BuildException("GenBuild parameters error. ");\r
}\r
+ PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion);\r
+ moduleId = new ModuleIdentification(moduleGuid, moduleVersion);\r
+ moduleId.setPackage(packageId);\r
+ Map<String, XmlObject> doc = GlobalData.getNativeMsa(moduleId);\r
+ SurfaceAreaQuery.setDoc(doc);\r
+ moduleId = SurfaceAreaQuery.getMsaHeader();\r
}\r
- includes.add("${DEST_DIR_DEBUG}");\r
- List<String> rawLibraries = SurfaceAreaQuery.getLibraryInstance(this.arch, CommonDefinition.AlwaysConsumed);\r
- if (rawLibraries != null) {\r
- Iterator iter = rawLibraries.iterator();\r
- while (iter.hasNext()) {\r
- libraries.add((String) iter.next());\r
- }\r
+ else {\r
+ Map<String, XmlObject> doc = GlobalData.getNativeMsa(msaFile);\r
+ SurfaceAreaQuery.setDoc(doc);\r
+ moduleId = SurfaceAreaQuery.getMsaHeader();\r
}\r
- normalize();\r
- }\r
-\r
- /**\r
- Normalize all dependent library instance and include pathes' format. \r
- \r
- **/\r
- private void normalize() {\r
- String[] includesArray = includes.toArray(new String[includes.size()]);\r
- includes.clear();\r
- for (int i = 0; i < includesArray.length; i++) {\r
- includes.add((new File(includesArray[i])).getPath());\r
+ String[] producedLibraryClasses = SurfaceAreaQuery.getLibraryClasses("ALWAYS_PRODUCED",null);\r
+ if (producedLibraryClasses.length == 0) {\r
+ moduleId.setLibrary(false);\r
}\r
- String[] librariesArray = libraries.toArray(new String[libraries.size()]);\r
- libraries.clear();\r
- for (int i = 0; i < librariesArray.length; i++) {\r
- libraries.add((new File(librariesArray[i])).getPath());\r
+ else {\r
+ moduleId.setLibrary(true);\r
}\r
- }\r
-\r
- /**\r
- Restore some important ANT property. If current build is single module \r
- build, here will set many default values.\r
- \r
- <p> If current build is single module build, then the default <code>ARCH</code>\r
- is <code>IA32</code>. Also set up the properties <code>PACKAGE</code>, \r
- <code>PACKAGE_DIR</code>, <code>TARGET</code> and <code>MODULE_DIR</code></p>\r
- \r
- <p> Note that for package build, package name is stored in <code>PLATFORM</code>\r
- and package directory is stored in <code>PLATFORM_DIR</code>. </p> \r
- \r
- @see org.tianocore.build.global.OutputManager\r
- **/\r
- private void recallFixedProperties() {\r
+ \r
//\r
- // If build is for module build\r
+ // Judge whether it is single module build or not\r
//\r
- if (getProject().getProperty("PACKAGE_DIR") == null) {\r
- ToolChainFactory toolChainFactory = new ToolChainFactory(getProject());\r
- toolChainFactory.setupToolChain();\r
+ if (isSingleModuleBuild) {\r
//\r
- // PACKAGE PACKAGE_DIR ARCH (Default) COMMON_FILE BUILD_MACRO\r
+ // Single Module build\r
//\r
- if (getProject().getProperty("ARCH") == null) {\r
- getProject().setProperty("ARCH", "IA32");\r
- }\r
- String packageName = GlobalData.getPackageNameForModule(baseName);\r
- getProject().setProperty("PACKAGE", packageName);\r
- \r
- String packageDir = GlobalData.getPackagePath(packageName);\r
- getProject().setProperty("PACKAGE_DIR",\r
- getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + packageDir);\r
- \r
- getProject().setProperty("TARGET", toolChainFactory.getCurrentTarget());\r
+ prepareSingleModuleBuild();\r
+ }\r
+ else {\r
+ //\r
+ // Platform build. Restore the platform related info\r
+ //\r
+ String filename = getProject().getProperty("PLATFORM_FILE");\r
+ PlatformIdentification platformId = GlobalData.getPlatform(filename);\r
+ getProject().setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));\r
+ getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));\r
\r
- getProject().setProperty("MODULE_DIR",\r
- getProject().replaceProperties(getProject().getProperty("MODULE_DIR")));\r
+ String packageGuid = getProject().getProperty("PACKAGE_GUID");\r
+ String packageVersion = getProject().getProperty("PACKAGE_VERSION");\r
+ PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion);\r
+ moduleId.setPackage(packageId);\r
}\r
- if (OutputManager.PLATFORM != null) {\r
- getProject().setProperty("PLATFORM", OutputManager.PLATFORM);\r
+ \r
+ //\r
+ // If single module : intersection MSA supported ARCHs and tools def!!\r
+ // else, get arch from pass down\r
+ //\r
+ String[] archList = new String[0];\r
+ if ( getProject().getProperty("ARCH") != null ) {\r
+ archList = getProject().getProperty("ARCH").split(" ");\r
}\r
- if (OutputManager.PLATFORM_DIR != null) {\r
- getProject().setProperty("PLATFORM_DIR", OutputManager.PLATFORM_DIR);\r
+ else {\r
+ archList = GlobalData.getToolChainInfo().getArchs();\r
}\r
- }\r
-\r
- /**\r
- The whole BaseName_build.xml is composed of seven part. \r
- <ul>\r
- <li> ANT properties; </li>\r
- <li> Dependent module (dependent library instances in most case); </li>\r
- <li> Source files; </li>\r
- <li> Sections if module is not library; </li>\r
- <li> Output (different for library module and driver module); </li>\r
- <li> Clean; </li>\r
- <li> Clean all. </li>\r
- </ul>\r
- \r
- @throws BuildException\r
- Error throws during BaseName_build.xml generating. \r
- **/\r
- private void genBuildFile() throws BuildException {\r
- FfsProcess fp = new FfsProcess();\r
- DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();\r
- try {\r
- DocumentBuilder dombuilder = domfac.newDocumentBuilder();\r
- Document document = dombuilder.newDocument();\r
- Comment rootComment = document.createComment(info);\r
- //\r
- // create root element and its attributes\r
- //\r
- Element root = document.createElement("project");\r
- //\r
- // root.setAttribute("name", base_name);\r
- //\r
- root.setAttribute("default", "main");\r
- root.setAttribute("basedir", ".");\r
- //\r
- // element for External ANT tasks\r
- //\r
- root.appendChild(document.createComment("Apply external ANT tasks"));\r
- Element ele = document.createElement("taskdef");\r
- ele.setAttribute("resource", "frameworktasks.tasks");\r
- root.appendChild(ele);\r
- ele = document.createElement("taskdef");\r
- ele.setAttribute("resource", "cpptasks.tasks");\r
- root.appendChild(ele);\r
- ele = document.createElement("typedef");\r
- ele.setAttribute("resource", "cpptasks.types");\r
- root.appendChild(ele);\r
- ele = document.createElement("taskdef");\r
- ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");\r
- root.appendChild(ele);\r
- //\r
- // elements for Properties\r
- //\r
- root.appendChild(document.createComment("All Properties"));\r
- ele = document.createElement("property");\r
- ele.setAttribute("name", "BASE_NAME");\r
- ele.setAttribute("value", baseName);\r
- root.appendChild(ele);\r
- //\r
- // Generate the default target,\r
- // which depends on init, sections and output target\r
- //\r
- root.appendChild(document.createComment("Default target"));\r
- ele = document.createElement("target");\r
- ele.setAttribute("name", "main");\r
- ele.setAttribute("depends", "libraries, sourcefiles, sections, output");\r
- root.appendChild(ele);\r
- //\r
- // compile all source files\r
- //\r
- root.appendChild(document.createComment("Compile all dependency Library instances."));\r
- ele = document.createElement("target");\r
- ele.setAttribute("name", "libraries");\r
- //\r
- // Parse all sourfiles but files specified in sections\r
- //\r
- applyLibraryInstance(document, ele);\r
- root.appendChild(ele);\r
- //\r
- // compile all source files\r
- //\r
- root.appendChild(document.createComment("sourcefiles target"));\r
- ele = document.createElement("target");\r
- ele.setAttribute("name", "sourcefiles");\r
- //\r
- // Parse all sourfiles but files specified in sections\r
- //\r
- applyCompileElement(document, ele);\r
- root.appendChild(ele);\r
- //\r
- // generate the init target\r
- // main purpose is create all nessary pathes\r
- // generate the sections target\r
- //\r
- root.appendChild(document.createComment("sections target"));\r
- ele = document.createElement("target");\r
- ele.setAttribute("name", "sections");\r
- applySectionsElement(document, ele, fp);\r
- root.appendChild(ele);\r
- //\r
- // generate the output target\r
- //\r
- root.appendChild(document.createComment("output target"));\r
- ele = document.createElement("target");\r
- ele.setAttribute("name", "output");\r
- applyOutputElement(document, ele, fp);\r
- root.appendChild(ele);\r
- //\r
- // generate the clean target\r
- //\r
- root.appendChild(document.createComment("clean target"));\r
- ele = document.createElement("target");\r
- ele.setAttribute("name", "clean");\r
- applyCleanElement(document, ele);\r
- root.appendChild(ele);\r
- //\r
- // generate the Clean All target\r
- //\r
- root.appendChild(document.createComment("Clean All target"));\r
- ele = document.createElement("target");\r
- ele.setAttribute("name", "cleanall");\r
- applyDeepcleanElement(document, ele);\r
- root.appendChild(ele);\r
- //\r
- // add the root element to the document\r
- //\r
- document.appendChild(rootComment);\r
- document.appendChild(root);\r
- //\r
- // Prepare the DOM document for writing\r
- //\r
- Source source = new DOMSource(document);\r
- //\r
- // Prepare the output file\r
- //\r
- File file = new File(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName\r
- + "_build.xml");\r
- //\r
- // generate all directory path\r
- //\r
- (new File(file.getParent())).mkdirs();\r
- Result result = new StreamResult(file);\r
- //\r
- // Write the DOM document to the file\r
- //\r
- Transformer xformer = TransformerFactory.newInstance().newTransformer();\r
- xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");\r
- xformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
- xformer.transform(source, result);\r
- } catch (Exception ex) {\r
- throw new BuildException("Module [" + baseName + "] generating build file failed.\n" + ex.getMessage());\r
+ \r
+ \r
+ //\r
+ // Judge if arch is all supported by current module. If not, throw Exception.\r
+ //\r
+ List moduleSupportedArchs = SurfaceAreaQuery.getModuleSupportedArchs();\r
+ if (moduleSupportedArchs != null) {\r
+ for (int k = 0; k < archList.length; k++) {\r
+ if ( ! moduleSupportedArchs.contains(archList[k])) {\r
+ throw new BuildException("ARCH [" + archList[k] + "] is not supported by " + moduleId + ". " + moduleId + " only supports [" + moduleSupportedArchs + "].");\r
+ }\r
+ }\r
}\r
- }\r
-\r
- /**\r
- Generate the clean elements for BaseName_build.xml. \r
- \r
- @param document current BaseName_build.xml XML document\r
- @param root Root element for current\r
- **/\r
- private void applyCleanElement(Document document, Node root) {\r
- String[] libinstances = libraries.toArray(new String[libraries.size()]);\r
- for (int i = 0; i < libinstances.length; i++) {\r
- File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");\r
-\r
- Element ifEle = document.createElement("if");\r
- Element availableEle = document.createElement("available");\r
- availableEle.setAttribute("file", file.getPath());\r
- ifEle.appendChild(availableEle);\r
- Element elseEle = document.createElement("then");\r
-\r
- Element ele = document.createElement("ant");\r
- ele.setAttribute("antfile", file.getPath());\r
- ele.setAttribute("inheritAll", "false");\r
- ele.setAttribute("target", libinstances[i] + "_clean");\r
- //\r
- // Workspace_DIR\r
- //\r
- Element property = document.createElement("property");\r
- property.setAttribute("name", "WORKSPACE_DIR");\r
- property.setAttribute("value", "${WORKSPACE_DIR}");\r
- ele.appendChild(property);\r
- //\r
- // Package Dir\r
- //\r
- property = document.createElement("property");\r
- property.setAttribute("name", "PACKAGE_DIR");\r
- property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar\r
- + GlobalData.getPackagePathForModule(libinstances[i]));\r
- ele.appendChild(property);\r
- //\r
- // ARCH\r
- //\r
- property = document.createElement("property");\r
- property.setAttribute("name", "ARCH");\r
- property.setAttribute("value", "${ARCH}");\r
- ele.appendChild(property);\r
- //\r
- // TARGET\r
+ \r
+ for (int k = 0; k < archList.length; k++) {\r
+ getProject().setProperty("ARCH", archList[k]);\r
+ \r
+ FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, archList[k]);\r
+ \r
//\r
- property = document.createElement("property");\r
- property.setAttribute("name", "TARGET");\r
- property.setAttribute("value", "${TARGET}");\r
- ele.appendChild(property);\r
+ // Whether the module is built before\r
//\r
- // PACKAGE\r
+ if (GlobalData.isModuleBuilt(fpdModuleId)) {\r
+ return ;\r
+ }\r
+ else {\r
+ GlobalData.registerBuiltModule(fpdModuleId);\r
+ }\r
+ \r
//\r
- property = document.createElement("property");\r
- property.setAttribute("name", "PACKAGE");\r
- property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));\r
- ele.appendChild(property);\r
-\r
- elseEle.appendChild(ele);\r
- ifEle.appendChild(elseEle);\r
- root.appendChild(ifEle);\r
+ // For Every TOOLCHAIN, TARGET\r
+ //\r
+ String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
+ for (int i = 0; i < targetList.length; i ++){\r
+ //\r
+ // Prepare for target related common properties\r
+ // TARGET\r
+ //\r
+ getProject().setProperty("TARGET", targetList[i]);\r
+ String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
+ for(int j = 0; j < toolchainList.length; j ++){\r
+ //\r
+ // check if any tool is defined for current target + toolchain + arch\r
+ // don't do anything if no tools found\r
+ // \r
+ if (GlobalData.isCommandSet(targetList[i], toolchainList[j], archList[k]) == false) {\r
+ System.out.println("Warning: No build issued. No tools found for [target=" + targetList[i] + " toolchain=" + toolchainList[j] + " arch=" + archList[k] + "]\n");\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Prepare for toolchain related common properties\r
+ // TOOLCHAIN\r
+ //\r
+ getProject().setProperty("TOOLCHAIN", toolchainList[j]);\r
+\r
+ System.out.println("Build " + moduleId + " start >>>");\r
+ System.out.println("Target: " + targetList[i] + " Tagname: " + toolchainList[j] + " Arch: " + archList[k]);\r
+ SurfaceAreaQuery.setDoc(GlobalData.getDoc(fpdModuleId));\r
+ \r
+ //\r
+ // Prepare for all other common properties\r
+ // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR\r
+ // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE\r
+ // MODULE_DIR, MODULE_RELATIVE_DIR\r
+ // SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH\r
+ // LIBS, OBJECTS, SDB_FILES\r
+ //\r
+ setModuleCommonProperties(archList[k]);\r
+ \r
+ //\r
+ // OutputManage prepare for \r
+ // BIN_DIR, DEST_DIR_DEBUG, DEST_DIR_OUTPUT, BUILD_DIR, FV_DIR\r
+ //\r
+ OutputManager.getInstance().update(getProject());\r
+ \r
+ if (type.equalsIgnoreCase("all") || type.equalsIgnoreCase("build")) {\r
+ applyBuild(targetList[i], toolchainList[j], fpdModuleId);\r
+ }\r
+ else if (type.equalsIgnoreCase("clean")) {\r
+ applyClean(fpdModuleId);\r
+ }\r
+ else if (type.equalsIgnoreCase("cleanall")) {\r
+ applyCleanall(fpdModuleId);\r
+ }\r
+ }\r
+ }\r
}\r
- }\r
-\r
- /**\r
- Generate the cleanall elements for BaseName_build.xml. \r
- \r
- @param document current BaseName_build.xml XML document\r
- @param root Root element for current\r
- **/\r
- private void applyDeepcleanElement(Document document, Node root) {\r
- String[] libinstances = libraries.toArray(new String[libraries.size()]);\r
- for (int i = 0; i < libinstances.length; i++) {\r
- File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");\r
-\r
- Element ifEle = document.createElement("if");\r
- Element availableEle = document.createElement("available");\r
- availableEle.setAttribute("file", file.getPath());\r
- ifEle.appendChild(availableEle);\r
- Element elseEle = document.createElement("then");\r
-\r
- Element ele = document.createElement("ant");\r
- ele.setAttribute("antfile", file.getPath());\r
- ele.setAttribute("inheritAll", "false");\r
- ele.setAttribute("target", libinstances[i] + "_cleanall");\r
- //\r
- // Workspace_DIR\r
- //\r
- Element property = document.createElement("property");\r
- property.setAttribute("name", "WORKSPACE_DIR");\r
- property.setAttribute("value", "${WORKSPACE_DIR}");\r
- ele.appendChild(property);\r
- //\r
- // Package Dir\r
- //\r
- property = document.createElement("property");\r
- property.setAttribute("name", "PACKAGE_DIR");\r
- property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar\r
- + GlobalData.getPackagePathForModule(libinstances[i]));\r
- ele.appendChild(property);\r
- //\r
- // ARCH\r
- //\r
- property = document.createElement("property");\r
- property.setAttribute("name", "ARCH");\r
- property.setAttribute("value", "${ARCH}");\r
- ele.appendChild(property);\r
- //\r
- // TARGET\r
- //\r
- property = document.createElement("property");\r
- property.setAttribute("name", "TARGET");\r
- property.setAttribute("value", "${TARGET}");\r
- ele.appendChild(property);\r
- //\r
- // PACKAGE\r
- //\r
- property = document.createElement("property");\r
- property.setAttribute("name", "PACKAGE");\r
- property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));\r
- ele.appendChild(property);\r
-\r
- elseEle.appendChild(ele);\r
- ifEle.appendChild(elseEle);\r
- root.appendChild(ifEle);\r
+ popProperties();\r
+ }catch (Exception e){\r
+ throw new BuildException(e.getMessage());\r
}\r
}\r
\r
/**\r
- Generate the dependent library instances elements for BaseName_build.xml. \r
+ This method is used to prepare Platform-related information. \r
\r
- @param document current BaseName_build.xml XML document\r
- @param root Root element for current\r
- **/\r
- private void applyLibraryInstance(Document document, Node root) {\r
- String[] libinstances = libraries.toArray(new String[libraries.size()]);\r
- for (int i = 0; i < libinstances.length; i++) {\r
- Element ele = document.createElement("ant");\r
- File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");\r
- ele.setAttribute("antfile", file.getPath());\r
- ele.setAttribute("inheritAll", "false");\r
- ele.setAttribute("target", libinstances[i]);\r
- //\r
- // Workspace_DIR\r
- //\r
- Element property = document.createElement("property");\r
- property.setAttribute("name", "WORKSPACE_DIR");\r
- property.setAttribute("value", "${WORKSPACE_DIR}");\r
- ele.appendChild(property);\r
- //\r
- // Package Dir\r
- //\r
- property = document.createElement("property");\r
- property.setAttribute("name", "PACKAGE_DIR");\r
- property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar\r
- + GlobalData.getPackagePathForModule(libinstances[i]));\r
- ele.appendChild(property);\r
- //\r
- // ARCH\r
- //\r
- property = document.createElement("property");\r
- property.setAttribute("name", "ARCH");\r
- property.setAttribute("value", "${ARCH}");\r
- ele.appendChild(property);\r
- //\r
- // TARGET\r
- //\r
- property = document.createElement("property");\r
- property.setAttribute("name", "TARGET");\r
- property.setAttribute("value", "${TARGET}");\r
- ele.appendChild(property);\r
- //\r
- // PACKAGE\r
- //\r
- property = document.createElement("property");\r
- property.setAttribute("name", "PACKAGE");\r
- property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));\r
- ele.appendChild(property);\r
- root.appendChild(ele);\r
- }\r
- Element expand = document.createElement("Expand");\r
- root.appendChild(expand);\r
- }\r
- \r
- /**\r
- Generate the build source files elements for BaseName_build.xml. \r
- \r
- @param document current BaseName_build.xml XML document\r
- @param root Root element for current\r
+ <p>In Single Module Build mode, platform-related information is not ready.\r
+ The method read the system environment variable <code>ACTIVE_PLATFORM</code> \r
+ and search in the Framework Database. Note that platform name in the Framework\r
+ Database must be unique. </p>\r
+ \r
**/\r
- private void applyCompileElement(Document document, Node root) {\r
- FileProcess fileProcess = new FileProcess();\r
- fileProcess.init(getProject(), includes, sourceFiles, document);\r
- Node[] files = this.getSourceFiles();\r
+ private void prepareSingleModuleBuild(){\r
//\r
- // Parse all unicode files\r
+ // Find out the package which the module belongs to\r
+ // TBD: Enhance it!!!!\r
//\r
- for (int i = 0; i < files.length; i++) {\r
- String filetype = getFiletype(files[i]);\r
- if (filetype != null) {\r
- fileProcess.parseFile(getFilename(files[i]), filetype, root, true);\r
- } else {\r
- fileProcess.parseFile(getFilename(files[i]), root, true);\r
- }\r
- }\r
- if (fileProcess.isUnicodeExist()) {\r
- Element ele = document.createElement("Build_Unicode_Database");\r
- ele.setAttribute("FILEPATH", ".");\r
- ele.setAttribute("FILENAME", "${BASE_NAME}");\r
- root.appendChild(ele);\r
- }\r
-\r
+ PackageIdentification packageId = GlobalData.getPackageForModule(moduleId);\r
+ \r
+ moduleId.setPackage(packageId);\r
+ \r
//\r
- // Parse AutoGen.c & AutoGen.h\r
+ // Read ACTIVE_PLATFORM's FPD file (Call FpdParserTask's method)\r
//\r
- if (!baseName.equalsIgnoreCase("Shell")) {\r
- fileProcess.parseFile(getProject().getProperty("DEST_DIR_DEBUG") + File.separatorChar + "AutoGen.c", root,\r
- false);\r
+ String filename = getProject().getProperty("PLATFORM_FILE");\r
+ \r
+ if (filename == null){\r
+ throw new BuildException("Plese set ACTIVE_PLATFORM if you want to build a single module. ");\r
}\r
+ \r
+ PlatformIdentification platformId = GlobalData.getPlatform(filename);\r
+ \r
//\r
- // Parse all source files\r
+ // Read FPD file\r
//\r
- for (int i = 0; i < files.length; i++) {\r
- String filetype = getFiletype(files[i]);\r
- if (filetype != null) {\r
- fileProcess.parseFile(getFilename(files[i]), filetype, root, false);\r
- } else {\r
- fileProcess.parseFile(getFilename(files[i]), root, false);\r
- }\r
- }\r
+ FpdParserTask fpdParser = new FpdParserTask();\r
+ fpdParser.setProject(getProject());\r
+ fpdParser.parseFpdFile(platformId.getFpdFile());\r
+ \r
//\r
- // root.appendChild(parallelEle);\r
+ // Prepare for Platform related common properties\r
+ // PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR\r
//\r
- Iterator iter = sourceFiles.iterator();\r
- String str = "";\r
- while (iter.hasNext()) {\r
- str += " " + (String) iter.next();\r
- }\r
- getProject().setProperty("SOURCE_FILES", str);\r
+ getProject().setProperty("PLATFORM", platformId.getName());\r
+ getProject().setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));\r
+ getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));\r
}\r
\r
- /**\r
- Generate the section elements for BaseName_build.xml. Library module will\r
- skip this process. \r
- \r
- @param document current BaseName_build.xml XML document\r
- @param root Root element for current\r
- **/\r
- private void applySectionsElement(Document document, Node root, FfsProcess fp) {\r
- if (fp.initSections(buildType, getProject())) {\r
- String targetFilename = guid + "-" + baseName + FpdParserTask.getSuffix(componentType);\r
- String[] list = fp.getGenSectionElements(document, baseName, guid, targetFilename);\r
-\r
- for (int i = 0; i < list.length; i++) {\r
- Element ele = document.createElement(list[i]);\r
- ele.setAttribute("FILEPATH", ".");\r
- ele.setAttribute("FILENAME", "${BASE_NAME}");\r
- root.appendChild(ele);\r
- }\r
- }\r
- }\r
\r
/**\r
- Generate the output elements for BaseName_build.xml. If module is library,\r
- call the <em>LIB</em> command, else call the <em>GenFfs</em> command. \r
- \r
- @param document current BaseName_build.xml XML document\r
- @param root Root element for current\r
+ Set Module-Related information to properties.\r
**/\r
- private void applyOutputElement(Document document, Node root, FfsProcess fp) {\r
- if (flag == GlobalData.ONLY_LIBMSA || flag == GlobalData.LIBMSA_AND_LIBMBD) {\r
- //\r
- // call Lib command\r
- //\r
- Element cc = document.createElement("Build_Library");\r
- cc.setAttribute("FILENAME", baseName);\r
- root.appendChild(cc);\r
- }\r
+ private void setModuleCommonProperties(String arch) {\r
//\r
- // if it is a module but library\r
+ // Prepare for all other common properties\r
+ // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR\r
//\r
+ PackageIdentification packageId = moduleId.getPackage();\r
+ getProject().setProperty("PACKAGE", packageId.getName());\r
+ getProject().setProperty("PACKAGE_GUID", packageId.getGuid());\r
+ getProject().setProperty("PACKAGE_VERSION", packageId.getVersion());\r
+ getProject().setProperty("PACKAGE_DIR", packageId.getPackageDir().replaceAll("(\\\\)", "/"));\r
+ getProject().setProperty("PACKAGE_RELATIVE_DIR", packageId.getPackageRelativeDir().replaceAll("(\\\\)", "/"));\r
+ \r
+ //\r
+ // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE\r
+ // MODULE_DIR, MODULE_RELATIVE_DIR\r
+ //\r
+ getProject().setProperty("MODULE", moduleId.getName());\r
+ String baseName = SurfaceAreaQuery.getModuleOutputFileBasename();\r
+ if (baseName == null) {\r
+ getProject().setProperty("BASE_NAME", moduleId.getName());\r
+ }\r
else {\r
- if (fp.getFfsNode() != null) {\r
- root.appendChild(fp.getFfsNode());\r
+ getProject().setProperty("BASE_NAME", baseName);\r
+ }\r
+ getProject().setProperty("GUID", moduleId.getGuid());\r
+ getProject().setProperty("FILE_GUID", moduleId.getGuid());\r
+ getProject().setProperty("VERSION", moduleId.getVersion());\r
+ getProject().setProperty("MODULE_TYPE", moduleId.getModuleType());\r
+ getProject().setProperty("MODULE_DIR", moduleId.getMsaFile().getParent().replaceAll("(\\\\)", "/"));\r
+ getProject().setProperty("MODULE_RELATIVE_DIR", moduleId.getModuleRelativePath().replaceAll("(\\\\)", "/"));\r
+ \r
+ //\r
+ // SUBSYSTEM\r
+ //\r
+ String[][] subsystemMap = { { "BASE", "EFI_BOOT_SERVICE_DRIVER"},\r
+ { "SEC", "EFI_BOOT_SERVICE_DRIVER" }, \r
+ { "PEI_CORE", "EFI_BOOT_SERVICE_DRIVER" }, \r
+ { "PEIM", "EFI_BOOT_SERVICE_DRIVER" }, \r
+ { "DXE_CORE", "EFI_BOOT_SERVICE_DRIVER" },\r
+ { "DXE_DRIVER", "EFI_BOOT_SERVICE_DRIVER" }, \r
+ { "DXE_RUNTIME_DRIVER", "EFI_RUNTIME_DRIVER" }, \r
+ { "DXE_SAL_DRIVER", "EFI_BOOT_SERVICE_DRIVER" }, \r
+ { "DXE_SMM_DRIVER", "EFI_BOOT_SERVICE_DRIVER" }, \r
+ { "TOOL", "EFI_BOOT_SERVICE_DRIVER" }, \r
+ { "UEFI_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
+ { "UEFI_APPLICATION", "EFI_APPLICATION" }, \r
+ { "USER_DEFINED", "EFI_BOOT_SERVICE_DRIVER"} }; \r
+ \r
+ String subsystem = "EFI_BOOT_SERVICE_DRIVER";\r
+ for (int i = 0; i < subsystemMap.length; i++) {\r
+ if (moduleId.getModuleType().equalsIgnoreCase(subsystemMap[i][0])) {\r
+ subsystem = subsystemMap[i][1];\r
+ break ;\r
}\r
}\r
- }\r
-\r
- /**\r
- Get file name from node. If some wrong, return string with zero length. \r
- \r
- @param node Filename node of MSA/MBD or specified in each Section\r
- @return File name\r
- **/\r
- private String getFilename(Node node) {\r
- String path = null;\r
- String filename = "${MODULE_DIR}" + File.separatorChar;\r
- String str = "";\r
- try {\r
- FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);\r
- str = file.getFilename().getStringValue().trim();\r
- path = file.getFilename().getPath();\r
- } catch (Exception e) {\r
- str = "";\r
- }\r
- if (path != null) {\r
- filename += path + File.separatorChar + str;\r
- } else {\r
- filename += str;\r
- }\r
- return getProject().replaceProperties(filename);\r
- }\r
-\r
- /**\r
- Get file type from node. If some wrong or not specified, return \r
- <code>null</code>. \r
- \r
- @param node Filename node of MSA/MBD or specified in each Section\r
- @return File type\r
- **/\r
- private String getFiletype(Node node) {\r
- String str = null;\r
- try {\r
- FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);\r
- str = file.getFilename().getFileType();\r
- } catch (Exception e) {\r
- str = null;\r
- }\r
- return str;\r
- }\r
-\r
- /**\r
- Return all source files but AutoGen.c.\r
- \r
- @return source files Node array\r
- **/\r
- public Node[] getSourceFiles() {\r
- XmlObject[] files = SurfaceAreaQuery.getSourceFiles(arch);\r
- if (files == null) {\r
- return new Node[0];\r
+ getProject().setProperty("SUBSYSTEM", subsystem);\r
+ \r
+ //\r
+ // ENTRYPOINT\r
+ //\r
+ if (arch.equalsIgnoreCase("EBC")) {\r
+ getProject().setProperty("ENTRYPOINT", "EfiStart");\r
}\r
- Vector<Node> vector = new Vector<Node>();\r
- for (int i = 0; i < files.length; i++) {\r
- vector.addElement(files[i].getDomNode());\r
+ else {\r
+ getProject().setProperty("ENTRYPOINT", "_ModuleEntryPoint");\r
}\r
+ \r
//\r
- // To be consider sourcefiles from Sections\r
+ // LIBS, OBJECTS, SDB_FILES\r
//\r
- return vector.toArray(new Node[vector.size()]);\r
- }\r
-\r
- /**\r
- Get current module's base name. \r
- \r
- @return base name\r
- **/\r
- public String getBaseName() {\r
- return baseName;\r
- }\r
-\r
- /**\r
- Set MBD surface area file. For ANT use.\r
- \r
- @param mbdFilename Surface Area file\r
- **/\r
- public void setMbdFilename(File mbdFilename) {\r
- this.mbdFilename = mbdFilename;\r
- }\r
-\r
- /**\r
- Set MSA surface area file. For ANT use.\r
- \r
- @param msaFilename Surface Area file\r
- **/\r
- public void setMsaFilename(File msaFilename) {\r
- this.msaFilename = msaFilename;\r
+ getProject().setProperty("OBJECTS", "");\r
+ getProject().setProperty("SDB_FILES", "");\r
+ getProject().setProperty("LIBS", "");\r
}\r
\r
- /**\r
- Compile flags setup. \r
- \r
- <p> Take command <code>CC</code> and arch <code>IA32</code> for example, \r
- Those flags are from <code>ToolChainFactory</code>: </p>\r
- <ul>\r
- <li> IA32_CC </li>\r
- <li> IA32_CC_STD_FLAGS </li>\r
- <li> IA32_CC_GLOBAL_FLAGS </li>\r
- <li> IA32_CC_GLOBAL_ADD_FLAGS </li>\r
- <li> IA32_CC_GLOBAL_SUB_FLAGS </li>\r
- </ul>\r
- Those flags can user-define: \r
- <ul>\r
- <li> IA32_CC_PROJ_FLAGS </li>\r
- <li> IA32_CC_PROJ_ADD_FLAGS </li>\r
- <li> IA32_CC_PROJ_SUB_FLAGS </li>\r
- <li> CC_PROJ_FLAGS </li>\r
- <li> CC_PROJ_ADD_FLAGS </li>\r
- <li> CC_PROJ_SUB_FLAGS </li>\r
- <li> CC_FLAGS </li>\r
- <li> IA32_CC_FLAGS </li>\r
- </ul>\r
- \r
- <p> The final flags is composed of STD, GLOBAL and PROJ. If CC_FLAGS or\r
- IA32_CC_FLAGS is specified, STD, GLOBAL and PROJ will not affect. </p>\r
- \r
- Note that the <code>ToolChainFactory</code> executes only once \r
- during whole build process. \r
- **/\r
- private void flagsSetup() {\r
- Project project = getProject();\r
- //\r
- // If ToolChain has been set up before, do nothing.\r
- //\r
- ToolChainFactory toolChainFactory = new ToolChainFactory(project);\r
- toolChainFactory.setupToolChain();\r
-\r
- String[] cmd = ToolChainFactory.commandType;\r
- Set<String> addSet = new HashSet<String>(40);\r
- Set<String> subSet = new HashSet<String>(40);\r
- for (int i = 0; i < cmd.length; i++) {\r
- String str = ToolChainFactory.getValue(arch + "_" + cmd[i]);\r
+ private void getCompilerFlags(String target, String toolchain, FpdModuleIdentification fpdModuleId) throws EdkException {\r
+ String[] cmd = GlobalData.getToolChainInfo().getCommands();\r
+ for ( int m = 0; m < cmd.length; m++) {\r
//\r
- // Command line path+command name\r
- //\r
- if (str != null) {\r
- project.setProperty(cmd[i], str);\r
- }\r
- //\r
- // ARCH_CMD_STD_FLAGS\r
- //\r
- str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_STD_FLAGS");\r
- if (str != null) {\r
- putFlagsToSet(addSet, str);\r
- project.setProperty(cmd[i] + "_STD_FLAGS", str);\r
- }\r
+ // Set cmd, like CC, DLINK\r
//\r
- // ARCH_CMD_GLOBAL_FLAGS\r
- //\r
- str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_FLAGS");\r
- if (str != null) {\r
- putFlagsToSet(addSet, str);\r
- }\r
- //\r
- // ARCH_CMD_GLOBAL_ADD_FLAGS\r
- //\r
- str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_ADD_FLAGS");\r
- if (str != null) {\r
- putFlagsToSet(addSet, str);\r
- }\r
- //\r
- // ARCH_CMD_GLOBAL_SUB_FLAGS\r
- //\r
- str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_SUB_FLAGS");\r
- if (str != null) {\r
- putFlagsToSet(subSet, str);\r
- }\r
+ String[] key = new String[]{target, toolchain, fpdModuleId.getArch(), cmd[m], null};\r
+ key[4] = "PATH";\r
+ String cmdPath = GlobalData.getCommandSetting(key, fpdModuleId);\r
+ key[4] = "NAME";\r
+ String cmdName = GlobalData.getCommandSetting(key, fpdModuleId);\r
+ File cmdFile = new File(cmdPath + File.separatorChar + cmdName);\r
+ getProject().setProperty(cmd[m], cmdFile.getPath().replaceAll("(\\\\)", "/"));\r
+ \r
//\r
- // ARCH_CMD_PROJ_FLAGS\r
+ // set CC_FLAGS\r
//\r
- str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_FLAGS");\r
- if (str != null) {\r
- putFlagsToSet(addSet, str);\r
- }\r
+ key[4] = "FLAGS";\r
+ String cmdFlags = GlobalData.getCommandSetting(key, fpdModuleId);\r
+ Set<String> addset = new LinkedHashSet<String>();\r
+ Set<String> subset = new LinkedHashSet<String>();\r
+ putFlagsToSet(addset, cmdFlags);\r
+ getProject().setProperty(cmd[m] + "_FLAGS", getProject().replaceProperties(getFlags(addset, subset)));\r
+ \r
//\r
- // ARCH_CMD_PROG_FLAGS\r
+ // Set CC_EXT\r
//\r
- str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_ADD_FLAGS");\r
- if (str != null) {\r
- putFlagsToSet(addSet, str);\r
+ key[4] = "EXT";\r
+ String extName = GlobalData.getCommandSetting(key, fpdModuleId);\r
+ if ( extName != null && ! extName.equalsIgnoreCase("")) {\r
+ getProject().setProperty(cmd[m] + "_EXT", extName);\r
}\r
- //\r
- // ARCH_CMD_PROG_FLAGS\r
- //\r
- str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_SUB_FLAGS");\r
- if (str != null) {\r
- putFlagsToSet(subSet, str);\r
+ else {\r
+ getProject().setProperty(cmd[m] + "_EXT", "");\r
}\r
+ \r
//\r
- // CMD_PROJ_FLAGS\r
+ // set CC_FAMILY\r
//\r
- str = project.getProperty(cmd[i] + "_PROJ_FLAGS");\r
- if (str != null) {\r
- putFlagsToSet(addSet, str);\r
+ key[4] = "FAMILY";\r
+ String toolChainFamily = GlobalData.getCommandSetting(key, fpdModuleId);\r
+ if (toolChainFamily != null) {\r
+ getProject().setProperty(cmd[m] + "_FAMILY", toolChainFamily);\r
}\r
+ \r
//\r
- // CMD_PROG_FLAGS\r
+ // set CC_SPATH\r
//\r
- str = project.getProperty(cmd[i] + "_PROJ_ADD_FLAGS");\r
- if (str != null) {\r
- putFlagsToSet(addSet, str);\r
+ key[4] = "SPATH";\r
+ String spath = GlobalData.getCommandSetting(key, fpdModuleId);\r
+ if (spath != null) {\r
+ getProject().setProperty(cmd[m] + "_SPATH", spath.replaceAll("(\\\\)", "/"));\r
}\r
- //\r
- // CMD_PROG_FLAGS\r
- //\r
- str = project.getProperty(cmd[i] + "_PROJ_SUB_FLAGS");\r
- if (str != null) {\r
- putFlagsToSet(subSet, str);\r
+ else {\r
+ getProject().setProperty(cmd[m] + "_SPATH", "");\r
}\r
+ \r
//\r
- // If IA32_CC_FLAGS or IA32_LIB_FLAGS .. has defined in BuildOptions\r
+ // set CC_DPATH\r
//\r
- if ((str = project.getProperty(arch + "_" + cmd[i] + "_FLAGS")) != null) {\r
- project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));\r
- addSet.clear();\r
- subSet.clear();\r
- putFlagsToSet(addSet, project.replaceProperties(str));\r
- project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));\r
- addSet.clear();\r
- subSet.clear();\r
+ key[4] = "DPATH";\r
+ String dpath = GlobalData.getCommandSetting(key, fpdModuleId);\r
+ if (dpath != null) {\r
+ getProject().setProperty(cmd[m] + "_DPATH", dpath.replaceAll("(\\\\)", "/"));\r
}\r
- //\r
- // If CC_FLAGS or LIB_FLAGS .. has defined in BuildOptions\r
- //\r
- else if ((str = project.getProperty(cmd[i] + "_FLAGS")) != null) {\r
- project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));\r
- addSet.clear();\r
- subSet.clear();\r
- putFlagsToSet(addSet, project.replaceProperties(str));\r
- project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));\r
- addSet.clear();\r
- subSet.clear();\r
- } else {\r
- project.setProperty(cmd[i] + "_FLAGS", getFlags(addSet, subSet));\r
- addSet.clear();\r
- subSet.clear();\r
+ else {\r
+ getProject().setProperty(cmd[m] + "_DPATH", "");\r
}\r
}\r
- project.setProperty("C_FLAGS", project.getProperty("CC_FLAGS"));\r
+ }\r
+ \r
+ public void setMsaFile(File msaFile) {\r
+ this.msaFile = msaFile;\r
}\r
\r
/**\r
- Initialize some properties will be used in current module build, including\r
- user-defined option from <em>Option</em> of <em>BuildOptions</em> in \r
- surface area. \r
+ Method is for ANT to initialize MSA file. \r
+ \r
+ @param msaFilename MSA file name\r
**/\r
- private void updateParameters() {\r
- getProject().setProperty("OBJECTS", "");\r
- getProject().setProperty("SDB_FILES", "");\r
- getProject().setProperty("BASE_NAME", baseName);\r
- if (map.get("MsaHeader") != null) {\r
- guid = SurfaceAreaQuery.getModuleGuid();//header.getGuid().getStringValue();\r
- componentType = SurfaceAreaQuery.getComponentType();//header.getComponentType().toString();\r
- if (!componentType.equalsIgnoreCase("LIBRARY")) {\r
- flag = GlobalData.MSA_AND_MBD;\r
- } else {\r
- flag = GlobalData.LIBMSA_AND_LIBMBD;\r
- }\r
- } \r
+ public void setMsaFile(String msaFilename) {\r
+ String moduleDir = getProject().getProperty("MODULE_DIR");\r
+ \r
+ //\r
+ // If is Single Module Build, then use the Base Dir defined in build.xml\r
+ //\r
+ if (moduleDir == null) {\r
+ moduleDir = getProject().getBaseDir().getPath();\r
+ }\r
+ msaFile = new File(moduleDir + File.separatorChar + msaFilename);\r
+ }\r
+ \r
+ public void addConfiguredModuleItem(ModuleItem moduleItem) {\r
+ PackageIdentification packageId = new PackageIdentification(moduleItem.getPackageGuid(), moduleItem.getPackageVersion());\r
+ ModuleIdentification moduleId = new ModuleIdentification(moduleItem.getModuleGuid(), moduleItem.getModuleVersion());\r
+ moduleId.setPackage(packageId);\r
+ this.moduleId = moduleId;\r
+ }\r
+ \r
+ /**\r
+ Add a property. \r
+ \r
+ @param p property\r
+ **/\r
+ public void addProperty(Property p) {\r
+ properties.addElement(p);\r
+ }\r
+\r
+ public void setType(String type) {\r
+ this.type = type;\r
+ }\r
+ \r
+ private void applyBuild(String buildTarget, String buildTagname, FpdModuleIdentification fpdModuleId) throws EdkException{\r
+ //\r
+ // AutoGen\r
+ //\r
+ \r
+ AutoGen autogen = new AutoGen(getProject().getProperty("FV_DIR"), getProject().getProperty("DEST_DIR_DEBUG"), fpdModuleId.getModule(),fpdModuleId.getArch());\r
+ autogen.genAutogen();\r
+ \r
+ \r
+ //\r
+ // Get compiler flags\r
+ //\r
+ getCompilerFlags(buildTarget, buildTagname, fpdModuleId);\r
\r
- else if (map.get("MsaLibHeader") != null) {\r
- flag = GlobalData.LIBMSA_AND_LIBMBD;\r
- MsaLibHeaderDocument.MsaLibHeader header = ((MsaLibHeaderDocument) map.get("MsaLibHeader"))\r
- .getMsaLibHeader();\r
- guid = header.getGuid().getStringValue();\r
- componentType = header.getComponentType().toString();\r
+ //\r
+ // Prepare LIBS\r
+ //\r
+ ModuleIdentification[] libinstances = SurfaceAreaQuery.getLibraryInstance(fpdModuleId.getArch());\r
+ String propertyLibs = "";\r
+ for (int i = 0; i < libinstances.length; i++) {\r
+ propertyLibs += " " + getProject().getProperty("BIN_DIR") + File.separatorChar + libinstances[i].getName() + ".lib";\r
}\r
+ getProject().setProperty("LIBS", propertyLibs.replaceAll("(\\\\)", "/"));\r
\r
- if (componentType != null) {\r
- getProject().setProperty("COMPONENT_TYPE", componentType);\r
+ //\r
+ // if it is CUSTOM_BUILD\r
+ // then call the exist BaseName_build.xml directly.\r
+ //\r
+ if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
+ GlobalData.log.info("Call user-defined " + moduleId.getName() + "_build.xml");\r
+ Ant ant = new Ant();\r
+ ant.setProject(getProject());\r
+ ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml");\r
+ ant.setInheritAll(true);\r
+ ant.init();\r
+ ant.execute();\r
+ return ;\r
}\r
-\r
- if (guid != null) {\r
- getProject().setProperty("FILE_GUID", guid);\r
+ \r
+ //\r
+ // Generate ${BASE_NAME}_build.xml\r
+ // TBD\r
+ //\r
+ String ffsKeyword = SurfaceAreaQuery.getModuleFfsKeyword();\r
+ ModuleBuildFileGenerator fileGenerator = new ModuleBuildFileGenerator(getProject(), ffsKeyword, fpdModuleId);\r
+ String buildFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
+ fileGenerator.genBuildFile(buildFilename);\r
+ \r
+ //\r
+ // Ant call ${BASE_NAME}_build.xml\r
+ //\r
+ Ant ant = new Ant();\r
+ ant.setProject(getProject());\r
+ ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml");\r
+ ant.setInheritAll(true);\r
+ ant.init();\r
+ ant.execute();\r
+ }\r
+ \r
+ private void applyClean(FpdModuleIdentification fpdModuleId){\r
+ //\r
+ // if it is CUSTOM_BUILD\r
+ // then call the exist BaseName_build.xml directly.\r
+ //\r
+ if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
+ GlobalData.log.info("Call user-defined " + moduleId.getName() + "_build.xml");\r
+ Ant ant = new Ant();\r
+ ant.setProject(getProject());\r
+ ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml");\r
+ ant.setTarget("clean");\r
+ ant.setInheritAll(true);\r
+ ant.init();\r
+ ant.execute();\r
+ return ;\r
}\r
+ \r
+ Ant ant = new Ant();\r
+ ant.setProject(getProject());\r
+ ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml");\r
+ ant.setTarget("clean");\r
+ ant.setInheritAll(true);\r
+ ant.init();\r
+ ant.execute();\r
+ \r
//\r
- // Get all options and set to properties\r
+ // Delete current module's DEST_DIR_OUTPUT\r
+ // TBD\r
+ }\r
+ \r
+ private void applyCleanall(FpdModuleIdentification fpdModuleId){\r
//\r
- String[][] options = SurfaceAreaQuery.getOptions(arch);\r
- for (int i = 0; i < options.length; i++) {\r
- if (options[i][0] != null && options[i][1] != null) {\r
- getProject().setProperty(options[i][0], getProject().replaceProperties(options[i][1]));\r
- }\r
+ // if it is CUSTOM_BUILD\r
+ // then call the exist BaseName_build.xml directly.\r
+ //\r
+ if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
+ GlobalData.log.info("Call user-defined " + moduleId.getName() + "_build.xml");\r
+ Ant ant = new Ant();\r
+ ant.setProject(getProject());\r
+ ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml");\r
+ ant.setTarget("cleanall");\r
+ ant.setInheritAll(true);\r
+ ant.init();\r
+ ant.execute();\r
+ return ;\r
}\r
+ \r
+ Ant ant = new Ant();\r
+ ant.setProject(getProject());\r
+ ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml");\r
+ ant.setTarget("cleanall");\r
+ ant.setInheritAll(true);\r
+ ant.init();\r
+ ant.execute();\r
+ \r
+ //\r
+ // Delete current module's DEST_DIR_OUTPUT\r
+ // TBD\r
+ }\r
+\r
\r
- buildType = getProject().getProperty("BUILD_TYPE");\r
- if (buildType == null) {\r
- buildType = componentType;\r
- }\r
\r
- }\r
\r
/**\r
Separate the string and instore in set.\r
@param str string to separate\r
**/\r
private void putFlagsToSet(Set<String> set, String str) {\r
+ if (str == null || str.length() == 0) {\r
+ return;\r
+ }\r
+\r
Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");\r
Matcher matcher = myPattern.matcher(str + " ");\r
while (matcher.find()) {\r
String item = str.substring(matcher.start(1), matcher.end(1));\r
- if (!set.contains(item)) {\r
- set.add(item);\r
- }\r
+ set.add(item);\r
}\r
}\r
\r
add.removeAll(sub);\r
Iterator iter = add.iterator();\r
while (iter.hasNext()) {\r
- String str = getProject().replaceProperties((String) iter.next());\r
+ String str = (String) iter.next();\r
result += str.substring(1, str.length() - 1) + " ";\r
}\r
return result;\r
@return flags with original format\r
**/\r
private String getRawFlags(Set<String> add, Set<String> sub) {\r
- String result = "";\r
+ String result = null;\r
add.removeAll(sub);\r
Iterator iter = add.iterator();\r
while (iter.hasNext()) {\r
- String str = getProject().replaceProperties((String) iter.next());\r
+ String str = (String) iter.next();\r
result += "\"" + str.substring(1, str.length() - 1) + "\", ";\r
}\r
return result;\r
}\r
\r
- /**\r
- Set base name. For ANT use.\r
- \r
- @param baseName Base name\r
- **/\r
- public void setBaseName(String baseName) {\r
- this.baseName = baseName;\r
+ private String parseOptionString(String optionString, Set<String> addSet, Set<String> subSet) {\r
+ boolean overrideOption = false;\r
+ Pattern pattern = Pattern.compile("ADD\\.\\[(.+)\\]");\r
+ Matcher matcher = pattern.matcher(optionString);\r
+\r
+ while (matcher.find()) {\r
+ overrideOption = true;\r
+ String addOption = optionString.substring(matcher.start(1), matcher.end(1)).trim();\r
+ putFlagsToSet(addSet, addOption);\r
+ \r
+ }\r
+\r
+ pattern = Pattern.compile("SUB\\.\\[(.+)\\]");\r
+ matcher = pattern.matcher(optionString);\r
+\r
+ while (matcher.find()) {\r
+ overrideOption = true;\r
+ String subOption = optionString.substring(matcher.start(1), matcher.end(1)).trim();\r
+ putFlagsToSet(subSet, subOption);\r
+ }\r
+\r
+ if (overrideOption == true) {\r
+ return null;\r
+ }\r
+\r
+ return optionString;\r
+ }\r
+ \r
+ private void pushProperties() {\r
+ backupPropertiesStack.push(getProject().getProperties());\r
+ }\r
+ \r
+ private void popProperties() {\r
+ Hashtable backupProperties = backupPropertiesStack.pop();\r
+ Set keys = backupProperties.keySet();\r
+ Iterator iter = keys.iterator();\r
+ while (iter.hasNext()) {\r
+ String item = (String)iter.next();\r
+ getProject().setProperty(item, (String)backupProperties.get(item));\r
+ }\r
}\r
\r
+ public void setSingleModuleBuild(boolean isSingleModuleBuild) {\r
+ this.isSingleModuleBuild = isSingleModuleBuild;\r
+ }\r
}\r