package org.tianocore.build;\r
\r
import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.InputStream;\r
import java.util.Vector;\r
\r
import javax.xml.namespace.QName;\r
-import javax.xml.parsers.DocumentBuilder;\r
-import javax.xml.parsers.DocumentBuilderFactory;\r
\r
import org.apache.tools.ant.BuildException;\r
import org.apache.tools.ant.Project;\r
import org.apache.xmlbeans.XmlCursor;\r
-import org.apache.xmlbeans.XmlObject;\r
+import org.tianocore.BuildOptionsDocument;\r
+import org.tianocore.build.global.GlobalData;\r
+import org.tianocore.build.global.SurfaceAreaQuery;\r
+import org.tianocore.build.id.FpdModuleIdentification;\r
+import org.tianocore.common.definitions.EdkDefinitions;\r
+import org.tianocore.common.logger.EdkLog;\r
import org.w3c.dom.Document;\r
import org.w3c.dom.Element;\r
-import org.w3c.dom.NamedNodeMap;\r
-import org.w3c.dom.Node;\r
-import org.w3c.dom.NodeList;\r
\r
/** \r
<p><code>FfsProcess</code> is a class to find the corresponding FFS layout. </p>\r
\r
- <p>Property <code>COMMON_FILE</code> specified which file to search. The element\r
- in <code>COMMON_FILE</code> is like following: </p>\r
+ <p>The FFS Layout is like following: </p>\r
\r
<pre>\r
<Ffs type="APPLICATION">\r
**/\r
public class FfsProcess {\r
\r
- ///\r
- /// Xml Document Node for corresponding FFS layout\r
- ///\r
- private Node ffs;\r
+ private BuildOptionsDocument.BuildOptions.Ffs ffsXmlObject;\r
\r
///\r
/// ANT script to call GenFfs\r
///\r
/// mapping from section type to section output file extension\r
///\r
- public static final String[][] sectionExt = { { "EFI_SECTION_FREEFORM_SUBTYPE_GUID", ".sec" },\r
- { "EFI_SECTION_VERSION", ".ver" },\r
- { "EFI_SECTION_USER_INTERFACE", ".ui" },\r
- { "EFI_SECTION_DXE_DEPEX", ".dpx" },\r
- { "EFI_SECTION_PEI_DEPEX", ".dpx" }, \r
- { "EFI_SECTION_PE32", ".pe32" },\r
- { "EFI_SECTION_PIC", ".pic" }, \r
- { "EFI_SECTION_TE", ".tes" },\r
- { "EFI_SECTION_RAW", ".sec" }, \r
- { "EFI_SECTION_COMPRESSION", ".sec" },\r
- { "EFI_SECTION_GUID_DEFINED", ".sec" },\r
- { "EFI_SECTION_COMPATIBILITY16", ".sec" },\r
- { "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", ".sec" } };\r
+ public static final String[][] sectionExt = EdkDefinitions.SectionTypeExtensions;\r
\r
/**\r
search in the type, if componentType is listed in type, return true; \r
}\r
\r
/**\r
- Find the corresponding FFS layout in <code>COMMON_FILE</code> if it\r
- does not specify in module's surface area. \r
+ Find the corresponding FFS layout in <code>FPD</code>. \r
\r
@param buildType Current module's component type\r
@param project Ant project\r
@return whether find the corresponding FFS layout\r
@throws BuildException\r
- If specified COMMON_FILE XML file is not valide.\r
+ If can't find FFS Layout in FPD.\r
**/\r
- public boolean initSections(String buildType, Project project) throws BuildException {\r
- //\r
- // first try to sections defined in PLATFORM level\r
+ public boolean initSections(String buildType, Project project, FpdModuleIdentification fpdModuleId) throws BuildException {\r
//\r
-\r
- //\r
- // if module specify sections itself, it's okay\r
- // otherwise find sections from WORKSPACE default setting with\r
- // ComponentType\r
+ // Try to find Ffs layout from FPD file\r
//\r
- if (ffs == null) {\r
- File file = new File(project.getProperty("COMMON_FILE"));\r
- //\r
- // if common file is not existed, just return\r
- //\r
- if (!file.exists()) {\r
- return false;\r
- }\r
- DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();\r
- try {\r
- DocumentBuilder dombuilder = domfac.newDocumentBuilder();\r
- InputStream is = new FileInputStream(file);\r
- Document doc = dombuilder.parse(is);\r
- Element root = doc.getDocumentElement();\r
- NodeList items = root.getChildNodes();\r
- for (int i = 0; i < items.getLength(); i++) {\r
- Node node = items.item(i);\r
- if (node.getNodeType() == Node.ELEMENT_NODE) {\r
- String nodeName = node.getNodeName();\r
- if (nodeName.equalsIgnoreCase("Ffs")) {\r
- NamedNodeMap attr = node.getAttributes();\r
- Node type = attr.getNamedItem("type");\r
- if (type != null) {\r
- if (isMatch(type.getTextContent(), buildType)) {\r
- ffs = node;\r
- return true;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- } catch (Exception e) {\r
- throw new BuildException("Parse COMMON_FILE [" + file.getPath() + "] error!\n" + e.getMessage());\r
+ SurfaceAreaQuery saq = new SurfaceAreaQuery(GlobalData.getFpdBuildOptionsMap());\r
+ BuildOptionsDocument.BuildOptions.Ffs[] ffsArray = saq.getFpdFfs();\r
+ for (int i = 0; i < ffsArray.length; i++) {\r
+ if (isMatch(ffsArray[i].getFfsKey(), buildType)) {\r
+ ffsXmlObject = ffsArray[i];\r
+ return true;\r
}\r
}\r
- if (ffs == null) {\r
- return false;\r
+ \r
+ //\r
+ // If FfsFormatKey is not null, report exception and fail build\r
+ // Otherwise report warning message\r
+ //\r
+ if (buildType == null) {\r
+ EdkLog.log(EdkLog.EDK_WARNING, "Warning: this module doesn't specify a FfsFormatKey. ");\r
} else {\r
- return true;\r
+ throw new BuildException("Can't find the FfsFormatKey [" + buildType + "] attribute in the FPD file!"); \r
}\r
+\r
+ return false;\r
}\r
\r
/**\r
**/\r
public String[] getGenSectionElements(Document document, String basename, String guid, String targetFilename) {\r
this.basename = basename;\r
- if (ffs == null) {\r
+ if (ffsXmlObject == null) {\r
return new String[0];\r
}\r
Vector<String> sectionList = new Vector<String>();\r
XmlCursor cursor = null;\r
- try {\r
- cursor = XmlObject.Factory.parse(ffs).newCursor();\r
- } catch (Exception e) {\r
- return null;\r
- }\r
+\r
+ cursor = ffsXmlObject.newCursor();\r
+\r
int mode = MODE_NONE;\r
- Element root = document.createElement("genffsfile");\r
- root.setAttribute("outputDir", "${BIN_DIR}");\r
- root.setAttribute("BaseName", basename);\r
- root.setAttribute("fileGuid", guid);\r
- cursor.toFirstChild();\r
+ Element genffsfileEle = document.createElement("genffsfile");\r
+ genffsfileEle.setAttribute("outputDir", "${BIN_DIR}");\r
+ genffsfileEle.setAttribute("moduleType", "${MODULE_TYPE}");\r
+ genffsfileEle.setAttribute("BaseName", basename);\r
+ genffsfileEle.setAttribute("fileGuid", guid);\r
+\r
if (cursor.toFirstChild()) {\r
do {\r
if (cursor.getName().getLocalPart().equalsIgnoreCase("Attribute")) {\r
String name = cursor.getAttributeText(new QName("Name"));\r
String value = cursor.getAttributeText(new QName("Value"));\r
- root.setAttribute(changeAttributeName(name), value);\r
+ genffsfileEle.setAttribute(changeAttributeName(name), value);\r
} else if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {\r
cursor.push();\r
- dealSection(mode, document, root, cursor, sectionList);\r
+ dealSection(mode, document, genffsfileEle, cursor, sectionList);\r
cursor.pop();\r
} else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {\r
cursor.push();\r
- dealSections(mode, document, root, cursor, sectionList);\r
+ dealSections(mode, document, genffsfileEle, cursor, sectionList);\r
cursor.pop();\r
}\r
} while (cursor.toNextSibling());\r
outofdateEle.appendChild(sourceEle);\r
Element targetEle = document.createElement("targetfiles");\r
Element fileEle = document.createElement("file");\r
- fileEle.setAttribute("name", "${BIN_DIR}\\" + targetFilename);\r
+ fileEle.setAttribute("name", "${BIN_DIR}" + File.separatorChar + targetFilename);\r
targetEle.appendChild(fileEle);\r
outofdateEle.appendChild(targetEle);\r
Element sequentialEle = document.createElement("sequential");\r
- sequentialEle.appendChild(root);\r
+ sequentialEle.appendChild(genffsfileEle);\r
outofdateEle.appendChild(sequentialEle);\r
ffsNode = outofdateEle;\r
return result;\r
**/\r
private void dealSections(int mode, Document doc, Element root, XmlCursor cursor, Vector<String> list) {\r
String type = cursor.getAttributeText(new QName("EncapsulationType"));\r
- if (type == null) {\r
+ String toolName = cursor.getAttributeText(new QName("ToolName"));\r
+ String sectType = cursor.getAttributeText(new QName("SectionType"));\r
+ if (type == null && sectType == null) {\r
if (cursor.toFirstChild()) {\r
do {\r
if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {\r
return;\r
}\r
Element ele;\r
- if (type.equalsIgnoreCase("COMPRESS")) {\r
+ Element toolEle = null;\r
+ if (type.equalsIgnoreCase("COMPRESS") && (toolName == null || toolName.equalsIgnoreCase(""))) {\r
mode = MODE_COMPRESS;\r
//\r
- // <compress compressName = "dummy">\r
- //\r
- ele = doc.createElement("compress");\r
- ele.setAttribute("compressName", "dummy");\r
+ // <gensection sectiontype="EFI_SECTION_COMPRESSION"> \r
+ // \r
+ ele = doc.createElement("gensection");\r
+ ele.setAttribute("sectionType", "EFI_SECTION_COMPRESSION");\r
+ \r
} else {\r
mode = MODE_GUID_DEFINED;\r
//\r
+ // <gensection sectiontype="EFI_SECTION_GUID_DEFINED">\r
+ // \r
+ ele = doc.createElement("gensection");\r
+ if (type != null) {\r
+ ele.setAttribute("sectiontype", "EFI_SECTION_GUID_DEFINED");\r
+ } else {\r
+ ele.setAttribute("sectiontype", sectType);\r
+ }\r
+ //\r
// <tool toolName="${OEMTOOLPATH}\toolname"\r
// outputPath = "${DEST_DIR_OUTPUT}">\r
//\r
- ele = doc.createElement("tool");\r
- ele.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "Bin"\r
+ toolEle = doc.createElement("tool");\r
+ if (toolName == null || toolName.equalsIgnoreCase("")) {\r
+ toolEle.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "bin"\r
+ File.separatorChar + "GenCRC32Section");\r
- ele.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");\r
+ }else{\r
+ File toolExe = new File(toolName);\r
+ //\r
+ // If <Tool> element exist, add sub element under <tool> . \r
+ // \r
+ if (toolExe.isAbsolute()) {\r
+ toolEle.setAttribute("toolName", toolName);\r
+ } else {\r
+ toolEle.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "bin"\r
+ + File.separatorChar + toolName);\r
+ }\r
+ }\r
+ \r
+ toolEle.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");\r
+ ele.appendChild(toolEle);\r
}\r
if (cursor.toFirstChild()) {\r
do {\r
if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {\r
cursor.push();\r
- dealSection(mode, doc, ele, cursor, list);\r
+ if (toolEle == null) {\r
+ dealSection(mode, doc, ele, cursor, list);\r
+ } else {\r
+ dealSection(mode, doc, toolEle, cursor, list);\r
+ }\r
+ \r
cursor.pop();\r
} else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {\r
cursor.push();\r
- dealSections(mode, doc, ele, cursor, list);\r
+ if (toolEle == null) {\r
+ dealSections(mode, doc, ele, cursor, list);\r
+ } else {\r
+ dealSections(mode, doc, toolEle, cursor, list);\r
+ }\r
+ \r
cursor.pop();\r
}\r
} while (cursor.toNextSibling());\r
**/\r
private void dealSection(int mode, Document doc, Element root, XmlCursor cursor, Vector<String> list) {\r
String type = cursor.getAttributeText(new QName("SectionType"));\r
- list.addElement(type);\r
+ \r
+ //\r
+ // Judge if file is specified? Yes, just use the file, else call Build Macro\r
+ // If fileName is null, means without FileNames specify in FPD file\r
+ //\r
+ String fileName = null;\r
+ cursor.push();\r
+ if (cursor.toFirstChild()) {\r
+ do {\r
+ if (cursor.getName().getLocalPart().equalsIgnoreCase("Filenames")) {\r
+ cursor.push();\r
+ if (cursor.toFirstChild()) {\r
+ do {\r
+ if (cursor.getName().getLocalPart().equalsIgnoreCase("Filename")) {\r
+ fileName = cursor.getTextValue();\r
+ }\r
+ } while (cursor.toNextSibling());\r
+ }\r
+ cursor.pop();\r
+ }\r
+ } while (cursor.toNextSibling());\r
+ }\r
+\r
+ cursor.pop();\r
+ \r
+ if (fileName == null) {\r
+ list.addElement(type);\r
+ }\r
if (mode == MODE_GUID_DEFINED) {\r
//\r
// <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>\r
//\r
Element ele = doc.createElement("input");\r
- ele.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));\r
+ if (fileName == null) {\r
+ ele.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));\r
+ } else {\r
+ ele.setAttribute("file", "${PLATFORM_DIR}" + File.separatorChar + fileName);\r
+ }\r
root.appendChild(ele);\r
} else {\r
//\r
// <sectFile fileName= "..."/>\r
//\r
Element ele = doc.createElement("sectFile");\r
- ele.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));\r
+ if (fileName == null) {\r
+ ele.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));\r
+ } else {\r
+ ele.setAttribute("fileName", "${PLATFORM_DIR}" + File.separatorChar + fileName);\r
+ }\r
root.appendChild(ele);\r
}\r
}\r
\r
/**\r
- Get the corresponding section file suffix.\r
+ Get the corresponding section file suffix.\r
\r
@param type Section type\r
@return Corresponding section file extension\r