]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/GenBuild/org/tianocore/build/GenBuildTask.java
Introduce a new property INCLUDE_PATHS. This property can used by customized build...
[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
345 fpdParser.parseFpdFile(platformId.getFpdFile());\r
ff225cbb 346\r
878ddf1f 347 //\r
a29c47e0 348 // Prepare for Platform related common properties\r
349 // PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR\r
878ddf1f 350 //\r
1fa1cb75 351 PropertyManager.setProperty("PLATFORM", platformId.getName());\r
352 PropertyManager.setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));\r
353 PropertyManager.setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));\r
878ddf1f 354 }\r
355\r
878ddf1f 356\r
357 /**\r
a29c47e0 358 Set Module-Related information to properties.\r
82516887 359 \r
360 @param arch current build ARCH\r
878ddf1f 361 **/\r
a29c47e0 362 private void setModuleCommonProperties(String arch) {\r
878ddf1f 363 //\r
a29c47e0 364 // Prepare for all other common properties\r
365 // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR\r
878ddf1f 366 //\r
a29c47e0 367 PackageIdentification packageId = moduleId.getPackage();\r
1fa1cb75 368 PropertyManager.setProperty("PACKAGE", packageId.getName());\r
369 PropertyManager.setProperty("PACKAGE_GUID", packageId.getGuid());\r
370 PropertyManager.setProperty("PACKAGE_VERSION", packageId.getVersion());\r
371 PropertyManager.setProperty("PACKAGE_DIR", packageId.getPackageDir().replaceAll("(\\\\)", "/"));\r
372 PropertyManager.setProperty("PACKAGE_RELATIVE_DIR", packageId.getPackageRelativeDir().replaceAll("(\\\\)", "/"));\r
ff225cbb 373\r
a29c47e0 374 //\r
375 // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE\r
376 // MODULE_DIR, MODULE_RELATIVE_DIR\r
377 //\r
1fa1cb75 378 PropertyManager.setProperty("MODULE", moduleId.getName());\r
a29c47e0 379 String baseName = SurfaceAreaQuery.getModuleOutputFileBasename();\r
380 if (baseName == null) {\r
1fa1cb75 381 PropertyManager.setProperty("BASE_NAME", moduleId.getName());\r
82516887 382 } else {\r
1fa1cb75 383 PropertyManager.setProperty("BASE_NAME", baseName);\r
a29c47e0 384 }\r
1fa1cb75 385 PropertyManager.setProperty("GUID", moduleId.getGuid());\r
386 PropertyManager.setProperty("FILE_GUID", moduleId.getGuid());\r
387 PropertyManager.setProperty("VERSION", moduleId.getVersion());\r
388 PropertyManager.setProperty("MODULE_TYPE", moduleId.getModuleType());\r
389 PropertyManager.setProperty("MODULE_DIR", moduleId.getMsaFile().getParent().replaceAll("(\\\\)", "/"));\r
390 PropertyManager.setProperty("MODULE_RELATIVE_DIR", moduleId.getModuleRelativePath().replaceAll("(\\\\)", "/"));\r
ff225cbb 391\r
a29c47e0 392 //\r
393 // SUBSYSTEM\r
394 //\r
395 String[][] subsystemMap = { { "BASE", "EFI_BOOT_SERVICE_DRIVER"},\r
ff225cbb 396 { "SEC", "EFI_BOOT_SERVICE_DRIVER" },\r
397 { "PEI_CORE", "EFI_BOOT_SERVICE_DRIVER" },\r
398 { "PEIM", "EFI_BOOT_SERVICE_DRIVER" },\r
a29c47e0 399 { "DXE_CORE", "EFI_BOOT_SERVICE_DRIVER" },\r
ff225cbb 400 { "DXE_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
401 { "DXE_RUNTIME_DRIVER", "EFI_RUNTIME_DRIVER" },\r
402 { "DXE_SAL_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
403 { "DXE_SMM_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
404 { "TOOL", "EFI_BOOT_SERVICE_DRIVER" },\r
a29c47e0 405 { "UEFI_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
ff225cbb 406 { "UEFI_APPLICATION", "EFI_APPLICATION" },\r
407 { "USER_DEFINED", "EFI_BOOT_SERVICE_DRIVER"} };\r
408\r
a29c47e0 409 String subsystem = "EFI_BOOT_SERVICE_DRIVER";\r
410 for (int i = 0; i < subsystemMap.length; i++) {\r
411 if (moduleId.getModuleType().equalsIgnoreCase(subsystemMap[i][0])) {\r
412 subsystem = subsystemMap[i][1];\r
413 break ;\r
878ddf1f 414 }\r
415 }\r
1fa1cb75 416 PropertyManager.setProperty("SUBSYSTEM", subsystem);\r
ff225cbb 417\r
a29c47e0 418 //\r
419 // ENTRYPOINT\r
420 //\r
421 if (arch.equalsIgnoreCase("EBC")) {\r
1fa1cb75 422 PropertyManager.setProperty("ENTRYPOINT", "EfiStart");\r
82516887 423 } else {\r
1fa1cb75 424 PropertyManager.setProperty("ENTRYPOINT", "_ModuleEntryPoint");\r
878ddf1f 425 }\r
ff225cbb 426\r
1fa1cb75 427 PropertyManager.setProperty("OBJECTS", "");\r
878ddf1f 428 }\r
429\r
a29c47e0 430 private void getCompilerFlags(String target, String toolchain, FpdModuleIdentification fpdModuleId) throws EdkException {\r
431 String[] cmd = GlobalData.getToolChainInfo().getCommands();\r
432 for ( int m = 0; m < cmd.length; m++) {\r
878ddf1f 433 //\r
a29c47e0 434 // Set cmd, like CC, DLINK\r
878ddf1f 435 //\r
a29c47e0 436 String[] key = new String[]{target, toolchain, fpdModuleId.getArch(), cmd[m], null};\r
4a6a5026 437 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_PATH;\r
a29c47e0 438 String cmdPath = GlobalData.getCommandSetting(key, fpdModuleId);\r
4a6a5026 439 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_NAME;\r
a29c47e0 440 String cmdName = GlobalData.getCommandSetting(key, fpdModuleId);\r
441 File cmdFile = new File(cmdPath + File.separatorChar + cmdName);\r
1fa1cb75 442 PropertyManager.setProperty(cmd[m], cmdFile.getPath().replaceAll("(\\\\)", "/"));\r
ff225cbb 443\r
878ddf1f 444 //\r
a29c47e0 445 // set CC_FLAGS\r
878ddf1f 446 //\r
4a6a5026 447 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS;\r
a29c47e0 448 String cmdFlags = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 449 Set<String> addset = new LinkedHashSet<String>();\r
450 Set<String> subset = new LinkedHashSet<String>();\r
451 putFlagsToSet(addset, cmdFlags);\r
1fa1cb75 452 PropertyManager.setProperty(cmd[m] + "_FLAGS", getProject().replaceProperties(getFlags(addset, subset)));\r
ff225cbb 453\r
878ddf1f 454 //\r
a29c47e0 455 // Set CC_EXT\r
878ddf1f 456 //\r
4a6a5026 457 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_EXT;\r
a29c47e0 458 String extName = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 459 if ( extName != null && ! extName.equalsIgnoreCase("")) {\r
1fa1cb75 460 PropertyManager.setProperty(cmd[m] + "_EXT", extName);\r
82516887 461 } else {\r
1fa1cb75 462 PropertyManager.setProperty(cmd[m] + "_EXT", "");\r
878ddf1f 463 }\r
ff225cbb 464\r
878ddf1f 465 //\r
a29c47e0 466 // set CC_FAMILY\r
878ddf1f 467 //\r
4a6a5026 468 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FAMILY;\r
a29c47e0 469 String toolChainFamily = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 470 if (toolChainFamily != null) {\r
1fa1cb75 471 PropertyManager.setProperty(cmd[m] + "_FAMILY", toolChainFamily);\r
878ddf1f 472 }\r
ff225cbb 473\r
878ddf1f 474 //\r
a29c47e0 475 // set CC_SPATH\r
878ddf1f 476 //\r
4a6a5026 477 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_SPATH;\r
a29c47e0 478 String spath = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 479 if (spath != null) {\r
1fa1cb75 480 PropertyManager.setProperty(cmd[m] + "_SPATH", spath.replaceAll("(\\\\)", "/"));\r
82516887 481 } else {\r
1fa1cb75 482 PropertyManager.setProperty(cmd[m] + "_SPATH", "");\r
878ddf1f 483 }\r
ff225cbb 484\r
878ddf1f 485 //\r
a29c47e0 486 // set CC_DPATH\r
878ddf1f 487 //\r
4a6a5026 488 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_DPATH;\r
a29c47e0 489 String dpath = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 490 if (dpath != null) {\r
1fa1cb75 491 PropertyManager.setProperty(cmd[m] + "_DPATH", dpath.replaceAll("(\\\\)", "/"));\r
82516887 492 } else {\r
1fa1cb75 493 PropertyManager.setProperty(cmd[m] + "_DPATH", "");\r
878ddf1f 494 }\r
495 }\r
a29c47e0 496 }\r
ff225cbb 497\r
a29c47e0 498 public void setMsaFile(File msaFile) {\r
499 this.msaFile = msaFile;\r
878ddf1f 500 }\r
501\r
502 /**\r
ff225cbb 503 Method is for ANT to initialize MSA file.\r
504\r
a29c47e0 505 @param msaFilename MSA file name\r
878ddf1f 506 **/\r
a29c47e0 507 public void setMsaFile(String msaFilename) {\r
508 String moduleDir = getProject().getProperty("MODULE_DIR");\r
ff225cbb 509\r
a29c47e0 510 //\r
511 // If is Single Module Build, then use the Base Dir defined in build.xml\r
512 //\r
513 if (moduleDir == null) {\r
514 moduleDir = getProject().getBaseDir().getPath();\r
878ddf1f 515 }\r
a29c47e0 516 msaFile = new File(moduleDir + File.separatorChar + msaFilename);\r
517 }\r
ff225cbb 518\r
a29c47e0 519 public void addConfiguredModuleItem(ModuleItem moduleItem) {\r
520 PackageIdentification packageId = new PackageIdentification(moduleItem.getPackageGuid(), moduleItem.getPackageVersion());\r
521 ModuleIdentification moduleId = new ModuleIdentification(moduleItem.getModuleGuid(), moduleItem.getModuleVersion());\r
522 moduleId.setPackage(packageId);\r
523 this.moduleId = moduleId;\r
524 }\r
ff225cbb 525\r
a29c47e0 526 /**\r
ff225cbb 527 Add a property.\r
528\r
a29c47e0 529 @param p property\r
530 **/\r
531 public void addProperty(Property p) {\r
532 properties.addElement(p);\r
533 }\r
534\r
535 public void setType(String type) {\r
536 this.type = type;\r
537 }\r
ff225cbb 538\r
82516887 539 private void applyBuild(String buildTarget, String buildTagname, FpdModuleIdentification fpdModuleId) throws BuildException{\r
a29c47e0 540 //\r
541 // AutoGen\r
542 //\r
ff225cbb 543\r
73b4e31a 544 AutoGen autogen = new AutoGen(getProject().getProperty("FV_DIR"), getProject().getProperty("DEST_DIR_DEBUG"), fpdModuleId.getModule(),fpdModuleId.getArch());\r
136adffc 545 autogen.genAutogen();\r
ff225cbb 546\r
547\r
a29c47e0 548 //\r
549 // Get compiler flags\r
550 //\r
82516887 551 try {\r
552 getCompilerFlags(buildTarget, buildTagname, fpdModuleId);\r
553 }\r
554 catch (EdkException ee) {\r
555 throw new BuildException(ee.getMessage());\r
556 }\r
557 \r
a29c47e0 558 //\r
559 // Prepare LIBS\r
560 //\r
561 ModuleIdentification[] libinstances = SurfaceAreaQuery.getLibraryInstance(fpdModuleId.getArch());\r
562 String propertyLibs = "";\r
563 for (int i = 0; i < libinstances.length; i++) {\r
564 propertyLibs += " " + getProject().getProperty("BIN_DIR") + File.separatorChar + libinstances[i].getName() + ".lib";\r
878ddf1f 565 }\r
1fa1cb75 566 PropertyManager.setProperty("LIBS", propertyLibs.replaceAll("(\\\\)", "/"));\r
ff225cbb 567\r
bf3a7173 568 //\r
569 // Get all includepath and set to INCLUDE_PATHS\r
570 //\r
571 String[] includes = prepareIncludePaths(fpdModuleId);\r
572 \r
a29c47e0 573 //\r
574 // if it is CUSTOM_BUILD\r
575 // then call the exist BaseName_build.xml directly.\r
576 //\r
577 if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
4b5f5549 578 System.out.println("Call user-defined " + moduleId.getName() + "_build.xml");\r
82516887 579 \r
580 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";\r
581 antCall(antFilename, null);\r
582 \r
a29c47e0 583 return ;\r
878ddf1f 584 }\r
ff225cbb 585\r
878ddf1f 586 //\r
a29c47e0 587 // Generate ${BASE_NAME}_build.xml\r
588 // TBD\r
878ddf1f 589 //\r
a29c47e0 590 String ffsKeyword = SurfaceAreaQuery.getModuleFfsKeyword();\r
bf3a7173 591 ModuleBuildFileGenerator fileGenerator = new ModuleBuildFileGenerator(getProject(), ffsKeyword, fpdModuleId, includes);\r
a29c47e0 592 String buildFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
593 fileGenerator.genBuildFile(buildFilename);\r
ff225cbb 594\r
a29c47e0 595 //\r
596 // Ant call ${BASE_NAME}_build.xml\r
597 //\r
82516887 598 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
599 antCall(antFilename, null);\r
a29c47e0 600 }\r
ff225cbb 601\r
a29c47e0 602 private void applyClean(FpdModuleIdentification fpdModuleId){\r
603 //\r
604 // if it is CUSTOM_BUILD\r
605 // then call the exist BaseName_build.xml directly.\r
606 //\r
607 if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
4b5f5549 608 System.out.println("Calling user-defined " + moduleId.getName() + "_build.xml");\r
82516887 609 \r
610 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";\r
611 antCall(antFilename, "clean");\r
612 \r
a29c47e0 613 return ;\r
878ddf1f 614 }\r
ff225cbb 615\r
82516887 616 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
617 antCall(antFilename, "clean");\r
a29c47e0 618 }\r
ff225cbb 619\r
a29c47e0 620 private void applyCleanall(FpdModuleIdentification fpdModuleId){\r
621 //\r
622 // if it is CUSTOM_BUILD\r
623 // then call the exist BaseName_build.xml directly.\r
624 //\r
625 if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
4b5f5549 626 System.out.println("Calling user-defined " + moduleId.getName() + "_build.xml");\r
82516887 627\r
628 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";\r
629 antCall(antFilename, "cleanall");\r
630 \r
a29c47e0 631 return ;\r
878ddf1f 632 }\r
82516887 633 \r
634 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
635 antCall(antFilename, "cleanall");\r
636 }\r
ff225cbb 637\r
82516887 638 private void antCall(String antFilename, String target) {\r
a29c47e0 639 Ant ant = new Ant();\r
640 ant.setProject(getProject());\r
82516887 641 ant.setAntfile(antFilename);\r
642 if (target != null) {\r
643 ant.setTarget(target);\r
644 }\r
a29c47e0 645 ant.setInheritAll(true);\r
646 ant.init();\r
647 ant.execute();\r
878ddf1f 648 }\r
649\r
a29c47e0 650\r
878ddf1f 651 /**\r
652 Separate the string and instore in set.\r
ff225cbb 653\r
654 <p> String is separated by Java Regulation Expression\r
878ddf1f 655 "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>\r
ff225cbb 656\r
878ddf1f 657 <p>For example: </p>\r
ff225cbb 658\r
878ddf1f 659 <pre>\r
660 "/nologo", "/W3", "/WX"\r
661 "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""\r
662 </pre>\r
ff225cbb 663\r
878ddf1f 664 @param set store the separated string\r
665 @param str string to separate\r
666 **/\r
667 private void putFlagsToSet(Set<String> set, String str) {\r
a29c47e0 668 if (str == null || str.length() == 0) {\r
669 return;\r
670 }\r
671\r
878ddf1f 672 Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");\r
673 Matcher matcher = myPattern.matcher(str + " ");\r
674 while (matcher.find()) {\r
675 String item = str.substring(matcher.start(1), matcher.end(1));\r
a29c47e0 676 set.add(item);\r
878ddf1f 677 }\r
678 }\r
ff225cbb 679\r
878ddf1f 680 /**\r
ff225cbb 681 Generate the final flags string will be used by compile command.\r
682\r
878ddf1f 683 @param add the add flags set\r
684 @param sub the sub flags set\r
685 @return final flags after add set substract sub set\r
686 **/\r
687 private String getFlags(Set<String> add, Set<String> sub) {\r
688 String result = "";\r
689 add.removeAll(sub);\r
690 Iterator iter = add.iterator();\r
691 while (iter.hasNext()) {\r
a29c47e0 692 String str = (String) iter.next();\r
878ddf1f 693 result += str.substring(1, str.length() - 1) + " ";\r
694 }\r
695 return result;\r
696 }\r
697\r
de4bb9f6 698 public void setSingleModuleBuild(boolean isSingleModuleBuild) {\r
699 this.isSingleModuleBuild = isSingleModuleBuild;\r
700 }\r
bf3a7173 701 \r
702 private String[] prepareIncludePaths(FpdModuleIdentification fpdModuleId) {\r
703 //\r
704 // Prepare the includes: PackageDependencies and Output debug direactory\r
705 //\r
706 Set<String> includes = new LinkedHashSet<String>();\r
707 String arch = fpdModuleId.getArch();\r
708 \r
709 //\r
710 // WORKSPACE\r
711 //\r
712 includes.add("${WORKSPACE_DIR}" + File.separatorChar);\r
713 \r
714 //\r
715 // Module iteself\r
716 //\r
717 includes.add("${MODULE_DIR}");\r
718 includes.add("${MODULE_DIR}" + File.separatorChar + archDir(arch));\r
719 \r
720 //\r
721 // Packages in PackageDenpendencies\r
722 //\r
723 PackageIdentification[] packageDependencies = SurfaceAreaQuery.getDependencePkg(fpdModuleId.getArch());\r
724 for (int i = 0; i < packageDependencies.length; i++) {\r
725 GlobalData.refreshPackageIdentification(packageDependencies[i]);\r
726 File packageFile = packageDependencies[i].getSpdFile();\r
727 includes.add(packageFile.getParent() + File.separatorChar + "Include");\r
728 includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));\r
729 }\r
730\r
731 //\r
732 // All Dependency Library Instance's PackageDependencies\r
733 //\r
734 ModuleIdentification[] libinstances = SurfaceAreaQuery.getLibraryInstance(fpdModuleId.getArch());\r
735 for (int i = 0; i < libinstances.length; i++) {\r
736 SurfaceAreaQuery.push(GlobalData.getDoc(libinstances[i], fpdModuleId.getArch()));\r
737 PackageIdentification[] libraryPackageDependencies = SurfaceAreaQuery.getDependencePkg(fpdModuleId.getArch());\r
738 for (int j = 0; j < libraryPackageDependencies.length; j++) {\r
739 GlobalData.refreshPackageIdentification(libraryPackageDependencies[j]);\r
740 File packageFile = libraryPackageDependencies[j].getSpdFile();\r
741 includes.add(packageFile.getParent() + File.separatorChar + "Include");\r
742 includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));\r
743 }\r
744 SurfaceAreaQuery.pop();\r
745 }\r
746 \r
747 \r
748 //\r
749 // The package which the module belongs to\r
750 // TBD\r
751 includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include");\r
752 includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));\r
753\r
754 //\r
755 // Debug files output directory\r
756 //\r
757 includes.add("${DEST_DIR_DEBUG}");\r
758 \r
759 //\r
760 // set to INCLUDE_PATHS property\r
761 //\r
762 Iterator<String> iter = includes.iterator();\r
763 StringBuffer includePaths = new StringBuffer();\r
764 while (iter.hasNext()) {\r
765 includePaths.append(iter.next());\r
766 includePaths.append("; ");\r
767 }\r
768 PropertyManager.setProperty("INCLUDE_PATHS", getProject().replaceProperties(includePaths.toString()).replaceAll("(\\\\)", "/"));\r
769 \r
770 return includes.toArray(new String[includes.size()]);\r
771 }\r
772 \r
773 /**\r
774 Return the name of the directory that corresponds to the architecture.\r
775 This is a translation from the XML Schema tag to a directory that\r
776 corresponds to our directory name coding convention.\r
777 \r
778 **/\r
779 private String archDir(String arch) {\r
780 return arch.replaceFirst("X64", "x64")\r
781 .replaceFirst("IPF", "Ipf")\r
782 .replaceFirst("IA32", "Ia32")\r
783 .replaceFirst("ARM", "Arm")\r
784 .replaceFirst("EBC", "Ebc");\r
785 } \r
878ddf1f 786}\r