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