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
;
87 private SurfaceAreaQuery saq
= null;
89 public FfsProcess(SurfaceAreaQuery saq
) {
94 search in the type, if componentType is listed in type, return true;
95 otherwise return false.
97 @param type a list supported component type separated by comma
98 @param componentType current module component type
99 @return whether componentType is one of type
101 private boolean isMatch(String type
, String componentType
) {
102 String
[] items
= type
.split("[ \t]*,[ \t]*");
103 for (int i
= 0; i
< items
.length
; i
++) {
104 if (items
[i
].equalsIgnoreCase(componentType
)) {
112 Find the corresponding FFS layout in <code>FPD</code>.
114 @param buildType Current module's component type
115 @param project Ant project
116 @return whether find the corresponding FFS layout
117 @throws BuildException
118 If can't find FFS Layout in FPD.
120 public boolean initSections(String buildType
, Project project
, FpdModuleIdentification fpdModuleId
) throws BuildException
{
122 // Try to find Ffs layout from FPD file
124 saq
.push(GlobalData
.getFpdBuildOptions());
125 BuildOptionsDocument
.BuildOptions
.Ffs
[] ffsArray
= saq
.getFpdFfs();
127 for (int i
= 0; i
< ffsArray
.length
; i
++) {
128 if (isMatch(ffsArray
[i
].getFfsKey(), buildType
)) {
129 ffsXmlObject
= ffsArray
[i
];
135 // If FfsFormatKey is not null, report exception and fail build
136 // Otherwise report warning message
138 if (buildType
== null) {
139 System
.out
.println("Warning: this module doesn't specify a FfsFormatKey. ");
141 throw new BuildException("Can't find the FfsFormatKey [" + buildType
+ "] attribute in the FPD file!");
148 Recursive parse the FFS layout. Find out all section type here used.
150 @param document BaseName_build.xml Xml document
151 @param basename Module's base name
152 @param guid Module's GUID
153 @param targetFilename Module's final file name (GUID-BaseName.APP)
154 @return List of section type
156 public String
[] getGenSectionElements(Document document
, String basename
, String guid
, String targetFilename
) {
157 this.basename
= basename
;
158 if (ffsXmlObject
== null) {
159 return new String
[0];
161 Vector
<String
> sectionList
= new Vector
<String
>();
162 XmlCursor cursor
= null;
164 cursor
= ffsXmlObject
.newCursor();
165 } catch (Exception e
) {
168 int mode
= MODE_NONE
;
169 Element genffsfileEle
= document
.createElement("genffsfile");
170 genffsfileEle
.setAttribute("outputDir", "${BIN_DIR}");
171 genffsfileEle
.setAttribute("moduleType", "${MODULE_TYPE}");
172 genffsfileEle
.setAttribute("BaseName", basename
);
173 genffsfileEle
.setAttribute("fileGuid", guid
);
175 if (cursor
.toFirstChild()) {
177 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Attribute")) {
178 String name
= cursor
.getAttributeText(new QName("Name"));
179 String value
= cursor
.getAttributeText(new QName("Value"));
180 genffsfileEle
.setAttribute(changeAttributeName(name
), value
);
181 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
183 dealSection(mode
, document
, genffsfileEle
, cursor
, sectionList
);
185 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
187 dealSections(mode
, document
, genffsfileEle
, cursor
, sectionList
);
190 } while (cursor
.toNextSibling());
195 Element outofdateEle
= document
.createElement("OnDependency");
196 Element sourceEle
= document
.createElement("sourcefiles");
197 String
[] result
= new String
[sectionList
.size()];
198 for (int i
= 0; i
< sectionList
.size(); i
++) {
199 result
[i
] = (String
) sectionList
.get(i
);
200 Element pathEle
= document
.createElement("file");
201 pathEle
.setAttribute("name", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
202 + getSectionExt(result
[i
]));
203 sourceEle
.appendChild(pathEle
);
205 outofdateEle
.appendChild(sourceEle
);
206 Element targetEle
= document
.createElement("targetfiles");
207 Element fileEle
= document
.createElement("file");
208 fileEle
.setAttribute("name", "${BIN_DIR}" + File
.separatorChar
+ targetFilename
);
209 targetEle
.appendChild(fileEle
);
210 outofdateEle
.appendChild(targetEle
);
211 Element sequentialEle
= document
.createElement("sequential");
212 sequentialEle
.appendChild(genffsfileEle
);
213 outofdateEle
.appendChild(sequentialEle
);
214 ffsNode
= outofdateEle
;
219 Change the attribute name. For example:
222 Before change: FFS_ATTRIB_CHECKSUM
223 After change: ffsATTRIBCHECKSUM
226 @param name Original attribute name
227 @return Changed attribute name
229 private String
changeAttributeName(String name
) {
230 String
[] strs
= name
.split("_");
231 String str
= strs
[0].toLowerCase();
232 for (int j
= 1; j
< strs
.length
; j
++) {
239 Recursively deal with Sections. If sections does not specify a type, then omit it.
241 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
242 @param doc Xml Document
243 @param root Root Node
244 @param cursor Current FFS layout cursor
245 @param list List of section type here used
247 private void dealSections(int mode
, Document doc
, Element root
, XmlCursor cursor
, Vector
<String
> list
) {
248 String type
= cursor
.getAttributeText(new QName("EncapsulationType"));
250 if (cursor
.toFirstChild()) {
252 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
254 dealSection(mode
, doc
, root
, cursor
, list
);
256 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
258 dealSections(mode
, doc
, root
, cursor
, list
);
261 } while (cursor
.toNextSibling());
266 if (type
.equalsIgnoreCase("COMPRESS")) {
267 mode
= MODE_COMPRESS
;
269 // <compress compressName = "dummy">
271 ele
= doc
.createElement("compress");
272 ele
.setAttribute("compressName", "dummy");
274 mode
= MODE_GUID_DEFINED
;
276 // <tool toolName="${OEMTOOLPATH}\toolname"
277 // outputPath = "${DEST_DIR_OUTPUT}">
279 ele
= doc
.createElement("tool");
280 ele
.setAttribute("toolName", "${WORKSPACE_DIR}" + File
.separatorChar
+ "Tools" + File
.separatorChar
+ "bin"
281 + File
.separatorChar
+ "GenCRC32Section");
282 ele
.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");
284 if (cursor
.toFirstChild()) {
286 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
288 dealSection(mode
, doc
, ele
, cursor
, list
);
290 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
292 dealSections(mode
, doc
, ele
, cursor
, list
);
295 } while (cursor
.toNextSibling());
297 root
.appendChild(ele
);
301 Recursively deal with section.
303 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
304 @param doc Xml Document
305 @param root Root Node
306 @param cursor Current FFS layout cursor
307 @param list List of section type here used
309 private void dealSection(int mode
, Document doc
, Element root
, XmlCursor cursor
, Vector
<String
> list
) {
310 String type
= cursor
.getAttributeText(new QName("SectionType"));
313 // Judge if file is specified? Yes, just use the file, else call Build Macro
314 // If fileName is null, means without FileNames specify in FPD file
316 String fileName
= null;
318 if (cursor
.toFirstChild()) {
320 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Filenames")) {
322 if (cursor
.toFirstChild()) {
324 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Filename")) {
325 fileName
= cursor
.getTextValue();
327 } while (cursor
.toNextSibling());
331 } while (cursor
.toNextSibling());
336 if (fileName
== null) {
337 list
.addElement(type
);
339 if (mode
== MODE_GUID_DEFINED
) {
341 // <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>
343 Element ele
= doc
.createElement("input");
344 if (fileName
== null) {
345 ele
.setAttribute("file", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
+ getSectionExt(type
));
347 ele
.setAttribute("file", "${PLATFORM_DIR}" + File
.separatorChar
+ fileName
);
349 root
.appendChild(ele
);
352 // <sectFile fileName= "..."/>
354 Element ele
= doc
.createElement("sectFile");
355 if (fileName
== null) {
356 ele
.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
+ getSectionExt(type
));
358 ele
.setAttribute("fileName", "${PLATFORM_DIR}" + File
.separatorChar
+ fileName
);
360 root
.appendChild(ele
);
365 Get the corresponding section file suffix.
367 @param type Section type
368 @return Corresponding section file extension
370 private String
getSectionExt(String type
) {
371 for (int i
= 0; i
< sectionExt
.length
; i
++) {
372 if (sectionExt
[i
][0].equalsIgnoreCase(type
)) {
373 return sectionExt
[i
][1];
380 Return the ANT script to call GenFfs Tool.
382 @return ANT script to call GenFfs Tool
384 public Element
getFfsNode() {