Introduce a new property INCLUDE_PATHS. This property can used by customized build...
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / GenBuildTask.java
1 /** @file
2 This file is ANT task GenBuild.
3
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.
6
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
12
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.
15 **/
16 package org.tianocore.build;
17
18 import java.io.File;
19 import java.util.Iterator;
20 import java.util.LinkedHashSet;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24 import java.util.Vector;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27
28 import org.apache.tools.ant.BuildException;
29 import org.apache.tools.ant.taskdefs.Ant;
30 import org.apache.tools.ant.taskdefs.Property;
31 import org.apache.xmlbeans.XmlObject;
32
33 import org.tianocore.common.definitions.ToolDefinitions;
34 import org.tianocore.common.exception.EdkException;
35 import org.tianocore.common.logger.EdkLog;
36 import org.tianocore.build.autogen.AutoGen;
37 import org.tianocore.build.fpd.FpdParserTask;
38 import org.tianocore.build.global.GenBuildLogger;
39 import org.tianocore.build.global.GlobalData;
40 import org.tianocore.build.global.OutputManager;
41 import org.tianocore.build.global.PropertyManager;
42 import org.tianocore.build.global.SurfaceAreaQuery;
43 import org.tianocore.build.id.FpdModuleIdentification;
44 import org.tianocore.build.id.ModuleIdentification;
45 import org.tianocore.build.id.PackageIdentification;
46 import org.tianocore.build.id.PlatformIdentification;
47 import org.tianocore.build.tools.ModuleItem;
48
49 /**
50 <p>
51 <code>GenBuildTask</code> is an ANT task that can be used in ANT build
52 system.
53
54 <p>The main function of this task is to parse module's surface area (MSA),
55 then generate the corresponding <em>BaseName_build.xml</em> (the real ANT
56 build script) and call this to build the module. The whole process including:
57
58 <pre>
59 1. generate AutoGen.c and AutoGen.h;
60 2. build all dependent library instances;
61 3. build all source files inlcude AutoGen.c;
62 4. generate sections;
63 5. generate FFS file if it is driver module while LIB file if it is Library module.
64 </pre>
65
66
67 <p>
68 The usage is (take module <em>HelloWorld</em> for example):
69 </p>
70
71 <pre>
72 &lt;GenBuild
73 msaFile="${PACKAGE_DIR}/Application/HelloWorld/HelloWorld.msa"
74 type="cleanall" /&gt;
75 </pre>
76
77 <p>
78 This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and
79 <em>AutoGen.h</em>.
80 </p>
81
82 <p>
83 This task will also set properties for current module, such as PACKAGE,
84 PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
85 (relative to Workspace), MODULE or BASE_NAME, GUID, VERSION, MODULE_DIR,
86 MODULE_RELATIVE_DIR (relative to Package), CONFIG_DIR, BIN_DIR,
87 DEST_DIR_DEBUG, DEST_DIR_OUTPUT, TARGET, ARCH, TOOLCHAIN, TOOLCHAIN_FAMILY,
88 SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH, all compiler command related
89 properties (CC, CC_FLAGS, CC_DPATH, CC_SPATH, CC_FAMILY, CC_EXT).
90 </p>
91
92 @since GenBuild 1.0
93 **/
94 public class GenBuildTask extends Ant {
95
96 ///
97 /// Module surface area file.
98 ///
99 File msaFile;
100
101 private String type = "all";
102
103 ///
104 /// Module's Identification.
105 ///
106 private ModuleIdentification moduleId;
107
108 private Vector<Property> properties = new Vector<Property>();
109
110 private boolean isSingleModuleBuild = false;
111
112 /**
113 Public construct method. It is necessary for ANT task.
114 **/
115 public GenBuildTask() {
116 }
117
118 /**
119
120 @throws BuildException
121 From module build, exception from module surface area invalid.
122 **/
123 public void execute() throws BuildException {
124 //
125 // set Logger
126 //
127 GenBuildLogger logger = new GenBuildLogger(getProject());
128 EdkLog.setLogLevel(getProject().getProperty("env.LOGLEVEL"));
129 EdkLog.setLogger(logger);
130
131 PropertyManager.setProject(getProject());
132 PropertyManager.save();
133 //
134 // Enable all specified properties
135 //
136 Iterator<Property> iter = properties.iterator();
137 while (iter.hasNext()) {
138 Property item = iter.next();
139 PropertyManager.setProperty(item.getName(), item.getValue());
140 }
141
142 //
143 // GenBuild should specify either msaFile or moduleGuid & packageGuid
144 //
145 if (msaFile == null ) {
146 String moduleGuid = getProject().getProperty("MODULE_GUID");
147 String moduleVersion = getProject().getProperty("MODULE_VERSION");
148 String packageGuid = getProject().getProperty("PACKAGE_GUID");
149 String packageVersion = getProject().getProperty("PACKAGE_VERSION");
150 if (moduleGuid == null || packageGuid == null) {
151 throw new BuildException("GenBuild parameter error.");
152 }
153 PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion);
154 moduleId = new ModuleIdentification(moduleGuid, moduleVersion);
155 moduleId.setPackage(packageId);
156 Map<String, XmlObject> doc = GlobalData.getNativeMsa(moduleId);
157 SurfaceAreaQuery.setDoc(doc);
158 moduleId = SurfaceAreaQuery.getMsaHeader();
159 } else {
160 Map<String, XmlObject> doc = GlobalData.getNativeMsa(msaFile);
161 SurfaceAreaQuery.setDoc(doc);
162 moduleId = SurfaceAreaQuery.getMsaHeader();
163 }
164 String[] producedLibraryClasses = SurfaceAreaQuery.getLibraryClasses("ALWAYS_PRODUCED",null);
165 if (producedLibraryClasses.length == 0) {
166 moduleId.setLibrary(false);
167 } else {
168 moduleId.setLibrary(true);
169 }
170
171 //
172 // Judge whether it is single module build or not
173 //
174 if (isSingleModuleBuild) {
175 //
176 // Single Module build
177 //
178 prepareSingleModuleBuild();
179 } else {
180 //
181 // Platform build. Restore the platform related info
182 //
183 String filename = getProject().getProperty("PLATFORM_FILE");
184 PlatformIdentification platformId = GlobalData.getPlatform(filename);
185 PropertyManager.setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));
186 PropertyManager.setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));
187
188 String packageGuid = getProject().getProperty("PACKAGE_GUID");
189 String packageVersion = getProject().getProperty("PACKAGE_VERSION");
190 PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion);
191 moduleId.setPackage(packageId);
192 }
193
194 //
195 // If single module : get arch from pass down, otherwise intersection MSA
196 // supported ARCHs and tools def
197 //
198 Set<String> archListSupByToolChain = new LinkedHashSet<String>();
199 String[] archs = GlobalData.getToolChainInfo().getArchs();
200
201 for (int i = 0; i < archs.length; i ++) {
202 archListSupByToolChain.add(archs[i]);
203 }
204
205 Set<String> archSet = new LinkedHashSet<String>();
206
207 if ( getProject().getProperty("ARCH") != null) {
208 String[] fpdArchList = getProject().getProperty("ARCH").split(" ");
209
210 for (int i = 0; i < fpdArchList.length; i++) {
211 if (archListSupByToolChain.contains(fpdArchList[i])) {
212 archSet.add(fpdArchList[i]);
213 }
214 }
215 } else {
216 archSet = archListSupByToolChain;
217 }
218
219 String[] archList = archSet.toArray(new String[archSet.size()]);
220
221 //
222 // Judge if arch is all supported by current module. If not, throw Exception.
223 //
224 List moduleSupportedArchs = SurfaceAreaQuery.getModuleSupportedArchs();
225 if (moduleSupportedArchs != null) {
226 for (int k = 0; k < archList.length; k++) {
227 if ( ! moduleSupportedArchs.contains(archList[k])) {
228 throw new BuildException("Specified architecture [" + archList[k] + "] is not supported by " + moduleId + ". The module " + moduleId + " only supports [" + moduleSupportedArchs + "] architectures.");
229 }
230 }
231 }
232
233 for (int k = 0; k < archList.length; k++) {
234
235 PropertyManager.setProperty("ARCH", archList[k]);
236
237 FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, archList[k]);
238
239 //
240 // Whether the module is built before
241 //
242 if (moduleId.isLibrary() == false && GlobalData.hasFpdModuleSA(fpdModuleId) == false) {
243 System.out.println("\nWARNING: " + moduleId + " for " + archList[k] + " was not found in current platform FPD file!\n");
244 continue;
245 } else if (GlobalData.isModuleBuilt(fpdModuleId)) {
246 break;
247 } else {
248 GlobalData.registerBuiltModule(fpdModuleId);
249 }
250
251 //
252 // For Every TOOLCHAIN, TARGET
253 //
254 String[] targetList = GlobalData.getToolChainInfo().getTargets();
255 for (int i = 0; i < targetList.length; i ++){
256 //
257 // Prepare for target related common properties
258 // TARGET
259 //
260 PropertyManager.setProperty("TARGET", targetList[i]);
261 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
262 for(int j = 0; j < toolchainList.length; j ++){
263 //
264 // check if any tool is defined for current target + toolchain + arch
265 // don't do anything if no tools found
266 //
267 if (GlobalData.isCommandSet(targetList[i], toolchainList[j], archList[k]) == false) {
268 System.out.println("Warning: No build issued. No tools were found for [target=" + targetList[i] + " toolchain=" + toolchainList[j] + " arch=" + archList[k] + "]\n");
269 continue;
270 }
271
272 //
273 // Prepare for toolchain related common properties
274 // TOOLCHAIN
275 //
276 PropertyManager.setProperty("TOOLCHAIN", toolchainList[j]);
277
278 System.out.println("Build " + moduleId + " start >>>");
279 System.out.println("Target: " + targetList[i] + " Tagname: " + toolchainList[j] + " Arch: " + archList[k]);
280 SurfaceAreaQuery.setDoc(GlobalData.getDoc(fpdModuleId));
281
282 //
283 // Prepare for all other common properties
284 // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
285 // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE
286 // MODULE_DIR, MODULE_RELATIVE_DIR
287 // SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH
288 //
289 setModuleCommonProperties(archList[k]);
290
291 //
292 // OutputManage prepare for
293 // BIN_DIR, DEST_DIR_DEBUG, DEST_DIR_OUTPUT, BUILD_DIR, FV_DIR
294 //
295 OutputManager.getInstance().update(getProject());
296
297 if (type.equalsIgnoreCase("all") || type.equalsIgnoreCase("build")) {
298 applyBuild(targetList[i], toolchainList[j], fpdModuleId);
299 } else if (type.equalsIgnoreCase("clean")) {
300 applyClean(fpdModuleId);
301 } else if (type.equalsIgnoreCase("cleanall")) {
302 applyCleanall(fpdModuleId);
303 }
304 }
305 }
306 }
307
308 PropertyManager.restore();
309 }
310
311 /**
312 This method is used to prepare Platform-related information.
313
314 <p>In Single Module Build mode, platform-related information is not ready.
315 The method read the system environment variable <code>ACTIVE_PLATFORM</code>
316 and search in the Framework Database. Note that platform name in the Framework
317 Database must be unique. </p>
318
319 **/
320 private void prepareSingleModuleBuild(){
321 //
322 // Find out the package which the module belongs to
323 // TBD: Enhance it!!!!
324 //
325 PackageIdentification packageId = GlobalData.getPackageForModule(moduleId);
326
327 moduleId.setPackage(packageId);
328
329 //
330 // Read ACTIVE_PLATFORM's FPD file
331 //
332 String filename = getProject().getProperty("PLATFORM_FILE");
333
334 if (filename == null){
335 throw new BuildException("Please set ACTIVE_PLATFORM in the file: Tools/Conf/target.txt if you want to build a single module!");
336 }
337
338 PlatformIdentification platformId = GlobalData.getPlatform(filename);
339
340 //
341 // Read FPD file (Call FpdParserTask's method)
342 //
343 FpdParserTask fpdParser = new FpdParserTask();
344 fpdParser.setProject(getProject());
345 fpdParser.parseFpdFile(platformId.getFpdFile());
346
347 //
348 // Prepare for Platform related common properties
349 // PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR
350 //
351 PropertyManager.setProperty("PLATFORM", platformId.getName());
352 PropertyManager.setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));
353 PropertyManager.setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));
354 }
355
356
357 /**
358 Set Module-Related information to properties.
359
360 @param arch current build ARCH
361 **/
362 private void setModuleCommonProperties(String arch) {
363 //
364 // Prepare for all other common properties
365 // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
366 //
367 PackageIdentification packageId = moduleId.getPackage();
368 PropertyManager.setProperty("PACKAGE", packageId.getName());
369 PropertyManager.setProperty("PACKAGE_GUID", packageId.getGuid());
370 PropertyManager.setProperty("PACKAGE_VERSION", packageId.getVersion());
371 PropertyManager.setProperty("PACKAGE_DIR", packageId.getPackageDir().replaceAll("(\\\\)", "/"));
372 PropertyManager.setProperty("PACKAGE_RELATIVE_DIR", packageId.getPackageRelativeDir().replaceAll("(\\\\)", "/"));
373
374 //
375 // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE
376 // MODULE_DIR, MODULE_RELATIVE_DIR
377 //
378 PropertyManager.setProperty("MODULE", moduleId.getName());
379 String baseName = SurfaceAreaQuery.getModuleOutputFileBasename();
380 if (baseName == null) {
381 PropertyManager.setProperty("BASE_NAME", moduleId.getName());
382 } else {
383 PropertyManager.setProperty("BASE_NAME", baseName);
384 }
385 PropertyManager.setProperty("GUID", moduleId.getGuid());
386 PropertyManager.setProperty("FILE_GUID", moduleId.getGuid());
387 PropertyManager.setProperty("VERSION", moduleId.getVersion());
388 PropertyManager.setProperty("MODULE_TYPE", moduleId.getModuleType());
389 PropertyManager.setProperty("MODULE_DIR", moduleId.getMsaFile().getParent().replaceAll("(\\\\)", "/"));
390 PropertyManager.setProperty("MODULE_RELATIVE_DIR", moduleId.getModuleRelativePath().replaceAll("(\\\\)", "/"));
391
392 //
393 // SUBSYSTEM
394 //
395 String[][] subsystemMap = { { "BASE", "EFI_BOOT_SERVICE_DRIVER"},
396 { "SEC", "EFI_BOOT_SERVICE_DRIVER" },
397 { "PEI_CORE", "EFI_BOOT_SERVICE_DRIVER" },
398 { "PEIM", "EFI_BOOT_SERVICE_DRIVER" },
399 { "DXE_CORE", "EFI_BOOT_SERVICE_DRIVER" },
400 { "DXE_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
401 { "DXE_RUNTIME_DRIVER", "EFI_RUNTIME_DRIVER" },
402 { "DXE_SAL_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
403 { "DXE_SMM_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
404 { "TOOL", "EFI_BOOT_SERVICE_DRIVER" },
405 { "UEFI_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
406 { "UEFI_APPLICATION", "EFI_APPLICATION" },
407 { "USER_DEFINED", "EFI_BOOT_SERVICE_DRIVER"} };
408
409 String subsystem = "EFI_BOOT_SERVICE_DRIVER";
410 for (int i = 0; i < subsystemMap.length; i++) {
411 if (moduleId.getModuleType().equalsIgnoreCase(subsystemMap[i][0])) {
412 subsystem = subsystemMap[i][1];
413 break ;
414 }
415 }
416 PropertyManager.setProperty("SUBSYSTEM", subsystem);
417
418 //
419 // ENTRYPOINT
420 //
421 if (arch.equalsIgnoreCase("EBC")) {
422 PropertyManager.setProperty("ENTRYPOINT", "EfiStart");
423 } else {
424 PropertyManager.setProperty("ENTRYPOINT", "_ModuleEntryPoint");
425 }
426
427 PropertyManager.setProperty("OBJECTS", "");
428 }
429
430 private void getCompilerFlags(String target, String toolchain, FpdModuleIdentification fpdModuleId) throws EdkException {
431 String[] cmd = GlobalData.getToolChainInfo().getCommands();
432 for ( int m = 0; m < cmd.length; m++) {
433 //
434 // Set cmd, like CC, DLINK
435 //
436 String[] key = new String[]{target, toolchain, fpdModuleId.getArch(), cmd[m], null};
437 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_PATH;
438 String cmdPath = GlobalData.getCommandSetting(key, fpdModuleId);
439 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_NAME;
440 String cmdName = GlobalData.getCommandSetting(key, fpdModuleId);
441 File cmdFile = new File(cmdPath + File.separatorChar + cmdName);
442 PropertyManager.setProperty(cmd[m], cmdFile.getPath().replaceAll("(\\\\)", "/"));
443
444 //
445 // set CC_FLAGS
446 //
447 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS;
448 String cmdFlags = GlobalData.getCommandSetting(key, fpdModuleId);
449 Set<String> addset = new LinkedHashSet<String>();
450 Set<String> subset = new LinkedHashSet<String>();
451 putFlagsToSet(addset, cmdFlags);
452 PropertyManager.setProperty(cmd[m] + "_FLAGS", getProject().replaceProperties(getFlags(addset, subset)));
453
454 //
455 // Set CC_EXT
456 //
457 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_EXT;
458 String extName = GlobalData.getCommandSetting(key, fpdModuleId);
459 if ( extName != null && ! extName.equalsIgnoreCase("")) {
460 PropertyManager.setProperty(cmd[m] + "_EXT", extName);
461 } else {
462 PropertyManager.setProperty(cmd[m] + "_EXT", "");
463 }
464
465 //
466 // set CC_FAMILY
467 //
468 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FAMILY;
469 String toolChainFamily = GlobalData.getCommandSetting(key, fpdModuleId);
470 if (toolChainFamily != null) {
471 PropertyManager.setProperty(cmd[m] + "_FAMILY", toolChainFamily);
472 }
473
474 //
475 // set CC_SPATH
476 //
477 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_SPATH;
478 String spath = GlobalData.getCommandSetting(key, fpdModuleId);
479 if (spath != null) {
480 PropertyManager.setProperty(cmd[m] + "_SPATH", spath.replaceAll("(\\\\)", "/"));
481 } else {
482 PropertyManager.setProperty(cmd[m] + "_SPATH", "");
483 }
484
485 //
486 // set CC_DPATH
487 //
488 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_DPATH;
489 String dpath = GlobalData.getCommandSetting(key, fpdModuleId);
490 if (dpath != null) {
491 PropertyManager.setProperty(cmd[m] + "_DPATH", dpath.replaceAll("(\\\\)", "/"));
492 } else {
493 PropertyManager.setProperty(cmd[m] + "_DPATH", "");
494 }
495 }
496 }
497
498 public void setMsaFile(File msaFile) {
499 this.msaFile = msaFile;
500 }
501
502 /**
503 Method is for ANT to initialize MSA file.
504
505 @param msaFilename MSA file name
506 **/
507 public void setMsaFile(String msaFilename) {
508 String moduleDir = getProject().getProperty("MODULE_DIR");
509
510 //
511 // If is Single Module Build, then use the Base Dir defined in build.xml
512 //
513 if (moduleDir == null) {
514 moduleDir = getProject().getBaseDir().getPath();
515 }
516 msaFile = new File(moduleDir + File.separatorChar + msaFilename);
517 }
518
519 public void addConfiguredModuleItem(ModuleItem moduleItem) {
520 PackageIdentification packageId = new PackageIdentification(moduleItem.getPackageGuid(), moduleItem.getPackageVersion());
521 ModuleIdentification moduleId = new ModuleIdentification(moduleItem.getModuleGuid(), moduleItem.getModuleVersion());
522 moduleId.setPackage(packageId);
523 this.moduleId = moduleId;
524 }
525
526 /**
527 Add a property.
528
529 @param p property
530 **/
531 public void addProperty(Property p) {
532 properties.addElement(p);
533 }
534
535 public void setType(String type) {
536 this.type = type;
537 }
538
539 private void applyBuild(String buildTarget, String buildTagname, FpdModuleIdentification fpdModuleId) throws BuildException{
540 //
541 // AutoGen
542 //
543
544 AutoGen autogen = new AutoGen(getProject().getProperty("FV_DIR"), getProject().getProperty("DEST_DIR_DEBUG"), fpdModuleId.getModule(),fpdModuleId.getArch());
545 autogen.genAutogen();
546
547
548 //
549 // Get compiler flags
550 //
551 try {
552 getCompilerFlags(buildTarget, buildTagname, fpdModuleId);
553 }
554 catch (EdkException ee) {
555 throw new BuildException(ee.getMessage());
556 }
557
558 //
559 // Prepare LIBS
560 //
561 ModuleIdentification[] libinstances = SurfaceAreaQuery.getLibraryInstance(fpdModuleId.getArch());
562 String propertyLibs = "";
563 for (int i = 0; i < libinstances.length; i++) {
564 propertyLibs += " " + getProject().getProperty("BIN_DIR") + File.separatorChar + libinstances[i].getName() + ".lib";
565 }
566 PropertyManager.setProperty("LIBS", propertyLibs.replaceAll("(\\\\)", "/"));
567
568 //
569 // Get all includepath and set to INCLUDE_PATHS
570 //
571 String[] includes = prepareIncludePaths(fpdModuleId);
572
573 //
574 // if it is CUSTOM_BUILD
575 // then call the exist BaseName_build.xml directly.
576 //
577 if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
578 System.out.println("Call user-defined " + moduleId.getName() + "_build.xml");
579
580 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";
581 antCall(antFilename, null);
582
583 return ;
584 }
585
586 //
587 // Generate ${BASE_NAME}_build.xml
588 // TBD
589 //
590 String ffsKeyword = SurfaceAreaQuery.getModuleFfsKeyword();
591 ModuleBuildFileGenerator fileGenerator = new ModuleBuildFileGenerator(getProject(), ffsKeyword, fpdModuleId, includes);
592 String buildFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";
593 fileGenerator.genBuildFile(buildFilename);
594
595 //
596 // Ant call ${BASE_NAME}_build.xml
597 //
598 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";
599 antCall(antFilename, null);
600 }
601
602 private void applyClean(FpdModuleIdentification fpdModuleId){
603 //
604 // if it is CUSTOM_BUILD
605 // then call the exist BaseName_build.xml directly.
606 //
607 if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
608 System.out.println("Calling user-defined " + moduleId.getName() + "_build.xml");
609
610 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";
611 antCall(antFilename, "clean");
612
613 return ;
614 }
615
616 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";
617 antCall(antFilename, "clean");
618 }
619
620 private void applyCleanall(FpdModuleIdentification fpdModuleId){
621 //
622 // if it is CUSTOM_BUILD
623 // then call the exist BaseName_build.xml directly.
624 //
625 if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
626 System.out.println("Calling user-defined " + moduleId.getName() + "_build.xml");
627
628 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";
629 antCall(antFilename, "cleanall");
630
631 return ;
632 }
633
634 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";
635 antCall(antFilename, "cleanall");
636 }
637
638 private void antCall(String antFilename, String target) {
639 Ant ant = new Ant();
640 ant.setProject(getProject());
641 ant.setAntfile(antFilename);
642 if (target != null) {
643 ant.setTarget(target);
644 }
645 ant.setInheritAll(true);
646 ant.init();
647 ant.execute();
648 }
649
650
651 /**
652 Separate the string and instore in set.
653
654 <p> String is separated by Java Regulation Expression
655 "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>
656
657 <p>For example: </p>
658
659 <pre>
660 "/nologo", "/W3", "/WX"
661 "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""
662 </pre>
663
664 @param set store the separated string
665 @param str string to separate
666 **/
667 private void putFlagsToSet(Set<String> set, String str) {
668 if (str == null || str.length() == 0) {
669 return;
670 }
671
672 Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");
673 Matcher matcher = myPattern.matcher(str + " ");
674 while (matcher.find()) {
675 String item = str.substring(matcher.start(1), matcher.end(1));
676 set.add(item);
677 }
678 }
679
680 /**
681 Generate the final flags string will be used by compile command.
682
683 @param add the add flags set
684 @param sub the sub flags set
685 @return final flags after add set substract sub set
686 **/
687 private String getFlags(Set<String> add, Set<String> sub) {
688 String result = "";
689 add.removeAll(sub);
690 Iterator iter = add.iterator();
691 while (iter.hasNext()) {
692 String str = (String) iter.next();
693 result += str.substring(1, str.length() - 1) + " ";
694 }
695 return result;
696 }
697
698 public void setSingleModuleBuild(boolean isSingleModuleBuild) {
699 this.isSingleModuleBuild = isSingleModuleBuild;
700 }
701
702 private String[] prepareIncludePaths(FpdModuleIdentification fpdModuleId) {
703 //
704 // Prepare the includes: PackageDependencies and Output debug direactory
705 //
706 Set<String> includes = new LinkedHashSet<String>();
707 String arch = fpdModuleId.getArch();
708
709 //
710 // WORKSPACE
711 //
712 includes.add("${WORKSPACE_DIR}" + File.separatorChar);
713
714 //
715 // Module iteself
716 //
717 includes.add("${MODULE_DIR}");
718 includes.add("${MODULE_DIR}" + File.separatorChar + archDir(arch));
719
720 //
721 // Packages in PackageDenpendencies
722 //
723 PackageIdentification[] packageDependencies = SurfaceAreaQuery.getDependencePkg(fpdModuleId.getArch());
724 for (int i = 0; i < packageDependencies.length; i++) {
725 GlobalData.refreshPackageIdentification(packageDependencies[i]);
726 File packageFile = packageDependencies[i].getSpdFile();
727 includes.add(packageFile.getParent() + File.separatorChar + "Include");
728 includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));
729 }
730
731 //
732 // All Dependency Library Instance's PackageDependencies
733 //
734 ModuleIdentification[] libinstances = SurfaceAreaQuery.getLibraryInstance(fpdModuleId.getArch());
735 for (int i = 0; i < libinstances.length; i++) {
736 SurfaceAreaQuery.push(GlobalData.getDoc(libinstances[i], fpdModuleId.getArch()));
737 PackageIdentification[] libraryPackageDependencies = SurfaceAreaQuery.getDependencePkg(fpdModuleId.getArch());
738 for (int j = 0; j < libraryPackageDependencies.length; j++) {
739 GlobalData.refreshPackageIdentification(libraryPackageDependencies[j]);
740 File packageFile = libraryPackageDependencies[j].getSpdFile();
741 includes.add(packageFile.getParent() + File.separatorChar + "Include");
742 includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));
743 }
744 SurfaceAreaQuery.pop();
745 }
746
747
748 //
749 // The package which the module belongs to
750 // TBD
751 includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include");
752 includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));
753
754 //
755 // Debug files output directory
756 //
757 includes.add("${DEST_DIR_DEBUG}");
758
759 //
760 // set to INCLUDE_PATHS property
761 //
762 Iterator<String> iter = includes.iterator();
763 StringBuffer includePaths = new StringBuffer();
764 while (iter.hasNext()) {
765 includePaths.append(iter.next());
766 includePaths.append("; ");
767 }
768 PropertyManager.setProperty("INCLUDE_PATHS", getProject().replaceProperties(includePaths.toString()).replaceAll("(\\\\)", "/"));
769
770 return includes.toArray(new String[includes.size()]);
771 }
772
773 /**
774 Return the name of the directory that corresponds to the architecture.
775 This is a translation from the XML Schema tag to a directory that
776 corresponds to our directory name coding convention.
777
778 **/
779 private String archDir(String arch) {
780 return arch.replaceFirst("X64", "x64")
781 .replaceFirst("IPF", "Ipf")
782 .replaceFirst("IA32", "Ia32")
783 .replaceFirst("ARM", "Arm")
784 .replaceFirst("EBC", "Ebc");
785 }
786 }