]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/GenBuild/org/tianocore/build/global/LibBuildFileGenerator.java
Change to new XML Schema.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / global / LibBuildFileGenerator.java
CommitLineData
878ddf1f 1/** @file\r
2 This file is an ANT task.\r
3 \r
4 LibBuildFileGenerator task is used to generate module's build.xml file.\r
5\r
6Copyright (c) 2006, Intel Corporation\r
7All rights reserved. This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16package org.tianocore.build.global;\r
17\r
18import java.io.File;\r
19import java.util.HashMap;\r
20import java.util.Iterator;\r
21import java.util.Map;\r
22import java.util.Set;\r
23import java.util.Vector;\r
24\r
25import javax.xml.parsers.DocumentBuilder;\r
26import javax.xml.parsers.DocumentBuilderFactory;\r
27import javax.xml.transform.OutputKeys;\r
28import javax.xml.transform.Result;\r
29import javax.xml.transform.Source;\r
30import javax.xml.transform.Transformer;\r
31import javax.xml.transform.TransformerFactory;\r
32import javax.xml.transform.dom.DOMSource;\r
33import javax.xml.transform.stream.StreamResult;\r
34\r
35import org.apache.tools.ant.BuildException;\r
36import org.apache.tools.ant.Task;\r
37import org.apache.xmlbeans.XmlObject;\r
38import org.tianocore.MsaHeaderDocument.MsaHeader;\r
39import org.tianocore.MsaLibHeaderDocument.MsaLibHeader;\r
40import org.w3c.dom.Document;\r
41import org.w3c.dom.Element;\r
42\r
43/**\r
44 This class <code>LibBuildFileGenerator</code> is an ANT task to generate \r
45 build.xml for each module. Here are two usages. \r
46 \r
47 <ul>\r
48 <li>\r
49 For one module (<b>bf</b> is LibBuildFileGenerator task name):\r
50 <pre>\r
51 &lt;bf buildFile="Application\HelloWorld\HelloWorld.msa" /&gt;\r
52 </pre>\r
53 </li>\r
54 <li>\r
55 For one package:\r
56 <pre>\r
57 &lt;bf recursive="true" /&gt;\r
58 </pre>\r
59 </li>\r
60 </ul>\r
61 \r
62 @since GenBuild 1.0\r
63**/\r
64public class LibBuildFileGenerator extends Task {\r
65\r
66 private File buildFile;\r
67\r
68 private boolean recursive = false;\r
69 \r
70 private String license = " Copyright (c) 2006, Intel Corporation \n"\r
71 + "All rights reserved. This program and the accompanying materials \n"\r
72 + "are licensed and made available under the terms and conditions of the BSD License \n"\r
73 + "which accompanies this distribution. The full text of the license may be found at \n"\r
74 + "http://opensource.org/licenses/bsd-license.php \n"\r
75 + "\n"\r
76 + "THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN \"AS IS\" BASIS, \n"\r
77 + "WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.";\r
78\r
79 private String base_name;\r
80 \r
81 private String module_relative_path;\r
82 \r
83 private File base_file = new File(".");\r
84 \r
85 /**\r
86 Public construct method. It is necessary for ANT task.\r
87 **/\r
88 public LibBuildFileGenerator () {\r
89 }\r
90\r
91 /**\r
92 ANT task's entry point, will be called after init(). \r
93 \r
94 @throws BuildException\r
95 buildFile do not specify while recursive set to false\r
96 **/\r
97 public void execute() throws BuildException {\r
98 if(recursive){\r
99 searchMsa(new File("."));\r
100 }\r
101 else {\r
102 Map<String,File> map = new HashMap<String,File>();\r
103 String basename = buildFile.getName();\r
104 int k = basename.lastIndexOf('.');\r
105 base_name = basename.substring(0, k);\r
106 map.put(base_name, buildFile);\r
107 genBuildFile(map);\r
108 }\r
109 }\r
110 \r
111 /**\r
112 Recursivly find all MSA files and record all modules. \r
113 \r
114 @param path Package path\r
115 **/\r
116 private void searchMsa(File path){\r
117 File[] files = path.listFiles();\r
118 Vector<File> vec = new Vector<File>();\r
119 for(int i=0; i < files.length; i ++){\r
120 if (files[i].isFile()){\r
121 if(files[i].getName().endsWith(".msa")){\r
122 System.out.println("#" + files[i].getPath());\r
123 vec.add(files[i]);\r
124 }\r
125 }\r
126 }\r
127 Map<String,File> mapBasename = new HashMap<String,File>();\r
128 if (vec.size() > 0){\r
129 base_name = null;\r
130 for ( int j = 0 ; j < vec.size(); j++){\r
131 if ( vec.size() > 1){\r
132 System.out.println("##" + vec.get(0));\r
133 }\r
134 File f = (File)vec.get(j);\r
135 SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();\r
136 Map<String, XmlObject> map = surfaceAreaParser.parseFile(f);\r
137 String baseName = "";\r
138 XmlObject header = null;\r
139 if ( (header = map.get("MsaHeader")) != null ){\r
140 baseName = ((MsaHeader)header).getBaseName().getStringValue();\r
141 }\r
142 else if ( (header = map.get("MsaLibHeader")) != null){\r
143 baseName = ((MsaLibHeader)header).getBaseName().getStringValue();\r
144 } else {\r
145 continue ;\r
146 }\r
147 if ( base_name == null || base_name.length() > baseName.length()){\r
148 base_name = baseName;\r
149 buildFile = f;\r
150 try {\r
151 module_relative_path = buildFile.getParent().substring(base_file.getPath().length() + 1);\r
152 }\r
153 catch(Exception e){\r
154 module_relative_path = ".";\r
155 }\r
156 }\r
157 mapBasename.put(baseName, f);\r
158 }\r
159 genBuildFile(mapBasename);\r
160 }\r
161\r
162 for(int i=0; i < files.length; i ++){\r
163 if (files[i].isDirectory()){\r
164 searchMsa(files[i]);\r
165 }\r
166 }\r
167 }\r
168 \r
169 /**\r
170 Generate build.xml.\r
171 \r
172 @param map All base name under one module directory\r
173 **/\r
174 private void genBuildFile(Map map) {\r
175 DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();\r
176 try {\r
177 DocumentBuilder dombuilder = domfac.newDocumentBuilder();\r
178 Document document = dombuilder.newDocument();\r
179 //\r
180 // create root element and its attributes\r
181 //\r
182 document.appendChild(document.createComment(license));\r
183 Element root = document.createElement("project");\r
184 root.setAttribute("default", base_name);\r
185 root.setAttribute("basedir", ".");\r
186 //\r
187 // element for External ANT tasks\r
188 //\r
189 root.appendChild(document.createComment("Apply external ANT tasks"));\r
190 Element ele = document.createElement("taskdef");\r
191 ele.setAttribute("resource", "GenBuild.tasks");\r
192 root.appendChild(ele);\r
193 //\r
194 // <taskdef resource="net/sf/antcontrib/antlib.xml" />\r
195 //\r
196 ele = document.createElement("taskdef");\r
197 ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");\r
198 root.appendChild(ele);\r
199 \r
200 ele = document.createElement("property");\r
201 ele.setAttribute("environment", "env");\r
202 root.appendChild(ele);\r
203\r
204 ele = document.createElement("property");\r
205 ele.setAttribute("name", "WORKSPACE_DIR");\r
206 ele.setAttribute("value", "${env.WORKSPACE}");\r
207 root.appendChild(ele);\r
208 \r
209 ele = document.createElement("import");\r
210 ele.setAttribute("file", "${WORKSPACE_DIR}"+File.separatorChar+"Tools"+File.separatorChar+"Conf"+File.separatorChar+"BuildMacro.xml");\r
211 root.appendChild(ele);\r
212 \r
213 root.appendChild(document.createComment("MODULE_RELATIVE PATH is relative to PACKAGE_DIR"));\r
214 ele = document.createElement("property");\r
215 ele.setAttribute("name", "MODULE_RELATIVE_PATH");\r
216 ele.setAttribute("value", module_relative_path);\r
217 root.appendChild(ele);\r
218\r
219 ele = document.createElement("property");\r
220 ele.setAttribute("name", "MODULE_DIR");\r
221 ele.setAttribute("value", "${PACKAGE_DIR}" + File.separatorChar + "${MODULE_RELATIVE_PATH}");\r
222 root.appendChild(ele);\r
223\r
224 ele = document.createElement("property");\r
225 ele.setAttribute("name", "COMMON_FILE");\r
226 ele.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar + "Tools"\r
227 + File.separatorChar + "Conf" + File.separatorChar + "Common.xml");\r
228 root.appendChild(ele);\r
229 \r
230 //\r
231 // generate the buildfmd target\r
232 //\r
233 Set set = map.keySet();\r
234 Iterator iter = set.iterator();\r
235 while (iter.hasNext()){\r
236 String bName = (String)iter.next();\r
237 File msaFile = (File)map.get(bName);\r
238 String msaFilename = "${MODULE_DIR}" + File.separatorChar + msaFile.getName();\r
239 String mbdFilename = msaFilename.substring(0 , msaFilename.length() - 4) + ".mbd";\r
240 ele = document.createElement("target");\r
241 ele.setAttribute("name", bName);\r
242 Element target = document.createElement("GenBuild");\r
243 target.setAttribute("msaFilename", msaFilename);\r
244 target.setAttribute("mbdFilename", mbdFilename);\r
245 target.setAttribute("baseName", bName);\r
246 ele.appendChild(target);\r
247 root.appendChild(ele);\r
248 }\r
249\r
250 root.appendChild(ele);\r
251 //\r
252 // Default clean\r
253 //\r
254 ele = document.createElement("target");\r
255 ele.setAttribute("name", "clean");\r
256 ele.setAttribute("depends", base_name + "_clean");\r
257 root.appendChild(ele);\r
258 //\r
259 // Default Clean ALl\r
260 //\r
261 ele = document.createElement("target");\r
262 ele.setAttribute("name", "cleanall");\r
263 ele.setAttribute("depends", base_name + "_cleanall");\r
264 root.appendChild(ele);\r
265 //\r
266 // Every clean target for each BaseName\r
267 //\r
268 set = map.keySet();\r
269 iter = set.iterator();\r
270 while (iter.hasNext()){\r
271 String bName = (String)iter.next();\r
272 File msaFile = (File)map.get(bName);\r
273 String msaFilename = "${MODULE_DIR}" + File.separatorChar + msaFile.getName();\r
274 String mbdFilename = msaFilename.substring(0 , msaFilename.length() - 4) + ".mbd";\r
275 \r
276 ele = document.createElement("target");\r
277 ele.setAttribute("name", bName + "_clean");\r
278 //\r
279 // Output Dir\r
280 //\r
281 Element target = document.createElement("OutputDirSetup");\r
282 target.setAttribute("msaFilename", msaFilename);\r
283 target.setAttribute("mbdFilename", mbdFilename);\r
284 target.setAttribute("baseName", bName);\r
285 ele.appendChild(target);\r
286 //\r
287 // Call BaseName_build.xml clean\r
288 //\r
289 Element ifEle = document.createElement("if");\r
290 Element availableEle = document.createElement("available");\r
291 availableEle.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");\r
292 ifEle.appendChild(availableEle);\r
293 Element elseEle = document.createElement("then");\r
294 \r
295 Element moduleEle = document.createElement("ant");\r
296 moduleEle.setAttribute("antfile", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");\r
297 moduleEle.setAttribute("target", "clean");\r
298 \r
299 elseEle.appendChild(moduleEle);\r
300 ifEle.appendChild(elseEle);\r
301 ele.appendChild(ifEle);\r
302 //\r
303 // just delete\r
304 //\r
305 Element clean = document.createElement("delete");\r
306 clean.setAttribute("dir", "${DEST_DIR_OUTPUT}");\r
307 clean.setAttribute("excludes", "*.xml");\r
308 ele.appendChild(clean);\r
309 \r
310 root.appendChild(ele);\r
311 }\r
312 //\r
313 // Every Clean ALl target for each BaseName\r
314 //\r
315 set = map.keySet();\r
316 iter = set.iterator();\r
317 while (iter.hasNext()){\r
318 String bName = (String)iter.next();\r
319 File msaFile = (File)map.get(bName);\r
320 String msaFilename = "${MODULE_DIR}" + File.separatorChar + msaFile.getName();\r
321 String mbdFilename = msaFilename.substring(0 , msaFilename.length() - 4) + ".mbd";\r
322 \r
323 ele = document.createElement("target");\r
324 ele.setAttribute("name", bName + "_cleanall");\r
325 //\r
326 // Output Dir\r
327 //\r
328 Element target = document.createElement("OutputDirSetup");\r
329 target.setAttribute("msaFilename", msaFilename);\r
330 target.setAttribute("mbdFilename", mbdFilename);\r
331 target.setAttribute("baseName", bName);\r
332 ele.appendChild(target);\r
333 //\r
334 // Call BaseName_build.xml clean\r
335 //\r
336 Element ifEle = document.createElement("if");\r
337 Element availableEle = document.createElement("available");\r
338 availableEle.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");\r
339 ifEle.appendChild(availableEle);\r
340 Element elseEle = document.createElement("then");\r
341 \r
342 Element moduleEle = document.createElement("ant");\r
343 moduleEle.setAttribute("antfile", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");\r
344 moduleEle.setAttribute("target", "cleanall");\r
345 \r
346 elseEle.appendChild(moduleEle);\r
347 ifEle.appendChild(elseEle);\r
348 ele.appendChild(ifEle);\r
349 //\r
350 // just delete\r
351 //\r
352 Element clean = document.createElement("delete");\r
353 clean.setAttribute("dir", "${DEST_DIR_OUTPUT}");\r
354 ele.appendChild(clean);\r
355 \r
356 clean = document.createElement("delete");\r
357 clean.setAttribute("dir", "${DEST_DIR_DEBUG}");\r
358 ele.appendChild(clean);\r
359 \r
360 clean = document.createElement("delete");\r
361 Element fileset = document.createElement("fileset");\r
362 fileset.setAttribute("dir", "${BIN_DIR}");\r
363 fileset.setAttribute("includes", "**" + bName + "*");\r
364 clean.appendChild(fileset);\r
365 ele.appendChild(clean);\r
366 \r
367 root.appendChild(ele);\r
368 }\r
369 document.appendChild(root);\r
370 //\r
371 // Prepare the DOM document for writing\r
372 //\r
373 Source source = new DOMSource(document);\r
374 //\r
375 // Prepare the output file\r
376 //\r
377 String filename = buildFile.getParent() + File.separatorChar + "build.xml";\r
378 File file = new File(getProject().replaceProperties(filename));\r
379 //\r
380 // generate all directory path\r
381 //\r
382 Result result = new StreamResult(file);\r
383 //\r
384 // Write the DOM document to the file\r
385 //\r
386 Transformer xformer = TransformerFactory.newInstance()\r
387 .newTransformer();\r
388 xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");\r
389 xformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
390 xformer.transform(source, result);\r
391 } catch (Exception ex) {\r
392 System.out.println("##" + ex);\r
393 }\r
394 }\r
395 \r
396 \r
397 public File getBuildFile() {\r
398 return buildFile;\r
399 }\r
400\r
401 public void setBuildFile(File buildFile) {\r
402 this.buildFile = buildFile;\r
403 }\r
404\r
405 public boolean isRecursive() {\r
406 return recursive;\r
407 }\r
408\r
409 public void setRecursive(boolean recursive) {\r
410 this.recursive = recursive;\r
411 }\r
412}\r