2 This file is ANT task GenBuild.
4 The file is used to parse a specified Module, and generate its build time
5 ANT script build.xml, then call the the ANT script to build the module.
7 Copyright (c) 2006, Intel Corporation
8 All rights reserved. This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 package org
.tianocore
.build
;
19 import java
.util
.HashMap
;
20 import java
.util
.HashSet
;
21 import java
.util
.Iterator
;
22 import java
.util
.LinkedHashSet
;
23 import java
.util
.List
;
26 import java
.util
.Vector
;
27 import java
.util
.regex
.Matcher
;
28 import java
.util
.regex
.Pattern
;
30 import javax
.xml
.parsers
.DocumentBuilder
;
31 import javax
.xml
.parsers
.DocumentBuilderFactory
;
32 import javax
.xml
.transform
.OutputKeys
;
33 import javax
.xml
.transform
.Result
;
34 import javax
.xml
.transform
.Source
;
35 import javax
.xml
.transform
.Transformer
;
36 import javax
.xml
.transform
.TransformerFactory
;
37 import javax
.xml
.transform
.dom
.DOMSource
;
38 import javax
.xml
.transform
.stream
.StreamResult
;
40 import org
.apache
.tools
.ant
.BuildException
;
41 import org
.apache
.tools
.ant
.Project
;
42 import org
.apache
.tools
.ant
.Task
;
43 import org
.apache
.tools
.ant
.taskdefs
.Ant
;
44 import org
.apache
.xmlbeans
.XmlObject
;
45 import org
.w3c
.dom
.Comment
;
46 import org
.w3c
.dom
.Document
;
47 import org
.w3c
.dom
.Element
;
48 import org
.w3c
.dom
.Node
;
50 import org
.tianocore
.build
.autogen
.AutoGen
;
51 import org
.tianocore
.build
.autogen
.CommonDefinition
;
52 import org
.tianocore
.build
.fpd
.FpdParserTask
;
53 import org
.tianocore
.build
.global
.GenBuildLogger
;
54 import org
.tianocore
.build
.global
.GlobalData
;
55 import org
.tianocore
.build
.global
.OutputManager
;
56 import org
.tianocore
.build
.global
.SurfaceAreaQuery
;
57 import org
.tianocore
.build
.toolchain
.ToolChainFactory
;
58 import org
.tianocore
.logger
.EdkLog
;
59 import org
.tianocore
.FilenameDocument
;
60 import org
.tianocore
.MsaHeaderDocument
;
61 import org
.tianocore
.MsaLibHeaderDocument
;
65 <code>GenBuildTask</code> is an ANT task that can be used in ANT build
66 system. The main function of this task is to parse module's surface area,
67 then generate the corresponding <em>BaseName_build.xml</em> (the real ANT
68 build script) and call this to build the module.
72 The usage is (take module <em>HelloWorld</em> for example):
76 <GenBuild baseName="HelloWorld"
77 mbdFilename="${MODULE_DIR}/HelloWorld.mbd"
78 msaFilename="${MODULE_DIR}/HelloWorld.msa"/>
82 This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and
83 <em>AutoGen.h</em>. The task also parses the development environment
84 configuration files, such as collecting package information, setting compiler
91 public class GenBuildTask
extends Task
{
94 /// Module surface area file.
99 /// Module build description file.
104 /// Module surface area information after overrided.
106 public Map
<String
, XmlObject
> map
= new HashMap
<String
, XmlObject
>();
109 /// Module's base name.
111 private String baseName
;
114 /// Current build Arch, such as IA32, X64, IPF and so on.
119 /// Module's GUID (Globally Unique Identifier).
124 /// Module's component type, such as SEC, LIBRARY, BS_DRIVER and so on.
126 private String componentType
;
129 /// This value is used in build time. Override module's component type. When
130 /// search FFS (Sections information) in common file, buildtype instead of
133 private String buildType
;
136 /// List all required includes for current build module.
138 public Set
<String
> includes
= new LinkedHashSet
<String
>();
141 /// List all libraries for current build module.
143 public Set
<String
> libraries
= new LinkedHashSet
<String
>();
146 /// List all source files for current build module.
148 public Set
<String
> sourceFiles
= new LinkedHashSet
<String
>();
151 /// Flag to identify what surface area files are specified. Current value is
152 /// <em>NO_SA</em>, <em>ONLY_MSA</em>, <em>ONLY_LIBMSA</em>,
153 /// <em>MSA_AND_MBD</em> or <em>LIBMSA_AND_LIBMBD</em>.
155 /// @see org.tianocore.build.global.GlobaData
157 private int flag
= GlobalData
.NO_SA
;
160 /// The information at the header of <em>build.xml</em>.
162 private String info
= "====================================================================\n"
164 + "File auto-generated by build utility\n"
167 + "Auto-generated ANT build file for building of EFI Modules/Platforms\n"
168 + "=====================================================================";
171 Public construct method. It is necessary for ANT task.
173 public GenBuildTask() {
177 ANT task's entry point, will be called after init(). The main steps is described
180 <li> Judge current build mode (MODULE | PACKAGE | PLATFORM). This step will execute
181 only once in whole build process; </li>
182 <li> Initialize global information (Framework DB, SPD files and all MSA files
183 listed in SPD). This step will execute only once in whole build process; </li>
184 <li> Restore some important ANT property. If current build is single module
185 build, here will set many default values; </li>
186 <li> Get the current module's overridded surface area information from
188 <li> Set up the output directories, including BIN_DIR, DEST_DIR_OUTPUT and
189 DEST_DIR_DEBUG; </li>
190 <li> Get module dependent library instances and include pathes; </li>
191 <li> Judge whether current module is built. If yes, skip it; </li>
192 <li> Call AutoGen and PCD to generate AutoGen.c & AutoGen.h </li>
193 <li> Set up the compile flags; </li>
194 <li> Generate BaseName_build.xml; </li>
195 <li> Call to BaseName_build.xml, and build the current module. </li>
198 <p>Build is dependent on BuildMacro.xml which define many macro. </p>
200 @throws BuildException
201 From module build, exception from module surface area invalid.
203 public void execute() throws BuildException
{
204 System
.out
.println("Module [" + baseName
+ "] start.");
206 // Inital GenBuild log method
208 GenBuildLogger logger
= new GenBuildLogger(getProject());
209 EdkLog
.setLogger(logger
);
210 EdkLog
.setLogLevel(1);
212 OutputManager
.update(getProject());
213 GlobalData
.initInfo("Tools" + File
.separatorChar
+ "Conf" + File
.separatorChar
+ "FrameworkDatabase.db",
214 getProject().getProperty("WORKSPACE_DIR"));
215 recallFixedProperties();
216 arch
= getProject().getProperty("ARCH");
217 arch
= arch
.toUpperCase();
218 map
= GlobalData
.getDoc(baseName
);
220 // Initialize SurfaceAreaQuery
222 SurfaceAreaQuery
.setDoc(map
);
224 // Setup Output Management
226 String
[] outdir
= SurfaceAreaQuery
.getOutputDirectory();
227 OutputManager
.update(getProject(), outdir
[1], outdir
[0]);
229 updateIncludesAndLibraries();
231 if (GlobalData
.isModuleBuilt(baseName
, arch
)) {
234 GlobalData
.registerBuiltModule(baseName
, arch
);
239 AutoGen autogen
= new AutoGen(getProject().getProperty("DEST_DIR_DEBUG"), baseName
, arch
);
240 autogen
.genAutogen();
246 // Update flags like CC_FLAGS, LIB_FLAGS etc.
249 GlobalData
.addLibrary(baseName
, arch
, getProject().getProperty("BIN_DIR") + File
.separatorChar
+ baseName
+ ".lib");
250 GlobalData
.addModuleLibrary(baseName
, arch
, libraries
);
252 // If ComponentType is USER_DEFINED,
253 // then call the exist BaseName_build.xml directly.
255 if (buildType
.equalsIgnoreCase("CUSTOM_BUILD")) {
256 System
.out
.println("Call user-defined " + baseName
+ "_build.xml");
258 ant
.setProject(getProject());
259 ant
.setAntfile(getProject().getProperty("MODULE_DIR") + File
.separatorChar
+ baseName
+ "_build.xml");
260 ant
.setInheritAll(true);
266 // Generate ${BASE_NAME}_build.xml file
268 System
.out
.println("Generate " + baseName
+ "_build.xml");
270 System
.out
.println("Call the " + baseName
+ "_build.xml");
272 ant
.setProject(getProject());
273 ant
.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File
.separatorChar
+ baseName
+ "_build.xml");
274 ant
.setInheritAll(true);
280 Return the name of the directory that corresponds to the architecture.
281 This is a translation from the XML Schema tag to a directory that
282 corresponds to our directory name coding convention.
285 private String
archDir(String arch
) {
286 return arch
.replaceFirst("X64", "x64")
287 .replaceFirst("IPF", "Ipf")
288 .replaceFirst("IA32", "Ia32")
289 .replaceFirst("ARM", "Arm")
290 .replaceFirst("EBC", "Ebc");
294 Get the dependent library instances and include package name from
295 surface area, and initialize module include pathes.
298 private void updateIncludesAndLibraries() {
299 List
<String
> rawIncludes
= SurfaceAreaQuery
.getIncludePackageName(arch
);
300 if (rawIncludes
!= null) {
301 Iterator iter
= rawIncludes
.iterator();
302 while (iter
.hasNext()) {
303 String packageName
= (String
) iter
.next();
304 includes
.add("${WORKSPACE_DIR}" + File
.separatorChar
+ GlobalData
.getPackagePath(packageName
)
305 + File
.separatorChar
+ "Include");
306 includes
.add("${WORKSPACE_DIR}" + File
.separatorChar
+ GlobalData
.getPackagePath(packageName
)
307 + File
.separatorChar
+ "Include" + File
.separatorChar
+ archDir(arch
));
310 includes
.add("${DEST_DIR_DEBUG}");
311 List
<String
> rawLibraries
= SurfaceAreaQuery
.getLibraryInstance(this.arch
, CommonDefinition
.AlwaysConsumed
);
312 if (rawLibraries
!= null) {
313 Iterator iter
= rawLibraries
.iterator();
314 while (iter
.hasNext()) {
315 libraries
.add((String
) iter
.next());
322 Normalize all dependent library instance and include pathes' format.
325 private void normalize() {
326 String
[] includesArray
= includes
.toArray(new String
[includes
.size()]);
328 for (int i
= 0; i
< includesArray
.length
; i
++) {
329 includes
.add((new File(includesArray
[i
])).getPath());
331 String
[] librariesArray
= libraries
.toArray(new String
[libraries
.size()]);
333 for (int i
= 0; i
< librariesArray
.length
; i
++) {
334 libraries
.add((new File(librariesArray
[i
])).getPath());
339 Restore some important ANT property. If current build is single module
340 build, here will set many default values.
342 <p> If current build is single module build, then the default <code>ARCH</code>
343 is <code>IA32</code>. Also set up the properties <code>PACKAGE</code>,
344 <code>PACKAGE_DIR</code>, <code>TARGET</code> and <code>MODULE_DIR</code></p>
346 <p> Note that for package build, package name is stored in <code>PLATFORM</code>
347 and package directory is stored in <code>PLATFORM_DIR</code>. </p>
349 @see org.tianocore.build.global.OutputManager
351 private void recallFixedProperties() {
353 // If build is for module build
355 if (getProject().getProperty("PACKAGE_DIR") == null) {
356 ToolChainFactory toolChainFactory
= new ToolChainFactory(getProject());
357 toolChainFactory
.setupToolChain();
359 // PACKAGE PACKAGE_DIR ARCH (Default) COMMON_FILE BUILD_MACRO
361 if (getProject().getProperty("ARCH") == null) {
362 getProject().setProperty("ARCH", "IA32");
364 String packageName
= GlobalData
.getPackageNameForModule(baseName
);
365 getProject().setProperty("PACKAGE", packageName
);
367 String packageDir
= GlobalData
.getPackagePath(packageName
);
368 getProject().setProperty("PACKAGE_DIR",
369 getProject().getProperty("WORKSPACE_DIR") + File
.separatorChar
+ packageDir
);
371 getProject().setProperty("TARGET", toolChainFactory
.getCurrentTarget());
373 getProject().setProperty("MODULE_DIR",
374 getProject().replaceProperties(getProject().getProperty("MODULE_DIR")));
376 if (OutputManager
.PLATFORM
!= null) {
377 getProject().setProperty("PLATFORM", OutputManager
.PLATFORM
);
379 if (OutputManager
.PLATFORM_DIR
!= null) {
380 getProject().setProperty("PLATFORM_DIR", OutputManager
.PLATFORM_DIR
);
385 The whole BaseName_build.xml is composed of seven part.
387 <li> ANT properties; </li>
388 <li> Dependent module (dependent library instances in most case); </li>
389 <li> Source files; </li>
390 <li> Sections if module is not library; </li>
391 <li> Output (different for library module and driver module); </li>
393 <li> Clean all. </li>
396 @throws BuildException
397 Error throws during BaseName_build.xml generating.
399 private void genBuildFile() throws BuildException
{
400 FfsProcess fp
= new FfsProcess();
401 DocumentBuilderFactory domfac
= DocumentBuilderFactory
.newInstance();
403 DocumentBuilder dombuilder
= domfac
.newDocumentBuilder();
404 Document document
= dombuilder
.newDocument();
405 Comment rootComment
= document
.createComment(info
);
407 // create root element and its attributes
409 Element root
= document
.createElement("project");
411 // root.setAttribute("name", base_name);
413 root
.setAttribute("default", "main");
414 root
.setAttribute("basedir", ".");
416 // element for External ANT tasks
418 root
.appendChild(document
.createComment("Apply external ANT tasks"));
419 Element ele
= document
.createElement("taskdef");
420 ele
.setAttribute("resource", "frameworktasks.tasks");
421 root
.appendChild(ele
);
422 ele
= document
.createElement("taskdef");
423 ele
.setAttribute("resource", "cpptasks.tasks");
424 root
.appendChild(ele
);
425 ele
= document
.createElement("typedef");
426 ele
.setAttribute("resource", "cpptasks.types");
427 root
.appendChild(ele
);
428 ele
= document
.createElement("taskdef");
429 ele
.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
430 root
.appendChild(ele
);
432 // elements for Properties
434 root
.appendChild(document
.createComment("All Properties"));
435 ele
= document
.createElement("property");
436 ele
.setAttribute("name", "BASE_NAME");
437 ele
.setAttribute("value", baseName
);
438 root
.appendChild(ele
);
440 // Generate the default target,
441 // which depends on init, sections and output target
443 root
.appendChild(document
.createComment("Default target"));
444 ele
= document
.createElement("target");
445 ele
.setAttribute("name", "main");
446 ele
.setAttribute("depends", "libraries, sourcefiles, sections, output");
447 root
.appendChild(ele
);
449 // compile all source files
451 root
.appendChild(document
.createComment("Compile all dependency Library instances."));
452 ele
= document
.createElement("target");
453 ele
.setAttribute("name", "libraries");
455 // Parse all sourfiles but files specified in sections
457 applyLibraryInstance(document
, ele
);
458 root
.appendChild(ele
);
460 // compile all source files
462 root
.appendChild(document
.createComment("sourcefiles target"));
463 ele
= document
.createElement("target");
464 ele
.setAttribute("name", "sourcefiles");
466 // Parse all sourfiles but files specified in sections
468 applyCompileElement(document
, ele
);
469 root
.appendChild(ele
);
471 // generate the init target
472 // main purpose is create all nessary pathes
473 // generate the sections target
475 root
.appendChild(document
.createComment("sections target"));
476 ele
= document
.createElement("target");
477 ele
.setAttribute("name", "sections");
478 applySectionsElement(document
, ele
, fp
);
479 root
.appendChild(ele
);
481 // generate the output target
483 root
.appendChild(document
.createComment("output target"));
484 ele
= document
.createElement("target");
485 ele
.setAttribute("name", "output");
486 applyOutputElement(document
, ele
, fp
);
487 root
.appendChild(ele
);
489 // generate the clean target
491 root
.appendChild(document
.createComment("clean target"));
492 ele
= document
.createElement("target");
493 ele
.setAttribute("name", "clean");
494 applyCleanElement(document
, ele
);
495 root
.appendChild(ele
);
497 // generate the Clean All target
499 root
.appendChild(document
.createComment("Clean All target"));
500 ele
= document
.createElement("target");
501 ele
.setAttribute("name", "cleanall");
502 applyDeepcleanElement(document
, ele
);
503 root
.appendChild(ele
);
505 // add the root element to the document
507 document
.appendChild(rootComment
);
508 document
.appendChild(root
);
510 // Prepare the DOM document for writing
512 Source source
= new DOMSource(document
);
514 // Prepare the output file
516 File file
= new File(getProject().getProperty("DEST_DIR_OUTPUT") + File
.separatorChar
+ baseName
519 // generate all directory path
521 (new File(file
.getParent())).mkdirs();
522 Result result
= new StreamResult(file
);
524 // Write the DOM document to the file
526 Transformer xformer
= TransformerFactory
.newInstance().newTransformer();
527 xformer
.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
528 xformer
.setOutputProperty(OutputKeys
.INDENT
, "yes");
529 xformer
.transform(source
, result
);
530 } catch (Exception ex
) {
531 throw new BuildException("Module [" + baseName
+ "] generating build file failed.\n" + ex
.getMessage());
536 Generate the clean elements for BaseName_build.xml.
538 @param document current BaseName_build.xml XML document
539 @param root Root element for current
541 private void applyCleanElement(Document document
, Node root
) {
542 String
[] libinstances
= libraries
.toArray(new String
[libraries
.size()]);
543 for (int i
= 0; i
< libinstances
.length
; i
++) {
544 File file
= new File(GlobalData
.getModulePath(libinstances
[i
]) + File
.separatorChar
+ "build.xml");
546 Element ifEle
= document
.createElement("if");
547 Element availableEle
= document
.createElement("available");
548 availableEle
.setAttribute("file", file
.getPath());
549 ifEle
.appendChild(availableEle
);
550 Element elseEle
= document
.createElement("then");
552 Element ele
= document
.createElement("ant");
553 ele
.setAttribute("antfile", file
.getPath());
554 ele
.setAttribute("inheritAll", "false");
555 ele
.setAttribute("target", libinstances
[i
] + "_clean");
559 Element property
= document
.createElement("property");
560 property
.setAttribute("name", "WORKSPACE_DIR");
561 property
.setAttribute("value", "${WORKSPACE_DIR}");
562 ele
.appendChild(property
);
566 property
= document
.createElement("property");
567 property
.setAttribute("name", "PACKAGE_DIR");
568 property
.setAttribute("value", "${WORKSPACE_DIR}" + File
.separatorChar
569 + GlobalData
.getPackagePathForModule(libinstances
[i
]));
570 ele
.appendChild(property
);
574 property
= document
.createElement("property");
575 property
.setAttribute("name", "ARCH");
576 property
.setAttribute("value", "${ARCH}");
577 ele
.appendChild(property
);
581 property
= document
.createElement("property");
582 property
.setAttribute("name", "TARGET");
583 property
.setAttribute("value", "${TARGET}");
584 ele
.appendChild(property
);
588 property
= document
.createElement("property");
589 property
.setAttribute("name", "PACKAGE");
590 property
.setAttribute("value", GlobalData
.getPackageNameForModule(libinstances
[i
]));
591 ele
.appendChild(property
);
593 elseEle
.appendChild(ele
);
594 ifEle
.appendChild(elseEle
);
595 root
.appendChild(ifEle
);
600 Generate the cleanall elements for BaseName_build.xml.
602 @param document current BaseName_build.xml XML document
603 @param root Root element for current
605 private void applyDeepcleanElement(Document document
, Node root
) {
606 String
[] libinstances
= libraries
.toArray(new String
[libraries
.size()]);
607 for (int i
= 0; i
< libinstances
.length
; i
++) {
608 File file
= new File(GlobalData
.getModulePath(libinstances
[i
]) + File
.separatorChar
+ "build.xml");
610 Element ifEle
= document
.createElement("if");
611 Element availableEle
= document
.createElement("available");
612 availableEle
.setAttribute("file", file
.getPath());
613 ifEle
.appendChild(availableEle
);
614 Element elseEle
= document
.createElement("then");
616 Element ele
= document
.createElement("ant");
617 ele
.setAttribute("antfile", file
.getPath());
618 ele
.setAttribute("inheritAll", "false");
619 ele
.setAttribute("target", libinstances
[i
] + "_cleanall");
623 Element property
= document
.createElement("property");
624 property
.setAttribute("name", "WORKSPACE_DIR");
625 property
.setAttribute("value", "${WORKSPACE_DIR}");
626 ele
.appendChild(property
);
630 property
= document
.createElement("property");
631 property
.setAttribute("name", "PACKAGE_DIR");
632 property
.setAttribute("value", "${WORKSPACE_DIR}" + File
.separatorChar
633 + GlobalData
.getPackagePathForModule(libinstances
[i
]));
634 ele
.appendChild(property
);
638 property
= document
.createElement("property");
639 property
.setAttribute("name", "ARCH");
640 property
.setAttribute("value", "${ARCH}");
641 ele
.appendChild(property
);
645 property
= document
.createElement("property");
646 property
.setAttribute("name", "TARGET");
647 property
.setAttribute("value", "${TARGET}");
648 ele
.appendChild(property
);
652 property
= document
.createElement("property");
653 property
.setAttribute("name", "PACKAGE");
654 property
.setAttribute("value", GlobalData
.getPackageNameForModule(libinstances
[i
]));
655 ele
.appendChild(property
);
657 elseEle
.appendChild(ele
);
658 ifEle
.appendChild(elseEle
);
659 root
.appendChild(ifEle
);
664 Generate the dependent library instances elements for BaseName_build.xml.
666 @param document current BaseName_build.xml XML document
667 @param root Root element for current
669 private void applyLibraryInstance(Document document
, Node root
) {
670 String
[] libinstances
= libraries
.toArray(new String
[libraries
.size()]);
671 for (int i
= 0; i
< libinstances
.length
; i
++) {
672 Element ele
= document
.createElement("ant");
673 File file
= new File(GlobalData
.getModulePath(libinstances
[i
]) + File
.separatorChar
+ "build.xml");
674 ele
.setAttribute("antfile", file
.getPath());
675 ele
.setAttribute("inheritAll", "false");
676 ele
.setAttribute("target", libinstances
[i
]);
680 Element property
= document
.createElement("property");
681 property
.setAttribute("name", "WORKSPACE_DIR");
682 property
.setAttribute("value", "${WORKSPACE_DIR}");
683 ele
.appendChild(property
);
687 property
= document
.createElement("property");
688 property
.setAttribute("name", "PACKAGE_DIR");
689 property
.setAttribute("value", "${WORKSPACE_DIR}" + File
.separatorChar
690 + GlobalData
.getPackagePathForModule(libinstances
[i
]));
691 ele
.appendChild(property
);
695 property
= document
.createElement("property");
696 property
.setAttribute("name", "ARCH");
697 property
.setAttribute("value", "${ARCH}");
698 ele
.appendChild(property
);
702 property
= document
.createElement("property");
703 property
.setAttribute("name", "TARGET");
704 property
.setAttribute("value", "${TARGET}");
705 ele
.appendChild(property
);
709 property
= document
.createElement("property");
710 property
.setAttribute("name", "PACKAGE");
711 property
.setAttribute("value", GlobalData
.getPackageNameForModule(libinstances
[i
]));
712 ele
.appendChild(property
);
713 root
.appendChild(ele
);
715 Element expand
= document
.createElement("Expand");
716 root
.appendChild(expand
);
720 Generate the build source files elements for BaseName_build.xml.
722 @param document current BaseName_build.xml XML document
723 @param root Root element for current
725 private void applyCompileElement(Document document
, Node root
) {
726 FileProcess fileProcess
= new FileProcess();
727 fileProcess
.init(getProject(), includes
, sourceFiles
, document
);
728 Node
[] files
= this.getSourceFiles();
730 // Parse all unicode files
732 for (int i
= 0; i
< files
.length
; i
++) {
733 String filetype
= getFiletype(files
[i
]);
734 if (filetype
!= null) {
735 fileProcess
.parseFile(getFilename(files
[i
]), filetype
, root
, true);
737 fileProcess
.parseFile(getFilename(files
[i
]), root
, true);
740 if (fileProcess
.isUnicodeExist()) {
741 Element ele
= document
.createElement("Build_Unicode_Database");
742 ele
.setAttribute("FILEPATH", ".");
743 ele
.setAttribute("FILENAME", "${BASE_NAME}");
744 root
.appendChild(ele
);
748 // Parse AutoGen.c & AutoGen.h
750 if (!baseName
.equalsIgnoreCase("Shell")) {
751 fileProcess
.parseFile(getProject().getProperty("DEST_DIR_DEBUG") + File
.separatorChar
+ "AutoGen.c", root
,
755 // Parse all source files
757 for (int i
= 0; i
< files
.length
; i
++) {
758 String filetype
= getFiletype(files
[i
]);
759 if (filetype
!= null) {
760 fileProcess
.parseFile(getFilename(files
[i
]), filetype
, root
, false);
762 fileProcess
.parseFile(getFilename(files
[i
]), root
, false);
766 // root.appendChild(parallelEle);
768 Iterator iter
= sourceFiles
.iterator();
770 while (iter
.hasNext()) {
771 str
+= " " + (String
) iter
.next();
773 getProject().setProperty("SOURCE_FILES", str
);
777 Generate the section elements for BaseName_build.xml. Library module will
780 @param document current BaseName_build.xml XML document
781 @param root Root element for current
783 private void applySectionsElement(Document document
, Node root
, FfsProcess fp
) {
784 if (fp
.initSections(buildType
, getProject())) {
785 String targetFilename
= guid
+ "-" + baseName
+ FpdParserTask
.getSuffix(componentType
);
786 String
[] list
= fp
.getGenSectionElements(document
, baseName
, guid
, targetFilename
);
788 for (int i
= 0; i
< list
.length
; i
++) {
789 Element ele
= document
.createElement(list
[i
]);
790 ele
.setAttribute("FILEPATH", ".");
791 ele
.setAttribute("FILENAME", "${BASE_NAME}");
792 root
.appendChild(ele
);
798 Generate the output elements for BaseName_build.xml. If module is library,
799 call the <em>LIB</em> command, else call the <em>GenFfs</em> command.
801 @param document current BaseName_build.xml XML document
802 @param root Root element for current
804 private void applyOutputElement(Document document
, Node root
, FfsProcess fp
) {
805 if (flag
== GlobalData
.ONLY_LIBMSA
|| flag
== GlobalData
.LIBMSA_AND_LIBMBD
) {
809 Element cc
= document
.createElement("Build_Library");
810 cc
.setAttribute("FILENAME", baseName
);
811 root
.appendChild(cc
);
814 // if it is a module but library
817 if (fp
.getFfsNode() != null) {
818 root
.appendChild(fp
.getFfsNode());
824 Get file name from node. If some wrong, return string with zero length.
826 @param node Filename node of MSA/MBD or specified in each Section
829 private String
getFilename(Node node
) {
831 String filename
= "${MODULE_DIR}" + File
.separatorChar
;
834 FilenameDocument file
= (FilenameDocument
) XmlObject
.Factory
.parse(node
);
835 str
= file
.getFilename().getStringValue().trim();
836 path
= file
.getFilename().getPath();
837 } catch (Exception e
) {
841 filename
+= path
+ File
.separatorChar
+ str
;
845 return getProject().replaceProperties(filename
);
849 Get file type from node. If some wrong or not specified, return
852 @param node Filename node of MSA/MBD or specified in each Section
855 private String
getFiletype(Node node
) {
858 FilenameDocument file
= (FilenameDocument
) XmlObject
.Factory
.parse(node
);
859 str
= file
.getFilename().getFileType();
860 } catch (Exception e
) {
867 Return all source files but AutoGen.c.
869 @return source files Node array
871 public Node
[] getSourceFiles() {
872 XmlObject
[] files
= SurfaceAreaQuery
.getSourceFiles(arch
);
876 Vector
<Node
> vector
= new Vector
<Node
>();
877 for (int i
= 0; i
< files
.length
; i
++) {
878 vector
.addElement(files
[i
].getDomNode());
881 // To be consider sourcefiles from Sections
883 return vector
.toArray(new Node
[vector
.size()]);
887 Get current module's base name.
891 public String
getBaseName() {
896 Set MBD surface area file. For ANT use.
898 @param mbdFilename Surface Area file
900 public void setMbdFilename(File mbdFilename
) {
901 this.mbdFilename
= mbdFilename
;
905 Set MSA surface area file. For ANT use.
907 @param msaFilename Surface Area file
909 public void setMsaFilename(File msaFilename
) {
910 this.msaFilename
= msaFilename
;
916 <p> Take command <code>CC</code> and arch <code>IA32</code> for example,
917 Those flags are from <code>ToolChainFactory</code>: </p>
920 <li> IA32_CC_STD_FLAGS </li>
921 <li> IA32_CC_GLOBAL_FLAGS </li>
922 <li> IA32_CC_GLOBAL_ADD_FLAGS </li>
923 <li> IA32_CC_GLOBAL_SUB_FLAGS </li>
925 Those flags can user-define:
927 <li> IA32_CC_PROJ_FLAGS </li>
928 <li> IA32_CC_PROJ_ADD_FLAGS </li>
929 <li> IA32_CC_PROJ_SUB_FLAGS </li>
930 <li> CC_PROJ_FLAGS </li>
931 <li> CC_PROJ_ADD_FLAGS </li>
932 <li> CC_PROJ_SUB_FLAGS </li>
934 <li> IA32_CC_FLAGS </li>
937 <p> The final flags is composed of STD, GLOBAL and PROJ. If CC_FLAGS or
938 IA32_CC_FLAGS is specified, STD, GLOBAL and PROJ will not affect. </p>
940 Note that the <code>ToolChainFactory</code> executes only once
941 during whole build process.
943 private void flagsSetup() {
944 Project project
= getProject();
946 // If ToolChain has been set up before, do nothing.
948 ToolChainFactory toolChainFactory
= new ToolChainFactory(project
);
949 toolChainFactory
.setupToolChain();
951 String
[] cmd
= ToolChainFactory
.commandType
;
952 Set
<String
> addSet
= new HashSet
<String
>(40);
953 Set
<String
> subSet
= new HashSet
<String
>(40);
954 for (int i
= 0; i
< cmd
.length
; i
++) {
955 String str
= ToolChainFactory
.getValue(arch
+ "_" + cmd
[i
]);
957 // Command line path+command name
960 project
.setProperty(cmd
[i
], str
);
963 // ARCH_CMD_STD_FLAGS
965 str
= ToolChainFactory
.getValue(arch
+ "_" + cmd
[i
] + "_STD_FLAGS");
967 putFlagsToSet(addSet
, str
);
968 project
.setProperty(cmd
[i
] + "_STD_FLAGS", str
);
971 // ARCH_CMD_GLOBAL_FLAGS
973 str
= ToolChainFactory
.getValue(arch
+ "_" + cmd
[i
] + "_GLOBAL_FLAGS");
975 putFlagsToSet(addSet
, str
);
978 // ARCH_CMD_GLOBAL_ADD_FLAGS
980 str
= ToolChainFactory
.getValue(arch
+ "_" + cmd
[i
] + "_GLOBAL_ADD_FLAGS");
982 putFlagsToSet(addSet
, str
);
985 // ARCH_CMD_GLOBAL_SUB_FLAGS
987 str
= ToolChainFactory
.getValue(arch
+ "_" + cmd
[i
] + "_GLOBAL_SUB_FLAGS");
989 putFlagsToSet(subSet
, str
);
992 // ARCH_CMD_PROJ_FLAGS
994 str
= project
.getProperty(arch
+ "_" + cmd
[i
] + "_PROJ_FLAGS");
996 putFlagsToSet(addSet
, str
);
999 // ARCH_CMD_PROG_FLAGS
1001 str
= project
.getProperty(arch
+ "_" + cmd
[i
] + "_PROJ_ADD_FLAGS");
1003 putFlagsToSet(addSet
, str
);
1006 // ARCH_CMD_PROG_FLAGS
1008 str
= project
.getProperty(arch
+ "_" + cmd
[i
] + "_PROJ_SUB_FLAGS");
1010 putFlagsToSet(subSet
, str
);
1015 str
= project
.getProperty(cmd
[i
] + "_PROJ_FLAGS");
1017 putFlagsToSet(addSet
, str
);
1022 str
= project
.getProperty(cmd
[i
] + "_PROJ_ADD_FLAGS");
1024 putFlagsToSet(addSet
, str
);
1029 str
= project
.getProperty(cmd
[i
] + "_PROJ_SUB_FLAGS");
1031 putFlagsToSet(subSet
, str
);
1034 // If IA32_CC_FLAGS or IA32_LIB_FLAGS .. has defined in BuildOptions
1036 if ((str
= project
.getProperty(arch
+ "_" + cmd
[i
] + "_FLAGS")) != null) {
1037 project
.setProperty(cmd
[i
] + "_FLAGS", getRawFlags(addSet
, subSet
));
1040 putFlagsToSet(addSet
, project
.replaceProperties(str
));
1041 project
.setProperty(cmd
[i
] + "_FLAGS", project
.replaceProperties(getFlags(addSet
, subSet
)));
1046 // If CC_FLAGS or LIB_FLAGS .. has defined in BuildOptions
1048 else if ((str
= project
.getProperty(cmd
[i
] + "_FLAGS")) != null) {
1049 project
.setProperty(cmd
[i
] + "_FLAGS", getRawFlags(addSet
, subSet
));
1052 putFlagsToSet(addSet
, project
.replaceProperties(str
));
1053 project
.setProperty(cmd
[i
] + "_FLAGS", project
.replaceProperties(getFlags(addSet
, subSet
)));
1057 project
.setProperty(cmd
[i
] + "_FLAGS", getFlags(addSet
, subSet
));
1062 project
.setProperty("C_FLAGS", project
.getProperty("CC_FLAGS"));
1066 Initialize some properties will be used in current module build, including
1067 user-defined option from <em>Option</em> of <em>BuildOptions</em> in
1070 private void updateParameters() {
1071 getProject().setProperty("OBJECTS", "");
1072 getProject().setProperty("SDB_FILES", "");
1073 getProject().setProperty("BASE_NAME", baseName
);
1074 if (map
.get("MsaHeader") != null) {
1075 guid
= SurfaceAreaQuery
.getModuleGuid();//header.getGuid().getStringValue();
1076 componentType
= SurfaceAreaQuery
.getComponentType();//header.getComponentType().toString();
1077 if (!componentType
.equalsIgnoreCase("LIBRARY")) {
1078 flag
= GlobalData
.MSA_AND_MBD
;
1080 flag
= GlobalData
.LIBMSA_AND_LIBMBD
;
1084 else if (map
.get("MsaLibHeader") != null) {
1085 flag
= GlobalData
.LIBMSA_AND_LIBMBD
;
1086 MsaLibHeaderDocument
.MsaLibHeader header
= ((MsaLibHeaderDocument
) map
.get("MsaLibHeader"))
1088 guid
= header
.getGuid().getStringValue();
1089 componentType
= header
.getComponentType().toString();
1092 if (componentType
!= null) {
1093 getProject().setProperty("COMPONENT_TYPE", componentType
);
1097 getProject().setProperty("FILE_GUID", guid
);
1100 // Get all options and set to properties
1102 String
[][] options
= SurfaceAreaQuery
.getOptions(arch
);
1103 for (int i
= 0; i
< options
.length
; i
++) {
1104 if (options
[i
][0] != null && options
[i
][1] != null) {
1105 getProject().setProperty(options
[i
][0], getProject().replaceProperties(options
[i
][1]));
1109 buildType
= getProject().getProperty("BUILD_TYPE");
1110 if (buildType
== null) {
1111 buildType
= componentType
;
1117 Separate the string and instore in set.
1119 <p> String is separated by Java Regulation Expression
1120 "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>
1122 <p>For example: </p>
1125 "/nologo", "/W3", "/WX"
1126 "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""
1129 @param set store the separated string
1130 @param str string to separate
1132 private void putFlagsToSet(Set
<String
> set
, String str
) {
1133 Pattern myPattern
= Pattern
.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");
1134 Matcher matcher
= myPattern
.matcher(str
+ " ");
1135 while (matcher
.find()) {
1136 String item
= str
.substring(matcher
.start(1), matcher
.end(1));
1137 if (!set
.contains(item
)) {
1144 Generate the final flags string will be used by compile command.
1146 @param add the add flags set
1147 @param sub the sub flags set
1148 @return final flags after add set substract sub set
1150 private String
getFlags(Set
<String
> add
, Set
<String
> sub
) {
1153 Iterator iter
= add
.iterator();
1154 while (iter
.hasNext()) {
1155 String str
= getProject().replaceProperties((String
) iter
.next());
1156 result
+= str
.substring(1, str
.length() - 1) + " ";
1162 Generate the flags string with original format. The format is defined by
1163 Java Regulation Expression "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>
1165 <p>For example: </p>
1168 "/nologo", "/W3", "/WX"
1169 "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""
1172 @param add the add flags set
1173 @param sub the sub flags set
1174 @return flags with original format
1176 private String
getRawFlags(Set
<String
> add
, Set
<String
> sub
) {
1179 Iterator iter
= add
.iterator();
1180 while (iter
.hasNext()) {
1181 String str
= getProject().replaceProperties((String
) iter
.next());
1182 result
+= "\"" + str
.substring(1, str
.length() - 1) + "\", ";
1188 Set base name. For ANT use.
1190 @param baseName Base name
1192 public void setBaseName(String baseName
) {
1193 this.baseName
= baseName
;