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