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
.Hashtable
;
20 import java
.util
.Iterator
;
21 import java
.util
.LinkedHashSet
;
22 import java
.util
.List
;
25 import java
.util
.Vector
;
26 import java
.util
.regex
.Matcher
;
27 import java
.util
.regex
.Pattern
;
29 import org
.apache
.tools
.ant
.BuildException
;
30 import org
.apache
.tools
.ant
.BuildListener
;
31 import org
.apache
.tools
.ant
.Project
;
32 import org
.apache
.tools
.ant
.taskdefs
.Ant
;
33 import org
.apache
.tools
.ant
.taskdefs
.Property
;
34 import org
.apache
.xmlbeans
.XmlObject
;
36 import org
.tianocore
.common
.definitions
.ToolDefinitions
;
37 import org
.tianocore
.common
.exception
.EdkException
;
38 import org
.tianocore
.common
.logger
.EdkLog
;
39 import org
.tianocore
.build
.autogen
.AutoGen
;
40 import org
.tianocore
.build
.exception
.AutoGenException
;
41 import org
.tianocore
.build
.exception
.GenBuildException
;
42 import org
.tianocore
.build
.exception
.PcdAutogenException
;
43 import org
.tianocore
.build
.exception
.PlatformPcdPreprocessBuildException
;
44 import org
.tianocore
.build
.fpd
.FpdParserTask
;
45 import org
.tianocore
.build
.global
.GlobalData
;
46 import org
.tianocore
.build
.global
.OutputManager
;
47 import org
.tianocore
.build
.global
.SurfaceAreaQuery
;
48 import org
.tianocore
.build
.id
.FpdModuleIdentification
;
49 import org
.tianocore
.build
.id
.ModuleIdentification
;
50 import org
.tianocore
.build
.id
.PackageIdentification
;
51 import org
.tianocore
.build
.id
.PlatformIdentification
;
52 import org
.tianocore
.build
.tools
.ModuleItem
;
56 <code>GenBuildTask</code> is an ANT task that can be used in ANT build
59 <p>The main function of this task is to parse module's surface area (MSA),
60 then generate the corresponding <em>BaseName_build.xml</em> (the real ANT
61 build script) and call this to build the module. The whole process including:
64 1. generate AutoGen.c and AutoGen.h;
65 2. build all dependent library instances;
66 3. build all source files inlcude AutoGen.c;
68 5. generate FFS file if it is driver module while LIB file if it is Library module.
73 The usage is (take module <em>HelloWorld</em> for example):
78 msaFile="${PACKAGE_DIR}/Application/HelloWorld/HelloWorld.msa"
83 This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and
88 This task will also set properties for current module, such as PACKAGE,
89 PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
90 (relative to Workspace), MODULE or BASE_NAME, GUID, VERSION, MODULE_DIR,
91 MODULE_RELATIVE_DIR (relative to Package), CONFIG_DIR, BIN_DIR,
92 DEST_DIR_DEBUG, DEST_DIR_OUTPUT, TARGET, ARCH, TOOLCHAIN, TOOLCHAIN_FAMILY,
93 SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH, all compiler command related
94 properties (CC, CC_FLAGS, CC_DPATH, CC_SPATH, CC_FAMILY, CC_EXT).
99 public class GenBuildTask
extends Ant
{
102 /// Module surface area file.
106 public ModuleIdentification parentId
;
108 private String type
= "all";
111 /// Module's Identification.
113 private ModuleIdentification moduleId
;
115 private Vector
<Property
> properties
= new Vector
<Property
>();
117 private boolean isSingleModuleBuild
= false;
119 private SurfaceAreaQuery saq
= null;
122 Public construct method. It is necessary for ANT task.
124 public GenBuildTask() {
129 @throws BuildException
130 From module build, exception from module surface area invalid.
132 public void execute() throws BuildException
{
135 } catch (PcdAutogenException e
) {
137 // Add more logic process here
139 throw new BuildException(e
.getMessage());
140 } catch (AutoGenException e
) {
142 // Add more logic process here
144 throw new BuildException(e
.getMessage());
145 } catch (PlatformPcdPreprocessBuildException e
) {
147 // Add more logic process here
149 throw new BuildException(e
.getMessage());
150 } catch (GenBuildException e
) {
152 // Add more logic process here
154 throw new BuildException(e
.getMessage());
155 } catch (EdkException e
) {
157 // Add more logic process here
159 throw new BuildException(e
.getMessage());
163 private void processGenBuild() throws EdkException
, BuildException
, GenBuildException
, AutoGenException
, PcdAutogenException
, PlatformPcdPreprocessBuildException
{
164 if (!FrameworkBuildTask
.multithread
) {
169 // Enable all specified properties
171 Iterator
<Property
> iter
= properties
.iterator();
172 while (iter
.hasNext()) {
173 Property item
= iter
.next();
174 getProject().setProperty(item
.getName(), item
.getValue());
178 // GenBuild should specify either msaFile or moduleGuid & packageGuid
180 if (msaFile
== null ) {
181 String moduleGuid
= getProject().getProperty("MODULE_GUID");
182 String moduleVersion
= getProject().getProperty("MODULE_VERSION");
183 String packageGuid
= getProject().getProperty("PACKAGE_GUID");
184 String packageVersion
= getProject().getProperty("PACKAGE_VERSION");
186 // If one of module Guid or package Guid is not specified, report error
188 if (moduleGuid
== null || packageGuid
== null) {
189 throw new BuildException("GenBuild parameter error.");
192 PackageIdentification packageId
= new PackageIdentification(packageGuid
, packageVersion
);
193 GlobalData
.refreshPackageIdentification(packageId
);
194 moduleId
= new ModuleIdentification(moduleGuid
, moduleVersion
);
195 moduleId
.setPackage(packageId
);
196 GlobalData
.refreshModuleIdentification(moduleId
);
197 Map
<String
, XmlObject
> doc
= GlobalData
.getNativeMsa(moduleId
);
198 saq
= new SurfaceAreaQuery(doc
);
200 Map
<String
, XmlObject
> doc
= GlobalData
.getNativeMsa(msaFile
);
201 saq
= new SurfaceAreaQuery(doc
);
202 moduleId
= saq
.getMsaHeader();
205 String
[] producedLibraryClasses
= saq
.getLibraryClasses("ALWAYS_PRODUCED",null);
206 if (producedLibraryClasses
.length
== 0) {
207 moduleId
.setLibrary(false);
209 moduleId
.setLibrary(true);
213 // Judge whether it is single module build or not
215 if (isSingleModuleBuild
) {
217 // Single Module build
219 prepareSingleModuleBuild();
223 // If single module : get arch from pass down, otherwise intersection MSA
224 // supported ARCHs and tools def
226 Set
<String
> archListSupByToolChain
= new LinkedHashSet
<String
>();
227 String
[] archs
= GlobalData
.getToolChainInfo().getArchs();
229 for (int i
= 0; i
< archs
.length
; i
++) {
230 archListSupByToolChain
.add(archs
[i
]);
233 Set
<String
> archSet
= new LinkedHashSet
<String
>();
235 if ( getProject().getProperty("ARCH") != null) {
236 String
[] fpdArchList
= getProject().getProperty("ARCH").split(" ");
238 for (int i
= 0; i
< fpdArchList
.length
; i
++) {
239 if (archListSupByToolChain
.contains(fpdArchList
[i
])) {
240 archSet
.add(fpdArchList
[i
]);
244 archSet
= archListSupByToolChain
;
247 String
[] archList
= archSet
.toArray(new String
[archSet
.size()]);
250 // Judge if arch is all supported by current module. If not, throw Exception.
252 List moduleSupportedArchs
= saq
.getModuleSupportedArchs();
253 if (moduleSupportedArchs
!= null) {
254 for (int k
= 0; k
< archList
.length
; k
++) {
255 if ( ! moduleSupportedArchs
.contains(archList
[k
])) {
256 throw new BuildException("Specified architecture [" + archList
[k
] + "] is not supported by " + moduleId
+ ". The module " + moduleId
+ " only supports [" + moduleSupportedArchs
+ "] architectures.");
261 for (int k
= 0; k
< archList
.length
; k
++) {
263 getProject().setProperty("ARCH", archList
[k
]);
265 FpdModuleIdentification fpdModuleId
= new FpdModuleIdentification(moduleId
, archList
[k
]);
268 // Whether the module is built before
270 if (moduleId
.isLibrary() == false && GlobalData
.hasFpdModuleSA(fpdModuleId
) == false) {
271 EdkLog
.log(this, EdkLog
.EDK_WARNING
, "Warning: " + moduleId
+ " for " + archList
[k
] + " was not found in current platform FPD file!\n");
273 } else if (GlobalData
.isModuleBuilt(fpdModuleId
)) {
276 GlobalData
.registerBuiltModule(fpdModuleId
);
280 // For Every TOOLCHAIN, TARGET
282 String
[] targetList
= GlobalData
.getToolChainInfo().getTargets();
283 for (int i
= 0; i
< targetList
.length
; i
++){
285 // Prepare for target related common properties
288 getProject().setProperty("TARGET", targetList
[i
]);
289 String
[] toolchainList
= GlobalData
.getToolChainInfo().getTagnames();
290 for(int j
= 0; j
< toolchainList
.length
; j
++){
292 // check if any tool is defined for current target + toolchain + arch
293 // don't do anything if no tools found
295 if (GlobalData
.isCommandSet(targetList
[i
], toolchainList
[j
], archList
[k
]) == false) {
296 EdkLog
.log(this, EdkLog
.EDK_WARNING
, "Warning: No build issued. No tools were found for [target=" + targetList
[i
] + " toolchain=" + toolchainList
[j
] + " arch=" + archList
[k
] + "]\n");
301 // Prepare for toolchain related common properties
304 getProject().setProperty("TOOLCHAIN", toolchainList
[j
]);
306 EdkLog
.log(this, "Build " + moduleId
+ " start >>>");
307 EdkLog
.log(this, "Target: " + targetList
[i
] + " Tagname: " + toolchainList
[j
] + " Arch: " + archList
[k
]);
308 saq
.push(GlobalData
.getDoc(fpdModuleId
));
311 // Prepare for all other common properties
312 // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
313 // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE
314 // MODULE_DIR, MODULE_RELATIVE_DIR
315 // SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH
317 setModuleCommonProperties(archList
[k
]);
320 // OutputManage prepare for
321 // BIN_DIR, DEST_DIR_DEBUG, DEST_DIR_OUTPUT, BUILD_DIR, FV_DIR
323 OutputManager
.getInstance().update(getProject());
325 if (type
.equalsIgnoreCase("all") || type
.equalsIgnoreCase("build")) {
326 applyBuild(targetList
[i
], toolchainList
[j
], fpdModuleId
);
327 } else if (type
.equalsIgnoreCase("clean")) {
328 applyClean(fpdModuleId
);
329 } else if (type
.equalsIgnoreCase("cleanall")) {
330 applyCleanall(fpdModuleId
);
338 This method is used to prepare Platform-related information.
340 <p>In Single Module Build mode, platform-related information is not ready.
341 The method read the system environment variable <code>ACTIVE_PLATFORM</code>
342 and search in the Framework Database. Note that platform name in the Framework
343 Database must be unique. </p>
346 private void prepareSingleModuleBuild() throws EdkException
{
348 // Find out the package which the module belongs to
349 // TBD: Enhance it!!!!
351 PackageIdentification packageId
= GlobalData
.getPackageForModule(moduleId
);
352 GlobalData
.refreshPackageIdentification(packageId
);
353 moduleId
.setPackage(packageId
);
354 GlobalData
.refreshModuleIdentification(moduleId
);
357 // Read ACTIVE_PLATFORM's FPD file
359 String filename
= getProject().getProperty("PLATFORM_FILE");
361 if (filename
== null){
362 throw new BuildException("Please set ACTIVE_PLATFORM in the file: Tools/Conf/target.txt if you want to build a single module!");
365 PlatformIdentification platformId
= GlobalData
.getPlatform(filename
);
368 // Read FPD file (Call FpdParserTask's method)
370 FpdParserTask fpdParser
= new FpdParserTask();
371 fpdParser
.setProject(getProject());
372 fpdParser
.parseFpdFile(platformId
.getFpdFile());
373 getProject().setProperty("ARCH", fpdParser
.getAllArchForModule(moduleId
));
376 private void cleanupProperties() {
377 Project newProject
= new Project();
379 Hashtable
<String
, String
> passdownProperties
= FrameworkBuildTask
.originalProperties
;
380 Iterator
<String
> iter
= passdownProperties
.keySet().iterator();
381 while (iter
.hasNext()) {
382 String item
= iter
.next();
383 newProject
.setProperty(item
, passdownProperties
.get(item
));
386 newProject
.setInputHandler(getProject().getInputHandler());
388 Iterator listenerIter
= getProject().getBuildListeners().iterator();
389 while (listenerIter
.hasNext()) {
390 newProject
.addBuildListener((BuildListener
) listenerIter
.next());
393 getProject().initSubProject(newProject
);
395 setProject(newProject
);
399 Set Module-Related information to properties.
401 @param arch current build ARCH
403 private void setModuleCommonProperties(String arch
) {
405 // Prepare for all other common properties
406 // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
408 PackageIdentification packageId
= moduleId
.getPackage();
409 getProject().setProperty("PACKAGE", packageId
.getName());
410 getProject().setProperty("PACKAGE_GUID", packageId
.getGuid());
411 getProject().setProperty("PACKAGE_VERSION", packageId
.getVersion());
412 getProject().setProperty("PACKAGE_DIR", packageId
.getPackageDir().replaceAll("(\\\\)", "/"));
413 getProject().setProperty("PACKAGE_RELATIVE_DIR", packageId
.getPackageRelativeDir().replaceAll("(\\\\)", "/"));
416 // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE
417 // MODULE_DIR, MODULE_RELATIVE_DIR
419 getProject().setProperty("MODULE", moduleId
.getName());
420 String baseName
= saq
.getModuleOutputFileBasename();
421 if (baseName
== null) {
422 getProject().setProperty("BASE_NAME", moduleId
.getName());
424 getProject().setProperty("BASE_NAME", baseName
);
426 getProject().setProperty("GUID", moduleId
.getGuid());
427 getProject().setProperty("FILE_GUID", moduleId
.getGuid());
428 getProject().setProperty("VERSION", moduleId
.getVersion());
429 getProject().setProperty("MODULE_TYPE", moduleId
.getModuleType());
430 getProject().setProperty("MODULE_DIR", moduleId
.getMsaFile().getParent().replaceAll("(\\\\)", "/"));
431 getProject().setProperty("MODULE_RELATIVE_DIR", moduleId
.getModuleRelativePath().replaceAll("(\\\\)", "/"));
436 String
[][] subsystemMap
= { { "BASE", "EFI_BOOT_SERVICE_DRIVER"},
437 { "SEC", "EFI_BOOT_SERVICE_DRIVER" },
438 { "PEI_CORE", "EFI_BOOT_SERVICE_DRIVER" },
439 { "PEIM", "EFI_BOOT_SERVICE_DRIVER" },
440 { "DXE_CORE", "EFI_BOOT_SERVICE_DRIVER" },
441 { "DXE_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
442 { "DXE_RUNTIME_DRIVER", "EFI_RUNTIME_DRIVER" },
443 { "DXE_SAL_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
444 { "DXE_SMM_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
445 { "TOOL", "EFI_BOOT_SERVICE_DRIVER" },
446 { "UEFI_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
447 { "UEFI_APPLICATION", "EFI_APPLICATION" },
448 { "USER_DEFINED", "EFI_BOOT_SERVICE_DRIVER"} };
450 String subsystem
= "EFI_BOOT_SERVICE_DRIVER";
451 for (int i
= 0; i
< subsystemMap
.length
; i
++) {
452 if (moduleId
.getModuleType().equalsIgnoreCase(subsystemMap
[i
][0])) {
453 subsystem
= subsystemMap
[i
][1];
457 getProject().setProperty("SUBSYSTEM", subsystem
);
462 if (arch
.equalsIgnoreCase("EBC")) {
463 getProject().setProperty("ENTRYPOINT", "EfiStart");
465 getProject().setProperty("ENTRYPOINT", "_ModuleEntryPoint");
468 getProject().setProperty("OBJECTS", "");
471 private void getCompilerFlags(String target
, String toolchain
, FpdModuleIdentification fpdModuleId
) throws EdkException
{
472 String
[] cmd
= GlobalData
.getToolChainInfo().getCommands();
473 for ( int m
= 0; m
< cmd
.length
; m
++) {
475 // Set cmd, like CC, DLINK
477 String
[] key
= new String
[]{target
, toolchain
, fpdModuleId
.getArch(), cmd
[m
], null};
478 key
[4] = ToolDefinitions
.TOOLS_DEF_ATTRIBUTE_PATH
;
479 String cmdPath
= GlobalData
.getCommandSetting(key
, fpdModuleId
);
480 key
[4] = ToolDefinitions
.TOOLS_DEF_ATTRIBUTE_NAME
;
481 String cmdName
= GlobalData
.getCommandSetting(key
, fpdModuleId
);
482 File cmdFile
= new File(cmdPath
+ File
.separatorChar
+ cmdName
);
483 getProject().setProperty(cmd
[m
], cmdFile
.getPath().replaceAll("(\\\\)", "/"));
488 key
[4] = ToolDefinitions
.TOOLS_DEF_ATTRIBUTE_FLAGS
;
489 String cmdFlags
= GlobalData
.getCommandSetting(key
, fpdModuleId
);
490 Set
<String
> addset
= new LinkedHashSet
<String
>();
491 Set
<String
> subset
= new LinkedHashSet
<String
>();
492 putFlagsToSet(addset
, cmdFlags
);
493 getProject().setProperty(cmd
[m
] + "_FLAGS", getProject().replaceProperties(getFlags(addset
, subset
)));
498 key
[4] = ToolDefinitions
.TOOLS_DEF_ATTRIBUTE_EXT
;
499 String extName
= GlobalData
.getCommandSetting(key
, fpdModuleId
);
500 if ( extName
!= null && ! extName
.equalsIgnoreCase("")) {
501 getProject().setProperty(cmd
[m
] + "_EXT", extName
);
503 getProject().setProperty(cmd
[m
] + "_EXT", "");
509 key
[4] = ToolDefinitions
.TOOLS_DEF_ATTRIBUTE_FAMILY
;
510 String toolChainFamily
= GlobalData
.getCommandSetting(key
, fpdModuleId
);
511 if (toolChainFamily
!= null) {
512 getProject().setProperty(cmd
[m
] + "_FAMILY", toolChainFamily
);
518 key
[4] = ToolDefinitions
.TOOLS_DEF_ATTRIBUTE_SPATH
;
519 String spath
= GlobalData
.getCommandSetting(key
, fpdModuleId
);
521 getProject().setProperty(cmd
[m
] + "_SPATH", spath
.replaceAll("(\\\\)", "/"));
523 getProject().setProperty(cmd
[m
] + "_SPATH", "");
529 key
[4] = ToolDefinitions
.TOOLS_DEF_ATTRIBUTE_DPATH
;
530 String dpath
= GlobalData
.getCommandSetting(key
, fpdModuleId
);
532 getProject().setProperty(cmd
[m
] + "_DPATH", dpath
.replaceAll("(\\\\)", "/"));
534 getProject().setProperty(cmd
[m
] + "_DPATH", "");
539 public void setMsaFile(File msaFile
) {
540 this.msaFile
= msaFile
;
544 Method is for ANT to initialize MSA file.
546 @param msaFilename MSA file name
548 public void setMsaFile(String msaFilename
) {
549 String moduleDir
= getProject().getProperty("MODULE_DIR");
552 // If is Single Module Build, then use the Base Dir defined in build.xml
554 if (moduleDir
== null) {
555 moduleDir
= getProject().getBaseDir().getPath();
557 msaFile
= new File(moduleDir
+ File
.separatorChar
+ msaFilename
);
560 public void addConfiguredModuleItem(ModuleItem moduleItem
) {
561 PackageIdentification packageId
= new PackageIdentification(moduleItem
.getPackageGuid(), moduleItem
.getPackageVersion());
562 ModuleIdentification moduleId
= new ModuleIdentification(moduleItem
.getModuleGuid(), moduleItem
.getModuleVersion());
563 moduleId
.setPackage(packageId
);
564 this.moduleId
= moduleId
;
572 public void addProperty(Property p
) {
573 properties
.addElement(p
);
576 public void setType(String type
) {
580 private void applyBuild(String buildTarget
, String buildTagname
, FpdModuleIdentification fpdModuleId
) throws EdkException
{
582 // Call AutoGen to generate AutoGen.c and AutoGen.h
584 AutoGen autogen
= new AutoGen(getProject().getProperty("FV_DIR"), getProject().getProperty("DEST_DIR_DEBUG"), fpdModuleId
.getModule(),fpdModuleId
.getArch(), saq
, parentId
);
585 autogen
.genAutogen();
588 // Get compiler flags
591 getCompilerFlags(buildTarget
, buildTagname
, fpdModuleId
);
593 catch (EdkException ee
) {
594 throw new BuildException(ee
.getMessage());
600 ModuleIdentification
[] libinstances
= saq
.getLibraryInstance(fpdModuleId
.getArch());
601 String propertyLibs
= "";
602 for (int i
= 0; i
< libinstances
.length
; i
++) {
603 propertyLibs
+= getProject().getProperty("BIN_DIR") + File
.separatorChar
+ libinstances
[i
].getName() + ".lib" + " ";
605 getProject().setProperty("LIBS", propertyLibs
.replaceAll("(\\\\)", "/"));
608 // Get all includepath and set to INCLUDE_PATHS
610 String
[] includes
= prepareIncludePaths(fpdModuleId
);
613 // if it is CUSTOM_BUILD
614 // then call the exist BaseName_build.xml directly.
616 if (moduleId
.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
617 EdkLog
.log(this, "Call user-defined " + moduleId
.getName() + "_build.xml");
619 String antFilename
= getProject().getProperty("MODULE_DIR") + File
.separatorChar
+ moduleId
.getName() + "_build.xml";
620 antCall(antFilename
, null);
626 // Generate ${BASE_NAME}_build.xml
629 String ffsKeyword
= saq
.getModuleFfsKeyword();
630 ModuleBuildFileGenerator fileGenerator
= new ModuleBuildFileGenerator(getProject(), ffsKeyword
, fpdModuleId
, includes
, saq
);
631 String buildFilename
= getProject().getProperty("DEST_DIR_OUTPUT") + File
.separatorChar
+ moduleId
.getName() + "_build.xml";
632 fileGenerator
.genBuildFile(buildFilename
);
635 // Ant call ${BASE_NAME}_build.xml
637 String antFilename
= getProject().getProperty("DEST_DIR_OUTPUT") + File
.separatorChar
+ moduleId
.getName() + "_build.xml";
638 antCall(antFilename
, null);
641 private void applyClean(FpdModuleIdentification fpdModuleId
){
643 // if it is CUSTOM_BUILD
644 // then call the exist BaseName_build.xml directly.
646 if (moduleId
.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
647 EdkLog
.log(this, "Calling user-defined " + moduleId
.getName() + "_build.xml");
649 String antFilename
= getProject().getProperty("MODULE_DIR") + File
.separatorChar
+ moduleId
.getName() + "_build.xml";
650 antCall(antFilename
, "clean");
655 String antFilename
= getProject().getProperty("DEST_DIR_OUTPUT") + File
.separatorChar
+ moduleId
.getName() + "_build.xml";
656 antCall(antFilename
, "clean");
659 private void applyCleanall(FpdModuleIdentification fpdModuleId
){
661 // if it is CUSTOM_BUILD
662 // then call the exist BaseName_build.xml directly.
664 if (moduleId
.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
665 EdkLog
.log(this, "Calling user-defined " + moduleId
.getName() + "_build.xml");
667 String antFilename
= getProject().getProperty("MODULE_DIR") + File
.separatorChar
+ moduleId
.getName() + "_build.xml";
668 antCall(antFilename
, "cleanall");
673 String antFilename
= getProject().getProperty("DEST_DIR_OUTPUT") + File
.separatorChar
+ moduleId
.getName() + "_build.xml";
674 antCall(antFilename
, "cleanall");
677 private void antCall(String antFilename
, String target
) {
679 ant
.setProject(getProject());
680 ant
.setAntfile(antFilename
);
681 if (target
!= null) {
682 ant
.setTarget(target
);
684 ant
.setInheritAll(true);
691 Separate the string and instore in set.
693 <p> String is separated by Java Regulation Expression
694 "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>
699 "/nologo", "/W3", "/WX"
700 "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""
703 @param set store the separated string
704 @param str string to separate
706 private void putFlagsToSet(Set
<String
> set
, String str
) {
707 if (str
== null || str
.length() == 0) {
711 Pattern myPattern
= Pattern
.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");
712 Matcher matcher
= myPattern
.matcher(str
+ " ");
713 while (matcher
.find()) {
714 String item
= str
.substring(matcher
.start(1), matcher
.end(1));
720 Generate the final flags string will be used by compile command.
722 @param add the add flags set
723 @param sub the sub flags set
724 @return final flags after add set substract sub set
726 private String
getFlags(Set
<String
> add
, Set
<String
> sub
) {
729 Iterator iter
= add
.iterator();
730 while (iter
.hasNext()) {
731 String str
= (String
) iter
.next();
732 result
+= str
.substring(1, str
.length() - 1) + " ";
737 public void setSingleModuleBuild(boolean isSingleModuleBuild
) {
738 this.isSingleModuleBuild
= isSingleModuleBuild
;
741 private String
[] prepareIncludePaths(FpdModuleIdentification fpdModuleId
) throws EdkException
{
743 // Prepare the includes: PackageDependencies and Output debug direactory
745 Set
<String
> includes
= new LinkedHashSet
<String
>();
746 String arch
= fpdModuleId
.getArch();
751 includes
.add("${WORKSPACE_DIR}" + File
.separatorChar
);
756 includes
.add("${MODULE_DIR}");
757 includes
.add("${MODULE_DIR}" + File
.separatorChar
+ archDir(arch
));
760 // Packages in PackageDenpendencies
762 PackageIdentification
[] packageDependencies
= saq
.getDependencePkg(fpdModuleId
.getArch());
763 for (int i
= 0; i
< packageDependencies
.length
; i
++) {
764 GlobalData
.refreshPackageIdentification(packageDependencies
[i
]);
765 File packageFile
= packageDependencies
[i
].getSpdFile();
766 includes
.add(packageFile
.getParent() + File
.separatorChar
+ "Include");
767 includes
.add(packageFile
.getParent() + File
.separatorChar
+ "Include" + File
.separatorChar
+ archDir(arch
));
771 // All Dependency Library Instance's PackageDependencies
773 ModuleIdentification
[] libinstances
= saq
.getLibraryInstance(fpdModuleId
.getArch());
774 for (int i
= 0; i
< libinstances
.length
; i
++) {
775 saq
.push(GlobalData
.getDoc(libinstances
[i
], fpdModuleId
.getArch()));
776 PackageIdentification
[] libraryPackageDependencies
= saq
.getDependencePkg(fpdModuleId
.getArch());
777 for (int j
= 0; j
< libraryPackageDependencies
.length
; j
++) {
778 GlobalData
.refreshPackageIdentification(libraryPackageDependencies
[j
]);
779 File packageFile
= libraryPackageDependencies
[j
].getSpdFile();
780 includes
.add(packageFile
.getParent() + File
.separatorChar
+ "Include");
781 includes
.add(packageFile
.getParent() + File
.separatorChar
+ "Include" + File
.separatorChar
+ archDir(arch
));
788 // The package which the module belongs to
790 includes
.add(fpdModuleId
.getModule().getPackage().getPackageDir() + File
.separatorChar
+ "Include");
791 includes
.add(fpdModuleId
.getModule().getPackage().getPackageDir() + File
.separatorChar
+ "Include" + File
.separatorChar
+ archDir(arch
));
794 // Debug files output directory
796 includes
.add("${DEST_DIR_DEBUG}");
799 // set to INCLUDE_PATHS property
801 Iterator
<String
> iter
= includes
.iterator();
802 StringBuffer includePaths
= new StringBuffer();
803 while (iter
.hasNext()) {
804 includePaths
.append(iter
.next());
805 includePaths
.append("; ");
807 getProject().setProperty("INCLUDE_PATHS", getProject().replaceProperties(includePaths
.toString()).replaceAll("(\\\\)", "/"));
809 return includes
.toArray(new String
[includes
.size()]);
813 Return the name of the directory that corresponds to the architecture.
814 This is a translation from the XML Schema tag to a directory that
815 corresponds to our directory name coding convention.
818 private String
archDir(String arch
) {
819 return arch
.replaceFirst("X64", "x64")
820 .replaceFirst("IPF", "Ipf")
821 .replaceFirst("IA32", "Ia32")
822 .replaceFirst("ARM", "Arm")
823 .replaceFirst("EBC", "Ebc");
827 public void setExternalProperties(Vector
<Property
> v
) {