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 saq
= new SurfaceAreaQuery(GlobalData
.getFpdBuildOptionsMap());
119 BuildOptionsDocument
.BuildOptions
.Ffs
[] ffsArray
= saq
.getFpdFfs();
120 for (int i
= 0; i
< ffsArray
.length
; i
++) {
121 if (isMatch(ffsArray
[i
].getFfsKey(), buildType
)) {
122 ffsXmlObject
= ffsArray
[i
];
128 // If FfsFormatKey is not null, report exception and fail build
129 // Otherwise report warning message
131 if (buildType
== null) {
132 System
.out
.println("Warning: this module doesn't specify a FfsFormatKey. ");
134 throw new BuildException("Can't find the FfsFormatKey [" + buildType
+ "] attribute in the FPD file!");
141 Recursive parse the FFS layout. Find out all section type here used.
143 @param document BaseName_build.xml Xml document
144 @param basename Module's base name
145 @param guid Module's GUID
146 @param targetFilename Module's final file name (GUID-BaseName.APP)
147 @return List of section type
149 public String
[] getGenSectionElements(Document document
, String basename
, String guid
, String targetFilename
) {
150 this.basename
= basename
;
151 if (ffsXmlObject
== null) {
152 return new String
[0];
154 Vector
<String
> sectionList
= new Vector
<String
>();
155 XmlCursor cursor
= null;
157 cursor
= ffsXmlObject
.newCursor();
158 } catch (Exception e
) {
161 int mode
= MODE_NONE
;
162 Element genffsfileEle
= document
.createElement("genffsfile");
163 genffsfileEle
.setAttribute("outputDir", "${BIN_DIR}");
164 genffsfileEle
.setAttribute("moduleType", "${MODULE_TYPE}");
165 genffsfileEle
.setAttribute("BaseName", basename
);
166 genffsfileEle
.setAttribute("fileGuid", guid
);
168 if (cursor
.toFirstChild()) {
170 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Attribute")) {
171 String name
= cursor
.getAttributeText(new QName("Name"));
172 String value
= cursor
.getAttributeText(new QName("Value"));
173 genffsfileEle
.setAttribute(changeAttributeName(name
), value
);
174 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
176 dealSection(mode
, document
, genffsfileEle
, cursor
, sectionList
);
178 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
180 dealSections(mode
, document
, genffsfileEle
, cursor
, sectionList
);
183 } while (cursor
.toNextSibling());
188 Element outofdateEle
= document
.createElement("OnDependency");
189 Element sourceEle
= document
.createElement("sourcefiles");
190 String
[] result
= new String
[sectionList
.size()];
191 for (int i
= 0; i
< sectionList
.size(); i
++) {
192 result
[i
] = (String
) sectionList
.get(i
);
193 Element pathEle
= document
.createElement("file");
194 pathEle
.setAttribute("name", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
195 + getSectionExt(result
[i
]));
196 sourceEle
.appendChild(pathEle
);
198 outofdateEle
.appendChild(sourceEle
);
199 Element targetEle
= document
.createElement("targetfiles");
200 Element fileEle
= document
.createElement("file");
201 fileEle
.setAttribute("name", "${BIN_DIR}" + File
.separatorChar
+ targetFilename
);
202 targetEle
.appendChild(fileEle
);
203 outofdateEle
.appendChild(targetEle
);
204 Element sequentialEle
= document
.createElement("sequential");
205 sequentialEle
.appendChild(genffsfileEle
);
206 outofdateEle
.appendChild(sequentialEle
);
207 ffsNode
= outofdateEle
;
212 Change the attribute name. For example:
215 Before change: FFS_ATTRIB_CHECKSUM
216 After change: ffsATTRIBCHECKSUM
219 @param name Original attribute name
220 @return Changed attribute name
222 private String
changeAttributeName(String name
) {
223 String
[] strs
= name
.split("_");
224 String str
= strs
[0].toLowerCase();
225 for (int j
= 1; j
< strs
.length
; j
++) {
232 Recursively deal with Sections. If sections does not specify a type, then omit it.
234 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
235 @param doc Xml Document
236 @param root Root Node
237 @param cursor Current FFS layout cursor
238 @param list List of section type here used
240 private void dealSections(int mode
, Document doc
, Element root
, XmlCursor cursor
, Vector
<String
> list
) {
241 String type
= cursor
.getAttributeText(new QName("EncapsulationType"));
243 if (cursor
.toFirstChild()) {
245 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
247 dealSection(mode
, doc
, root
, cursor
, list
);
249 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
251 dealSections(mode
, doc
, root
, cursor
, list
);
254 } while (cursor
.toNextSibling());
259 if (type
.equalsIgnoreCase("COMPRESS")) {
260 mode
= MODE_COMPRESS
;
262 // <compress compressName = "dummy">
264 ele
= doc
.createElement("compress");
265 ele
.setAttribute("compressName", "dummy");
267 mode
= MODE_GUID_DEFINED
;
269 // <tool toolName="${OEMTOOLPATH}\toolname"
270 // outputPath = "${DEST_DIR_OUTPUT}">
272 ele
= doc
.createElement("tool");
273 ele
.setAttribute("toolName", "${WORKSPACE_DIR}" + File
.separatorChar
+ "Tools" + File
.separatorChar
+ "bin"
274 + File
.separatorChar
+ "GenCRC32Section");
275 ele
.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");
277 if (cursor
.toFirstChild()) {
279 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
281 dealSection(mode
, doc
, ele
, cursor
, list
);
283 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
285 dealSections(mode
, doc
, ele
, cursor
, list
);
288 } while (cursor
.toNextSibling());
290 root
.appendChild(ele
);
294 Recursively deal with section.
296 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
297 @param doc Xml Document
298 @param root Root Node
299 @param cursor Current FFS layout cursor
300 @param list List of section type here used
302 private void dealSection(int mode
, Document doc
, Element root
, XmlCursor cursor
, Vector
<String
> list
) {
303 String type
= cursor
.getAttributeText(new QName("SectionType"));
306 // Judge if file is specified? Yes, just use the file, else call Build Macro
307 // If fileName is null, means without FileNames specify in FPD file
309 String fileName
= null;
311 if (cursor
.toFirstChild()) {
313 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Filenames")) {
315 if (cursor
.toFirstChild()) {
317 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Filename")) {
318 fileName
= cursor
.getTextValue();
320 } while (cursor
.toNextSibling());
324 } while (cursor
.toNextSibling());
329 if (fileName
== null) {
330 list
.addElement(type
);
332 if (mode
== MODE_GUID_DEFINED
) {
334 // <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>
336 Element ele
= doc
.createElement("input");
337 if (fileName
== null) {
338 ele
.setAttribute("file", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
+ getSectionExt(type
));
340 ele
.setAttribute("file", "${PLATFORM_DIR}" + File
.separatorChar
+ fileName
);
342 root
.appendChild(ele
);
345 // <sectFile fileName= "..."/>
347 Element ele
= doc
.createElement("sectFile");
348 if (fileName
== null) {
349 ele
.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
+ getSectionExt(type
));
351 ele
.setAttribute("fileName", "${PLATFORM_DIR}" + File
.separatorChar
+ fileName
);
353 root
.appendChild(ele
);
358 Get the corresponding section file suffix.
360 @param type Section type
361 @return Corresponding section file extension
363 private String
getSectionExt(String type
) {
364 for (int i
= 0; i
< sectionExt
.length
; i
++) {
365 if (sectionExt
[i
][0].equalsIgnoreCase(type
)) {
366 return sectionExt
[i
][1];
373 Return the ANT script to call GenFfs Tool.
375 @return ANT script to call GenFfs Tool
377 public Element
getFfsNode() {