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