]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/GenBuild/org/tianocore/build/FfsProcess.java
Using Common Definitions. Remove some unused codes.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / FfsProcess.java
CommitLineData
878ddf1f 1/** @file\r
2 File is FfsProcess class which is used to get the corresponding FFS layout\r
3 information for driver module. \r
4 \r
5Copyright (c) 2006, Intel Corporation\r
6All rights reserved. This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10 \r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13**/\r
14package org.tianocore.build;\r
15\r
16import java.io.File;\r
878ddf1f 17import java.util.Vector;\r
18\r
19import javax.xml.namespace.QName;\r
878ddf1f 20\r
21import org.apache.tools.ant.BuildException;\r
22import org.apache.tools.ant.Project;\r
23import org.apache.xmlbeans.XmlCursor;\r
a29c47e0 24import org.tianocore.BuildOptionsDocument;\r
25import org.tianocore.build.global.GlobalData;\r
26import org.tianocore.build.global.SurfaceAreaQuery;\r
27import org.tianocore.build.id.FpdModuleIdentification;\r
4a6a5026 28import org.tianocore.common.definitions.EdkDefinitions;\r
878ddf1f 29import org.w3c.dom.Document;\r
30import org.w3c.dom.Element;\r
878ddf1f 31\r
32/** \r
33 <p><code>FfsProcess</code> is a class to find the corresponding FFS layout. </p>\r
34 \r
35 <p>Property <code>COMMON_FILE</code> specified which file to search. The element\r
36 in <code>COMMON_FILE</code> is like following: </p>\r
37 \r
38 <pre>\r
39 &lt;Ffs type="APPLICATION"&gt;\r
40 &lt;Attribute Name="FFS_FILETYPE" Value="EFI_FV_FILETYPE_APPLICATION" /&gt;\r
41 &lt;Attribute Name="FFS_ATTRIB_CHECKSUM" Value="TRUE" /&gt;\r
42 &lt;Sections EncapsulationType="Compress"&gt;\r
43 &lt;Sections EncapsulationType="Guid-Defined"&gt;\r
44 &lt;Section SectionType="EFI_SECTION_PE32" /&gt; \r
45 &lt;Section SectionType="EFI_SECTION_USER_INTERFACE" /&gt;\r
46 &lt;Section SectionType="EFI_SECTION_VERSION" /&gt; \r
47 &lt;/Sections&gt;\r
48 &lt;/Sections&gt;\r
49 &lt;/Ffs&gt;\r
50 </pre>\r
51 \r
52 @since GenBuild 1.0\r
53**/\r
54public class FfsProcess {\r
55\r
a29c47e0 56 private BuildOptionsDocument.BuildOptions.Ffs ffsXmlObject;\r
878ddf1f 57\r
58 ///\r
59 /// ANT script to call GenFfs\r
60 ///\r
61 private Element ffsNode = null;\r
62\r
63 ///\r
64 /// Module base name\r
65 ///\r
66 private String basename;\r
67\r
68 ///\r
69 /// Sections type: normal\r
70 ///\r
71 private static int MODE_NONE = 0;\r
72\r
73 ///\r
74 /// Sections type: compress\r
75 ///\r
76 private static int MODE_COMPRESS = 1;\r
77\r
78 ///\r
79 /// Sections type: guid-define\r
80 ///\r
81 private static int MODE_GUID_DEFINED = 2;\r
82\r
83 ///\r
84 /// mapping from section type to section output file extension\r
85 ///\r
4a6a5026 86 public static final String[][] sectionExt = EdkDefinitions.SectionTypeExtensions;\r
878ddf1f 87\r
88 /**\r
89 search in the type, if componentType is listed in type, return true; \r
90 otherwise return false.\r
91 \r
92 @param type a list supported component type separated by comma\r
93 @param componentType current module component type\r
94 @return whether componentType is one of type \r
95 **/\r
96 private boolean isMatch(String type, String componentType) {\r
97 String[] items = type.split("[ \t]*,[ \t]*");\r
98 for (int i = 0; i < items.length; i++) {\r
99 if (items[i].equalsIgnoreCase(componentType)) {\r
100 return true;\r
101 }\r
102 }\r
103 return false;\r
104 }\r
105\r
106 /**\r
107 Find the corresponding FFS layout in <code>COMMON_FILE</code> if it\r
108 does not specify in module's surface area. \r
109 \r
110 @param buildType Current module's component type\r
111 @param project Ant project\r
112 @return whether find the corresponding FFS layout\r
113 @throws BuildException\r
114 If specified COMMON_FILE XML file is not valide.\r
115 **/\r
a29c47e0 116 public boolean initSections(String buildType, Project project, FpdModuleIdentification fpdModuleId) throws BuildException {\r
878ddf1f 117 //\r
82516887 118 // Try to find Ffs layout from FPD file\r
a29c47e0 119 //\r
120 SurfaceAreaQuery.push(GlobalData.getFpdBuildOptions());\r
121 BuildOptionsDocument.BuildOptions.Ffs[] ffsArray = SurfaceAreaQuery.getFpdFfs();\r
122 SurfaceAreaQuery.pop();\r
123 for (int i = 0; i < ffsArray.length; i++) {\r
124 if (isMatch(ffsArray[i].getFfsKey(), buildType)) {\r
125 ffsXmlObject = ffsArray[i];\r
126 return true;\r
127 }\r
128 }\r
129 \r
878ddf1f 130 //\r
e64c74dd 131 // If FfsFormatKey is not null, report exception and fail build\r
132 // Otherwise report warning message\r
878ddf1f 133 //\r
e64c74dd 134 if (buildType == null) {\r
135 System.out.println("Warning: this module doesn't specify a FfsFormatKey. ");\r
82516887 136 } else {\r
391dbbb1 137 throw new BuildException("Can't find the FfsFormatKey [" + buildType + "] attribute in the FPD file!"); \r
878ddf1f 138 }\r
e64c74dd 139\r
82516887 140 return false;\r
878ddf1f 141 }\r
142 \r
143 /**\r
144 Recursive parse the FFS layout. Find out all section type here used. \r
145 \r
146 @param document BaseName_build.xml Xml document\r
147 @param basename Module's base name\r
148 @param guid Module's GUID\r
149 @param targetFilename Module's final file name (GUID-BaseName.APP)\r
150 @return List of section type\r
151 **/\r
152 public String[] getGenSectionElements(Document document, String basename, String guid, String targetFilename) {\r
153 this.basename = basename;\r
82516887 154 if (ffsXmlObject == null) {\r
878ddf1f 155 return new String[0];\r
156 }\r
157 Vector<String> sectionList = new Vector<String>();\r
158 XmlCursor cursor = null;\r
159 try {\r
82516887 160 cursor = ffsXmlObject.newCursor();\r
878ddf1f 161 } catch (Exception e) {\r
162 return null;\r
163 }\r
164 int mode = MODE_NONE;\r
82516887 165 Element genffsfileEle = document.createElement("genffsfile");\r
166 genffsfileEle.setAttribute("outputDir", "${BIN_DIR}");\r
167 genffsfileEle.setAttribute("moduleType", "${MODULE_TYPE}");\r
168 genffsfileEle.setAttribute("BaseName", basename);\r
169 genffsfileEle.setAttribute("fileGuid", guid);\r
170\r
878ddf1f 171 if (cursor.toFirstChild()) {\r
172 do {\r
173 if (cursor.getName().getLocalPart().equalsIgnoreCase("Attribute")) {\r
174 String name = cursor.getAttributeText(new QName("Name"));\r
175 String value = cursor.getAttributeText(new QName("Value"));\r
82516887 176 genffsfileEle.setAttribute(changeAttributeName(name), value);\r
878ddf1f 177 } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {\r
178 cursor.push();\r
82516887 179 dealSection(mode, document, genffsfileEle, cursor, sectionList);\r
878ddf1f 180 cursor.pop();\r
181 } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {\r
182 cursor.push();\r
82516887 183 dealSections(mode, document, genffsfileEle, cursor, sectionList);\r
878ddf1f 184 cursor.pop();\r
185 }\r
186 } while (cursor.toNextSibling());\r
187 }\r
188 //\r
189 // Check dependency \r
190 //\r
191 Element outofdateEle = document.createElement("OnDependency");\r
192 Element sourceEle = document.createElement("sourcefiles");\r
193 String[] result = new String[sectionList.size()];\r
194 for (int i = 0; i < sectionList.size(); i++) {\r
195 result[i] = (String) sectionList.get(i);\r
196 Element pathEle = document.createElement("file");\r
197 pathEle.setAttribute("name", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename\r
198 + getSectionExt(result[i]));\r
199 sourceEle.appendChild(pathEle);\r
200 }\r
201 outofdateEle.appendChild(sourceEle);\r
202 Element targetEle = document.createElement("targetfiles");\r
203 Element fileEle = document.createElement("file");\r
52cbbdbc 204 fileEle.setAttribute("name", "${BIN_DIR}" + File.separatorChar + targetFilename);\r
878ddf1f 205 targetEle.appendChild(fileEle);\r
206 outofdateEle.appendChild(targetEle);\r
207 Element sequentialEle = document.createElement("sequential");\r
82516887 208 sequentialEle.appendChild(genffsfileEle);\r
878ddf1f 209 outofdateEle.appendChild(sequentialEle);\r
210 ffsNode = outofdateEle;\r
211 return result;\r
212 }\r
213\r
214 /**\r
215 Change the attribute name. For example: \r
216 \r
217 <pre>\r
218 Before change: FFS_ATTRIB_CHECKSUM \r
219 After change: ffsATTRIBCHECKSUM\r
220 </pre>\r
221 \r
222 @param name Original attribute name\r
223 @return Changed attribute name\r
224 **/\r
225 private String changeAttributeName(String name) {\r
226 String[] strs = name.split("_");\r
227 String str = strs[0].toLowerCase();\r
228 for (int j = 1; j < strs.length; j++) {\r
229 str += strs[j];\r
230 }\r
231 return str;\r
232 }\r
233\r
234 /**\r
235 Recursively deal with Sections. If sections does not specify a type, then omit it.\r
236 \r
237 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)\r
238 @param doc Xml Document\r
239 @param root Root Node\r
240 @param cursor Current FFS layout cursor\r
241 @param list List of section type here used\r
242 **/\r
243 private void dealSections(int mode, Document doc, Element root, XmlCursor cursor, Vector<String> list) {\r
244 String type = cursor.getAttributeText(new QName("EncapsulationType"));\r
245 if (type == null) {\r
246 if (cursor.toFirstChild()) {\r
247 do {\r
248 if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {\r
249 cursor.push();\r
250 dealSection(mode, doc, root, cursor, list);\r
251 cursor.pop();\r
252 } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {\r
253 cursor.push();\r
254 dealSections(mode, doc, root, cursor, list);\r
255 cursor.pop();\r
256 }\r
257 } while (cursor.toNextSibling());\r
258 }\r
259 return;\r
260 }\r
261 Element ele;\r
262 if (type.equalsIgnoreCase("COMPRESS")) {\r
263 mode = MODE_COMPRESS;\r
264 //\r
265 // <compress compressName = "dummy">\r
266 //\r
267 ele = doc.createElement("compress");\r
268 ele.setAttribute("compressName", "dummy");\r
269 } else {\r
270 mode = MODE_GUID_DEFINED;\r
271 //\r
272 // <tool toolName="${OEMTOOLPATH}\toolname"\r
273 // outputPath = "${DEST_DIR_OUTPUT}">\r
274 //\r
275 ele = doc.createElement("tool");\r
a33f3dd1 276 ele.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "bin"\r
878ddf1f 277 + File.separatorChar + "GenCRC32Section");\r
278 ele.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");\r
279 }\r
280 if (cursor.toFirstChild()) {\r
281 do {\r
282 if (cursor.getName().getLocalPart().equalsIgnoreCase("Section")) {\r
283 cursor.push();\r
284 dealSection(mode, doc, ele, cursor, list);\r
285 cursor.pop();\r
286 } else if (cursor.getName().getLocalPart().equalsIgnoreCase("Sections")) {\r
287 cursor.push();\r
288 dealSections(mode, doc, ele, cursor, list);\r
289 cursor.pop();\r
290 }\r
291 } while (cursor.toNextSibling());\r
292 }\r
293 root.appendChild(ele);\r
294 }\r
295 \r
296 /**\r
297 Recursively deal with section.\r
298 \r
299 @param mode Current node mode (MODE_NONE | MODE_COMPREE | MODE_GUID_DEFINED)\r
300 @param doc Xml Document\r
301 @param root Root Node\r
302 @param cursor Current FFS layout cursor\r
303 @param list List of section type here used\r
304 **/\r
305 private void dealSection(int mode, Document doc, Element root, XmlCursor cursor, Vector<String> list) {\r
306 String type = cursor.getAttributeText(new QName("SectionType"));\r
8a9783c1 307 \r
308 //\r
309 // Judge if file is specified? Yes, just use the file, else call Build Macro\r
310 // If fileName is null, means without FileNames specify in FPD file\r
311 //\r
312 String fileName = null;\r
313 cursor.push();\r
314 if (cursor.toFirstChild()) {\r
315 do {\r
316 if (cursor.getName().getLocalPart().equalsIgnoreCase("Filenames")) {\r
317 cursor.push();\r
318 if (cursor.toFirstChild()) {\r
319 do {\r
320 if (cursor.getName().getLocalPart().equalsIgnoreCase("Filename")) {\r
321 fileName = cursor.getTextValue();\r
322 }\r
323 } while (cursor.toNextSibling());\r
324 }\r
325 cursor.pop();\r
326 }\r
327 } while (cursor.toNextSibling());\r
328 }\r
329\r
330 cursor.pop();\r
331 \r
332 if (fileName == null) {\r
333 list.addElement(type);\r
334 }\r
878ddf1f 335 if (mode == MODE_GUID_DEFINED) {\r
336 //\r
337 // <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>\r
338 //\r
339 Element ele = doc.createElement("input");\r
8a9783c1 340 if (fileName == null) {\r
341 ele.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));\r
342 } else {\r
343 ele.setAttribute("file", "${PLATFORM_DIR}" + File.separatorChar + fileName);\r
344 }\r
878ddf1f 345 root.appendChild(ele);\r
346 } else {\r
347 //\r
348 // <sectFile fileName= "..."/>\r
349 //\r
350 Element ele = doc.createElement("sectFile");\r
8a9783c1 351 if (fileName == null) {\r
352 ele.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));\r
353 } else {\r
354 ele.setAttribute("fileName", "${PLATFORM_DIR}" + File.separatorChar + fileName);\r
355 }\r
878ddf1f 356 root.appendChild(ele);\r
357 }\r
358 }\r
359\r
360 /**\r
a29c47e0 361 Get the corresponding section file suffix.\r
878ddf1f 362 \r
363 @param type Section type\r
364 @return Corresponding section file extension\r
365 **/\r
366 private String getSectionExt(String type) {\r
367 for (int i = 0; i < sectionExt.length; i++) {\r
368 if (sectionExt[i][0].equalsIgnoreCase(type)) {\r
369 return sectionExt[i][1];\r
370 }\r
371 }\r
372 return ".sec";\r
373 }\r
374\r
375 /**\r
376 Return the ANT script to call GenFfs Tool.\r
377 \r
378 @return ANT script to call GenFfs Tool\r
379 **/\r
380 public Element getFfsNode() {\r
381 return ffsNode;\r
382 }\r
383}\r