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
.GlobalData
;
54 import org
.tianocore
.build
.global
.OutputManager
;
55 import org
.tianocore
.build
.global
.SurfaceAreaQuery
;
56 import org
.tianocore
.build
.toolchain
.ToolChainFactory
;
57 import org
.tianocore
.FilenameDocument
;
58 import org
.tianocore
.MsaHeaderDocument
;
59 import org
.tianocore
.MsaLibHeaderDocument
;
63 <code>GenBuildTask</code> is an ANT task that can be used in ANT build
64 system. The main function of this task is to parse module's surface area,
65 then generate the corresponding <em>BaseName_build.xml</em> (the real ANT
66 build script) and call this to build the module.
70 The usage is (take module <em>HelloWorld</em> for example):
74 <GenBuild baseName="HelloWorld"
75 mbdFilename="${MODULE_DIR}/HelloWorld.mbd"
76 msaFilename="${MODULE_DIR}/HelloWorld.msa"/>
80 This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and
81 <em>AutoGen.h</em>. The task also parses the development environment
82 configuration files, such as collecting package information, setting compiler
89 public class GenBuildTask
extends Task
{
92 /// Module surface area file.
97 /// Module build description file.
102 /// Module surface area information after overrided.
104 public Map
<String
, XmlObject
> map
= new HashMap
<String
, XmlObject
>();
107 /// Module's base name.
109 private String baseName
;
112 /// Current build Arch, such as IA32, X64, IPF and so on.
117 /// Module's GUID (Globally Unique Identifier).
122 /// Module's component type, such as SEC, LIBRARY, BS_DRIVER and so on.
124 private String componentType
;
127 /// This value is used in build time. Override module's component type. When
128 /// search FFS (Sections information) in common file, buildtype instead of
131 private String buildType
;
134 /// List all required includes for current build module.
136 public Set
<String
> includes
= new LinkedHashSet
<String
>();
139 /// List all libraries for current build module.
141 public Set
<String
> libraries
= new LinkedHashSet
<String
>();
144 /// List all source files for current build module.
146 public Set
<String
> sourceFiles
= new LinkedHashSet
<String
>();
149 /// Flag to identify what surface area files are specified. Current value is
150 /// <em>NO_SA</em>, <em>ONLY_MSA</em>, <em>ONLY_LIBMSA</em>,
151 /// <em>MSA_AND_MBD</em> or <em>LIBMSA_AND_LIBMBD</em>.
153 /// @see org.tianocore.build.global.GlobaData
155 private int flag
= GlobalData
.NO_SA
;
158 /// The information at the header of <em>build.xml</em>.
160 private String info
= "====================================================================\n"
162 + "File auto-generated by build utility\n"
165 + "Auto-generated ANT build file for building of EFI Modules/Platforms\n"
166 + "=====================================================================";
169 Public construct method. It is necessary for ANT task.
171 public GenBuildTask() {
175 ANT task's entry point, will be called after init(). The main steps is described
178 <li> Judge current build mode (MODULE | PACKAGE | PLATFORM). This step will execute
179 only once in whole build process; </li>
180 <li> Initialize global information (Framework DB, SPD files and all MSA files
181 listed in SPD). This step will execute only once in whole build process; </li>
182 <li> Restore some important ANT property. If current build is single module
183 build, here will set many default values; </li>
184 <li> Get the current module's overridded surface area information from
186 <li> Set up the output directories, including BIN_DIR, DEST_DIR_OUTPUT and
187 DEST_DIR_DEBUG; </li>
188 <li> Get module dependent library instances and include pathes; </li>
189 <li> Judge whether current module is built. If yes, skip it; </li>
190 <li> Call AutoGen and PCD to generate AutoGen.c & AutoGen.h </li>
191 <li> Set up the compile flags; </li>
192 <li> Generate BaseName_build.xml; </li>
193 <li> Call to BaseName_build.xml, and build the current module. </li>
196 <p>Build is dependent on BuildMacro.xml which define many macro. </p>
198 @throws BuildException
199 From module build, exception from module surface area invalid.
201 public void execute() throws BuildException
{
202 System
.out
.println("Module [" + baseName
+ "] start.");
203 OutputManager
.update(getProject());
204 GlobalData
.initInfo("Tools" + File
.separatorChar
+ "Conf" + File
.separatorChar
+ "FrameworkDatabase.db",
205 getProject().getProperty("WORKSPACE_DIR"));
206 recallFixedProperties();
207 arch
= getProject().getProperty("ARCH");
208 arch
= arch
.toUpperCase();
209 map
= GlobalData
.getDoc(baseName
);
211 // Initialize SurfaceAreaQuery
213 SurfaceAreaQuery
.setDoc(map
);
215 // Setup Output Management
217 String
[] outdir
= SurfaceAreaQuery
.getOutputDirectory();
218 OutputManager
.update(getProject(), outdir
[1], outdir
[0]);
220 updateIncludesAndLibraries();
222 if (GlobalData
.isModuleBuilt(baseName
, arch
)) {
225 GlobalData
.registerBuiltModule(baseName
, arch
);
230 AutoGen autogen
= new AutoGen(getProject().getProperty("DEST_DIR_DEBUG"), baseName
, arch
);
231 autogen
.genAutogen();
237 // Update flags like CC_FLAGS, LIB_FLAGS etc.
240 GlobalData
.addLibrary(baseName
, arch
, getProject().getProperty("BIN_DIR") + File
.separatorChar
+ baseName
+ ".lib");
241 GlobalData
.addModuleLibrary(baseName
, arch
, libraries
);
243 // If ComponentType is USER_DEFINED,
244 // then call the exist BaseName_build.xml directly.
246 if (buildType
.equalsIgnoreCase("CUSTOM_BUILD")) {
247 System
.out
.println("Call user-defined " + baseName
+ "_build.xml");
249 ant
.setProject(getProject());
250 ant
.setAntfile(getProject().getProperty("MODULE_DIR") + File
.separatorChar
+ baseName
+ "_build.xml");
251 ant
.setInheritAll(true);
257 // Generate ${BASE_NAME}_build.xml file
259 System
.out
.println("Generate " + baseName
+ "_build.xml");
261 System
.out
.println("Call the " + baseName
+ "_build.xml");
263 ant
.setProject(getProject());
264 ant
.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File
.separatorChar
+ baseName
+ "_build.xml");
265 ant
.setInheritAll(true);
271 Return the name of the directory that corresponds to the architecture.
272 This is a translation from the XML Schema tag to a directory that
273 corresponds to our directory name coding convention.
276 private String
archDir(String arch
) {
277 return arch
.replaceFirst("X64", "x64")
278 .replaceFirst("IPF", "Ipf")
279 .replaceFirst("IA32", "Ia32")
280 .replaceFirst("ARM", "Arm")
281 .replaceFirst("EBC", "Ebc");
285 Get the dependent library instances and include package name from
286 surface area, and initialize module include pathes.
289 private void updateIncludesAndLibraries() {
290 List
<String
> rawIncludes
= SurfaceAreaQuery
.getIncludePackageName(arch
);
291 if (rawIncludes
!= null) {
292 Iterator iter
= rawIncludes
.iterator();
293 while (iter
.hasNext()) {
294 String packageName
= (String
) iter
.next();
295 includes
.add("${WORKSPACE_DIR}" + File
.separatorChar
+ GlobalData
.getPackagePath(packageName
)
296 + File
.separatorChar
+ "Include");
297 includes
.add("${WORKSPACE_DIR}" + File
.separatorChar
+ GlobalData
.getPackagePath(packageName
)
298 + File
.separatorChar
+ "Include" + File
.separatorChar
+ archDir(arch
));
301 includes
.add("${DEST_DIR_DEBUG}");
302 List
<String
> rawLibraries
= SurfaceAreaQuery
.getLibraryInstance(this.arch
, CommonDefinition
.AlwaysConsumed
);
303 if (rawLibraries
!= null) {
304 Iterator iter
= rawLibraries
.iterator();
305 while (iter
.hasNext()) {
306 libraries
.add((String
) iter
.next());
313 Normalize all dependent library instance and include pathes' format.
316 private void normalize() {
317 String
[] includesArray
= includes
.toArray(new String
[includes
.size()]);
319 for (int i
= 0; i
< includesArray
.length
; i
++) {
320 includes
.add((new File(includesArray
[i
])).getPath());
322 String
[] librariesArray
= libraries
.toArray(new String
[libraries
.size()]);
324 for (int i
= 0; i
< librariesArray
.length
; i
++) {
325 libraries
.add((new File(librariesArray
[i
])).getPath());
330 Restore some important ANT property. If current build is single module
331 build, here will set many default values.
333 <p> If current build is single module build, then the default <code>ARCH</code>
334 is <code>IA32</code>. Also set up the properties <code>PACKAGE</code>,
335 <code>PACKAGE_DIR</code>, <code>TARGET</code> and <code>MODULE_DIR</code></p>
337 <p> Note that for package build, package name is stored in <code>PLATFORM</code>
338 and package directory is stored in <code>PLATFORM_DIR</code>. </p>
340 @see org.tianocore.build.global.OutputManager
342 private void recallFixedProperties() {
344 // If build is for module build
346 if (getProject().getProperty("PACKAGE_DIR") == null) {
347 ToolChainFactory toolChainFactory
= new ToolChainFactory(getProject());
348 toolChainFactory
.setupToolChain();
350 // PACKAGE PACKAGE_DIR ARCH (Default) COMMON_FILE BUILD_MACRO
352 if (getProject().getProperty("ARCH") == null) {
353 getProject().setProperty("ARCH", "IA32");
355 String packageName
= GlobalData
.getPackageNameForModule(baseName
);
356 getProject().setProperty("PACKAGE", packageName
);
358 String packageDir
= GlobalData
.getPackagePath(packageName
);
359 getProject().setProperty("PACKAGE_DIR",
360 getProject().getProperty("WORKSPACE_DIR") + File
.separatorChar
+ packageDir
);
362 getProject().setProperty("TARGET", toolChainFactory
.getCurrentTarget());
364 getProject().setProperty("MODULE_DIR",
365 getProject().replaceProperties(getProject().getProperty("MODULE_DIR")));
367 if (OutputManager
.PLATFORM
!= null) {
368 getProject().setProperty("PLATFORM", OutputManager
.PLATFORM
);
370 if (OutputManager
.PLATFORM_DIR
!= null) {
371 getProject().setProperty("PLATFORM_DIR", OutputManager
.PLATFORM_DIR
);
376 The whole BaseName_build.xml is composed of seven part.
378 <li> ANT properties; </li>
379 <li> Dependent module (dependent library instances in most case); </li>
380 <li> Source files; </li>
381 <li> Sections if module is not library; </li>
382 <li> Output (different for library module and driver module); </li>
384 <li> Clean all. </li>
387 @throws BuildException
388 Error throws during BaseName_build.xml generating.
390 private void genBuildFile() throws BuildException
{
391 FfsProcess fp
= new FfsProcess();
392 DocumentBuilderFactory domfac
= DocumentBuilderFactory
.newInstance();
394 DocumentBuilder dombuilder
= domfac
.newDocumentBuilder();
395 Document document
= dombuilder
.newDocument();
396 Comment rootComment
= document
.createComment(info
);
398 // create root element and its attributes
400 Element root
= document
.createElement("project");
402 // root.setAttribute("name", base_name);
404 root
.setAttribute("default", "main");
405 root
.setAttribute("basedir", ".");
407 // element for External ANT tasks
409 root
.appendChild(document
.createComment("Apply external ANT tasks"));
410 Element ele
= document
.createElement("taskdef");
411 ele
.setAttribute("resource", "frameworktasks.tasks");
412 root
.appendChild(ele
);
413 ele
= document
.createElement("taskdef");
414 ele
.setAttribute("resource", "cpptasks.tasks");
415 root
.appendChild(ele
);
416 ele
= document
.createElement("typedef");
417 ele
.setAttribute("resource", "cpptasks.types");
418 root
.appendChild(ele
);
419 ele
= document
.createElement("taskdef");
420 ele
.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
421 root
.appendChild(ele
);
423 // elements for Properties
425 root
.appendChild(document
.createComment("All Properties"));
426 ele
= document
.createElement("property");
427 ele
.setAttribute("name", "BASE_NAME");
428 ele
.setAttribute("value", baseName
);
429 root
.appendChild(ele
);
431 // Generate the default target,
432 // which depends on init, sections and output target
434 root
.appendChild(document
.createComment("Default target"));
435 ele
= document
.createElement("target");
436 ele
.setAttribute("name", "main");
437 ele
.setAttribute("depends", "libraries, sourcefiles, sections, output");
438 root
.appendChild(ele
);
440 // compile all source files
442 root
.appendChild(document
.createComment("Compile all dependency Library instances."));
443 ele
= document
.createElement("target");
444 ele
.setAttribute("name", "libraries");
446 // Parse all sourfiles but files specified in sections
448 applyLibraryInstance(document
, ele
);
449 root
.appendChild(ele
);
451 // compile all source files
453 root
.appendChild(document
.createComment("sourcefiles target"));
454 ele
= document
.createElement("target");
455 ele
.setAttribute("name", "sourcefiles");
457 // Parse all sourfiles but files specified in sections
459 applyCompileElement(document
, ele
);
460 root
.appendChild(ele
);
462 // generate the init target
463 // main purpose is create all nessary pathes
464 // generate the sections target
466 root
.appendChild(document
.createComment("sections target"));
467 ele
= document
.createElement("target");
468 ele
.setAttribute("name", "sections");
469 applySectionsElement(document
, ele
, fp
);
470 root
.appendChild(ele
);
472 // generate the output target
474 root
.appendChild(document
.createComment("output target"));
475 ele
= document
.createElement("target");
476 ele
.setAttribute("name", "output");
477 applyOutputElement(document
, ele
, fp
);
478 root
.appendChild(ele
);
480 // generate the clean target
482 root
.appendChild(document
.createComment("clean target"));
483 ele
= document
.createElement("target");
484 ele
.setAttribute("name", "clean");
485 applyCleanElement(document
, ele
);
486 root
.appendChild(ele
);
488 // generate the Clean All target
490 root
.appendChild(document
.createComment("Clean All target"));
491 ele
= document
.createElement("target");
492 ele
.setAttribute("name", "cleanall");
493 applyDeepcleanElement(document
, ele
);
494 root
.appendChild(ele
);
496 // add the root element to the document
498 document
.appendChild(rootComment
);
499 document
.appendChild(root
);
501 // Prepare the DOM document for writing
503 Source source
= new DOMSource(document
);
505 // Prepare the output file
507 File file
= new File(getProject().getProperty("DEST_DIR_OUTPUT") + File
.separatorChar
+ baseName
510 // generate all directory path
512 (new File(file
.getParent())).mkdirs();
513 Result result
= new StreamResult(file
);
515 // Write the DOM document to the file
517 Transformer xformer
= TransformerFactory
.newInstance().newTransformer();
518 xformer
.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
519 xformer
.setOutputProperty(OutputKeys
.INDENT
, "yes");
520 xformer
.transform(source
, result
);
521 } catch (Exception ex
) {
522 throw new BuildException("Module [" + baseName
+ "] generating build file failed.\n" + ex
.getMessage());
527 Generate the clean elements for BaseName_build.xml.
529 @param document current BaseName_build.xml XML document
530 @param root Root element for current
532 private void applyCleanElement(Document document
, Node root
) {
533 String
[] libinstances
= libraries
.toArray(new String
[libraries
.size()]);
534 for (int i
= 0; i
< libinstances
.length
; i
++) {
535 File file
= new File(GlobalData
.getModulePath(libinstances
[i
]) + File
.separatorChar
+ "build.xml");
537 Element ifEle
= document
.createElement("if");
538 Element availableEle
= document
.createElement("available");
539 availableEle
.setAttribute("file", file
.getPath());
540 ifEle
.appendChild(availableEle
);
541 Element elseEle
= document
.createElement("then");
543 Element ele
= document
.createElement("ant");
544 ele
.setAttribute("antfile", file
.getPath());
545 ele
.setAttribute("inheritAll", "false");
546 ele
.setAttribute("target", libinstances
[i
] + "_clean");
550 Element property
= document
.createElement("property");
551 property
.setAttribute("name", "WORKSPACE_DIR");
552 property
.setAttribute("value", "${WORKSPACE_DIR}");
553 ele
.appendChild(property
);
557 property
= document
.createElement("property");
558 property
.setAttribute("name", "PACKAGE_DIR");
559 property
.setAttribute("value", "${WORKSPACE_DIR}" + File
.separatorChar
560 + GlobalData
.getPackagePathForModule(libinstances
[i
]));
561 ele
.appendChild(property
);
565 property
= document
.createElement("property");
566 property
.setAttribute("name", "ARCH");
567 property
.setAttribute("value", "${ARCH}");
568 ele
.appendChild(property
);
572 property
= document
.createElement("property");
573 property
.setAttribute("name", "TARGET");
574 property
.setAttribute("value", "${TARGET}");
575 ele
.appendChild(property
);
579 property
= document
.createElement("property");
580 property
.setAttribute("name", "PACKAGE");
581 property
.setAttribute("value", GlobalData
.getPackageNameForModule(libinstances
[i
]));
582 ele
.appendChild(property
);
584 elseEle
.appendChild(ele
);
585 ifEle
.appendChild(elseEle
);
586 root
.appendChild(ifEle
);
591 Generate the cleanall elements for BaseName_build.xml.
593 @param document current BaseName_build.xml XML document
594 @param root Root element for current
596 private void applyDeepcleanElement(Document document
, Node root
) {
597 String
[] libinstances
= libraries
.toArray(new String
[libraries
.size()]);
598 for (int i
= 0; i
< libinstances
.length
; i
++) {
599 File file
= new File(GlobalData
.getModulePath(libinstances
[i
]) + File
.separatorChar
+ "build.xml");
601 Element ifEle
= document
.createElement("if");
602 Element availableEle
= document
.createElement("available");
603 availableEle
.setAttribute("file", file
.getPath());
604 ifEle
.appendChild(availableEle
);
605 Element elseEle
= document
.createElement("then");
607 Element ele
= document
.createElement("ant");
608 ele
.setAttribute("antfile", file
.getPath());
609 ele
.setAttribute("inheritAll", "false");
610 ele
.setAttribute("target", libinstances
[i
] + "_cleanall");
614 Element property
= document
.createElement("property");
615 property
.setAttribute("name", "WORKSPACE_DIR");
616 property
.setAttribute("value", "${WORKSPACE_DIR}");
617 ele
.appendChild(property
);
621 property
= document
.createElement("property");
622 property
.setAttribute("name", "PACKAGE_DIR");
623 property
.setAttribute("value", "${WORKSPACE_DIR}" + File
.separatorChar
624 + GlobalData
.getPackagePathForModule(libinstances
[i
]));
625 ele
.appendChild(property
);
629 property
= document
.createElement("property");
630 property
.setAttribute("name", "ARCH");
631 property
.setAttribute("value", "${ARCH}");
632 ele
.appendChild(property
);
636 property
= document
.createElement("property");
637 property
.setAttribute("name", "TARGET");
638 property
.setAttribute("value", "${TARGET}");
639 ele
.appendChild(property
);
643 property
= document
.createElement("property");
644 property
.setAttribute("name", "PACKAGE");
645 property
.setAttribute("value", GlobalData
.getPackageNameForModule(libinstances
[i
]));
646 ele
.appendChild(property
);
648 elseEle
.appendChild(ele
);
649 ifEle
.appendChild(elseEle
);
650 root
.appendChild(ifEle
);
655 Generate the dependent library instances elements for BaseName_build.xml.
657 @param document current BaseName_build.xml XML document
658 @param root Root element for current
660 private void applyLibraryInstance(Document document
, Node root
) {
661 String
[] libinstances
= libraries
.toArray(new String
[libraries
.size()]);
662 for (int i
= 0; i
< libinstances
.length
; i
++) {
663 Element ele
= document
.createElement("ant");
664 File file
= new File(GlobalData
.getModulePath(libinstances
[i
]) + File
.separatorChar
+ "build.xml");
665 ele
.setAttribute("antfile", file
.getPath());
666 ele
.setAttribute("inheritAll", "false");
667 ele
.setAttribute("target", libinstances
[i
]);
671 Element property
= document
.createElement("property");
672 property
.setAttribute("name", "WORKSPACE_DIR");
673 property
.setAttribute("value", "${WORKSPACE_DIR}");
674 ele
.appendChild(property
);
678 property
= document
.createElement("property");
679 property
.setAttribute("name", "PACKAGE_DIR");
680 property
.setAttribute("value", "${WORKSPACE_DIR}" + File
.separatorChar
681 + GlobalData
.getPackagePathForModule(libinstances
[i
]));
682 ele
.appendChild(property
);
686 property
= document
.createElement("property");
687 property
.setAttribute("name", "ARCH");
688 property
.setAttribute("value", "${ARCH}");
689 ele
.appendChild(property
);
693 property
= document
.createElement("property");
694 property
.setAttribute("name", "TARGET");
695 property
.setAttribute("value", "${TARGET}");
696 ele
.appendChild(property
);
700 property
= document
.createElement("property");
701 property
.setAttribute("name", "PACKAGE");
702 property
.setAttribute("value", GlobalData
.getPackageNameForModule(libinstances
[i
]));
703 ele
.appendChild(property
);
704 root
.appendChild(ele
);
706 Element expand
= document
.createElement("Expand");
707 root
.appendChild(expand
);
711 Generate the build source files elements for BaseName_build.xml.
713 @param document current BaseName_build.xml XML document
714 @param root Root element for current
716 private void applyCompileElement(Document document
, Node root
) {
717 FileProcess fileProcess
= new FileProcess();
718 fileProcess
.init(getProject(), includes
, sourceFiles
, document
);
719 Node
[] files
= this.getSourceFiles();
721 // Parse all unicode files
723 for (int i
= 0; i
< files
.length
; i
++) {
724 String filetype
= getFiletype(files
[i
]);
725 if (filetype
!= null) {
726 fileProcess
.parseFile(getFilename(files
[i
]), filetype
, root
, true);
728 fileProcess
.parseFile(getFilename(files
[i
]), root
, true);
731 if (fileProcess
.isUnicodeExist()) {
732 Element ele
= document
.createElement("Build_Unicode_Database");
733 ele
.setAttribute("FILEPATH", ".");
734 ele
.setAttribute("FILENAME", "${BASE_NAME}");
735 root
.appendChild(ele
);
739 // Parse AutoGen.c & AutoGen.h
741 if (!baseName
.equalsIgnoreCase("Shell")) {
742 fileProcess
.parseFile(getProject().getProperty("DEST_DIR_DEBUG") + File
.separatorChar
+ "AutoGen.c", root
,
746 // Parse all source files
748 for (int i
= 0; i
< files
.length
; i
++) {
749 String filetype
= getFiletype(files
[i
]);
750 if (filetype
!= null) {
751 fileProcess
.parseFile(getFilename(files
[i
]), filetype
, root
, false);
753 fileProcess
.parseFile(getFilename(files
[i
]), root
, false);
757 // root.appendChild(parallelEle);
759 Iterator iter
= sourceFiles
.iterator();
761 while (iter
.hasNext()) {
762 str
+= " " + (String
) iter
.next();
764 getProject().setProperty("SOURCE_FILES", str
);
768 Generate the section elements for BaseName_build.xml. Library module will
771 @param document current BaseName_build.xml XML document
772 @param root Root element for current
774 private void applySectionsElement(Document document
, Node root
, FfsProcess fp
) {
775 if (fp
.initSections(buildType
, getProject())) {
776 String targetFilename
= guid
+ "-" + baseName
+ FpdParserTask
.getSuffix(componentType
);
777 String
[] list
= fp
.getGenSectionElements(document
, baseName
, guid
, targetFilename
);
779 for (int i
= 0; i
< list
.length
; i
++) {
780 Element ele
= document
.createElement(list
[i
]);
781 ele
.setAttribute("FILEPATH", ".");
782 ele
.setAttribute("FILENAME", "${BASE_NAME}");
783 root
.appendChild(ele
);
789 Generate the output elements for BaseName_build.xml. If module is library,
790 call the <em>LIB</em> command, else call the <em>GenFfs</em> command.
792 @param document current BaseName_build.xml XML document
793 @param root Root element for current
795 private void applyOutputElement(Document document
, Node root
, FfsProcess fp
) {
796 if (flag
== GlobalData
.ONLY_LIBMSA
|| flag
== GlobalData
.LIBMSA_AND_LIBMBD
) {
800 Element cc
= document
.createElement("Build_Library");
801 cc
.setAttribute("FILENAME", baseName
);
802 root
.appendChild(cc
);
805 // if it is a module but library
808 if (fp
.getFfsNode() != null) {
809 root
.appendChild(fp
.getFfsNode());
815 Get file name from node. If some wrong, return string with zero length.
817 @param node Filename node of MSA/MBD or specified in each Section
820 private String
getFilename(Node node
) {
822 String filename
= "${MODULE_DIR}" + File
.separatorChar
;
825 FilenameDocument file
= (FilenameDocument
) XmlObject
.Factory
.parse(node
);
826 str
= file
.getFilename().getStringValue().trim();
827 path
= file
.getFilename().getPath();
828 } catch (Exception e
) {
832 filename
+= path
+ File
.separatorChar
+ str
;
836 return getProject().replaceProperties(filename
);
840 Get file type from node. If some wrong or not specified, return
843 @param node Filename node of MSA/MBD or specified in each Section
846 private String
getFiletype(Node node
) {
849 FilenameDocument file
= (FilenameDocument
) XmlObject
.Factory
.parse(node
);
850 str
= file
.getFilename().getFileType();
851 } catch (Exception e
) {
858 Return all source files but AutoGen.c.
860 @return source files Node array
862 public Node
[] getSourceFiles() {
863 XmlObject
[] files
= SurfaceAreaQuery
.getSourceFiles(arch
);
867 Vector
<Node
> vector
= new Vector
<Node
>();
868 for (int i
= 0; i
< files
.length
; i
++) {
869 vector
.addElement(files
[i
].getDomNode());
872 // To be consider sourcefiles from Sections
874 return vector
.toArray(new Node
[vector
.size()]);
878 Get current module's base name.
882 public String
getBaseName() {
887 Set MBD surface area file. For ANT use.
889 @param mbdFilename Surface Area file
891 public void setMbdFilename(File mbdFilename
) {
892 this.mbdFilename
= mbdFilename
;
896 Set MSA surface area file. For ANT use.
898 @param msaFilename Surface Area file
900 public void setMsaFilename(File msaFilename
) {
901 this.msaFilename
= msaFilename
;
907 <p> Take command <code>CC</code> and arch <code>IA32</code> for example,
908 Those flags are from <code>ToolChainFactory</code>: </p>
911 <li> IA32_CC_STD_FLAGS </li>
912 <li> IA32_CC_GLOBAL_FLAGS </li>
913 <li> IA32_CC_GLOBAL_ADD_FLAGS </li>
914 <li> IA32_CC_GLOBAL_SUB_FLAGS </li>
916 Those flags can user-define:
918 <li> IA32_CC_PROJ_FLAGS </li>
919 <li> IA32_CC_PROJ_ADD_FLAGS </li>
920 <li> IA32_CC_PROJ_SUB_FLAGS </li>
921 <li> CC_PROJ_FLAGS </li>
922 <li> CC_PROJ_ADD_FLAGS </li>
923 <li> CC_PROJ_SUB_FLAGS </li>
925 <li> IA32_CC_FLAGS </li>
928 <p> The final flags is composed of STD, GLOBAL and PROJ. If CC_FLAGS or
929 IA32_CC_FLAGS is specified, STD, GLOBAL and PROJ will not affect. </p>
931 Note that the <code>ToolChainFactory</code> executes only once
932 during whole build process.
934 private void flagsSetup() {
935 Project project
= getProject();
937 // If ToolChain has been set up before, do nothing.
939 ToolChainFactory toolChainFactory
= new ToolChainFactory(project
);
940 toolChainFactory
.setupToolChain();
942 String
[] cmd
= ToolChainFactory
.commandType
;
943 Set
<String
> addSet
= new HashSet
<String
>(40);
944 Set
<String
> subSet
= new HashSet
<String
>(40);
945 for (int i
= 0; i
< cmd
.length
; i
++) {
946 String str
= ToolChainFactory
.getValue(arch
+ "_" + cmd
[i
]);
948 // Command line path+command name
951 project
.setProperty(cmd
[i
], str
);
954 // ARCH_CMD_STD_FLAGS
956 str
= ToolChainFactory
.getValue(arch
+ "_" + cmd
[i
] + "_STD_FLAGS");
958 putFlagsToSet(addSet
, str
);
959 project
.setProperty(cmd
[i
] + "_STD_FLAGS", str
);
962 // ARCH_CMD_GLOBAL_FLAGS
964 str
= ToolChainFactory
.getValue(arch
+ "_" + cmd
[i
] + "_GLOBAL_FLAGS");
966 putFlagsToSet(addSet
, str
);
969 // ARCH_CMD_GLOBAL_ADD_FLAGS
971 str
= ToolChainFactory
.getValue(arch
+ "_" + cmd
[i
] + "_GLOBAL_ADD_FLAGS");
973 putFlagsToSet(addSet
, str
);
976 // ARCH_CMD_GLOBAL_SUB_FLAGS
978 str
= ToolChainFactory
.getValue(arch
+ "_" + cmd
[i
] + "_GLOBAL_SUB_FLAGS");
980 putFlagsToSet(subSet
, str
);
983 // ARCH_CMD_PROJ_FLAGS
985 str
= project
.getProperty(arch
+ "_" + cmd
[i
] + "_PROJ_FLAGS");
987 putFlagsToSet(addSet
, str
);
990 // ARCH_CMD_PROG_FLAGS
992 str
= project
.getProperty(arch
+ "_" + cmd
[i
] + "_PROJ_ADD_FLAGS");
994 putFlagsToSet(addSet
, str
);
997 // ARCH_CMD_PROG_FLAGS
999 str
= project
.getProperty(arch
+ "_" + cmd
[i
] + "_PROJ_SUB_FLAGS");
1001 putFlagsToSet(subSet
, str
);
1006 str
= project
.getProperty(cmd
[i
] + "_PROJ_FLAGS");
1008 putFlagsToSet(addSet
, str
);
1013 str
= project
.getProperty(cmd
[i
] + "_PROJ_ADD_FLAGS");
1015 putFlagsToSet(addSet
, str
);
1020 str
= project
.getProperty(cmd
[i
] + "_PROJ_SUB_FLAGS");
1022 putFlagsToSet(subSet
, str
);
1025 // If IA32_CC_FLAGS or IA32_LIB_FLAGS .. has defined in BuildOptions
1027 if ((str
= project
.getProperty(arch
+ "_" + cmd
[i
] + "_FLAGS")) != null) {
1028 project
.setProperty(cmd
[i
] + "_FLAGS", getRawFlags(addSet
, subSet
));
1031 putFlagsToSet(addSet
, project
.replaceProperties(str
));
1032 project
.setProperty(cmd
[i
] + "_FLAGS", project
.replaceProperties(getFlags(addSet
, subSet
)));
1037 // If CC_FLAGS or LIB_FLAGS .. has defined in BuildOptions
1039 else if ((str
= project
.getProperty(cmd
[i
] + "_FLAGS")) != null) {
1040 project
.setProperty(cmd
[i
] + "_FLAGS", getRawFlags(addSet
, subSet
));
1043 putFlagsToSet(addSet
, project
.replaceProperties(str
));
1044 project
.setProperty(cmd
[i
] + "_FLAGS", project
.replaceProperties(getFlags(addSet
, subSet
)));
1048 project
.setProperty(cmd
[i
] + "_FLAGS", getFlags(addSet
, subSet
));
1053 project
.setProperty("C_FLAGS", project
.getProperty("CC_FLAGS"));
1057 Initialize some properties will be used in current module build, including
1058 user-defined option from <em>Option</em> of <em>BuildOptions</em> in
1061 private void updateParameters() {
1062 getProject().setProperty("OBJECTS", "");
1063 getProject().setProperty("SDB_FILES", "");
1064 getProject().setProperty("BASE_NAME", baseName
);
1065 if (map
.get("MsaHeader") != null) {
1066 guid
= SurfaceAreaQuery
.getModuleGuid();//header.getGuid().getStringValue();
1067 componentType
= SurfaceAreaQuery
.getComponentType();//header.getComponentType().toString();
1068 if (!componentType
.equalsIgnoreCase("LIBRARY")) {
1069 flag
= GlobalData
.MSA_AND_MBD
;
1071 flag
= GlobalData
.LIBMSA_AND_LIBMBD
;
1075 else if (map
.get("MsaLibHeader") != null) {
1076 flag
= GlobalData
.LIBMSA_AND_LIBMBD
;
1077 MsaLibHeaderDocument
.MsaLibHeader header
= ((MsaLibHeaderDocument
) map
.get("MsaLibHeader"))
1079 guid
= header
.getGuid().getStringValue();
1080 componentType
= header
.getComponentType().toString();
1083 if (componentType
!= null) {
1084 getProject().setProperty("COMPONENT_TYPE", componentType
);
1088 getProject().setProperty("FILE_GUID", guid
);
1091 // Get all options and set to properties
1093 String
[][] options
= SurfaceAreaQuery
.getOptions(arch
);
1094 for (int i
= 0; i
< options
.length
; i
++) {
1095 if (options
[i
][0] != null && options
[i
][1] != null) {
1096 getProject().setProperty(options
[i
][0], getProject().replaceProperties(options
[i
][1]));
1100 buildType
= getProject().getProperty("BUILD_TYPE");
1101 if (buildType
== null) {
1102 buildType
= componentType
;
1108 Separate the string and instore in set.
1110 <p> String is separated by Java Regulation Expression
1111 "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>
1113 <p>For example: </p>
1116 "/nologo", "/W3", "/WX"
1117 "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""
1120 @param set store the separated string
1121 @param str string to separate
1123 private void putFlagsToSet(Set
<String
> set
, String str
) {
1124 Pattern myPattern
= Pattern
.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");
1125 Matcher matcher
= myPattern
.matcher(str
+ " ");
1126 while (matcher
.find()) {
1127 String item
= str
.substring(matcher
.start(1), matcher
.end(1));
1128 if (!set
.contains(item
)) {
1135 Generate the final flags string will be used by compile command.
1137 @param add the add flags set
1138 @param sub the sub flags set
1139 @return final flags after add set substract sub set
1141 private String
getFlags(Set
<String
> add
, Set
<String
> sub
) {
1144 Iterator iter
= add
.iterator();
1145 while (iter
.hasNext()) {
1146 String str
= getProject().replaceProperties((String
) iter
.next());
1147 result
+= str
.substring(1, str
.length() - 1) + " ";
1153 Generate the flags string with original format. The format is defined by
1154 Java Regulation Expression "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>
1156 <p>For example: </p>
1159 "/nologo", "/W3", "/WX"
1160 "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""
1163 @param add the add flags set
1164 @param sub the sub flags set
1165 @return flags with original format
1167 private String
getRawFlags(Set
<String
> add
, Set
<String
> sub
) {
1170 Iterator iter
= add
.iterator();
1171 while (iter
.hasNext()) {
1172 String str
= getProject().replaceProperties((String
) iter
.next());
1173 result
+= "\"" + str
.substring(1, str
.length() - 1) + "\", ";
1179 Set base name. For ANT use.
1181 @param baseName Base name
1183 public void setBaseName(String baseName
) {
1184 this.baseName
= baseName
;