- Fixed EDKT240. Now the Blank.pad file for alignment purpose will no longer be needed.
[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
e3cc4061 330 } else {\r
331 applyNonBuildTarget(fpdModuleId);\r
a29c47e0 332 }\r
333 }\r
334 }\r
878ddf1f 335 }\r
878ddf1f 336 }\r
337\r
338 /**\r
ff225cbb 339 This method is used to prepare Platform-related information.\r
340\r
a29c47e0 341 <p>In Single Module Build mode, platform-related information is not ready.\r
ff225cbb 342 The method read the system environment variable <code>ACTIVE_PLATFORM</code>\r
a29c47e0 343 and search in the Framework Database. Note that platform name in the Framework\r
344 Database must be unique. </p>\r
ff225cbb 345\r
878ddf1f 346 **/\r
892b0e7a 347 private void prepareSingleModuleBuild() throws EdkException {\r
878ddf1f 348 //\r
a29c47e0 349 // Find out the package which the module belongs to\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
86f3fef0 430 File msaFile = moduleId.getMsaFile();\r
431 String msaFileName = msaFile.getName();\r
432 getProject().setProperty("MODULE_DIR", msaFile.getParent().replaceAll("(\\\\)", "/"));\r
433 getProject().setProperty("MODULE_RELATIVE_DIR", moduleId.getModuleRelativePath().replaceAll("(\\\\)", "/") \r
bc022470 434 + File.separatorChar + msaFileName.substring(0, msaFileName.lastIndexOf('.')));\r
ff225cbb 435\r
a29c47e0 436 //\r
437 // SUBSYSTEM\r
438 //\r
439 String[][] subsystemMap = { { "BASE", "EFI_BOOT_SERVICE_DRIVER"},\r
ff225cbb 440 { "SEC", "EFI_BOOT_SERVICE_DRIVER" },\r
441 { "PEI_CORE", "EFI_BOOT_SERVICE_DRIVER" },\r
442 { "PEIM", "EFI_BOOT_SERVICE_DRIVER" },\r
a29c47e0 443 { "DXE_CORE", "EFI_BOOT_SERVICE_DRIVER" },\r
ff225cbb 444 { "DXE_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
445 { "DXE_RUNTIME_DRIVER", "EFI_RUNTIME_DRIVER" },\r
446 { "DXE_SAL_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
447 { "DXE_SMM_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
448 { "TOOL", "EFI_BOOT_SERVICE_DRIVER" },\r
a29c47e0 449 { "UEFI_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
ff225cbb 450 { "UEFI_APPLICATION", "EFI_APPLICATION" },\r
451 { "USER_DEFINED", "EFI_BOOT_SERVICE_DRIVER"} };\r
452\r
a29c47e0 453 String subsystem = "EFI_BOOT_SERVICE_DRIVER";\r
454 for (int i = 0; i < subsystemMap.length; i++) {\r
455 if (moduleId.getModuleType().equalsIgnoreCase(subsystemMap[i][0])) {\r
456 subsystem = subsystemMap[i][1];\r
457 break ;\r
878ddf1f 458 }\r
459 }\r
aca6c736 460 getProject().setProperty("SUBSYSTEM", subsystem);\r
ff225cbb 461\r
a29c47e0 462 //\r
463 // ENTRYPOINT\r
464 //\r
465 if (arch.equalsIgnoreCase("EBC")) {\r
aca6c736 466 getProject().setProperty("ENTRYPOINT", "EfiStart");\r
82516887 467 } else {\r
aca6c736 468 getProject().setProperty("ENTRYPOINT", "_ModuleEntryPoint");\r
878ddf1f 469 }\r
ff225cbb 470\r
aca6c736 471 getProject().setProperty("OBJECTS", "");\r
878ddf1f 472 }\r
473\r
a29c47e0 474 private void getCompilerFlags(String target, String toolchain, FpdModuleIdentification fpdModuleId) throws EdkException {\r
475 String[] cmd = GlobalData.getToolChainInfo().getCommands();\r
476 for ( int m = 0; m < cmd.length; m++) {\r
878ddf1f 477 //\r
a29c47e0 478 // Set cmd, like CC, DLINK\r
878ddf1f 479 //\r
a29c47e0 480 String[] key = new String[]{target, toolchain, fpdModuleId.getArch(), cmd[m], null};\r
4a6a5026 481 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_PATH;\r
a29c47e0 482 String cmdPath = GlobalData.getCommandSetting(key, fpdModuleId);\r
4a6a5026 483 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_NAME;\r
a29c47e0 484 String cmdName = GlobalData.getCommandSetting(key, fpdModuleId);\r
1549f516 485 if (cmdName.length() == 0) {\r
fd6c41f5 486 EdkLog.log(this, EdkLog.EDK_VERBOSE, "Warning: " + cmd[m] + " hasn't been defined!");\r
487 getProject().setProperty(cmd[m], "");\r
1549f516 488 continue;\r
489 }\r
a29c47e0 490 File cmdFile = new File(cmdPath + File.separatorChar + cmdName);\r
aca6c736 491 getProject().setProperty(cmd[m], cmdFile.getPath().replaceAll("(\\\\)", "/"));\r
ff225cbb 492\r
878ddf1f 493 //\r
a29c47e0 494 // set CC_FLAGS\r
878ddf1f 495 //\r
4a6a5026 496 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS;\r
a29c47e0 497 String cmdFlags = GlobalData.getCommandSetting(key, fpdModuleId);\r
e04a8a9a 498 if (cmdFlags != null) \r
499 {\r
e04a8a9a 500 getProject().setProperty(cmd[m] + "_FLAGS", cmdFlags);\r
501 } \r
502 else \r
503 {\r
504 getProject().setProperty(cmd[m] + "_FLAGS", "");\r
505 }\r
506\r
878ddf1f 507 //\r
a29c47e0 508 // Set CC_EXT\r
878ddf1f 509 //\r
4a6a5026 510 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_EXT;\r
a29c47e0 511 String extName = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 512 if ( extName != null && ! extName.equalsIgnoreCase("")) {\r
aca6c736 513 getProject().setProperty(cmd[m] + "_EXT", extName);\r
82516887 514 } else {\r
aca6c736 515 getProject().setProperty(cmd[m] + "_EXT", "");\r
878ddf1f 516 }\r
ff225cbb 517\r
878ddf1f 518 //\r
a29c47e0 519 // set CC_FAMILY\r
878ddf1f 520 //\r
4a6a5026 521 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FAMILY;\r
a29c47e0 522 String toolChainFamily = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 523 if (toolChainFamily != null) {\r
aca6c736 524 getProject().setProperty(cmd[m] + "_FAMILY", toolChainFamily);\r
878ddf1f 525 }\r
ff225cbb 526\r
878ddf1f 527 //\r
a29c47e0 528 // set CC_SPATH\r
878ddf1f 529 //\r
4a6a5026 530 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_SPATH;\r
a29c47e0 531 String spath = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 532 if (spath != null) {\r
aca6c736 533 getProject().setProperty(cmd[m] + "_SPATH", spath.replaceAll("(\\\\)", "/"));\r
82516887 534 } else {\r
aca6c736 535 getProject().setProperty(cmd[m] + "_SPATH", "");\r
878ddf1f 536 }\r
ff225cbb 537\r
878ddf1f 538 //\r
a29c47e0 539 // set CC_DPATH\r
878ddf1f 540 //\r
4a6a5026 541 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_DPATH;\r
a29c47e0 542 String dpath = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 543 if (dpath != null) {\r
aca6c736 544 getProject().setProperty(cmd[m] + "_DPATH", dpath.replaceAll("(\\\\)", "/"));\r
82516887 545 } else {\r
aca6c736 546 getProject().setProperty(cmd[m] + "_DPATH", "");\r
878ddf1f 547 }\r
c639781e 548 \r
549 //\r
550 // Set CC_LIBPATH\r
551 //\r
552 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_LIBPATH;\r
553 String libpath = GlobalData.getCommandSetting(key, fpdModuleId);\r
554 if (libpath != null) {\r
555 getProject().setProperty(cmd[m] + "_LIBPATH", libpath.replaceAll("(\\\\)", "/"));\r
556 } else {\r
557 getProject().setProperty(cmd[m] + "_LIBPATH", "");\r
558 }\r
559 \r
560 //\r
561 // Set CC_INCLUDEPATH\r
562 //\r
563 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_INCLUDEPATH;\r
564 String includepath = GlobalData.getCommandSetting(key, fpdModuleId);\r
565 if (dpath != null) {\r
566 getProject().setProperty(cmd[m] + "_INCLUDEPATH", includepath.replaceAll("(\\\\)", "/"));\r
567 } else {\r
568 getProject().setProperty(cmd[m] + "_INCLUDEPATH", "");\r
569 }\r
878ddf1f 570 }\r
a29c47e0 571 }\r
ff225cbb 572\r
a29c47e0 573 public void setMsaFile(File msaFile) {\r
574 this.msaFile = msaFile;\r
878ddf1f 575 }\r
576\r
577 /**\r
ff225cbb 578 Method is for ANT to initialize MSA file.\r
579\r
a29c47e0 580 @param msaFilename MSA file name\r
878ddf1f 581 **/\r
a29c47e0 582 public void setMsaFile(String msaFilename) {\r
583 String moduleDir = getProject().getProperty("MODULE_DIR");\r
ff225cbb 584\r
a29c47e0 585 //\r
586 // If is Single Module Build, then use the Base Dir defined in build.xml\r
587 //\r
588 if (moduleDir == null) {\r
589 moduleDir = getProject().getBaseDir().getPath();\r
878ddf1f 590 }\r
a29c47e0 591 msaFile = new File(moduleDir + File.separatorChar + msaFilename);\r
592 }\r
ff225cbb 593\r
a29c47e0 594 public void addConfiguredModuleItem(ModuleItem moduleItem) {\r
595 PackageIdentification packageId = new PackageIdentification(moduleItem.getPackageGuid(), moduleItem.getPackageVersion());\r
596 ModuleIdentification moduleId = new ModuleIdentification(moduleItem.getModuleGuid(), moduleItem.getModuleVersion());\r
597 moduleId.setPackage(packageId);\r
598 this.moduleId = moduleId;\r
599 }\r
ff225cbb 600\r
a29c47e0 601 /**\r
ff225cbb 602 Add a property.\r
603\r
a29c47e0 604 @param p property\r
605 **/\r
606 public void addProperty(Property p) {\r
607 properties.addElement(p);\r
608 }\r
609\r
610 public void setType(String type) {\r
611 this.type = type;\r
612 }\r
ff225cbb 613\r
892b0e7a 614 private void applyBuild(String buildTarget, String buildTagname, FpdModuleIdentification fpdModuleId) throws EdkException {\r
a29c47e0 615 //\r
83fba802 616 // Call AutoGen to generate AutoGen.c and AutoGen.h\r
a29c47e0 617 //\r
2eb7d78d 618 AutoGen autogen = new AutoGen(getProject().getProperty("FV_DIR"), getProject().getProperty("DEST_DIR_DEBUG"), fpdModuleId.getModule(),fpdModuleId.getArch(), saq, parentId);\r
136adffc 619 autogen.genAutogen();\r
ff225cbb 620\r
a29c47e0 621 //\r
622 // Get compiler flags\r
623 //\r
82516887 624 try {\r
625 getCompilerFlags(buildTarget, buildTagname, fpdModuleId);\r
626 }\r
627 catch (EdkException ee) {\r
628 throw new BuildException(ee.getMessage());\r
629 }\r
630 \r
a29c47e0 631 //\r
632 // Prepare LIBS\r
633 //\r
83fba802 634 ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());\r
a29c47e0 635 String propertyLibs = "";\r
636 for (int i = 0; i < libinstances.length; i++) {\r
498e9021 637 propertyLibs += getProject().getProperty("BIN_DIR") + File.separatorChar + libinstances[i].getName() + ".lib" + " ";\r
878ddf1f 638 }\r
aca6c736 639 getProject().setProperty("LIBS", propertyLibs.replaceAll("(\\\\)", "/"));\r
ff225cbb 640\r
bf3a7173 641 //\r
642 // Get all includepath and set to INCLUDE_PATHS\r
643 //\r
644 String[] includes = prepareIncludePaths(fpdModuleId);\r
645 \r
a29c47e0 646 //\r
647 // if it is CUSTOM_BUILD\r
648 // then call the exist BaseName_build.xml directly.\r
649 //\r
98840b10 650 String buildFilename = "";\r
651 if ((buildFilename = GetCustomizedBuildFile(fpdModuleId.getArch())) != "") {\r
652 EdkLog.log(this, "Call user-defined " + buildFilename);\r
82516887 653 \r
98840b10 654 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + buildFilename;\r
82516887 655 antCall(antFilename, null);\r
656 \r
a29c47e0 657 return ;\r
878ddf1f 658 }\r
ff225cbb 659\r
878ddf1f 660 //\r
a29c47e0 661 // Generate ${BASE_NAME}_build.xml\r
662 // TBD\r
878ddf1f 663 //\r
83fba802 664 String ffsKeyword = saq.getModuleFfsKeyword();\r
665 ModuleBuildFileGenerator fileGenerator = new ModuleBuildFileGenerator(getProject(), ffsKeyword, fpdModuleId, includes, saq);\r
98840b10 666 buildFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
a29c47e0 667 fileGenerator.genBuildFile(buildFilename);\r
ff225cbb 668\r
a29c47e0 669 //\r
670 // Ant call ${BASE_NAME}_build.xml\r
671 //\r
82516887 672 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
673 antCall(antFilename, null);\r
a29c47e0 674 }\r
ff225cbb 675\r
e3cc4061 676 private void applyNonBuildTarget(FpdModuleIdentification fpdModuleId){\r
677 //\r
678 // if it is CUSTOM_BUILD\r
679 // then call the exist BaseName_build.xml directly.\r
680 //\r
681 if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
682 EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml");\r
683 \r
684 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";\r
685 antCall(antFilename, this.type);\r
686 \r
687 return ;\r
688 }\r
689\r
690 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
691 antCall(antFilename, this.type);\r
692 }\r
693\r
a29c47e0 694 private void applyClean(FpdModuleIdentification fpdModuleId){\r
695 //\r
696 // if it is CUSTOM_BUILD\r
697 // then call the exist BaseName_build.xml directly.\r
698 //\r
699 if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
d965d1f6 700 EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml");\r
82516887 701 \r
702 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";\r
703 antCall(antFilename, "clean");\r
704 \r
a29c47e0 705 return ;\r
878ddf1f 706 }\r
ff225cbb 707\r
82516887 708 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
709 antCall(antFilename, "clean");\r
a29c47e0 710 }\r
ff225cbb 711\r
a29c47e0 712 private void applyCleanall(FpdModuleIdentification fpdModuleId){\r
713 //\r
714 // if it is CUSTOM_BUILD\r
715 // then call the exist BaseName_build.xml directly.\r
716 //\r
717 if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
d965d1f6 718 EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml");\r
82516887 719\r
720 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";\r
721 antCall(antFilename, "cleanall");\r
722 \r
a29c47e0 723 return ;\r
878ddf1f 724 }\r
82516887 725 \r
726 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
727 antCall(antFilename, "cleanall");\r
728 }\r
ff225cbb 729\r
82516887 730 private void antCall(String antFilename, String target) {\r
a29c47e0 731 Ant ant = new Ant();\r
732 ant.setProject(getProject());\r
82516887 733 ant.setAntfile(antFilename);\r
734 if (target != null) {\r
735 ant.setTarget(target);\r
736 }\r
a29c47e0 737 ant.setInheritAll(true);\r
738 ant.init();\r
739 ant.execute();\r
878ddf1f 740 }\r
741\r
de4bb9f6 742 public void setSingleModuleBuild(boolean isSingleModuleBuild) {\r
743 this.isSingleModuleBuild = isSingleModuleBuild;\r
744 }\r
bf3a7173 745 \r
892b0e7a 746 private String[] prepareIncludePaths(FpdModuleIdentification fpdModuleId) throws EdkException{\r
bf3a7173 747 //\r
748 // Prepare the includes: PackageDependencies and Output debug direactory\r
749 //\r
750 Set<String> includes = new LinkedHashSet<String>();\r
751 String arch = fpdModuleId.getArch();\r
752 \r
753 //\r
754 // WORKSPACE\r
755 //\r
756 includes.add("${WORKSPACE_DIR}" + File.separatorChar);\r
757 \r
758 //\r
759 // Module iteself\r
760 //\r
761 includes.add("${MODULE_DIR}");\r
762 includes.add("${MODULE_DIR}" + File.separatorChar + archDir(arch));\r
763 \r
764 //\r
765 // Packages in PackageDenpendencies\r
766 //\r
83fba802 767 PackageIdentification[] packageDependencies = saq.getDependencePkg(fpdModuleId.getArch());\r
bf3a7173 768 for (int i = 0; i < packageDependencies.length; i++) {\r
769 GlobalData.refreshPackageIdentification(packageDependencies[i]);\r
770 File packageFile = packageDependencies[i].getSpdFile();\r
771 includes.add(packageFile.getParent() + File.separatorChar + "Include");\r
772 includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));\r
773 }\r
774\r
775 //\r
776 // All Dependency Library Instance's PackageDependencies\r
777 //\r
83fba802 778 ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());\r
bf3a7173 779 for (int i = 0; i < libinstances.length; i++) {\r
83fba802 780 saq.push(GlobalData.getDoc(libinstances[i], fpdModuleId.getArch()));\r
781 PackageIdentification[] libraryPackageDependencies = saq.getDependencePkg(fpdModuleId.getArch());\r
bf3a7173 782 for (int j = 0; j < libraryPackageDependencies.length; j++) {\r
783 GlobalData.refreshPackageIdentification(libraryPackageDependencies[j]);\r
784 File packageFile = libraryPackageDependencies[j].getSpdFile();\r
785 includes.add(packageFile.getParent() + File.separatorChar + "Include");\r
786 includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));\r
787 }\r
83fba802 788 saq.pop();\r
bf3a7173 789 }\r
790 \r
791 \r
792 //\r
793 // The package which the module belongs to\r
794 // TBD\r
795 includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include");\r
796 includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));\r
797\r
798 //\r
799 // Debug files output directory\r
800 //\r
801 includes.add("${DEST_DIR_DEBUG}");\r
802 \r
803 //\r
804 // set to INCLUDE_PATHS property\r
805 //\r
806 Iterator<String> iter = includes.iterator();\r
807 StringBuffer includePaths = new StringBuffer();\r
808 while (iter.hasNext()) {\r
809 includePaths.append(iter.next());\r
810 includePaths.append("; ");\r
811 }\r
aca6c736 812 getProject().setProperty("INCLUDE_PATHS", getProject().replaceProperties(includePaths.toString()).replaceAll("(\\\\)", "/"));\r
bf3a7173 813 \r
814 return includes.toArray(new String[includes.size()]);\r
815 }\r
816 \r
817 /**\r
818 Return the name of the directory that corresponds to the architecture.\r
819 This is a translation from the XML Schema tag to a directory that\r
820 corresponds to our directory name coding convention.\r
821 \r
822 **/\r
823 private String archDir(String arch) {\r
824 return arch.replaceFirst("X64", "x64")\r
825 .replaceFirst("IPF", "Ipf")\r
826 .replaceFirst("IA32", "Ia32")\r
827 .replaceFirst("ARM", "Arm")\r
828 .replaceFirst("EBC", "Ebc");\r
19bf6b15 829 }\r
830 \r
831 \r
832 public void setExternalProperties(Vector<Property> v) {\r
833 this.properties = v;\r
834 }\r
98840b10 835\r
836 private String GetCustomizedBuildFile(String arch) {\r
837 String[][] files = saq.getSourceFiles(arch);\r
838 for (int i = 0; i < files.length; ++i) {\r
839 if (files[i][1].endsWith("build.xml")) {\r
840 return files[i][1];\r
841 }\r
842 }\r
843\r
844 return "";\r
845 }\r
878ddf1f 846}\r