add ContextTool to workspace/Tools
[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
ff225cbb 111\r
878ddf1f 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
ff225cbb 119\r
878ddf1f 120 @throws BuildException\r
121 From module build, exception from module surface area invalid.\r
122 **/\r
123 public void execute() throws BuildException {\r
136adffc 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
82516887 130\r
1fa1cb75 131 PropertyManager.setProject(getProject());\r
132 PropertyManager.save();\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
1fa1cb75 139 PropertyManager.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
157 SurfaceAreaQuery.setDoc(doc);\r
158 moduleId = SurfaceAreaQuery.getMsaHeader();\r
82516887 159 } else {\r
a29c47e0 160 Map<String, XmlObject> doc = GlobalData.getNativeMsa(msaFile);\r
161 SurfaceAreaQuery.setDoc(doc);\r
162 moduleId = SurfaceAreaQuery.getMsaHeader();\r
878ddf1f 163 }\r
42b78757 164 String[] producedLibraryClasses = SurfaceAreaQuery.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 //\r
181 // Platform build. Restore the platform related info\r
182 //\r
de4bb9f6 183 String filename = getProject().getProperty("PLATFORM_FILE");\r
184 PlatformIdentification platformId = GlobalData.getPlatform(filename);\r
1fa1cb75 185 PropertyManager.setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));\r
186 PropertyManager.setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));\r
ff225cbb 187\r
a29c47e0 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
878ddf1f 192 }\r
ff225cbb 193\r
a29c47e0 194 //\r
82516887 195 // If single module : get arch from pass down, otherwise intersection MSA \r
196 // supported ARCHs and tools def\r
a29c47e0 197 //\r
ff225cbb 198 Set<String> archListSupByToolChain = new LinkedHashSet<String>();\r
199 String[] archs = GlobalData.getToolChainInfo().getArchs();\r
200\r
3c696250 201 for (int i = 0; i < archs.length; i ++) {\r
202 archListSupByToolChain.add(archs[i]);\r
203 }\r
ff225cbb 204\r
3c696250 205 Set<String> archSet = new LinkedHashSet<String>();\r
ff225cbb 206\r
3c696250 207 if ( getProject().getProperty("ARCH") != null) {\r
208 String[] fpdArchList = getProject().getProperty("ARCH").split(" ");\r
ff225cbb 209\r
3c696250 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
82516887 215 } else {\r
216 archSet = archListSupByToolChain; \r
3c696250 217 }\r
ff225cbb 218\r
3c696250 219 String[] archList = archSet.toArray(new String[archSet.size()]);\r
ff225cbb 220\r
a29c47e0 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
391dbbb1 228 throw new BuildException("Specified architecture [" + archList[k] + "] is not supported by " + moduleId + ". The module " + moduleId + " only supports [" + moduleSupportedArchs + "] architectures.");\r
a29c47e0 229 }\r
230 }\r
878ddf1f 231 }\r
ff225cbb 232\r
a29c47e0 233 for (int k = 0; k < archList.length; k++) {\r
ff225cbb 234\r
1fa1cb75 235 PropertyManager.setProperty("ARCH", archList[k]);\r
ff225cbb 236\r
a29c47e0 237 FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, archList[k]);\r
ff225cbb 238\r
878ddf1f 239 //\r
a29c47e0 240 // Whether the module is built before\r
878ddf1f 241 //\r
34281092 242 if (moduleId.isLibrary() == false && GlobalData.hasFpdModuleSA(fpdModuleId) == false) {\r
391dbbb1 243 System.out.println("\nWARNING: " + moduleId + " for " + archList[k] + " was not found in current platform FPD file!\n");\r
34281092 244 continue;\r
245 } else if (GlobalData.isModuleBuilt(fpdModuleId)) {\r
1fa1cb75 246 break;\r
34281092 247 } else {\r
a29c47e0 248 GlobalData.registerBuiltModule(fpdModuleId);\r
249 }\r
ff225cbb 250\r
878ddf1f 251 //\r
a29c47e0 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
1fa1cb75 260 PropertyManager.setProperty("TARGET", targetList[i]);\r
a29c47e0 261 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
262 for(int j = 0; j < toolchainList.length; j ++){\r
c773bec0 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
ff225cbb 266 //\r
c773bec0 267 if (GlobalData.isCommandSet(targetList[i], toolchainList[j], archList[k]) == false) {\r
391dbbb1 268 System.out.println("Warning: No build issued. No tools were found for [target=" + targetList[i] + " toolchain=" + toolchainList[j] + " arch=" + archList[k] + "]\n");\r
c773bec0 269 continue;\r
270 }\r
271\r
a29c47e0 272 //\r
273 // Prepare for toolchain related common properties\r
274 // TOOLCHAIN\r
275 //\r
1fa1cb75 276 PropertyManager.setProperty("TOOLCHAIN", toolchainList[j]);\r
a29c47e0 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
ff225cbb 281\r
a29c47e0 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
a29c47e0 288 //\r
289 setModuleCommonProperties(archList[k]);\r
ff225cbb 290\r
a29c47e0 291 //\r
ff225cbb 292 // OutputManage prepare for\r
a29c47e0 293 // BIN_DIR, DEST_DIR_DEBUG, DEST_DIR_OUTPUT, BUILD_DIR, FV_DIR\r
294 //\r
295 OutputManager.getInstance().update(getProject());\r
ff225cbb 296\r
a29c47e0 297 if (type.equalsIgnoreCase("all") || type.equalsIgnoreCase("build")) {\r
298 applyBuild(targetList[i], toolchainList[j], fpdModuleId);\r
82516887 299 } else if (type.equalsIgnoreCase("clean")) {\r
a29c47e0 300 applyClean(fpdModuleId);\r
82516887 301 } else if (type.equalsIgnoreCase("cleanall")) {\r
a29c47e0 302 applyCleanall(fpdModuleId);\r
303 }\r
304 }\r
305 }\r
878ddf1f 306 }\r
82516887 307 \r
1fa1cb75 308 PropertyManager.restore();\r
878ddf1f 309 }\r
310\r
311 /**\r
ff225cbb 312 This method is used to prepare Platform-related information.\r
313\r
a29c47e0 314 <p>In Single Module Build mode, platform-related information is not ready.\r
ff225cbb 315 The method read the system environment variable <code>ACTIVE_PLATFORM</code>\r
a29c47e0 316 and search in the Framework Database. Note that platform name in the Framework\r
317 Database must be unique. </p>\r
ff225cbb 318\r
878ddf1f 319 **/\r
a29c47e0 320 private void prepareSingleModuleBuild(){\r
878ddf1f 321 //\r
a29c47e0 322 // Find out the package which the module belongs to\r
323 // TBD: Enhance it!!!!\r
878ddf1f 324 //\r
a29c47e0 325 PackageIdentification packageId = GlobalData.getPackageForModule(moduleId);\r
ff225cbb 326\r
a29c47e0 327 moduleId.setPackage(packageId);\r
ff225cbb 328\r
878ddf1f 329 //\r
82516887 330 // Read ACTIVE_PLATFORM's FPD file \r
878ddf1f 331 //\r
de4bb9f6 332 String filename = getProject().getProperty("PLATFORM_FILE");\r
ff225cbb 333\r
de4bb9f6 334 if (filename == null){\r
391dbbb1 335 throw new BuildException("Please set ACTIVE_PLATFORM in the file: Tools/Conf/target.txt if you want to build a single module!");\r
878ddf1f 336 }\r
ff225cbb 337\r
de4bb9f6 338 PlatformIdentification platformId = GlobalData.getPlatform(filename);\r
ff225cbb 339\r
878ddf1f 340 //\r
82516887 341 // Read FPD file (Call FpdParserTask's method)\r
878ddf1f 342 //\r
a29c47e0 343 FpdParserTask fpdParser = new FpdParserTask();\r
344 fpdParser.setProject(getProject());\r
07193171 345 fpdParser.parseFpdFile(platformId.getFpdFile());\r
3790e93c 346 PropertyManager.setProperty("ARCH", fpdParser.getAllArchForModule(moduleId));\r
ff225cbb 347\r
878ddf1f 348 //\r
a29c47e0 349 // Prepare for Platform related common properties\r
350 // PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR\r
878ddf1f 351 //\r
1fa1cb75 352 PropertyManager.setProperty("PLATFORM", platformId.getName());\r
353 PropertyManager.setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));\r
354 PropertyManager.setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));\r
878ddf1f 355 }\r
356\r
878ddf1f 357\r
358 /**\r
a29c47e0 359 Set Module-Related information to properties.\r
82516887 360 \r
361 @param arch current build ARCH\r
878ddf1f 362 **/\r
a29c47e0 363 private void setModuleCommonProperties(String arch) {\r
878ddf1f 364 //\r
a29c47e0 365 // Prepare for all other common properties\r
366 // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR\r
878ddf1f 367 //\r
a29c47e0 368 PackageIdentification packageId = moduleId.getPackage();\r
1fa1cb75 369 PropertyManager.setProperty("PACKAGE", packageId.getName());\r
370 PropertyManager.setProperty("PACKAGE_GUID", packageId.getGuid());\r
371 PropertyManager.setProperty("PACKAGE_VERSION", packageId.getVersion());\r
372 PropertyManager.setProperty("PACKAGE_DIR", packageId.getPackageDir().replaceAll("(\\\\)", "/"));\r
373 PropertyManager.setProperty("PACKAGE_RELATIVE_DIR", packageId.getPackageRelativeDir().replaceAll("(\\\\)", "/"));\r
ff225cbb 374\r
a29c47e0 375 //\r
376 // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE\r
377 // MODULE_DIR, MODULE_RELATIVE_DIR\r
378 //\r
1fa1cb75 379 PropertyManager.setProperty("MODULE", moduleId.getName());\r
a29c47e0 380 String baseName = SurfaceAreaQuery.getModuleOutputFileBasename();\r
381 if (baseName == null) {\r
1fa1cb75 382 PropertyManager.setProperty("BASE_NAME", moduleId.getName());\r
82516887 383 } else {\r
1fa1cb75 384 PropertyManager.setProperty("BASE_NAME", baseName);\r
a29c47e0 385 }\r
1fa1cb75 386 PropertyManager.setProperty("GUID", moduleId.getGuid());\r
387 PropertyManager.setProperty("FILE_GUID", moduleId.getGuid());\r
388 PropertyManager.setProperty("VERSION", moduleId.getVersion());\r
389 PropertyManager.setProperty("MODULE_TYPE", moduleId.getModuleType());\r
390 PropertyManager.setProperty("MODULE_DIR", moduleId.getMsaFile().getParent().replaceAll("(\\\\)", "/"));\r
391 PropertyManager.setProperty("MODULE_RELATIVE_DIR", moduleId.getModuleRelativePath().replaceAll("(\\\\)", "/"));\r
ff225cbb 392\r
a29c47e0 393 //\r
394 // SUBSYSTEM\r
395 //\r
396 String[][] subsystemMap = { { "BASE", "EFI_BOOT_SERVICE_DRIVER"},\r
ff225cbb 397 { "SEC", "EFI_BOOT_SERVICE_DRIVER" },\r
398 { "PEI_CORE", "EFI_BOOT_SERVICE_DRIVER" },\r
399 { "PEIM", "EFI_BOOT_SERVICE_DRIVER" },\r
a29c47e0 400 { "DXE_CORE", "EFI_BOOT_SERVICE_DRIVER" },\r
ff225cbb 401 { "DXE_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
402 { "DXE_RUNTIME_DRIVER", "EFI_RUNTIME_DRIVER" },\r
403 { "DXE_SAL_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
404 { "DXE_SMM_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
405 { "TOOL", "EFI_BOOT_SERVICE_DRIVER" },\r
a29c47e0 406 { "UEFI_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
ff225cbb 407 { "UEFI_APPLICATION", "EFI_APPLICATION" },\r
408 { "USER_DEFINED", "EFI_BOOT_SERVICE_DRIVER"} };\r
409\r
a29c47e0 410 String subsystem = "EFI_BOOT_SERVICE_DRIVER";\r
411 for (int i = 0; i < subsystemMap.length; i++) {\r
412 if (moduleId.getModuleType().equalsIgnoreCase(subsystemMap[i][0])) {\r
413 subsystem = subsystemMap[i][1];\r
414 break ;\r
878ddf1f 415 }\r
416 }\r
1fa1cb75 417 PropertyManager.setProperty("SUBSYSTEM", subsystem);\r
ff225cbb 418\r
a29c47e0 419 //\r
420 // ENTRYPOINT\r
421 //\r
422 if (arch.equalsIgnoreCase("EBC")) {\r
1fa1cb75 423 PropertyManager.setProperty("ENTRYPOINT", "EfiStart");\r
82516887 424 } else {\r
1fa1cb75 425 PropertyManager.setProperty("ENTRYPOINT", "_ModuleEntryPoint");\r
878ddf1f 426 }\r
ff225cbb 427\r
1fa1cb75 428 PropertyManager.setProperty("OBJECTS", "");\r
878ddf1f 429 }\r
430\r
a29c47e0 431 private void getCompilerFlags(String target, String toolchain, FpdModuleIdentification fpdModuleId) throws EdkException {\r
432 String[] cmd = GlobalData.getToolChainInfo().getCommands();\r
433 for ( int m = 0; m < cmd.length; m++) {\r
878ddf1f 434 //\r
a29c47e0 435 // Set cmd, like CC, DLINK\r
878ddf1f 436 //\r
a29c47e0 437 String[] key = new String[]{target, toolchain, fpdModuleId.getArch(), cmd[m], null};\r
4a6a5026 438 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_PATH;\r
a29c47e0 439 String cmdPath = GlobalData.getCommandSetting(key, fpdModuleId);\r
4a6a5026 440 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_NAME;\r
a29c47e0 441 String cmdName = GlobalData.getCommandSetting(key, fpdModuleId);\r
442 File cmdFile = new File(cmdPath + File.separatorChar + cmdName);\r
1fa1cb75 443 PropertyManager.setProperty(cmd[m], cmdFile.getPath().replaceAll("(\\\\)", "/"));\r
ff225cbb 444\r
878ddf1f 445 //\r
a29c47e0 446 // set CC_FLAGS\r
878ddf1f 447 //\r
4a6a5026 448 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS;\r
a29c47e0 449 String cmdFlags = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 450 Set<String> addset = new LinkedHashSet<String>();\r
451 Set<String> subset = new LinkedHashSet<String>();\r
452 putFlagsToSet(addset, cmdFlags);\r
1fa1cb75 453 PropertyManager.setProperty(cmd[m] + "_FLAGS", getProject().replaceProperties(getFlags(addset, subset)));\r
ff225cbb 454\r
878ddf1f 455 //\r
a29c47e0 456 // Set CC_EXT\r
878ddf1f 457 //\r
4a6a5026 458 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_EXT;\r
a29c47e0 459 String extName = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 460 if ( extName != null && ! extName.equalsIgnoreCase("")) {\r
1fa1cb75 461 PropertyManager.setProperty(cmd[m] + "_EXT", extName);\r
82516887 462 } else {\r
1fa1cb75 463 PropertyManager.setProperty(cmd[m] + "_EXT", "");\r
878ddf1f 464 }\r
ff225cbb 465\r
878ddf1f 466 //\r
a29c47e0 467 // set CC_FAMILY\r
878ddf1f 468 //\r
4a6a5026 469 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FAMILY;\r
a29c47e0 470 String toolChainFamily = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 471 if (toolChainFamily != null) {\r
1fa1cb75 472 PropertyManager.setProperty(cmd[m] + "_FAMILY", toolChainFamily);\r
878ddf1f 473 }\r
ff225cbb 474\r
878ddf1f 475 //\r
a29c47e0 476 // set CC_SPATH\r
878ddf1f 477 //\r
4a6a5026 478 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_SPATH;\r
a29c47e0 479 String spath = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 480 if (spath != null) {\r
1fa1cb75 481 PropertyManager.setProperty(cmd[m] + "_SPATH", spath.replaceAll("(\\\\)", "/"));\r
82516887 482 } else {\r
1fa1cb75 483 PropertyManager.setProperty(cmd[m] + "_SPATH", "");\r
878ddf1f 484 }\r
ff225cbb 485\r
878ddf1f 486 //\r
a29c47e0 487 // set CC_DPATH\r
878ddf1f 488 //\r
4a6a5026 489 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_DPATH;\r
a29c47e0 490 String dpath = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 491 if (dpath != null) {\r
1fa1cb75 492 PropertyManager.setProperty(cmd[m] + "_DPATH", dpath.replaceAll("(\\\\)", "/"));\r
82516887 493 } else {\r
1fa1cb75 494 PropertyManager.setProperty(cmd[m] + "_DPATH", "");\r
878ddf1f 495 }\r
496 }\r
a29c47e0 497 }\r
ff225cbb 498\r
a29c47e0 499 public void setMsaFile(File msaFile) {\r
500 this.msaFile = msaFile;\r
878ddf1f 501 }\r
502\r
503 /**\r
ff225cbb 504 Method is for ANT to initialize MSA file.\r
505\r
a29c47e0 506 @param msaFilename MSA file name\r
878ddf1f 507 **/\r
a29c47e0 508 public void setMsaFile(String msaFilename) {\r
509 String moduleDir = getProject().getProperty("MODULE_DIR");\r
ff225cbb 510\r
a29c47e0 511 //\r
512 // If is Single Module Build, then use the Base Dir defined in build.xml\r
513 //\r
514 if (moduleDir == null) {\r
515 moduleDir = getProject().getBaseDir().getPath();\r
878ddf1f 516 }\r
a29c47e0 517 msaFile = new File(moduleDir + File.separatorChar + msaFilename);\r
518 }\r
ff225cbb 519\r
a29c47e0 520 public void addConfiguredModuleItem(ModuleItem moduleItem) {\r
521 PackageIdentification packageId = new PackageIdentification(moduleItem.getPackageGuid(), moduleItem.getPackageVersion());\r
522 ModuleIdentification moduleId = new ModuleIdentification(moduleItem.getModuleGuid(), moduleItem.getModuleVersion());\r
523 moduleId.setPackage(packageId);\r
524 this.moduleId = moduleId;\r
525 }\r
ff225cbb 526\r
a29c47e0 527 /**\r
ff225cbb 528 Add a property.\r
529\r
a29c47e0 530 @param p property\r
531 **/\r
532 public void addProperty(Property p) {\r
533 properties.addElement(p);\r
534 }\r
535\r
536 public void setType(String type) {\r
537 this.type = type;\r
538 }\r
ff225cbb 539\r
82516887 540 private void applyBuild(String buildTarget, String buildTagname, FpdModuleIdentification fpdModuleId) throws BuildException{\r
a29c47e0 541 //\r
542 // AutoGen\r
543 //\r
ff225cbb 544\r
73b4e31a 545 AutoGen autogen = new AutoGen(getProject().getProperty("FV_DIR"), getProject().getProperty("DEST_DIR_DEBUG"), fpdModuleId.getModule(),fpdModuleId.getArch());\r
136adffc 546 autogen.genAutogen();\r
ff225cbb 547\r
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
562 ModuleIdentification[] libinstances = SurfaceAreaQuery.getLibraryInstance(fpdModuleId.getArch());\r
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
a29c47e0 591 String ffsKeyword = SurfaceAreaQuery.getModuleFfsKeyword();\r
bf3a7173 592 ModuleBuildFileGenerator fileGenerator = new ModuleBuildFileGenerator(getProject(), ffsKeyword, fpdModuleId, includes);\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
724 PackageIdentification[] packageDependencies = SurfaceAreaQuery.getDependencePkg(fpdModuleId.getArch());\r
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
735 ModuleIdentification[] libinstances = SurfaceAreaQuery.getLibraryInstance(fpdModuleId.getArch());\r
736 for (int i = 0; i < libinstances.length; i++) {\r
737 SurfaceAreaQuery.push(GlobalData.getDoc(libinstances[i], fpdModuleId.getArch()));\r
738 PackageIdentification[] libraryPackageDependencies = SurfaceAreaQuery.getDependencePkg(fpdModuleId.getArch());\r
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
745 SurfaceAreaQuery.pop();\r
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