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