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