1.modify the usage info
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / GenBuildTask.java
CommitLineData
878ddf1f 1/** @file\r
ff225cbb 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
878ddf1f 5 ANT script build.xml, then call the the ANT script to build the module.\r
ff225cbb 6\r
878ddf1f 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
aca6c736 19import java.util.Hashtable;\r
878ddf1f 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
878ddf1f 29import org.apache.tools.ant.BuildException;\r
aca6c736 30import org.apache.tools.ant.BuildListener;\r
31import org.apache.tools.ant.Project;\r
878ddf1f 32import org.apache.tools.ant.taskdefs.Ant;\r
a29c47e0 33import org.apache.tools.ant.taskdefs.Property;\r
878ddf1f 34import org.apache.xmlbeans.XmlObject;\r
878ddf1f 35\r
4a6a5026 36import org.tianocore.common.definitions.ToolDefinitions;\r
ff225cbb 37import org.tianocore.common.exception.EdkException;\r
91f7d582 38import org.tianocore.common.logger.EdkLog;\r
136adffc 39import org.tianocore.build.autogen.AutoGen;\r
878ddf1f 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
a29c47e0 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
878ddf1f 49\r
50/**\r
51 <p>\r
52 <code>GenBuildTask</code> is an ANT task that can be used in ANT build\r
4a6a5026 53 system. \r
54 \r
55 <p>The main function of this task is to parse module's surface area (MSA),\r
878ddf1f 56 then generate the corresponding <em>BaseName_build.xml</em> (the real ANT\r
a29c47e0 57 build script) and call this to build the module. The whole process including:\r
4b5f5549 58 \r
2d16dcec 59 <pre>\r
4a6a5026 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
ff225cbb 64 5. generate FFS file if it is driver module while LIB file if it is Library module.\r
2d16dcec 65 </pre>\r
66\r
ff225cbb 67\r
878ddf1f 68 <p>\r
69 The usage is (take module <em>HelloWorld</em> for example):\r
70 </p>\r
ff225cbb 71\r
878ddf1f 72 <pre>\r
4b5f5549 73 &lt;GenBuild \r
74 msaFile="${PACKAGE_DIR}/Application/HelloWorld/HelloWorld.msa"\r
75 type="cleanall" /&gt;\r
878ddf1f 76 </pre>\r
ff225cbb 77\r
878ddf1f 78 <p>\r
79 This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and\r
4b5f5549 80 <em>AutoGen.h</em>. \r
878ddf1f 81 </p>\r
ff225cbb 82\r
4b5f5549 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
878ddf1f 93 @since GenBuild 1.0\r
94**/\r
a29c47e0 95public class GenBuildTask extends Ant {\r
ff225cbb 96\r
878ddf1f 97 ///\r
98 /// Module surface area file.\r
99 ///\r
a29c47e0 100 File msaFile;\r
19bf6b15 101 \r
102 public ModuleIdentification parentId;\r
103 \r
82516887 104 private String type = "all"; \r
105 \r
878ddf1f 106 ///\r
a29c47e0 107 /// Module's Identification.\r
878ddf1f 108 ///\r
a29c47e0 109 private ModuleIdentification moduleId;\r
878ddf1f 110\r
a29c47e0 111 private Vector<Property> properties = new Vector<Property>();\r
de4bb9f6 112\r
de4bb9f6 113 private boolean isSingleModuleBuild = false;\r
83fba802 114 \r
115 private SurfaceAreaQuery saq = null;\r
ff225cbb 116\r
878ddf1f 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
ff225cbb 124\r
878ddf1f 125 @throws BuildException\r
126 From module build, exception from module surface area invalid.\r
127 **/\r
128 public void execute() throws BuildException {\r
aca6c736 129 if (!FrameworkBuildTask.multithread) {\r
130 cleanupProperties();\r
131 }\r
82516887 132\r
878ddf1f 133 //\r
a29c47e0 134 // Enable all specified properties\r
878ddf1f 135 //\r
a29c47e0 136 Iterator<Property> iter = properties.iterator();\r
137 while (iter.hasNext()) {\r
138 Property item = iter.next();\r
aca6c736 139 getProject().setProperty(item.getName(), item.getValue());\r
878ddf1f 140 }\r
ff225cbb 141\r
878ddf1f 142 //\r
a29c47e0 143 // GenBuild should specify either msaFile or moduleGuid & packageGuid\r
878ddf1f 144 //\r
a29c47e0 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
391dbbb1 151 throw new BuildException("GenBuild parameter error.");\r
878ddf1f 152 }\r
a29c47e0 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
83fba802 157 saq = new SurfaceAreaQuery(doc);\r
158 moduleId = saq.getMsaHeader();\r
82516887 159 } else {\r
a29c47e0 160 Map<String, XmlObject> doc = GlobalData.getNativeMsa(msaFile);\r
83fba802 161 saq = new SurfaceAreaQuery(doc);\r
162 moduleId = saq.getMsaHeader();\r
878ddf1f 163 }\r
83fba802 164 String[] producedLibraryClasses = saq.getLibraryClasses("ALWAYS_PRODUCED",null);\r
a29c47e0 165 if (producedLibraryClasses.length == 0) {\r
166 moduleId.setLibrary(false);\r
82516887 167 } else {\r
a29c47e0 168 moduleId.setLibrary(true);\r
878ddf1f 169 }\r
ff225cbb 170\r
878ddf1f 171 //\r
a29c47e0 172 // Judge whether it is single module build or not\r
878ddf1f 173 //\r
de4bb9f6 174 if (isSingleModuleBuild) {\r
878ddf1f 175 //\r
a29c47e0 176 // Single Module build\r
878ddf1f 177 //\r
a29c47e0 178 prepareSingleModuleBuild();\r
82516887 179 } else {\r
a29c47e0 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
878ddf1f 184 }\r
ff225cbb 185\r
a29c47e0 186 //\r
82516887 187 // If single module : get arch from pass down, otherwise intersection MSA \r
188 // supported ARCHs and tools def\r
a29c47e0 189 //\r
ff225cbb 190 Set<String> archListSupByToolChain = new LinkedHashSet<String>();\r
191 String[] archs = GlobalData.getToolChainInfo().getArchs();\r
192\r
3c696250 193 for (int i = 0; i < archs.length; i ++) {\r
194 archListSupByToolChain.add(archs[i]);\r
195 }\r
ff225cbb 196\r
3c696250 197 Set<String> archSet = new LinkedHashSet<String>();\r
ff225cbb 198\r
3c696250 199 if ( getProject().getProperty("ARCH") != null) {\r
200 String[] fpdArchList = getProject().getProperty("ARCH").split(" ");\r
ff225cbb 201\r
3c696250 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
82516887 207 } else {\r
208 archSet = archListSupByToolChain; \r
3c696250 209 }\r
ff225cbb 210\r
3c696250 211 String[] archList = archSet.toArray(new String[archSet.size()]);\r
ff225cbb 212\r
a29c47e0 213 //\r
214 // Judge if arch is all supported by current module. If not, throw Exception.\r
215 //\r
83fba802 216 List moduleSupportedArchs = saq.getModuleSupportedArchs();\r
a29c47e0 217 if (moduleSupportedArchs != null) {\r
218 for (int k = 0; k < archList.length; k++) {\r
219 if ( ! moduleSupportedArchs.contains(archList[k])) {\r
391dbbb1 220 throw new BuildException("Specified architecture [" + archList[k] + "] is not supported by " + moduleId + ". The module " + moduleId + " only supports [" + moduleSupportedArchs + "] architectures.");\r
a29c47e0 221 }\r
222 }\r
878ddf1f 223 }\r
ff225cbb 224\r
a29c47e0 225 for (int k = 0; k < archList.length; k++) {\r
ff225cbb 226\r
aca6c736 227 getProject().setProperty("ARCH", archList[k]);\r
ff225cbb 228\r
a29c47e0 229 FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, archList[k]);\r
ff225cbb 230\r
878ddf1f 231 //\r
a29c47e0 232 // Whether the module is built before\r
878ddf1f 233 //\r
34281092 234 if (moduleId.isLibrary() == false && GlobalData.hasFpdModuleSA(fpdModuleId) == false) {\r
91f7d582 235 EdkLog.log(this, EdkLog.EDK_WARNING, "Warning: " + moduleId + " for " + archList[k] + " was not found in current platform FPD file!\n");\r
34281092 236 continue;\r
237 } else if (GlobalData.isModuleBuilt(fpdModuleId)) {\r
1fa1cb75 238 break;\r
34281092 239 } else {\r
a29c47e0 240 GlobalData.registerBuiltModule(fpdModuleId);\r
241 }\r
ff225cbb 242\r
878ddf1f 243 //\r
a29c47e0 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
aca6c736 252 getProject().setProperty("TARGET", targetList[i]);\r
a29c47e0 253 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
254 for(int j = 0; j < toolchainList.length; j ++){\r
c773bec0 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
ff225cbb 258 //\r
c773bec0 259 if (GlobalData.isCommandSet(targetList[i], toolchainList[j], archList[k]) == false) {\r
91f7d582 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
c773bec0 261 continue;\r
262 }\r
263\r
a29c47e0 264 //\r
265 // Prepare for toolchain related common properties\r
266 // TOOLCHAIN\r
267 //\r
aca6c736 268 getProject().setProperty("TOOLCHAIN", toolchainList[j]);\r
a29c47e0 269\r
91f7d582 270 EdkLog.log(this, "Build " + moduleId + " start >>>");\r
271 EdkLog.log(this, "Target: " + targetList[i] + " Tagname: " + toolchainList[j] + " Arch: " + archList[k]);\r
83fba802 272 saq.push(GlobalData.getDoc(fpdModuleId));\r
ff225cbb 273\r
a29c47e0 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
a29c47e0 280 //\r
281 setModuleCommonProperties(archList[k]);\r
ff225cbb 282\r
a29c47e0 283 //\r
ff225cbb 284 // OutputManage prepare for\r
a29c47e0 285 // BIN_DIR, DEST_DIR_DEBUG, DEST_DIR_OUTPUT, BUILD_DIR, FV_DIR\r
286 //\r
287 OutputManager.getInstance().update(getProject());\r
ff225cbb 288\r
a29c47e0 289 if (type.equalsIgnoreCase("all") || type.equalsIgnoreCase("build")) {\r
290 applyBuild(targetList[i], toolchainList[j], fpdModuleId);\r
82516887 291 } else if (type.equalsIgnoreCase("clean")) {\r
a29c47e0 292 applyClean(fpdModuleId);\r
82516887 293 } else if (type.equalsIgnoreCase("cleanall")) {\r
a29c47e0 294 applyCleanall(fpdModuleId);\r
295 }\r
296 }\r
297 }\r
878ddf1f 298 }\r
878ddf1f 299 }\r
300\r
301 /**\r
ff225cbb 302 This method is used to prepare Platform-related information.\r
303\r
a29c47e0 304 <p>In Single Module Build mode, platform-related information is not ready.\r
ff225cbb 305 The method read the system environment variable <code>ACTIVE_PLATFORM</code>\r
a29c47e0 306 and search in the Framework Database. Note that platform name in the Framework\r
307 Database must be unique. </p>\r
ff225cbb 308\r
878ddf1f 309 **/\r
a29c47e0 310 private void prepareSingleModuleBuild(){\r
878ddf1f 311 //\r
a29c47e0 312 // Find out the package which the module belongs to\r
313 // TBD: Enhance it!!!!\r
878ddf1f 314 //\r
a29c47e0 315 PackageIdentification packageId = GlobalData.getPackageForModule(moduleId);\r
ff225cbb 316\r
a29c47e0 317 moduleId.setPackage(packageId);\r
ff225cbb 318\r
878ddf1f 319 //\r
82516887 320 // Read ACTIVE_PLATFORM's FPD file \r
878ddf1f 321 //\r
de4bb9f6 322 String filename = getProject().getProperty("PLATFORM_FILE");\r
ff225cbb 323\r
de4bb9f6 324 if (filename == null){\r
391dbbb1 325 throw new BuildException("Please set ACTIVE_PLATFORM in the file: Tools/Conf/target.txt if you want to build a single module!");\r
878ddf1f 326 }\r
ff225cbb 327\r
de4bb9f6 328 PlatformIdentification platformId = GlobalData.getPlatform(filename);\r
ff225cbb 329\r
878ddf1f 330 //\r
82516887 331 // Read FPD file (Call FpdParserTask's method)\r
878ddf1f 332 //\r
a29c47e0 333 FpdParserTask fpdParser = new FpdParserTask();\r
334 fpdParser.setProject(getProject());\r
07193171 335 fpdParser.parseFpdFile(platformId.getFpdFile());\r
aca6c736 336 getProject().setProperty("ARCH", fpdParser.getAllArchForModule(moduleId));\r
878ddf1f 337 }\r
338\r
aca6c736 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
878ddf1f 360\r
361 /**\r
a29c47e0 362 Set Module-Related information to properties.\r
82516887 363 \r
364 @param arch current build ARCH\r
878ddf1f 365 **/\r
a29c47e0 366 private void setModuleCommonProperties(String arch) {\r
878ddf1f 367 //\r
a29c47e0 368 // Prepare for all other common properties\r
369 // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR\r
878ddf1f 370 //\r
a29c47e0 371 PackageIdentification packageId = moduleId.getPackage();\r
aca6c736 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
ff225cbb 377\r
a29c47e0 378 //\r
379 // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE\r
380 // MODULE_DIR, MODULE_RELATIVE_DIR\r
381 //\r
aca6c736 382 getProject().setProperty("MODULE", moduleId.getName());\r
83fba802 383 String baseName = saq.getModuleOutputFileBasename();\r
a29c47e0 384 if (baseName == null) {\r
aca6c736 385 getProject().setProperty("BASE_NAME", moduleId.getName());\r
82516887 386 } else {\r
aca6c736 387 getProject().setProperty("BASE_NAME", baseName);\r
a29c47e0 388 }\r
aca6c736 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
ff225cbb 395\r
a29c47e0 396 //\r
397 // SUBSYSTEM\r
398 //\r
399 String[][] subsystemMap = { { "BASE", "EFI_BOOT_SERVICE_DRIVER"},\r
ff225cbb 400 { "SEC", "EFI_BOOT_SERVICE_DRIVER" },\r
401 { "PEI_CORE", "EFI_BOOT_SERVICE_DRIVER" },\r
402 { "PEIM", "EFI_BOOT_SERVICE_DRIVER" },\r
a29c47e0 403 { "DXE_CORE", "EFI_BOOT_SERVICE_DRIVER" },\r
ff225cbb 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
a29c47e0 409 { "UEFI_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
ff225cbb 410 { "UEFI_APPLICATION", "EFI_APPLICATION" },\r
411 { "USER_DEFINED", "EFI_BOOT_SERVICE_DRIVER"} };\r
412\r
a29c47e0 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
878ddf1f 418 }\r
419 }\r
aca6c736 420 getProject().setProperty("SUBSYSTEM", subsystem);\r
ff225cbb 421\r
a29c47e0 422 //\r
423 // ENTRYPOINT\r
424 //\r
425 if (arch.equalsIgnoreCase("EBC")) {\r
aca6c736 426 getProject().setProperty("ENTRYPOINT", "EfiStart");\r
82516887 427 } else {\r
aca6c736 428 getProject().setProperty("ENTRYPOINT", "_ModuleEntryPoint");\r
878ddf1f 429 }\r
ff225cbb 430\r
aca6c736 431 getProject().setProperty("OBJECTS", "");\r
878ddf1f 432 }\r
433\r
a29c47e0 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
878ddf1f 437 //\r
a29c47e0 438 // Set cmd, like CC, DLINK\r
878ddf1f 439 //\r
a29c47e0 440 String[] key = new String[]{target, toolchain, fpdModuleId.getArch(), cmd[m], null};\r
4a6a5026 441 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_PATH;\r
a29c47e0 442 String cmdPath = GlobalData.getCommandSetting(key, fpdModuleId);\r
4a6a5026 443 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_NAME;\r
a29c47e0 444 String cmdName = GlobalData.getCommandSetting(key, fpdModuleId);\r
445 File cmdFile = new File(cmdPath + File.separatorChar + cmdName);\r
aca6c736 446 getProject().setProperty(cmd[m], cmdFile.getPath().replaceAll("(\\\\)", "/"));\r
ff225cbb 447\r
878ddf1f 448 //\r
a29c47e0 449 // set CC_FLAGS\r
878ddf1f 450 //\r
4a6a5026 451 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS;\r
a29c47e0 452 String cmdFlags = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 453 Set<String> addset = new LinkedHashSet<String>();\r
454 Set<String> subset = new LinkedHashSet<String>();\r
455 putFlagsToSet(addset, cmdFlags);\r
aca6c736 456 getProject().setProperty(cmd[m] + "_FLAGS", getProject().replaceProperties(getFlags(addset, subset)));\r
ff225cbb 457\r
878ddf1f 458 //\r
a29c47e0 459 // Set CC_EXT\r
878ddf1f 460 //\r
4a6a5026 461 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_EXT;\r
a29c47e0 462 String extName = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 463 if ( extName != null && ! extName.equalsIgnoreCase("")) {\r
aca6c736 464 getProject().setProperty(cmd[m] + "_EXT", extName);\r
82516887 465 } else {\r
aca6c736 466 getProject().setProperty(cmd[m] + "_EXT", "");\r
878ddf1f 467 }\r
ff225cbb 468\r
878ddf1f 469 //\r
a29c47e0 470 // set CC_FAMILY\r
878ddf1f 471 //\r
4a6a5026 472 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FAMILY;\r
a29c47e0 473 String toolChainFamily = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 474 if (toolChainFamily != null) {\r
aca6c736 475 getProject().setProperty(cmd[m] + "_FAMILY", toolChainFamily);\r
878ddf1f 476 }\r
ff225cbb 477\r
878ddf1f 478 //\r
a29c47e0 479 // set CC_SPATH\r
878ddf1f 480 //\r
4a6a5026 481 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_SPATH;\r
a29c47e0 482 String spath = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 483 if (spath != null) {\r
aca6c736 484 getProject().setProperty(cmd[m] + "_SPATH", spath.replaceAll("(\\\\)", "/"));\r
82516887 485 } else {\r
aca6c736 486 getProject().setProperty(cmd[m] + "_SPATH", "");\r
878ddf1f 487 }\r
ff225cbb 488\r
878ddf1f 489 //\r
a29c47e0 490 // set CC_DPATH\r
878ddf1f 491 //\r
4a6a5026 492 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_DPATH;\r
a29c47e0 493 String dpath = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 494 if (dpath != null) {\r
aca6c736 495 getProject().setProperty(cmd[m] + "_DPATH", dpath.replaceAll("(\\\\)", "/"));\r
82516887 496 } else {\r
aca6c736 497 getProject().setProperty(cmd[m] + "_DPATH", "");\r
878ddf1f 498 }\r
499 }\r
a29c47e0 500 }\r
ff225cbb 501\r
a29c47e0 502 public void setMsaFile(File msaFile) {\r
503 this.msaFile = msaFile;\r
878ddf1f 504 }\r
505\r
506 /**\r
ff225cbb 507 Method is for ANT to initialize MSA file.\r
508\r
a29c47e0 509 @param msaFilename MSA file name\r
878ddf1f 510 **/\r
a29c47e0 511 public void setMsaFile(String msaFilename) {\r
512 String moduleDir = getProject().getProperty("MODULE_DIR");\r
ff225cbb 513\r
a29c47e0 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
878ddf1f 519 }\r
a29c47e0 520 msaFile = new File(moduleDir + File.separatorChar + msaFilename);\r
521 }\r
ff225cbb 522\r
a29c47e0 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
ff225cbb 529\r
a29c47e0 530 /**\r
ff225cbb 531 Add a property.\r
532\r
a29c47e0 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
ff225cbb 542\r
82516887 543 private void applyBuild(String buildTarget, String buildTagname, FpdModuleIdentification fpdModuleId) throws BuildException{\r
a29c47e0 544 //\r
83fba802 545 // Call AutoGen to generate AutoGen.c and AutoGen.h\r
a29c47e0 546 //\r
83fba802 547 AutoGen autogen = new AutoGen(getProject().getProperty("FV_DIR"), getProject().getProperty("DEST_DIR_DEBUG"), fpdModuleId.getModule(),fpdModuleId.getArch(), saq);\r
136adffc 548 autogen.genAutogen();\r
ff225cbb 549\r
a29c47e0 550 //\r
551 // Get compiler flags\r
552 //\r
82516887 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
a29c47e0 560 //\r
561 // Prepare LIBS\r
562 //\r
83fba802 563 ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());\r
a29c47e0 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
878ddf1f 567 }\r
aca6c736 568 getProject().setProperty("LIBS", propertyLibs.replaceAll("(\\\\)", "/"));\r
ff225cbb 569\r
bf3a7173 570 //\r
571 // Get all includepath and set to INCLUDE_PATHS\r
572 //\r
573 String[] includes = prepareIncludePaths(fpdModuleId);\r
574 \r
a29c47e0 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
91f7d582 580 EdkLog.log(this, "Call user-defined " + moduleId.getName() + "_build.xml");\r
82516887 581 \r
582 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";\r
583 antCall(antFilename, null);\r
584 \r
a29c47e0 585 return ;\r
878ddf1f 586 }\r
ff225cbb 587\r
878ddf1f 588 //\r
a29c47e0 589 // Generate ${BASE_NAME}_build.xml\r
590 // TBD\r
878ddf1f 591 //\r
83fba802 592 String ffsKeyword = saq.getModuleFfsKeyword();\r
593 ModuleBuildFileGenerator fileGenerator = new ModuleBuildFileGenerator(getProject(), ffsKeyword, fpdModuleId, includes, saq);\r
a29c47e0 594 String buildFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
595 fileGenerator.genBuildFile(buildFilename);\r
ff225cbb 596\r
a29c47e0 597 //\r
598 // Ant call ${BASE_NAME}_build.xml\r
599 //\r
82516887 600 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
601 antCall(antFilename, null);\r
a29c47e0 602 }\r
ff225cbb 603\r
a29c47e0 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
91f7d582 610 EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml");\r
82516887 611 \r
612 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";\r
613 antCall(antFilename, "clean");\r
614 \r
a29c47e0 615 return ;\r
878ddf1f 616 }\r
ff225cbb 617\r
82516887 618 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
619 antCall(antFilename, "clean");\r
a29c47e0 620 }\r
ff225cbb 621\r
a29c47e0 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
91f7d582 628 EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml");\r
82516887 629\r
630 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";\r
631 antCall(antFilename, "cleanall");\r
632 \r
a29c47e0 633 return ;\r
878ddf1f 634 }\r
82516887 635 \r
636 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
637 antCall(antFilename, "cleanall");\r
638 }\r
ff225cbb 639\r
82516887 640 private void antCall(String antFilename, String target) {\r
a29c47e0 641 Ant ant = new Ant();\r
642 ant.setProject(getProject());\r
82516887 643 ant.setAntfile(antFilename);\r
644 if (target != null) {\r
645 ant.setTarget(target);\r
646 }\r
a29c47e0 647 ant.setInheritAll(true);\r
648 ant.init();\r
649 ant.execute();\r
878ddf1f 650 }\r
651\r
a29c47e0 652\r
878ddf1f 653 /**\r
654 Separate the string and instore in set.\r
ff225cbb 655\r
656 <p> String is separated by Java Regulation Expression\r
878ddf1f 657 "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>\r
ff225cbb 658\r
878ddf1f 659 <p>For example: </p>\r
ff225cbb 660\r
878ddf1f 661 <pre>\r
662 "/nologo", "/W3", "/WX"\r
663 "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""\r
664 </pre>\r
ff225cbb 665\r
878ddf1f 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
a29c47e0 670 if (str == null || str.length() == 0) {\r
671 return;\r
672 }\r
673\r
878ddf1f 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
a29c47e0 678 set.add(item);\r
878ddf1f 679 }\r
680 }\r
ff225cbb 681\r
878ddf1f 682 /**\r
ff225cbb 683 Generate the final flags string will be used by compile command.\r
684\r
878ddf1f 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
a29c47e0 694 String str = (String) iter.next();\r
878ddf1f 695 result += str.substring(1, str.length() - 1) + " ";\r
696 }\r
697 return result;\r
698 }\r
699\r
de4bb9f6 700 public void setSingleModuleBuild(boolean isSingleModuleBuild) {\r
701 this.isSingleModuleBuild = isSingleModuleBuild;\r
702 }\r
bf3a7173 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
83fba802 725 PackageIdentification[] packageDependencies = saq.getDependencePkg(fpdModuleId.getArch());\r
bf3a7173 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
83fba802 736 ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());\r
bf3a7173 737 for (int i = 0; i < libinstances.length; i++) {\r
83fba802 738 saq.push(GlobalData.getDoc(libinstances[i], fpdModuleId.getArch()));\r
739 PackageIdentification[] libraryPackageDependencies = saq.getDependencePkg(fpdModuleId.getArch());\r
bf3a7173 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
83fba802 746 saq.pop();\r
bf3a7173 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
aca6c736 770 getProject().setProperty("INCLUDE_PATHS", getProject().replaceProperties(includePaths.toString()).replaceAll("(\\\\)", "/"));\r
bf3a7173 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
19bf6b15 787 }\r
788 \r
789 \r
790 public void setExternalProperties(Vector<Property> v) {\r
791 this.properties = v;\r
792 }\r
878ddf1f 793}\r