878ddf1f |
1 | /** @file\r |
2 | This file is ANT task GenBuild. \r |
3 | \r |
4 | The file is used to parse a specified Module, and generate its build time \r |
5 | ANT script build.xml, then call the the ANT script to build the module.\r |
6 | \r |
7 | Copyright (c) 2006, Intel Corporation\r |
8 | All rights reserved. This program and the accompanying materials\r |
9 | are licensed and made available under the terms and conditions of the BSD License\r |
10 | which accompanies this distribution. The full text of the license may be found at\r |
11 | http://opensource.org/licenses/bsd-license.php\r |
12 | \r |
13 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r |
14 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r |
15 | **/\r |
16 | package org.tianocore.build;\r |
17 | \r |
18 | import java.io.File;\r |
19 | import java.util.HashMap;\r |
20 | import java.util.HashSet;\r |
21 | import java.util.Iterator;\r |
22 | import java.util.LinkedHashSet;\r |
23 | import java.util.List;\r |
24 | import java.util.Map;\r |
25 | import java.util.Set;\r |
26 | import java.util.Vector;\r |
27 | import java.util.regex.Matcher;\r |
28 | import java.util.regex.Pattern;\r |
29 | \r |
30 | import javax.xml.parsers.DocumentBuilder;\r |
31 | import javax.xml.parsers.DocumentBuilderFactory;\r |
32 | import javax.xml.transform.OutputKeys;\r |
33 | import javax.xml.transform.Result;\r |
34 | import javax.xml.transform.Source;\r |
35 | import javax.xml.transform.Transformer;\r |
36 | import javax.xml.transform.TransformerFactory;\r |
37 | import javax.xml.transform.dom.DOMSource;\r |
38 | import javax.xml.transform.stream.StreamResult;\r |
39 | \r |
40 | import org.apache.tools.ant.BuildException;\r |
41 | import org.apache.tools.ant.Project;\r |
42 | import org.apache.tools.ant.Task;\r |
43 | import org.apache.tools.ant.taskdefs.Ant;\r |
44 | import org.apache.xmlbeans.XmlObject;\r |
45 | import org.w3c.dom.Comment;\r |
46 | import org.w3c.dom.Document;\r |
47 | import org.w3c.dom.Element;\r |
48 | import org.w3c.dom.Node;\r |
49 | \r |
50 | import org.tianocore.build.autogen.AutoGen;\r |
51 | import org.tianocore.build.autogen.CommonDefinition;\r |
52 | import org.tianocore.build.fpd.FpdParserTask;\r |
53 | import org.tianocore.build.global.GlobalData;\r |
54 | import org.tianocore.build.global.OutputManager;\r |
55 | import org.tianocore.build.global.SurfaceAreaQuery;\r |
56 | import org.tianocore.build.toolchain.ToolChainFactory;\r |
57 | import org.tianocore.FilenameDocument;\r |
58 | import org.tianocore.MsaHeaderDocument;\r |
59 | import org.tianocore.MsaLibHeaderDocument;\r |
60 | \r |
61 | /**\r |
62 | <p>\r |
63 | <code>GenBuildTask</code> is an ANT task that can be used in ANT build\r |
64 | system. The main function of this task is to parse module's surface area,\r |
65 | then generate the corresponding <em>BaseName_build.xml</em> (the real ANT\r |
66 | build script) and call this to build the module.\r |
67 | </p>\r |
68 | \r |
69 | <p>\r |
70 | The usage is (take module <em>HelloWorld</em> for example):\r |
71 | </p>\r |
72 | \r |
73 | <pre>\r |
74 | <GenBuild baseName="HelloWorld" \r |
75 | mbdFilename="${MODULE_DIR}/HelloWorld.mbd" \r |
76 | msaFilename="${MODULE_DIR}/HelloWorld.msa"/>\r |
77 | </pre>\r |
78 | \r |
79 | <p>\r |
80 | This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and\r |
81 | <em>AutoGen.h</em>. The task also parses the development environment\r |
82 | configuration files, such as collecting package information, setting compiler\r |
83 | flags and so on.\r |
84 | </p>\r |
85 | \r |
86 | \r |
87 | @since GenBuild 1.0\r |
88 | **/\r |
89 | public class GenBuildTask extends Task {\r |
90 | \r |
91 | ///\r |
92 | /// Module surface area file.\r |
93 | ///\r |
94 | File msaFilename;\r |
95 | \r |
96 | ///\r |
97 | /// Module build description file.\r |
98 | ///\r |
99 | File mbdFilename;\r |
100 | \r |
101 | ///\r |
102 | /// Module surface area information after overrided.\r |
103 | ///\r |
104 | public Map<String, XmlObject> map = new HashMap<String, XmlObject>();\r |
105 | \r |
106 | ///\r |
107 | /// Module's base name.\r |
108 | ///\r |
109 | private String baseName;\r |
110 | \r |
111 | ///\r |
112 | /// Current build Arch, such as IA32, X64, IPF and so on.\r |
113 | ///\r |
114 | private String arch;\r |
115 | \r |
116 | ///\r |
117 | /// Module's GUID (Globally Unique Identifier).\r |
118 | ///\r |
119 | private String guid;\r |
120 | \r |
121 | ///\r |
122 | /// Module's component type, such as SEC, LIBRARY, BS_DRIVER and so on.\r |
123 | ///\r |
124 | private String componentType;\r |
125 | \r |
126 | ///\r |
127 | /// This value is used in build time. Override module's component type. When\r |
128 | /// search FFS (Sections information) in common file, buildtype instead of\r |
129 | /// component type.\r |
130 | ///\r |
131 | private String buildType;\r |
132 | \r |
133 | ///\r |
134 | /// List all required includes for current build module.\r |
135 | ///\r |
136 | public Set<String> includes = new LinkedHashSet<String>();\r |
137 | \r |
138 | ///\r |
139 | /// List all libraries for current build module.\r |
140 | ///\r |
141 | public Set<String> libraries = new LinkedHashSet<String>();\r |
142 | \r |
143 | ///\r |
144 | /// List all source files for current build module.\r |
145 | ///\r |
146 | public Set<String> sourceFiles = new LinkedHashSet<String>();\r |
147 | \r |
148 | ///\r |
149 | /// Flag to identify what surface area files are specified. Current value is\r |
150 | /// <em>NO_SA</em>, <em>ONLY_MSA</em>, <em>ONLY_LIBMSA</em>,\r |
151 | /// <em>MSA_AND_MBD</em> or <em>LIBMSA_AND_LIBMBD</em>.\r |
152 | /// \r |
153 | /// @see org.tianocore.build.global.GlobaData\r |
154 | ///\r |
155 | private int flag = GlobalData.NO_SA;\r |
156 | \r |
157 | ///\r |
158 | /// The information at the header of <em>build.xml</em>.\r |
159 | ///\r |
160 | private String info = "====================================================================\n"\r |
161 | + "DO NOT EDIT \n"\r |
162 | + "File auto-generated by build utility\n"\r |
163 | + "\n"\r |
164 | + "Abstract:\n"\r |
165 | + "Auto-generated ANT build file for building of EFI Modules/Platforms\n"\r |
166 | + "=====================================================================";\r |
167 | \r |
168 | /**\r |
169 | Public construct method. It is necessary for ANT task.\r |
170 | **/\r |
171 | public GenBuildTask() {\r |
172 | }\r |
173 | \r |
174 | /**\r |
175 | ANT task's entry point, will be called after init(). The main steps is described\r |
176 | as following: \r |
177 | <ul>\r |
178 | <li> Judge current build mode (MODULE | PACKAGE | PLATFORM). This step will execute\r |
179 | only once in whole build process; </li>\r |
180 | <li> Initialize global information (Framework DB, SPD files and all MSA files \r |
181 | listed in SPD). This step will execute only once in whole build process; </li>\r |
182 | <li> Restore some important ANT property. If current build is single module \r |
183 | build, here will set many default values; </li>\r |
184 | <li> Get the current module's overridded surface area information from \r |
185 | global data; </li> \r |
186 | <li> Set up the output directories, including BIN_DIR, DEST_DIR_OUTPUT and\r |
187 | DEST_DIR_DEBUG; </li>\r |
188 | <li> Get module dependent library instances and include pathes; </li>\r |
189 | <li> Judge whether current module is built. If yes, skip it; </li>\r |
190 | <li> Call AutoGen and PCD to generate AutoGen.c & AutoGen.h </li>\r |
191 | <li> Set up the compile flags; </li>\r |
192 | <li> Generate BaseName_build.xml; </li>\r |
193 | <li> Call to BaseName_build.xml, and build the current module. </li>\r |
194 | </ul>\r |
195 | \r |
196 | <p>Build is dependent on BuildMacro.xml which define many macro. </p> \r |
197 | \r |
198 | @throws BuildException\r |
199 | From module build, exception from module surface area invalid.\r |
200 | **/\r |
201 | public void execute() throws BuildException {\r |
202 | System.out.println("Module [" + baseName + "] start.");\r |
203 | OutputManager.update(getProject());\r |
204 | GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db",\r |
205 | getProject().getProperty("WORKSPACE_DIR"));\r |
206 | recallFixedProperties();\r |
207 | arch = getProject().getProperty("ARCH");\r |
208 | arch = arch.toUpperCase();\r |
209 | map = GlobalData.getDoc(baseName);\r |
210 | //\r |
211 | // Initialize SurfaceAreaQuery\r |
212 | //\r |
213 | SurfaceAreaQuery.setDoc(map);\r |
214 | //\r |
215 | // Setup Output Management\r |
216 | //\r |
217 | String[] outdir = SurfaceAreaQuery.getOutputDirectory();\r |
218 | OutputManager.update(getProject(), outdir[1], outdir[0]);\r |
219 | \r |
220 | updateIncludesAndLibraries();\r |
221 | \r |
222 | if (GlobalData.isModuleBuilt(baseName, arch)) {\r |
223 | return;\r |
224 | } else {\r |
225 | GlobalData.registerBuiltModule(baseName, arch);\r |
226 | }\r |
227 | //\r |
228 | // Call AutoGen\r |
229 | //\r |
230 | AutoGen autogen = new AutoGen(getProject().getProperty("DEST_DIR_DEBUG"), baseName, arch);\r |
231 | autogen.genAutogen();\r |
232 | //\r |
233 | // Update parameters\r |
234 | //\r |
235 | updateParameters();\r |
236 | //\r |
237 | // Update flags like CC_FLAGS, LIB_FLAGS etc.\r |
238 | //\r |
239 | flagsSetup();\r |
240 | GlobalData.addLibrary(baseName, getProject().getProperty("BIN_DIR") + File.separatorChar + baseName + ".lib");\r |
241 | GlobalData.addModuleLibrary(baseName, libraries);\r |
242 | //\r |
243 | // If ComponentType is USER_DEFINED,\r |
244 | // then call the exist BaseName_build.xml directly.\r |
245 | //\r |
246 | if (buildType.equalsIgnoreCase("CUSTOM_BUILD")) {\r |
247 | System.out.println("Call user-defined " + baseName + "_build.xml");\r |
248 | Ant ant = new Ant();\r |
249 | ant.setProject(getProject());\r |
250 | ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + baseName + "_build.xml");\r |
251 | ant.setInheritAll(true);\r |
252 | ant.init();\r |
253 | ant.execute();\r |
254 | return;\r |
255 | }\r |
256 | //\r |
257 | // Generate ${BASE_NAME}_build.xml file\r |
258 | //\r |
259 | System.out.println("Generate " + baseName + "_build.xml");\r |
260 | genBuildFile();\r |
261 | System.out.println("Call the " + baseName + "_build.xml");\r |
262 | Ant ant = new Ant();\r |
263 | ant.setProject(getProject());\r |
264 | ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName + "_build.xml");\r |
265 | ant.setInheritAll(true);\r |
266 | ant.init();\r |
267 | ant.execute();\r |
268 | }\r |
269 | \r |
270 | /**\r |
271 | Get the dependent library instances and include package name from \r |
272 | surface area, and initialize module include pathes. \r |
273 | \r |
274 | **/\r |
275 | private void updateIncludesAndLibraries() {\r |
276 | List<String> rawIncludes = SurfaceAreaQuery.getIncludePackageName(arch);\r |
277 | if (rawIncludes != null) {\r |
278 | Iterator iter = rawIncludes.iterator();\r |
279 | while (iter.hasNext()) {\r |
280 | String packageName = (String) iter.next();\r |
281 | includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)\r |
282 | + File.separatorChar + "Include");\r |
283 | includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)\r |
284 | + File.separatorChar + "Include" + File.separatorChar + "${ARCH}");\r |
285 | }\r |
286 | }\r |
287 | includes.add("${DEST_DIR_DEBUG}");\r |
288 | List<String> rawLibraries = SurfaceAreaQuery.getLibraryInstance(this.arch, CommonDefinition.AlwaysConsumed);\r |
289 | if (rawLibraries != null) {\r |
290 | Iterator iter = rawLibraries.iterator();\r |
291 | while (iter.hasNext()) {\r |
292 | libraries.add((String) iter.next());\r |
293 | }\r |
294 | }\r |
295 | normalize();\r |
296 | }\r |
297 | \r |
298 | /**\r |
299 | Normalize all dependent library instance and include pathes' format. \r |
300 | \r |
301 | **/\r |
302 | private void normalize() {\r |
303 | String[] includesArray = includes.toArray(new String[includes.size()]);\r |
304 | includes.clear();\r |
305 | for (int i = 0; i < includesArray.length; i++) {\r |
306 | includes.add((new File(includesArray[i])).getPath());\r |
307 | }\r |
308 | String[] librariesArray = libraries.toArray(new String[libraries.size()]);\r |
309 | libraries.clear();\r |
310 | for (int i = 0; i < librariesArray.length; i++) {\r |
311 | libraries.add((new File(librariesArray[i])).getPath());\r |
312 | }\r |
313 | }\r |
314 | \r |
315 | /**\r |
316 | Restore some important ANT property. If current build is single module \r |
317 | build, here will set many default values.\r |
318 | \r |
319 | <p> If current build is single module build, then the default <code>ARCH</code>\r |
320 | is <code>IA32</code>. Also set up the properties <code>PACKAGE</code>, \r |
321 | <code>PACKAGE_DIR</code>, <code>TARGET</code> and <code>MODULE_DIR</code></p>\r |
322 | \r |
323 | <p> Note that for package build, package name is stored in <code>PLATFORM</code>\r |
324 | and package directory is stored in <code>PLATFORM_DIR</code>. </p> \r |
325 | \r |
326 | @see org.tianocore.build.global.OutputManager\r |
327 | **/\r |
328 | private void recallFixedProperties() {\r |
329 | //\r |
330 | // If build is for module build\r |
331 | //\r |
332 | if (getProject().getProperty("PACKAGE_DIR") == null) {\r |
333 | ToolChainFactory toolChainFactory = new ToolChainFactory(getProject());\r |
334 | toolChainFactory.setupToolChain();\r |
335 | //\r |
336 | // PACKAGE PACKAGE_DIR ARCH (Default) COMMON_FILE BUILD_MACRO\r |
337 | //\r |
338 | if (getProject().getProperty("ARCH") == null) {\r |
339 | getProject().setProperty("ARCH", "IA32");\r |
340 | }\r |
341 | String packageName = GlobalData.getPackageNameForModule(baseName);\r |
342 | getProject().setProperty("PACKAGE", packageName);\r |
343 | \r |
344 | String packageDir = GlobalData.getPackagePath(packageName);\r |
345 | getProject().setProperty("PACKAGE_DIR",\r |
346 | getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + packageDir);\r |
347 | \r |
348 | getProject().setProperty("TARGET", toolChainFactory.getCurrentTarget());\r |
349 | \r |
350 | getProject().setProperty("MODULE_DIR",\r |
351 | getProject().replaceProperties(getProject().getProperty("MODULE_DIR")));\r |
352 | }\r |
353 | if (OutputManager.PLATFORM != null) {\r |
354 | getProject().setProperty("PLATFORM", OutputManager.PLATFORM);\r |
355 | }\r |
356 | if (OutputManager.PLATFORM_DIR != null) {\r |
357 | getProject().setProperty("PLATFORM_DIR", OutputManager.PLATFORM_DIR);\r |
358 | }\r |
359 | }\r |
360 | \r |
361 | /**\r |
362 | The whole BaseName_build.xml is composed of seven part. \r |
363 | <ul>\r |
364 | <li> ANT properties; </li>\r |
365 | <li> Dependent module (dependent library instances in most case); </li>\r |
366 | <li> Source files; </li>\r |
367 | <li> Sections if module is not library; </li>\r |
368 | <li> Output (different for library module and driver module); </li>\r |
369 | <li> Clean; </li>\r |
370 | <li> Clean all. </li>\r |
371 | </ul>\r |
372 | \r |
373 | @throws BuildException\r |
374 | Error throws during BaseName_build.xml generating. \r |
375 | **/\r |
376 | private void genBuildFile() throws BuildException {\r |
377 | FfsProcess fp = new FfsProcess();\r |
378 | DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();\r |
379 | try {\r |
380 | DocumentBuilder dombuilder = domfac.newDocumentBuilder();\r |
381 | Document document = dombuilder.newDocument();\r |
382 | Comment rootComment = document.createComment(info);\r |
383 | //\r |
384 | // create root element and its attributes\r |
385 | //\r |
386 | Element root = document.createElement("project");\r |
387 | //\r |
388 | // root.setAttribute("name", base_name);\r |
389 | //\r |
390 | root.setAttribute("default", "main");\r |
391 | root.setAttribute("basedir", ".");\r |
392 | //\r |
393 | // element for External ANT tasks\r |
394 | //\r |
395 | root.appendChild(document.createComment("Apply external ANT tasks"));\r |
396 | Element ele = document.createElement("taskdef");\r |
397 | ele.setAttribute("resource", "frameworktasks.tasks");\r |
398 | root.appendChild(ele);\r |
399 | ele = document.createElement("taskdef");\r |
400 | ele.setAttribute("resource", "cpptasks.tasks");\r |
401 | root.appendChild(ele);\r |
402 | ele = document.createElement("typedef");\r |
403 | ele.setAttribute("resource", "cpptasks.types");\r |
404 | root.appendChild(ele);\r |
405 | ele = document.createElement("taskdef");\r |
406 | ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");\r |
407 | root.appendChild(ele);\r |
408 | //\r |
409 | // elements for Properties\r |
410 | //\r |
411 | root.appendChild(document.createComment("All Properties"));\r |
412 | ele = document.createElement("property");\r |
413 | ele.setAttribute("name", "BASE_NAME");\r |
414 | ele.setAttribute("value", baseName);\r |
415 | root.appendChild(ele);\r |
416 | //\r |
417 | // Generate the default target,\r |
418 | // which depends on init, sections and output target\r |
419 | //\r |
420 | root.appendChild(document.createComment("Default target"));\r |
421 | ele = document.createElement("target");\r |
422 | ele.setAttribute("name", "main");\r |
423 | ele.setAttribute("depends", "libraries, sourcefiles, sections, output");\r |
424 | root.appendChild(ele);\r |
425 | //\r |
426 | // compile all source files\r |
427 | //\r |
428 | root.appendChild(document.createComment("Compile all dependency Library instances."));\r |
429 | ele = document.createElement("target");\r |
430 | ele.setAttribute("name", "libraries");\r |
431 | //\r |
432 | // Parse all sourfiles but files specified in sections\r |
433 | //\r |
434 | applyLibraryInstance(document, ele);\r |
435 | root.appendChild(ele);\r |
436 | //\r |
437 | // compile all source files\r |
438 | //\r |
439 | root.appendChild(document.createComment("sourcefiles target"));\r |
440 | ele = document.createElement("target");\r |
441 | ele.setAttribute("name", "sourcefiles");\r |
442 | //\r |
443 | // Parse all sourfiles but files specified in sections\r |
444 | //\r |
445 | applyCompileElement(document, ele);\r |
446 | root.appendChild(ele);\r |
447 | //\r |
448 | // generate the init target\r |
449 | // main purpose is create all nessary pathes\r |
450 | // generate the sections target\r |
451 | //\r |
452 | root.appendChild(document.createComment("sections target"));\r |
453 | ele = document.createElement("target");\r |
454 | ele.setAttribute("name", "sections");\r |
455 | applySectionsElement(document, ele, fp);\r |
456 | root.appendChild(ele);\r |
457 | //\r |
458 | // generate the output target\r |
459 | //\r |
460 | root.appendChild(document.createComment("output target"));\r |
461 | ele = document.createElement("target");\r |
462 | ele.setAttribute("name", "output");\r |
463 | applyOutputElement(document, ele, fp);\r |
464 | root.appendChild(ele);\r |
465 | //\r |
466 | // generate the clean target\r |
467 | //\r |
468 | root.appendChild(document.createComment("clean target"));\r |
469 | ele = document.createElement("target");\r |
470 | ele.setAttribute("name", "clean");\r |
471 | applyCleanElement(document, ele);\r |
472 | root.appendChild(ele);\r |
473 | //\r |
474 | // generate the Clean All target\r |
475 | //\r |
476 | root.appendChild(document.createComment("Clean All target"));\r |
477 | ele = document.createElement("target");\r |
478 | ele.setAttribute("name", "cleanall");\r |
479 | applyDeepcleanElement(document, ele);\r |
480 | root.appendChild(ele);\r |
481 | //\r |
482 | // add the root element to the document\r |
483 | //\r |
484 | document.appendChild(rootComment);\r |
485 | document.appendChild(root);\r |
486 | //\r |
487 | // Prepare the DOM document for writing\r |
488 | //\r |
489 | Source source = new DOMSource(document);\r |
490 | //\r |
491 | // Prepare the output file\r |
492 | //\r |
493 | File file = new File(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName\r |
494 | + "_build.xml");\r |
495 | //\r |
496 | // generate all directory path\r |
497 | //\r |
498 | (new File(file.getParent())).mkdirs();\r |
499 | Result result = new StreamResult(file);\r |
500 | //\r |
501 | // Write the DOM document to the file\r |
502 | //\r |
503 | Transformer xformer = TransformerFactory.newInstance().newTransformer();\r |
504 | xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");\r |
505 | xformer.setOutputProperty(OutputKeys.INDENT, "yes");\r |
506 | xformer.transform(source, result);\r |
507 | } catch (Exception ex) {\r |
508 | throw new BuildException("Module [" + baseName + "] generating build file failed.\n" + ex.getMessage());\r |
509 | }\r |
510 | }\r |
511 | \r |
512 | /**\r |
513 | Generate the clean elements for BaseName_build.xml. \r |
514 | \r |
515 | @param document current BaseName_build.xml XML document\r |
516 | @param root Root element for current\r |
517 | **/\r |
518 | private void applyCleanElement(Document document, Node root) {\r |
519 | String[] libinstances = libraries.toArray(new String[libraries.size()]);\r |
520 | for (int i = 0; i < libinstances.length; i++) {\r |
521 | File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");\r |
522 | \r |
523 | Element ifEle = document.createElement("if");\r |
524 | Element availableEle = document.createElement("available");\r |
525 | availableEle.setAttribute("file", file.getPath());\r |
526 | ifEle.appendChild(availableEle);\r |
527 | Element elseEle = document.createElement("then");\r |
528 | \r |
529 | Element ele = document.createElement("ant");\r |
530 | ele.setAttribute("antfile", file.getPath());\r |
531 | ele.setAttribute("inheritAll", "false");\r |
532 | ele.setAttribute("target", libinstances[i] + "_clean");\r |
533 | //\r |
534 | // Workspace_DIR\r |
535 | //\r |
536 | Element property = document.createElement("property");\r |
537 | property.setAttribute("name", "WORKSPACE_DIR");\r |
538 | property.setAttribute("value", "${WORKSPACE_DIR}");\r |
539 | ele.appendChild(property);\r |
540 | //\r |
541 | // Package Dir\r |
542 | //\r |
543 | property = document.createElement("property");\r |
544 | property.setAttribute("name", "PACKAGE_DIR");\r |
545 | property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar\r |
546 | + GlobalData.getPackagePathForModule(libinstances[i]));\r |
547 | ele.appendChild(property);\r |
548 | //\r |
549 | // ARCH\r |
550 | //\r |
551 | property = document.createElement("property");\r |
552 | property.setAttribute("name", "ARCH");\r |
553 | property.setAttribute("value", "${ARCH}");\r |
554 | ele.appendChild(property);\r |
555 | //\r |
556 | // TARGET\r |
557 | //\r |
558 | property = document.createElement("property");\r |
559 | property.setAttribute("name", "TARGET");\r |
560 | property.setAttribute("value", "${TARGET}");\r |
561 | ele.appendChild(property);\r |
562 | //\r |
563 | // PACKAGE\r |
564 | //\r |
565 | property = document.createElement("property");\r |
566 | property.setAttribute("name", "PACKAGE");\r |
567 | property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));\r |
568 | ele.appendChild(property);\r |
569 | \r |
570 | elseEle.appendChild(ele);\r |
571 | ifEle.appendChild(elseEle);\r |
572 | root.appendChild(ifEle);\r |
573 | }\r |
574 | }\r |
575 | \r |
576 | /**\r |
577 | Generate the cleanall elements for BaseName_build.xml. \r |
578 | \r |
579 | @param document current BaseName_build.xml XML document\r |
580 | @param root Root element for current\r |
581 | **/\r |
582 | private void applyDeepcleanElement(Document document, Node root) {\r |
583 | String[] libinstances = libraries.toArray(new String[libraries.size()]);\r |
584 | for (int i = 0; i < libinstances.length; i++) {\r |
585 | File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");\r |
586 | \r |
587 | Element ifEle = document.createElement("if");\r |
588 | Element availableEle = document.createElement("available");\r |
589 | availableEle.setAttribute("file", file.getPath());\r |
590 | ifEle.appendChild(availableEle);\r |
591 | Element elseEle = document.createElement("then");\r |
592 | \r |
593 | Element ele = document.createElement("ant");\r |
594 | ele.setAttribute("antfile", file.getPath());\r |
595 | ele.setAttribute("inheritAll", "false");\r |
596 | ele.setAttribute("target", libinstances[i] + "_cleanall");\r |
597 | //\r |
598 | // Workspace_DIR\r |
599 | //\r |
600 | Element property = document.createElement("property");\r |
601 | property.setAttribute("name", "WORKSPACE_DIR");\r |
602 | property.setAttribute("value", "${WORKSPACE_DIR}");\r |
603 | ele.appendChild(property);\r |
604 | //\r |
605 | // Package Dir\r |
606 | //\r |
607 | property = document.createElement("property");\r |
608 | property.setAttribute("name", "PACKAGE_DIR");\r |
609 | property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar\r |
610 | + GlobalData.getPackagePathForModule(libinstances[i]));\r |
611 | ele.appendChild(property);\r |
612 | //\r |
613 | // ARCH\r |
614 | //\r |
615 | property = document.createElement("property");\r |
616 | property.setAttribute("name", "ARCH");\r |
617 | property.setAttribute("value", "${ARCH}");\r |
618 | ele.appendChild(property);\r |
619 | //\r |
620 | // TARGET\r |
621 | //\r |
622 | property = document.createElement("property");\r |
623 | property.setAttribute("name", "TARGET");\r |
624 | property.setAttribute("value", "${TARGET}");\r |
625 | ele.appendChild(property);\r |
626 | //\r |
627 | // PACKAGE\r |
628 | //\r |
629 | property = document.createElement("property");\r |
630 | property.setAttribute("name", "PACKAGE");\r |
631 | property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));\r |
632 | ele.appendChild(property);\r |
633 | \r |
634 | elseEle.appendChild(ele);\r |
635 | ifEle.appendChild(elseEle);\r |
636 | root.appendChild(ifEle);\r |
637 | }\r |
638 | }\r |
639 | \r |
640 | /**\r |
641 | Generate the dependent library instances elements for BaseName_build.xml. \r |
642 | \r |
643 | @param document current BaseName_build.xml XML document\r |
644 | @param root Root element for current\r |
645 | **/\r |
646 | private void applyLibraryInstance(Document document, Node root) {\r |
647 | String[] libinstances = libraries.toArray(new String[libraries.size()]);\r |
648 | for (int i = 0; i < libinstances.length; i++) {\r |
649 | Element ele = document.createElement("ant");\r |
650 | File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");\r |
651 | ele.setAttribute("antfile", file.getPath());\r |
652 | ele.setAttribute("inheritAll", "false");\r |
653 | ele.setAttribute("target", libinstances[i]);\r |
654 | //\r |
655 | // Workspace_DIR\r |
656 | //\r |
657 | Element property = document.createElement("property");\r |
658 | property.setAttribute("name", "WORKSPACE_DIR");\r |
659 | property.setAttribute("value", "${WORKSPACE_DIR}");\r |
660 | ele.appendChild(property);\r |
661 | //\r |
662 | // Package Dir\r |
663 | //\r |
664 | property = document.createElement("property");\r |
665 | property.setAttribute("name", "PACKAGE_DIR");\r |
666 | property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar\r |
667 | + GlobalData.getPackagePathForModule(libinstances[i]));\r |
668 | ele.appendChild(property);\r |
669 | //\r |
670 | // ARCH\r |
671 | //\r |
672 | property = document.createElement("property");\r |
673 | property.setAttribute("name", "ARCH");\r |
674 | property.setAttribute("value", "${ARCH}");\r |
675 | ele.appendChild(property);\r |
676 | //\r |
677 | // TARGET\r |
678 | //\r |
679 | property = document.createElement("property");\r |
680 | property.setAttribute("name", "TARGET");\r |
681 | property.setAttribute("value", "${TARGET}");\r |
682 | ele.appendChild(property);\r |
683 | //\r |
684 | // PACKAGE\r |
685 | //\r |
686 | property = document.createElement("property");\r |
687 | property.setAttribute("name", "PACKAGE");\r |
688 | property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));\r |
689 | ele.appendChild(property);\r |
690 | root.appendChild(ele);\r |
691 | }\r |
692 | Element expand = document.createElement("Expand");\r |
693 | root.appendChild(expand);\r |
694 | }\r |
695 | \r |
696 | /**\r |
697 | Generate the build source files elements for BaseName_build.xml. \r |
698 | \r |
699 | @param document current BaseName_build.xml XML document\r |
700 | @param root Root element for current\r |
701 | **/\r |
702 | private void applyCompileElement(Document document, Node root) {\r |
703 | FileProcess fileProcess = new FileProcess();\r |
704 | fileProcess.init(getProject(), includes, sourceFiles, document);\r |
705 | Node[] files = this.getSourceFiles();\r |
706 | //\r |
707 | // Parse all unicode files\r |
708 | //\r |
709 | for (int i = 0; i < files.length; i++) {\r |
710 | String filetype = getFiletype(files[i]);\r |
711 | if (filetype != null) {\r |
712 | fileProcess.parseFile(getFilename(files[i]), filetype, root, true);\r |
713 | } else {\r |
714 | fileProcess.parseFile(getFilename(files[i]), root, true);\r |
715 | }\r |
716 | }\r |
717 | if (fileProcess.isUnicodeExist()) {\r |
718 | Element ele = document.createElement("Build_Unicode_Database");\r |
719 | ele.setAttribute("FILEPATH", ".");\r |
720 | ele.setAttribute("FILENAME", "${BASE_NAME}");\r |
721 | root.appendChild(ele);\r |
722 | }\r |
723 | \r |
724 | //\r |
725 | // Parse AutoGen.c & AutoGen.h\r |
726 | //\r |
727 | if (!baseName.equalsIgnoreCase("Shell")) {\r |
728 | fileProcess.parseFile(getProject().getProperty("DEST_DIR_DEBUG") + File.separatorChar + "AutoGen.c", root,\r |
729 | false);\r |
730 | }\r |
731 | //\r |
732 | // Parse all source files\r |
733 | //\r |
734 | for (int i = 0; i < files.length; i++) {\r |
735 | String filetype = getFiletype(files[i]);\r |
736 | if (filetype != null) {\r |
737 | fileProcess.parseFile(getFilename(files[i]), filetype, root, false);\r |
738 | } else {\r |
739 | fileProcess.parseFile(getFilename(files[i]), root, false);\r |
740 | }\r |
741 | }\r |
742 | //\r |
743 | // root.appendChild(parallelEle);\r |
744 | //\r |
745 | Iterator iter = sourceFiles.iterator();\r |
746 | String str = "";\r |
747 | while (iter.hasNext()) {\r |
748 | str += " " + (String) iter.next();\r |
749 | }\r |
750 | getProject().setProperty("SOURCE_FILES", str);\r |
751 | }\r |
752 | \r |
753 | /**\r |
754 | Generate the section elements for BaseName_build.xml. Library module will\r |
755 | skip this process. \r |
756 | \r |
757 | @param document current BaseName_build.xml XML document\r |
758 | @param root Root element for current\r |
759 | **/\r |
760 | private void applySectionsElement(Document document, Node root, FfsProcess fp) {\r |
761 | if (fp.initSections(buildType, getProject())) {\r |
762 | String targetFilename = guid + "-" + baseName + FpdParserTask.getSuffix(componentType);\r |
763 | String[] list = fp.getGenSectionElements(document, baseName, guid, targetFilename);\r |
764 | \r |
765 | for (int i = 0; i < list.length; i++) {\r |
766 | Element ele = document.createElement(list[i]);\r |
767 | ele.setAttribute("FILEPATH", ".");\r |
768 | ele.setAttribute("FILENAME", "${BASE_NAME}");\r |
769 | root.appendChild(ele);\r |
770 | }\r |
771 | }\r |
772 | }\r |
773 | \r |
774 | /**\r |
775 | Generate the output elements for BaseName_build.xml. If module is library,\r |
776 | call the <em>LIB</em> command, else call the <em>GenFfs</em> command. \r |
777 | \r |
778 | @param document current BaseName_build.xml XML document\r |
779 | @param root Root element for current\r |
780 | **/\r |
781 | private void applyOutputElement(Document document, Node root, FfsProcess fp) {\r |
782 | if (flag == GlobalData.ONLY_LIBMSA || flag == GlobalData.LIBMSA_AND_LIBMBD) {\r |
783 | //\r |
784 | // call Lib command\r |
785 | //\r |
786 | Element cc = document.createElement("Build_Library");\r |
787 | cc.setAttribute("FILENAME", baseName);\r |
788 | root.appendChild(cc);\r |
789 | }\r |
790 | //\r |
791 | // if it is a module but library\r |
792 | //\r |
793 | else {\r |
794 | if (fp.getFfsNode() != null) {\r |
795 | root.appendChild(fp.getFfsNode());\r |
796 | }\r |
797 | }\r |
798 | }\r |
799 | \r |
800 | /**\r |
801 | Get file name from node. If some wrong, return string with zero length. \r |
802 | \r |
803 | @param node Filename node of MSA/MBD or specified in each Section\r |
804 | @return File name\r |
805 | **/\r |
806 | private String getFilename(Node node) {\r |
807 | String path = null;\r |
808 | String filename = "${MODULE_DIR}" + File.separatorChar;\r |
809 | String str = "";\r |
810 | try {\r |
811 | FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);\r |
812 | str = file.getFilename().getStringValue().trim();\r |
813 | path = file.getFilename().getPath();\r |
814 | } catch (Exception e) {\r |
815 | str = "";\r |
816 | }\r |
817 | if (path != null) {\r |
818 | filename += path + File.separatorChar + str;\r |
819 | } else {\r |
820 | filename += str;\r |
821 | }\r |
822 | return getProject().replaceProperties(filename);\r |
823 | }\r |
824 | \r |
825 | /**\r |
826 | Get file type from node. If some wrong or not specified, return \r |
827 | <code>null</code>. \r |
828 | \r |
829 | @param node Filename node of MSA/MBD or specified in each Section\r |
830 | @return File type\r |
831 | **/\r |
832 | private String getFiletype(Node node) {\r |
833 | String str = null;\r |
834 | try {\r |
835 | FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);\r |
836 | str = file.getFilename().getFileType();\r |
837 | } catch (Exception e) {\r |
838 | str = null;\r |
839 | }\r |
840 | return str;\r |
841 | }\r |
842 | \r |
843 | /**\r |
844 | Return all source files but AutoGen.c.\r |
845 | \r |
846 | @return source files Node array\r |
847 | **/\r |
848 | public Node[] getSourceFiles() {\r |
849 | XmlObject[] files = SurfaceAreaQuery.getSourceFiles(arch);\r |
850 | if (files == null) {\r |
851 | return new Node[0];\r |
852 | }\r |
853 | Vector<Node> vector = new Vector<Node>();\r |
854 | for (int i = 0; i < files.length; i++) {\r |
855 | vector.addElement(files[i].getDomNode());\r |
856 | }\r |
857 | //\r |
858 | // To be consider sourcefiles from Sections\r |
859 | //\r |
860 | return vector.toArray(new Node[vector.size()]);\r |
861 | }\r |
862 | \r |
863 | /**\r |
864 | Get current module's base name. \r |
865 | \r |
866 | @return base name\r |
867 | **/\r |
868 | public String getBaseName() {\r |
869 | return baseName;\r |
870 | }\r |
871 | \r |
872 | /**\r |
873 | Set MBD surface area file. For ANT use.\r |
874 | \r |
875 | @param mbdFilename Surface Area file\r |
876 | **/\r |
877 | public void setMbdFilename(File mbdFilename) {\r |
878 | this.mbdFilename = mbdFilename;\r |
879 | }\r |
880 | \r |
881 | /**\r |
882 | Set MSA surface area file. For ANT use.\r |
883 | \r |
884 | @param msaFilename Surface Area file\r |
885 | **/\r |
886 | public void setMsaFilename(File msaFilename) {\r |
887 | this.msaFilename = msaFilename;\r |
888 | }\r |
889 | \r |
890 | /**\r |
891 | Compile flags setup. \r |
892 | \r |
893 | <p> Take command <code>CC</code> and arch <code>IA32</code> for example, \r |
894 | Those flags are from <code>ToolChainFactory</code>: </p>\r |
895 | <ul>\r |
896 | <li> IA32_CC </li>\r |
897 | <li> IA32_CC_STD_FLAGS </li>\r |
898 | <li> IA32_CC_GLOBAL_FLAGS </li>\r |
899 | <li> IA32_CC_GLOBAL_ADD_FLAGS </li>\r |
900 | <li> IA32_CC_GLOBAL_SUB_FLAGS </li>\r |
901 | </ul>\r |
902 | Those flags can user-define: \r |
903 | <ul>\r |
904 | <li> IA32_CC_PROJ_FLAGS </li>\r |
905 | <li> IA32_CC_PROJ_ADD_FLAGS </li>\r |
906 | <li> IA32_CC_PROJ_SUB_FLAGS </li>\r |
907 | <li> CC_PROJ_FLAGS </li>\r |
908 | <li> CC_PROJ_ADD_FLAGS </li>\r |
909 | <li> CC_PROJ_SUB_FLAGS </li>\r |
910 | <li> CC_FLAGS </li>\r |
911 | <li> IA32_CC_FLAGS </li>\r |
912 | </ul>\r |
913 | \r |
914 | <p> The final flags is composed of STD, GLOBAL and PROJ. If CC_FLAGS or\r |
915 | IA32_CC_FLAGS is specified, STD, GLOBAL and PROJ will not affect. </p>\r |
916 | \r |
917 | Note that the <code>ToolChainFactory</code> executes only once \r |
918 | during whole build process. \r |
919 | **/\r |
920 | private void flagsSetup() {\r |
921 | Project project = getProject();\r |
922 | //\r |
923 | // If ToolChain has been set up before, do nothing.\r |
924 | //\r |
925 | ToolChainFactory toolChainFactory = new ToolChainFactory(project);\r |
926 | toolChainFactory.setupToolChain();\r |
927 | \r |
928 | String[] cmd = ToolChainFactory.commandType;\r |
929 | Set<String> addSet = new HashSet<String>(40);\r |
930 | Set<String> subSet = new HashSet<String>(40);\r |
931 | for (int i = 0; i < cmd.length; i++) {\r |
932 | String str = ToolChainFactory.getValue(arch + "_" + cmd[i]);\r |
933 | //\r |
934 | // Command line path+command name\r |
935 | //\r |
936 | if (str != null) {\r |
937 | project.setProperty(cmd[i], str);\r |
938 | }\r |
939 | //\r |
940 | // ARCH_CMD_STD_FLAGS\r |
941 | //\r |
942 | str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_STD_FLAGS");\r |
943 | if (str != null) {\r |
944 | putFlagsToSet(addSet, str);\r |
945 | project.setProperty(cmd[i] + "_STD_FLAGS", str);\r |
946 | }\r |
947 | //\r |
948 | // ARCH_CMD_GLOBAL_FLAGS\r |
949 | //\r |
950 | str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_FLAGS");\r |
951 | if (str != null) {\r |
952 | putFlagsToSet(addSet, str);\r |
953 | }\r |
954 | //\r |
955 | // ARCH_CMD_GLOBAL_ADD_FLAGS\r |
956 | //\r |
957 | str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_ADD_FLAGS");\r |
958 | if (str != null) {\r |
959 | putFlagsToSet(addSet, str);\r |
960 | }\r |
961 | //\r |
962 | // ARCH_CMD_GLOBAL_SUB_FLAGS\r |
963 | //\r |
964 | str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_SUB_FLAGS");\r |
965 | if (str != null) {\r |
966 | putFlagsToSet(subSet, str);\r |
967 | }\r |
968 | //\r |
969 | // ARCH_CMD_PROJ_FLAGS\r |
970 | //\r |
971 | str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_FLAGS");\r |
972 | if (str != null) {\r |
973 | putFlagsToSet(addSet, str);\r |
974 | }\r |
975 | //\r |
976 | // ARCH_CMD_PROG_FLAGS\r |
977 | //\r |
978 | str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_ADD_FLAGS");\r |
979 | if (str != null) {\r |
980 | putFlagsToSet(addSet, str);\r |
981 | }\r |
982 | //\r |
983 | // ARCH_CMD_PROG_FLAGS\r |
984 | //\r |
985 | str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_SUB_FLAGS");\r |
986 | if (str != null) {\r |
987 | putFlagsToSet(subSet, str);\r |
988 | }\r |
989 | //\r |
990 | // CMD_PROJ_FLAGS\r |
991 | //\r |
992 | str = project.getProperty(cmd[i] + "_PROJ_FLAGS");\r |
993 | if (str != null) {\r |
994 | putFlagsToSet(addSet, str);\r |
995 | }\r |
996 | //\r |
997 | // CMD_PROG_FLAGS\r |
998 | //\r |
999 | str = project.getProperty(cmd[i] + "_PROJ_ADD_FLAGS");\r |
1000 | if (str != null) {\r |
1001 | putFlagsToSet(addSet, str);\r |
1002 | }\r |
1003 | //\r |
1004 | // CMD_PROG_FLAGS\r |
1005 | //\r |
1006 | str = project.getProperty(cmd[i] + "_PROJ_SUB_FLAGS");\r |
1007 | if (str != null) {\r |
1008 | putFlagsToSet(subSet, str);\r |
1009 | }\r |
1010 | //\r |
1011 | // If IA32_CC_FLAGS or IA32_LIB_FLAGS .. has defined in BuildOptions\r |
1012 | //\r |
1013 | if ((str = project.getProperty(arch + "_" + cmd[i] + "_FLAGS")) != null) {\r |
1014 | project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));\r |
1015 | addSet.clear();\r |
1016 | subSet.clear();\r |
1017 | putFlagsToSet(addSet, project.replaceProperties(str));\r |
1018 | project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));\r |
1019 | addSet.clear();\r |
1020 | subSet.clear();\r |
1021 | }\r |
1022 | //\r |
1023 | // If CC_FLAGS or LIB_FLAGS .. has defined in BuildOptions\r |
1024 | //\r |
1025 | else if ((str = project.getProperty(cmd[i] + "_FLAGS")) != null) {\r |
1026 | project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));\r |
1027 | addSet.clear();\r |
1028 | subSet.clear();\r |
1029 | putFlagsToSet(addSet, project.replaceProperties(str));\r |
1030 | project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));\r |
1031 | addSet.clear();\r |
1032 | subSet.clear();\r |
1033 | } else {\r |
1034 | project.setProperty(cmd[i] + "_FLAGS", getFlags(addSet, subSet));\r |
1035 | addSet.clear();\r |
1036 | subSet.clear();\r |
1037 | }\r |
1038 | }\r |
1039 | project.setProperty("C_FLAGS", project.getProperty("CC_FLAGS"));\r |
1040 | }\r |
1041 | \r |
1042 | /**\r |
1043 | Initialize some properties will be used in current module build, including\r |
1044 | user-defined option from <em>Option</em> of <em>BuildOptions</em> in \r |
1045 | surface area. \r |
1046 | **/\r |
1047 | private void updateParameters() {\r |
1048 | getProject().setProperty("OBJECTS", "");\r |
1049 | getProject().setProperty("SDB_FILES", "");\r |
1050 | getProject().setProperty("BASE_NAME", baseName);\r |
1051 | if (map.get("MsaHeader") != null) {\r |
1052 | flag = GlobalData.MSA_AND_MBD;\r |
1053 | MsaHeaderDocument.MsaHeader header = ((MsaHeaderDocument) map.get("MsaHeader")).getMsaHeader();\r |
1054 | guid = header.getGuid().getStringValue();\r |
1055 | componentType = header.getComponentType().toString();\r |
1056 | } \r |
1057 | \r |
1058 | else if (map.get("MsaLibHeader") != null) {\r |
1059 | flag = GlobalData.LIBMSA_AND_LIBMBD;\r |
1060 | MsaLibHeaderDocument.MsaLibHeader header = ((MsaLibHeaderDocument) map.get("MsaLibHeader"))\r |
1061 | .getMsaLibHeader();\r |
1062 | guid = header.getGuid().getStringValue();\r |
1063 | componentType = header.getComponentType().toString();\r |
1064 | }\r |
1065 | \r |
1066 | if (componentType != null) {\r |
1067 | getProject().setProperty("COMPONENT_TYPE", componentType);\r |
1068 | }\r |
1069 | \r |
1070 | if (guid != null) {\r |
1071 | getProject().setProperty("FILE_GUID", guid);\r |
1072 | }\r |
1073 | //\r |
1074 | // Get all options and set to properties\r |
1075 | //\r |
1076 | String[][] options = SurfaceAreaQuery.getOptions(arch);\r |
1077 | for (int i = 0; i < options.length; i++) {\r |
1078 | if (options[i][0] != null && options[i][1] != null) {\r |
1079 | getProject().setProperty(options[i][0], getProject().replaceProperties(options[i][1]));\r |
1080 | }\r |
1081 | }\r |
1082 | \r |
1083 | buildType = getProject().getProperty("BUILD_TYPE");\r |
1084 | if (buildType == null) {\r |
1085 | buildType = componentType;\r |
1086 | }\r |
1087 | \r |
1088 | }\r |
1089 | \r |
1090 | /**\r |
1091 | Separate the string and instore in set.\r |
1092 | \r |
1093 | <p> String is separated by Java Regulation Expression \r |
1094 | "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>\r |
1095 | \r |
1096 | <p>For example: </p>\r |
1097 | \r |
1098 | <pre>\r |
1099 | "/nologo", "/W3", "/WX"\r |
1100 | "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""\r |
1101 | </pre>\r |
1102 | \r |
1103 | @param set store the separated string\r |
1104 | @param str string to separate\r |
1105 | **/\r |
1106 | private void putFlagsToSet(Set<String> set, String str) {\r |
1107 | Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");\r |
1108 | Matcher matcher = myPattern.matcher(str + " ");\r |
1109 | while (matcher.find()) {\r |
1110 | String item = str.substring(matcher.start(1), matcher.end(1));\r |
1111 | if (!set.contains(item)) {\r |
1112 | set.add(item);\r |
1113 | }\r |
1114 | }\r |
1115 | }\r |
1116 | \r |
1117 | /**\r |
1118 | Generate the final flags string will be used by compile command. \r |
1119 | \r |
1120 | @param add the add flags set\r |
1121 | @param sub the sub flags set\r |
1122 | @return final flags after add set substract sub set\r |
1123 | **/\r |
1124 | private String getFlags(Set<String> add, Set<String> sub) {\r |
1125 | String result = "";\r |
1126 | add.removeAll(sub);\r |
1127 | Iterator iter = add.iterator();\r |
1128 | while (iter.hasNext()) {\r |
1129 | String str = getProject().replaceProperties((String) iter.next());\r |
1130 | result += str.substring(1, str.length() - 1) + " ";\r |
1131 | }\r |
1132 | return result;\r |
1133 | }\r |
1134 | \r |
1135 | /**\r |
1136 | Generate the flags string with original format. The format is defined by \r |
1137 | Java Regulation Expression "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>\r |
1138 | \r |
1139 | <p>For example: </p>\r |
1140 | \r |
1141 | <pre>\r |
1142 | "/nologo", "/W3", "/WX"\r |
1143 | "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""\r |
1144 | </pre>\r |
1145 | \r |
1146 | @param add the add flags set\r |
1147 | @param sub the sub flags set\r |
1148 | @return flags with original format\r |
1149 | **/\r |
1150 | private String getRawFlags(Set<String> add, Set<String> sub) {\r |
1151 | String result = "";\r |
1152 | add.removeAll(sub);\r |
1153 | Iterator iter = add.iterator();\r |
1154 | while (iter.hasNext()) {\r |
1155 | String str = getProject().replaceProperties((String) iter.next());\r |
1156 | result += "\"" + str.substring(1, str.length() - 1) + "\", ";\r |
1157 | }\r |
1158 | return result;\r |
1159 | }\r |
1160 | \r |
1161 | /**\r |
1162 | Set base name. For ANT use.\r |
1163 | \r |
1164 | @param baseName Base name\r |
1165 | **/\r |
1166 | public void setBaseName(String baseName) {\r |
1167 | this.baseName = baseName;\r |
1168 | }\r |
1169 | \r |
1170 | }\r |