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
.w3c
.dom
.Document
;
30 import org
.w3c
.dom
.Element
;
33 <p><code>FfsProcess</code> is a class to find the corresponding FFS layout. </p>
35 <p>The FFS Layout is like following: </p>
38 <Ffs type="APPLICATION">
39 <Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_APPLICATION" />
40 <Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" />
41 <Sections EncapsulationType="Compress">
42 <Sections EncapsulationType="Guid-Defined">
43 <Section SectionType="EFI_SECTION_PE32" />
44 <Section SectionType="EFI_SECTION_USER_INTERFACE" />
45 <Section SectionType="EFI_SECTION_VERSION" />
53 public class FfsProcess
{
55 private BuildOptionsDocument
.BuildOptions
.Ffs ffsXmlObject
;
58 /// ANT script to call GenFfs
60 private Element ffsNode
= null;
65 private String basename
;
68 /// Sections type: normal
70 private static int MODE_NONE
= 0;
73 /// Sections type: compress
75 private static int MODE_COMPRESS
= 1;
78 /// Sections type: guid-define
80 private static int MODE_GUID_DEFINED
= 2;
83 /// mapping from section type to section output file extension
85 public static final String
[][] sectionExt
= EdkDefinitions
.SectionTypeExtensions
;
88 search in the type, if componentType is listed in type, return true;
89 otherwise return false.
91 @param type a list supported component type separated by comma
92 @param componentType current module component type
93 @return whether componentType is one of type
95 private boolean isMatch(String type
, String componentType
) {
96 String
[] items
= type
.split("[ \t]*,[ \t]*");
97 for (int i
= 0; i
< items
.length
; i
++) {
98 if (items
[i
].equalsIgnoreCase(componentType
)) {
106 Find the corresponding FFS layout in <code>FPD</code>.
108 @param buildType Current module's component type
109 @param project Ant project
110 @return whether find the corresponding FFS layout
111 @throws BuildException
112 If can't find FFS Layout in FPD.
114 public boolean initSections(String buildType
, Project project
, FpdModuleIdentification fpdModuleId
) throws BuildException
{
116 // Try to find Ffs layout from FPD file
118 SurfaceAreaQuery
.push(GlobalData
.getFpdBuildOptions());
119 BuildOptionsDocument
.BuildOptions
.Ffs
[] ffsArray
= SurfaceAreaQuery
.getFpdFfs();
120 SurfaceAreaQuery
.pop();
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 System
.out
.println("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();
159 } catch (Exception e
) {
162 int mode
= MODE_NONE
;
163 Element genffsfileEle
= document
.createElement("genffsfile");
164 genffsfileEle
.setAttribute("outputDir", "${BIN_DIR}");
165 genffsfileEle
.setAttribute("moduleType", "${MODULE_TYPE}");
166 genffsfileEle
.setAttribute("BaseName", basename
);
167 genffsfileEle
.setAttribute("fileGuid", guid
);
169 if (cursor
.toFirstChild()) {
171 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Attribute")) {
172 String name
= cursor
.getAttributeText(new QName("Name"));
173 String value
= cursor
.getAttributeText(new QName("Value"));
174 genffsfileEle
.setAttribute(changeAttributeName(name
), value
);
175 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
177 dealSection(mode
, document
, genffsfileEle
, cursor
, sectionList
);
179 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
181 dealSections(mode
, document
, genffsfileEle
, cursor
, sectionList
);
184 } while (cursor
.toNextSibling());
189 Element outofdateEle
= document
.createElement("OnDependency");
190 Element sourceEle
= document
.createElement("sourcefiles");
191 String
[] result
= new String
[sectionList
.size()];
192 for (int i
= 0; i
< sectionList
.size(); i
++) {
193 result
[i
] = (String
) sectionList
.get(i
);
194 Element pathEle
= document
.createElement("file");
195 pathEle
.setAttribute("name", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
196 + getSectionExt(result
[i
]));
197 sourceEle
.appendChild(pathEle
);
199 outofdateEle
.appendChild(sourceEle
);
200 Element targetEle
= document
.createElement("targetfiles");
201 Element fileEle
= document
.createElement("file");
202 fileEle
.setAttribute("name", "${BIN_DIR}" + File
.separatorChar
+ targetFilename
);
203 targetEle
.appendChild(fileEle
);
204 outofdateEle
.appendChild(targetEle
);
205 Element sequentialEle
= document
.createElement("sequential");
206 sequentialEle
.appendChild(genffsfileEle
);
207 outofdateEle
.appendChild(sequentialEle
);
208 ffsNode
= outofdateEle
;
213 Change the attribute name. For example:
216 Before change: FFS_ATTRIB_CHECKSUM
217 After change: ffsATTRIBCHECKSUM
220 @param name Original attribute name
221 @return Changed attribute name
223 private String
changeAttributeName(String name
) {
224 String
[] strs
= name
.split("_");
225 String str
= strs
[0].toLowerCase();
226 for (int j
= 1; j
< strs
.length
; j
++) {
233 Recursively deal with Sections. If sections does not specify a type, then omit it.
235 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
236 @param doc Xml Document
237 @param root Root Node
238 @param cursor Current FFS layout cursor
239 @param list List of section type here used
241 private void dealSections(int mode
, Document doc
, Element root
, XmlCursor cursor
, Vector
<String
> list
) {
242 String type
= cursor
.getAttributeText(new QName("EncapsulationType"));
244 if (cursor
.toFirstChild()) {
246 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
248 dealSection(mode
, doc
, root
, cursor
, list
);
250 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
252 dealSections(mode
, doc
, root
, cursor
, list
);
255 } while (cursor
.toNextSibling());
260 if (type
.equalsIgnoreCase("COMPRESS")) {
261 mode
= MODE_COMPRESS
;
263 // <compress compressName = "dummy">
265 ele
= doc
.createElement("compress");
266 ele
.setAttribute("compressName", "dummy");
268 mode
= MODE_GUID_DEFINED
;
270 // <tool toolName="${OEMTOOLPATH}\toolname"
271 // outputPath = "${DEST_DIR_OUTPUT}">
273 ele
= doc
.createElement("tool");
274 ele
.setAttribute("toolName", "${WORKSPACE_DIR}" + File
.separatorChar
+ "Tools" + File
.separatorChar
+ "bin"
275 + File
.separatorChar
+ "GenCRC32Section");
276 ele
.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");
278 if (cursor
.toFirstChild()) {
280 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
282 dealSection(mode
, doc
, ele
, cursor
, list
);
284 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
286 dealSections(mode
, doc
, ele
, cursor
, list
);
289 } while (cursor
.toNextSibling());
291 root
.appendChild(ele
);
295 Recursively deal with section.
297 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
298 @param doc Xml Document
299 @param root Root Node
300 @param cursor Current FFS layout cursor
301 @param list List of section type here used
303 private void dealSection(int mode
, Document doc
, Element root
, XmlCursor cursor
, Vector
<String
> list
) {
304 String type
= cursor
.getAttributeText(new QName("SectionType"));
307 // Judge if file is specified? Yes, just use the file, else call Build Macro
308 // If fileName is null, means without FileNames specify in FPD file
310 String fileName
= null;
312 if (cursor
.toFirstChild()) {
314 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Filenames")) {
316 if (cursor
.toFirstChild()) {
318 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Filename")) {
319 fileName
= cursor
.getTextValue();
321 } while (cursor
.toNextSibling());
325 } while (cursor
.toNextSibling());
330 if (fileName
== null) {
331 list
.addElement(type
);
333 if (mode
== MODE_GUID_DEFINED
) {
335 // <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>
337 Element ele
= doc
.createElement("input");
338 if (fileName
== null) {
339 ele
.setAttribute("file", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
+ getSectionExt(type
));
341 ele
.setAttribute("file", "${PLATFORM_DIR}" + File
.separatorChar
+ fileName
);
343 root
.appendChild(ele
);
346 // <sectFile fileName= "..."/>
348 Element ele
= doc
.createElement("sectFile");
349 if (fileName
== null) {
350 ele
.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
+ getSectionExt(type
));
352 ele
.setAttribute("fileName", "${PLATFORM_DIR}" + File
.separatorChar
+ fileName
);
354 root
.appendChild(ele
);
359 Get the corresponding section file suffix.
361 @param type Section type
362 @return Corresponding section file extension
364 private String
getSectionExt(String type
) {
365 for (int i
= 0; i
< sectionExt
.length
; i
++) {
366 if (sectionExt
[i
][0].equalsIgnoreCase(type
)) {
367 return sectionExt
[i
][1];
374 Return the ANT script to call GenFfs Tool.
376 @return ANT script to call GenFfs Tool
378 public Element
getFfsNode() {