2 File is FfsProcess class which is used to get the corresponding FFS layout
3 information for driver module.
5 Copyright (c) 2006, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 package org
.tianocore
.build
;
17 import java
.util
.Vector
;
19 import javax
.xml
.namespace
.QName
;
21 import org
.apache
.tools
.ant
.BuildException
;
22 import org
.apache
.tools
.ant
.Project
;
23 import org
.apache
.xmlbeans
.XmlCursor
;
24 import org
.tianocore
.BuildOptionsDocument
;
25 import org
.tianocore
.build
.global
.GlobalData
;
26 import org
.tianocore
.build
.global
.SurfaceAreaQuery
;
27 import org
.tianocore
.build
.id
.FpdModuleIdentification
;
28 import org
.tianocore
.common
.definitions
.EdkDefinitions
;
29 import org
.tianocore
.common
.logger
.EdkLog
;
30 import org
.w3c
.dom
.Document
;
31 import org
.w3c
.dom
.Element
;
34 <p><code>FfsProcess</code> is a class to find the corresponding FFS layout. </p>
36 <p>The FFS Layout is like following: </p>
39 <Ffs type="APPLICATION">
40 <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_APPLICATION" />
41 <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" />
42 <Sections EncapsulationType="Compress">
43 <Sections EncapsulationType="Guid-Defined">
44 <Section SectionType="EFI_SECTION_PE32" />
45 <Section SectionType="EFI_SECTION_USER_INTERFACE" />
46 <Section SectionType="EFI_SECTION_VERSION" />
54 public class FfsProcess
{
56 private BuildOptionsDocument
.BuildOptions
.Ffs ffsXmlObject
;
59 /// ANT script to call GenFfs
61 private Element ffsNode
= null;
66 private String basename
;
69 /// Sections type: normal
71 private static int MODE_NONE
= 0;
74 /// Sections type: compress
76 private static int MODE_COMPRESS
= 1;
79 /// Sections type: guid-define
81 private static int MODE_GUID_DEFINED
= 2;
84 /// mapping from section type to section output file extension
86 public static final String
[][] sectionExt
= EdkDefinitions
.SectionTypeExtensions
;
89 search in the type, if componentType is listed in type, return true;
90 otherwise return false.
92 @param type a list supported component type separated by comma
93 @param componentType current module component type
94 @return whether componentType is one of type
96 private boolean isMatch(String type
, String componentType
) {
97 String
[] items
= type
.split("[ \t]*,[ \t]*");
98 for (int i
= 0; i
< items
.length
; i
++) {
99 if (items
[i
].equalsIgnoreCase(componentType
)) {
107 Find the corresponding FFS layout in <code>FPD</code>.
109 @param buildType Current module's component type
110 @param project Ant project
111 @return whether find the corresponding FFS layout
112 @throws BuildException
113 If can't find FFS Layout in FPD.
115 public boolean initSections(String buildType
, Project project
, FpdModuleIdentification fpdModuleId
) throws BuildException
{
117 // Try to find Ffs layout from FPD file
119 SurfaceAreaQuery saq
= new SurfaceAreaQuery(GlobalData
.getFpdBuildOptionsMap());
120 BuildOptionsDocument
.BuildOptions
.Ffs
[] ffsArray
= saq
.getFpdFfs();
121 for (int i
= 0; i
< ffsArray
.length
; i
++) {
122 if (isMatch(ffsArray
[i
].getFfsKey(), buildType
)) {
123 ffsXmlObject
= ffsArray
[i
];
129 // If FfsFormatKey is not null, report exception and fail build
130 // Otherwise report warning message
132 if (buildType
== null) {
133 EdkLog
.log(EdkLog
.EDK_WARNING
, "Warning: this module doesn't specify a FfsFormatKey. ");
135 throw new BuildException("Can't find the FfsFormatKey [" + buildType
+ "] attribute in the FPD file!");
142 Recursive parse the FFS layout. Find out all section type here used.
144 @param document BaseName_build.xml Xml document
145 @param basename Module's base name
146 @param guid Module's GUID
147 @param targetFilename Module's final file name (GUID-BaseName.APP)
148 @return List of section type
150 public String
[] getGenSectionElements(Document document
, String basename
, String guid
, String targetFilename
) {
151 this.basename
= basename
;
152 if (ffsXmlObject
== null) {
153 return new String
[0];
155 Vector
<String
> sectionList
= new Vector
<String
>();
156 XmlCursor cursor
= null;
158 cursor
= ffsXmlObject
.newCursor();
160 int mode
= MODE_NONE
;
161 Element genffsfileEle
= document
.createElement("genffsfile");
162 genffsfileEle
.setAttribute("outputDir", "${BIN_DIR}");
163 genffsfileEle
.setAttribute("moduleType", "${MODULE_TYPE}");
164 genffsfileEle
.setAttribute("BaseName", basename
);
165 genffsfileEle
.setAttribute("fileGuid", guid
);
167 if (cursor
.toFirstChild()) {
169 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Attribute")) {
170 String name
= cursor
.getAttributeText(new QName("Name"));
171 String value
= cursor
.getAttributeText(new QName("Value"));
172 genffsfileEle
.setAttribute(changeAttributeName(name
), value
);
173 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
175 dealSection(mode
, document
, genffsfileEle
, cursor
, sectionList
);
177 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
179 dealSections(mode
, document
, genffsfileEle
, cursor
, sectionList
);
182 } while (cursor
.toNextSibling());
187 Element outofdateEle
= document
.createElement("OnDependency");
188 Element sourceEle
= document
.createElement("sourcefiles");
189 String
[] result
= new String
[sectionList
.size()];
190 for (int i
= 0; i
< sectionList
.size(); i
++) {
191 result
[i
] = (String
) sectionList
.get(i
);
192 Element pathEle
= document
.createElement("file");
193 pathEle
.setAttribute("name", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
194 + getSectionExt(result
[i
]));
195 sourceEle
.appendChild(pathEle
);
197 outofdateEle
.appendChild(sourceEle
);
198 Element targetEle
= document
.createElement("targetfiles");
199 Element fileEle
= document
.createElement("file");
200 fileEle
.setAttribute("name", "${BIN_DIR}" + File
.separatorChar
+ targetFilename
);
201 targetEle
.appendChild(fileEle
);
202 outofdateEle
.appendChild(targetEle
);
203 Element sequentialEle
= document
.createElement("sequential");
204 sequentialEle
.appendChild(genffsfileEle
);
205 outofdateEle
.appendChild(sequentialEle
);
206 ffsNode
= outofdateEle
;
211 Change the attribute name. For example:
214 Before change: FFS_ATTRIB_CHECKSUM
215 After change: ffsATTRIBCHECKSUM
218 @param name Original attribute name
219 @return Changed attribute name
221 private String
changeAttributeName(String name
) {
222 String
[] strs
= name
.split("_");
223 String str
= strs
[0].toLowerCase();
224 for (int j
= 1; j
< strs
.length
; j
++) {
231 Recursively deal with Sections. If sections does not specify a type, then omit it.
233 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
234 @param doc Xml Document
235 @param root Root Node
236 @param cursor Current FFS layout cursor
237 @param list List of section type here used
239 private void dealSections(int mode
, Document doc
, Element root
, XmlCursor cursor
, Vector
<String
> list
) {
240 String type
= cursor
.getAttributeText(new QName("EncapsulationType"));
242 if (cursor
.toFirstChild()) {
244 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
246 dealSection(mode
, doc
, root
, cursor
, list
);
248 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
250 dealSections(mode
, doc
, root
, cursor
, list
);
253 } while (cursor
.toNextSibling());
258 if (type
.equalsIgnoreCase("COMPRESS")) {
259 mode
= MODE_COMPRESS
;
261 // <compress compressName = "dummy">
263 ele
= doc
.createElement("compress");
264 ele
.setAttribute("compressName", "dummy");
266 mode
= MODE_GUID_DEFINED
;
268 // <tool toolName="${OEMTOOLPATH}\toolname"
269 // outputPath = "${DEST_DIR_OUTPUT}">
271 ele
= doc
.createElement("tool");
272 ele
.setAttribute("toolName", "${WORKSPACE_DIR}" + File
.separatorChar
+ "Tools" + File
.separatorChar
+ "bin"
273 + File
.separatorChar
+ "GenCRC32Section");
274 ele
.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");
276 if (cursor
.toFirstChild()) {
278 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
280 dealSection(mode
, doc
, ele
, cursor
, list
);
282 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
284 dealSections(mode
, doc
, ele
, cursor
, list
);
287 } while (cursor
.toNextSibling());
289 root
.appendChild(ele
);
293 Recursively deal with section.
295 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
296 @param doc Xml Document
297 @param root Root Node
298 @param cursor Current FFS layout cursor
299 @param list List of section type here used
301 private void dealSection(int mode
, Document doc
, Element root
, XmlCursor cursor
, Vector
<String
> list
) {
302 String type
= cursor
.getAttributeText(new QName("SectionType"));
305 // Judge if file is specified? Yes, just use the file, else call Build Macro
306 // If fileName is null, means without FileNames specify in FPD file
308 String fileName
= null;
310 if (cursor
.toFirstChild()) {
312 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Filenames")) {
314 if (cursor
.toFirstChild()) {
316 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Filename")) {
317 fileName
= cursor
.getTextValue();
319 } while (cursor
.toNextSibling());
323 } while (cursor
.toNextSibling());
328 if (fileName
== null) {
329 list
.addElement(type
);
331 if (mode
== MODE_GUID_DEFINED
) {
333 // <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>
335 Element ele
= doc
.createElement("input");
336 if (fileName
== null) {
337 ele
.setAttribute("file", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
+ getSectionExt(type
));
339 ele
.setAttribute("file", "${PLATFORM_DIR}" + File
.separatorChar
+ fileName
);
341 root
.appendChild(ele
);
344 // <sectFile fileName= "..."/>
346 Element ele
= doc
.createElement("sectFile");
347 if (fileName
== null) {
348 ele
.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
+ getSectionExt(type
));
350 ele
.setAttribute("fileName", "${PLATFORM_DIR}" + File
.separatorChar
+ fileName
);
352 root
.appendChild(ele
);
357 Get the corresponding section file suffix.
359 @param type Section type
360 @return Corresponding section file extension
362 private String
getSectionExt(String type
) {
363 for (int i
= 0; i
< sectionExt
.length
; i
++) {
364 if (sectionExt
[i
][0].equalsIgnoreCase(type
)) {
365 return sectionExt
[i
][1];
372 Return the ANT script to call GenFfs Tool.
374 @return ANT script to call GenFfs Tool
376 public Element
getFfsNode() {