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