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