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