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