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
.w3c
.dom
.Document
;
29 import org
.w3c
.dom
.Element
;
32 <p><code>FfsProcess</code> is a class to find the corresponding FFS layout. </p>
34 <p>Property <code>COMMON_FILE</code> specified which file to search. The element
35 in <code>COMMON_FILE</code> 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
= { { "EFI_SECTION_FREEFORM_SUBTYPE_GUID", ".sec" },
86 { "EFI_SECTION_VERSION", ".ver" },
87 { "EFI_SECTION_USER_INTERFACE", ".ui" },
88 { "EFI_SECTION_DXE_DEPEX", ".dpx" },
89 { "EFI_SECTION_PEI_DEPEX", ".dpx" },
90 { "EFI_SECTION_PE32", ".pe32" },
91 { "EFI_SECTION_PIC", ".pic" },
92 { "EFI_SECTION_TE", ".tes" },
93 { "EFI_SECTION_RAW", ".sec" },
94 { "EFI_SECTION_COMPRESSION", ".sec" },
95 { "EFI_SECTION_GUID_DEFINED", ".sec" },
96 { "EFI_SECTION_COMPATIBILITY16", ".sec" },
97 { "EFI_SECTION_FIRMWARE_VOLUME_IMAGE", ".sec" } };
100 search in the type, if componentType is listed in type, return true;
101 otherwise return false.
103 @param type a list supported component type separated by comma
104 @param componentType current module component type
105 @return whether componentType is one of type
107 private boolean isMatch(String type
, String componentType
) {
108 String
[] items
= type
.split("[ \t]*,[ \t]*");
109 for (int i
= 0; i
< items
.length
; i
++) {
110 if (items
[i
].equalsIgnoreCase(componentType
)) {
118 Find the corresponding FFS layout in <code>COMMON_FILE</code> if it
119 does not specify in module's surface area.
121 @param buildType Current module's component type
122 @param project Ant project
123 @return whether find the corresponding FFS layout
124 @throws BuildException
125 If specified COMMON_FILE XML file is not valide.
127 public boolean initSections(String buildType
, Project project
, FpdModuleIdentification fpdModuleId
) throws BuildException
{
129 // Try to find Ffs layout from FPD file
131 SurfaceAreaQuery
.push(GlobalData
.getFpdBuildOptions());
132 BuildOptionsDocument
.BuildOptions
.Ffs
[] ffsArray
= SurfaceAreaQuery
.getFpdFfs();
133 SurfaceAreaQuery
.pop();
134 for (int i
= 0; i
< ffsArray
.length
; i
++) {
135 if (isMatch(ffsArray
[i
].getFfsKey(), buildType
)) {
136 ffsXmlObject
= ffsArray
[i
];
142 // If FfsFormatKey is not null, report exception and fail build
143 // Otherwise report warning message
145 if (buildType
== null) {
146 System
.out
.println("Warning: this module doesn't specify a FfsFormatKey. ");
148 throw new BuildException("Can't find the FfsFormatKey [" + buildType
+ "] attribute in the FPD file!");
155 Recursive parse the FFS layout. Find out all section type here used.
157 @param document BaseName_build.xml Xml document
158 @param basename Module's base name
159 @param guid Module's GUID
160 @param targetFilename Module's final file name (GUID-BaseName.APP)
161 @return List of section type
163 public String
[] getGenSectionElements(Document document
, String basename
, String guid
, String targetFilename
) {
164 this.basename
= basename
;
165 if (ffsXmlObject
== null) {
166 return new String
[0];
168 Vector
<String
> sectionList
= new Vector
<String
>();
169 XmlCursor cursor
= null;
171 cursor
= ffsXmlObject
.newCursor();
172 } catch (Exception e
) {
175 int mode
= MODE_NONE
;
176 Element genffsfileEle
= document
.createElement("genffsfile");
177 genffsfileEle
.setAttribute("outputDir", "${BIN_DIR}");
178 genffsfileEle
.setAttribute("moduleType", "${MODULE_TYPE}");
179 genffsfileEle
.setAttribute("BaseName", basename
);
180 genffsfileEle
.setAttribute("fileGuid", guid
);
182 if (cursor
.toFirstChild()) {
184 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Attribute")) {
185 String name
= cursor
.getAttributeText(new QName("Name"));
186 String value
= cursor
.getAttributeText(new QName("Value"));
187 genffsfileEle
.setAttribute(changeAttributeName(name
), value
);
188 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
190 dealSection(mode
, document
, genffsfileEle
, cursor
, sectionList
);
192 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
194 dealSections(mode
, document
, genffsfileEle
, cursor
, sectionList
);
197 } while (cursor
.toNextSibling());
202 Element outofdateEle
= document
.createElement("OnDependency");
203 Element sourceEle
= document
.createElement("sourcefiles");
204 String
[] result
= new String
[sectionList
.size()];
205 for (int i
= 0; i
< sectionList
.size(); i
++) {
206 result
[i
] = (String
) sectionList
.get(i
);
207 Element pathEle
= document
.createElement("file");
208 pathEle
.setAttribute("name", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
209 + getSectionExt(result
[i
]));
210 sourceEle
.appendChild(pathEle
);
212 outofdateEle
.appendChild(sourceEle
);
213 Element targetEle
= document
.createElement("targetfiles");
214 Element fileEle
= document
.createElement("file");
215 fileEle
.setAttribute("name", "${BIN_DIR}" + File
.separatorChar
+ targetFilename
);
216 targetEle
.appendChild(fileEle
);
217 outofdateEle
.appendChild(targetEle
);
218 Element sequentialEle
= document
.createElement("sequential");
219 sequentialEle
.appendChild(genffsfileEle
);
220 outofdateEle
.appendChild(sequentialEle
);
221 ffsNode
= outofdateEle
;
226 Change the attribute name. For example:
229 Before change: FFS_ATTRIB_CHECKSUM
230 After change: ffsATTRIBCHECKSUM
233 @param name Original attribute name
234 @return Changed attribute name
236 private String
changeAttributeName(String name
) {
237 String
[] strs
= name
.split("_");
238 String str
= strs
[0].toLowerCase();
239 for (int j
= 1; j
< strs
.length
; j
++) {
246 Recursively deal with Sections. If sections does not specify a type, then omit it.
248 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
249 @param doc Xml Document
250 @param root Root Node
251 @param cursor Current FFS layout cursor
252 @param list List of section type here used
254 private void dealSections(int mode
, Document doc
, Element root
, XmlCursor cursor
, Vector
<String
> list
) {
255 String type
= cursor
.getAttributeText(new QName("EncapsulationType"));
257 if (cursor
.toFirstChild()) {
259 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
261 dealSection(mode
, doc
, root
, cursor
, list
);
263 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
265 dealSections(mode
, doc
, root
, cursor
, list
);
268 } while (cursor
.toNextSibling());
273 if (type
.equalsIgnoreCase("COMPRESS")) {
274 mode
= MODE_COMPRESS
;
276 // <compress compressName = "dummy">
278 ele
= doc
.createElement("compress");
279 ele
.setAttribute("compressName", "dummy");
281 mode
= MODE_GUID_DEFINED
;
283 // <tool toolName="${OEMTOOLPATH}\toolname"
284 // outputPath = "${DEST_DIR_OUTPUT}">
286 ele
= doc
.createElement("tool");
287 ele
.setAttribute("toolName", "${WORKSPACE_DIR}" + File
.separatorChar
+ "Tools" + File
.separatorChar
+ "bin"
288 + File
.separatorChar
+ "GenCRC32Section");
289 ele
.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");
291 if (cursor
.toFirstChild()) {
293 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Section")) {
295 dealSection(mode
, doc
, ele
, cursor
, list
);
297 } else if (cursor
.getName().getLocalPart().equalsIgnoreCase("Sections")) {
299 dealSections(mode
, doc
, ele
, cursor
, list
);
302 } while (cursor
.toNextSibling());
304 root
.appendChild(ele
);
308 Recursively deal with section.
310 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)
311 @param doc Xml Document
312 @param root Root Node
313 @param cursor Current FFS layout cursor
314 @param list List of section type here used
316 private void dealSection(int mode
, Document doc
, Element root
, XmlCursor cursor
, Vector
<String
> list
) {
317 String type
= cursor
.getAttributeText(new QName("SectionType"));
320 // Judge if file is specified? Yes, just use the file, else call Build Macro
321 // If fileName is null, means without FileNames specify in FPD file
323 String fileName
= null;
325 if (cursor
.toFirstChild()) {
327 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Filenames")) {
329 if (cursor
.toFirstChild()) {
331 if (cursor
.getName().getLocalPart().equalsIgnoreCase("Filename")) {
332 fileName
= cursor
.getTextValue();
334 } while (cursor
.toNextSibling());
338 } while (cursor
.toNextSibling());
343 if (fileName
== null) {
344 list
.addElement(type
);
346 if (mode
== MODE_GUID_DEFINED
) {
348 // <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>
350 Element ele
= doc
.createElement("input");
351 if (fileName
== null) {
352 ele
.setAttribute("file", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
+ getSectionExt(type
));
354 ele
.setAttribute("file", "${PLATFORM_DIR}" + File
.separatorChar
+ fileName
);
356 root
.appendChild(ele
);
359 // <sectFile fileName= "..."/>
361 Element ele
= doc
.createElement("sectFile");
362 if (fileName
== null) {
363 ele
.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File
.separatorChar
+ basename
+ getSectionExt(type
));
365 ele
.setAttribute("fileName", "${PLATFORM_DIR}" + File
.separatorChar
+ fileName
);
367 root
.appendChild(ele
);
372 Get the corresponding section file suffix.
374 @param type Section type
375 @return Corresponding section file extension
377 private String
getSectionExt(String type
) {
378 for (int i
= 0; i
< sectionExt
.length
; i
++) {
379 if (sectionExt
[i
][0].equalsIgnoreCase(type
)) {
380 return sectionExt
[i
][1];
387 Return the ANT script to call GenFfs Tool.
389 @return ANT script to call GenFfs Tool
391 public Element
getFfsNode() {