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