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>Property <code>COMMON_FILE</code> specified which file to search. The element
36 in <code>COMMON_FILE</code> 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>COMMON_FILE</code> if it
108 does not specify in module's surface area.
110 @param buildType Current module's component type
111 @param project Ant project
112 @return whether find the corresponding FFS layout
113 @throws BuildException
114 If specified COMMON_FILE XML file is not valide.
116 public boolean initSections(String buildType
, Project project
, FpdModuleIdentification fpdModuleId
) throws BuildException
{
118 // Try to find Ffs layout from FPD file
120 SurfaceAreaQuery
.push(GlobalData
.getFpdBuildOptions());
121 BuildOptionsDocument
.BuildOptions
.Ffs
[] ffsArray
= SurfaceAreaQuery
.getFpdFfs();
122 SurfaceAreaQuery
.pop();
123 for (int i
= 0; i
< ffsArray
.length
; i
++) {
124 if (isMatch(ffsArray
[i
].getFfsKey(), buildType
)) {
125 ffsXmlObject
= ffsArray
[i
];
131 // If FfsFormatKey is not null, report exception and fail build
132 // Otherwise report warning message
134 if (buildType
== null) {
135 System
.out
.println("Warning: this module doesn't specify a FfsFormatKey. ");
137 throw new BuildException("Can't find the FfsFormatKey [" + buildType
+ "] attribute in the FPD file!");
144 Recursive parse the FFS layout. Find out all section type here used.
146 @param document BaseName_build.xml Xml document
147 @param basename Module's base name
148 @param guid Module's GUID
149 @param targetFilename Module's final file name (GUID-BaseName.APP)
150 @return List of section type
152 public String
[] getGenSectionElements(Document document
, String basename
, String guid
, String targetFilename
) {
153 this.basename
= basename
;
154 if (ffsXmlObject
== null) {
155 return new String
[0];
157 Vector
<String
> sectionList
= new Vector
<String
>();
158 XmlCursor cursor
= null;
160 cursor
= ffsXmlObject
.newCursor();
161 } catch (Exception e
) {
164 int mode
= MODE_NONE
;
165 Element genffsfileEle
= document
.createElement("genffsfile");
166 genffsfileEle
.setAttribute("outputDir", "${BIN_DIR}");
167 genffsfileEle
.setAttribute("moduleType", "${MODULE_TYPE}");
168 genffsfileEle
.setAttribute("BaseName", basename
);
169 genffsfileEle
.setAttribute("fileGuid", guid
);
171 if (cursor
.toFirstChild()) {
173 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Attribute")) {
174 String name
= cursor
.getAttributeText(new QName("Name"));
175 String value
= cursor
.getAttributeText(new QName("Value"));
176 genffsfileEle
.setAttribute(changeAttributeName(name
), value
);
177 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
179 dealSection(mode
, document
, genffsfileEle
, cursor
, sectionList
);
181 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
183 dealSections(mode
, document
, genffsfileEle
, cursor
, sectionList
);
186 } while (cursor
.toNextSibling());
191 Element outofdateEle
= document
.createElement("OnDependency");
192 Element sourceEle
= document
.createElement("sourcefiles");
193 String
[] result
= new String
[sectionList
.size()];
194 for (int i
= 0; i
< sectionList
.size(); i
++) {
195 result
[i
] = (String
) sectionList
.get(i
);
196 Element pathEle
= document
.createElement("file");
197 pathEle
.setAttribute("name", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
198 + getSectionExt(result
[i
]));
199 sourceEle
.appendChild(pathEle
);
201 outofdateEle
.appendChild(sourceEle
);
202 Element targetEle
= document
.createElement("targetfiles");
203 Element fileEle
= document
.createElement("file");
204 fileEle
.setAttribute("name", "${BIN_DIR}" + File
.separatorChar
+ targetFilename
);
205 targetEle
.appendChild(fileEle
);
206 outofdateEle
.appendChild(targetEle
);
207 Element sequentialEle
= document
.createElement("sequential");
208 sequentialEle
.appendChild(genffsfileEle
);
209 outofdateEle
.appendChild(sequentialEle
);
210 ffsNode
= outofdateEle
;
215 Change the attribute name. For example:
218 Before change: FFS_ATTRIB_CHECKSUM
219 After change: ffsATTRIBCHECKSUM
222 @param name Original attribute name
223 @return Changed attribute name
225 private String
changeAttributeName(String name
) {
226 String
[] strs
= name
.split("_");
227 String str
= strs
[0].toLowerCase();
228 for (int j
= 1; j
< strs
.length
; j
++) {
235 Recursively deal with Sections. If sections does not specify a type, then omit it.
237 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
238 @param doc Xml Document
239 @param root Root Node
240 @param cursor Current FFS layout cursor
241 @param list List of section type here used
243 private void dealSections(int mode
, Document doc
, Element root
, XmlCursor cursor
, Vector
<String
> list
) {
244 String type
= cursor
.getAttributeText(new QName("EncapsulationType"));
246 if (cursor
.toFirstChild()) {
248 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
250 dealSection(mode
, doc
, root
, cursor
, list
);
252 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
254 dealSections(mode
, doc
, root
, cursor
, list
);
257 } while (cursor
.toNextSibling());
262 if (type
.equalsIgnoreCase("COMPRESS")) {
263 mode
= MODE_COMPRESS
;
265 // <compress compressName = "dummy">
267 ele
= doc
.createElement("compress");
268 ele
.setAttribute("compressName", "dummy");
270 mode
= MODE_GUID_DEFINED
;
272 // <tool toolName="${OEMTOOLPATH}\toolname"
273 // outputPath = "${DEST_DIR_OUTPUT}">
275 ele
= doc
.createElement("tool");
276 ele
.setAttribute("toolName", "${WORKSPACE_DIR}" + File
.separatorChar
+ "Tools" + File
.separatorChar
+ "bin"
277 + File
.separatorChar
+ "GenCRC32Section");
278 ele
.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");
280 if (cursor
.toFirstChild()) {
282 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
284 dealSection(mode
, doc
, ele
, cursor
, list
);
286 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
288 dealSections(mode
, doc
, ele
, cursor
, list
);
291 } while (cursor
.toNextSibling());
293 root
.appendChild(ele
);
297 Recursively deal with section.
299 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
300 @param doc Xml Document
301 @param root Root Node
302 @param cursor Current FFS layout cursor
303 @param list List of section type here used
305 private void dealSection(int mode
, Document doc
, Element root
, XmlCursor cursor
, Vector
<String
> list
) {
306 String type
= cursor
.getAttributeText(new QName("SectionType"));
309 // Judge if file is specified? Yes, just use the file, else call Build Macro
310 // If fileName is null, means without FileNames specify in FPD file
312 String fileName
= null;
314 if (cursor
.toFirstChild()) {
316 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Filenames")) {
318 if (cursor
.toFirstChild()) {
320 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Filename")) {
321 fileName
= cursor
.getTextValue();
323 } while (cursor
.toNextSibling());
327 } while (cursor
.toNextSibling());
332 if (fileName
== null) {
333 list
.addElement(type
);
335 if (mode
== MODE_GUID_DEFINED
) {
337 // <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>
339 Element ele
= doc
.createElement("input");
340 if (fileName
== null) {
341 ele
.setAttribute("file", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
+ getSectionExt(type
));
343 ele
.setAttribute("file", "${PLATFORM_DIR}" + File
.separatorChar
+ fileName
);
345 root
.appendChild(ele
);
348 // <sectFile fileName= "..."/>
350 Element ele
= doc
.createElement("sectFile");
351 if (fileName
== null) {
352 ele
.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
+ getSectionExt(type
));
354 ele
.setAttribute("fileName", "${PLATFORM_DIR}" + File
.separatorChar
+ fileName
);
356 root
.appendChild(ele
);
361 Get the corresponding section file suffix.
363 @param type Section type
364 @return Corresponding section file extension
366 private String
getSectionExt(String type
) {
367 for (int i
= 0; i
< sectionExt
.length
; i
++) {
368 if (sectionExt
[i
][0].equalsIgnoreCase(type
)) {
369 return sectionExt
[i
][1];
376 Return the ANT script to call GenFfs Tool.
378 @return ANT script to call GenFfs Tool
380 public Element
getFfsNode() {