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