(Fixed EDKT523) Added more check on "archString" to see if it's empty or not.
[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
2c9b03f2 210 moduleId.setBinary(saq.getBinaryModule());\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
bc022470 234 String archString = getProject().getProperty("ARCH");\r
de093b3c 235 if (archString != null && archString.length() > 0) {\r
bc022470 236 String[] fpdArchList = archString.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
c340a28e 261 if (archList.length == 0) {\r
bc022470 262 EdkLog.log(this, EdkLog.EDK_WARNING, "Warning: " + "[" + archString + "] is not supported for " + moduleId + " in this build!\n");\r
c340a28e 263 }\r
264\r
a29c47e0 265 for (int k = 0; k < archList.length; k++) {\r
ff225cbb 266\r
aca6c736 267 getProject().setProperty("ARCH", archList[k]);\r
ff225cbb 268\r
a29c47e0 269 FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, archList[k]);\r
ff225cbb 270\r
878ddf1f 271 //\r
a29c47e0 272 // Whether the module is built before\r
878ddf1f 273 //\r
34281092 274 if (moduleId.isLibrary() == false && GlobalData.hasFpdModuleSA(fpdModuleId) == false) {\r
d965d1f6 275 EdkLog.log(this, EdkLog.EDK_WARNING, "Warning: " + moduleId + " for " + archList[k] + " was not found in current platform FPD file!\n");\r
34281092 276 continue;\r
277 } else if (GlobalData.isModuleBuilt(fpdModuleId)) {\r
1fa1cb75 278 break;\r
34281092 279 } else {\r
a29c47e0 280 GlobalData.registerBuiltModule(fpdModuleId);\r
281 }\r
ff225cbb 282\r
878ddf1f 283 //\r
a29c47e0 284 // For Every TOOLCHAIN, TARGET\r
285 //\r
286 String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
287 for (int i = 0; i < targetList.length; i ++){\r
288 //\r
289 // Prepare for target related common properties\r
290 // TARGET\r
291 //\r
aca6c736 292 getProject().setProperty("TARGET", targetList[i]);\r
a29c47e0 293 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
294 for(int j = 0; j < toolchainList.length; j ++){\r
c773bec0 295 //\r
296 // check if any tool is defined for current target + toolchain + arch\r
297 // don't do anything if no tools found\r
ff225cbb 298 //\r
c773bec0 299 if (GlobalData.isCommandSet(targetList[i], toolchainList[j], archList[k]) == false) {\r
fd6c41f5 300 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 301 continue;\r
302 }\r
303\r
a29c47e0 304 //\r
305 // Prepare for toolchain related common properties\r
306 // TOOLCHAIN\r
307 //\r
aca6c736 308 getProject().setProperty("TOOLCHAIN", toolchainList[j]);\r
a29c47e0 309\r
d965d1f6 310 EdkLog.log(this, "Build " + moduleId + " start >>>");\r
311 EdkLog.log(this, "Target: " + targetList[i] + " Tagname: " + toolchainList[j] + " Arch: " + archList[k]);\r
83fba802 312 saq.push(GlobalData.getDoc(fpdModuleId));\r
ff225cbb 313\r
a29c47e0 314 //\r
315 // Prepare for all other common properties\r
316 // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR\r
317 // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE\r
318 // MODULE_DIR, MODULE_RELATIVE_DIR\r
319 // SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH\r
a29c47e0 320 //\r
321 setModuleCommonProperties(archList[k]);\r
ff225cbb 322\r
a29c47e0 323 //\r
ff225cbb 324 // OutputManage prepare for\r
a29c47e0 325 // BIN_DIR, DEST_DIR_DEBUG, DEST_DIR_OUTPUT, BUILD_DIR, FV_DIR\r
326 //\r
327 OutputManager.getInstance().update(getProject());\r
ff225cbb 328\r
a29c47e0 329 if (type.equalsIgnoreCase("all") || type.equalsIgnoreCase("build")) {\r
330 applyBuild(targetList[i], toolchainList[j], fpdModuleId);\r
e3cc4061 331 } else {\r
332 applyNonBuildTarget(fpdModuleId);\r
a29c47e0 333 }\r
334 }\r
335 }\r
878ddf1f 336 }\r
878ddf1f 337 }\r
338\r
339 /**\r
ff225cbb 340 This method is used to prepare Platform-related information.\r
341\r
a29c47e0 342 <p>In Single Module Build mode, platform-related information is not ready.\r
ff225cbb 343 The method read the system environment variable <code>ACTIVE_PLATFORM</code>\r
a29c47e0 344 and search in the Framework Database. Note that platform name in the Framework\r
345 Database must be unique. </p>\r
ff225cbb 346\r
878ddf1f 347 **/\r
892b0e7a 348 private void prepareSingleModuleBuild() throws EdkException {\r
878ddf1f 349 //\r
a29c47e0 350 // Find out the package which the module belongs to\r
878ddf1f 351 //\r
a29c47e0 352 PackageIdentification packageId = GlobalData.getPackageForModule(moduleId);\r
892b0e7a 353 GlobalData.refreshPackageIdentification(packageId);\r
a29c47e0 354 moduleId.setPackage(packageId);\r
892b0e7a 355 GlobalData.refreshModuleIdentification(moduleId);\r
ff225cbb 356\r
878ddf1f 357 //\r
82516887 358 // Read ACTIVE_PLATFORM's FPD file \r
878ddf1f 359 //\r
de4bb9f6 360 String filename = getProject().getProperty("PLATFORM_FILE");\r
ff225cbb 361\r
de4bb9f6 362 if (filename == null){\r
391dbbb1 363 throw new BuildException("Please set ACTIVE_PLATFORM in the file: Tools/Conf/target.txt if you want to build a single module!");\r
878ddf1f 364 }\r
ff225cbb 365\r
de4bb9f6 366 PlatformIdentification platformId = GlobalData.getPlatform(filename);\r
ff225cbb 367\r
878ddf1f 368 //\r
82516887 369 // Read FPD file (Call FpdParserTask's method)\r
878ddf1f 370 //\r
a29c47e0 371 FpdParserTask fpdParser = new FpdParserTask();\r
372 fpdParser.setProject(getProject());\r
07193171 373 fpdParser.parseFpdFile(platformId.getFpdFile());\r
aca6c736 374 getProject().setProperty("ARCH", fpdParser.getAllArchForModule(moduleId));\r
878ddf1f 375 }\r
376\r
aca6c736 377 private void cleanupProperties() {\r
378 Project newProject = new Project();\r
379\r
380 Hashtable<String, String> passdownProperties = FrameworkBuildTask.originalProperties;\r
381 Iterator<String> iter = passdownProperties.keySet().iterator();\r
382 while (iter.hasNext()) {\r
383 String item = iter.next();\r
384 newProject.setProperty(item, passdownProperties.get(item));\r
385 }\r
386\r
387 newProject.setInputHandler(getProject().getInputHandler());\r
388\r
389 Iterator listenerIter = getProject().getBuildListeners().iterator();\r
390 while (listenerIter.hasNext()) {\r
391 newProject.addBuildListener((BuildListener) listenerIter.next());\r
392 }\r
393\r
394 getProject().initSubProject(newProject);\r
395\r
396 setProject(newProject);\r
397 }\r
878ddf1f 398\r
399 /**\r
a29c47e0 400 Set Module-Related information to properties.\r
82516887 401 \r
402 @param arch current build ARCH\r
878ddf1f 403 **/\r
a29c47e0 404 private void setModuleCommonProperties(String arch) {\r
878ddf1f 405 //\r
a29c47e0 406 // Prepare for all other common properties\r
407 // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR\r
878ddf1f 408 //\r
a29c47e0 409 PackageIdentification packageId = moduleId.getPackage();\r
aca6c736 410 getProject().setProperty("PACKAGE", packageId.getName());\r
411 getProject().setProperty("PACKAGE_GUID", packageId.getGuid());\r
412 getProject().setProperty("PACKAGE_VERSION", packageId.getVersion());\r
413 getProject().setProperty("PACKAGE_DIR", packageId.getPackageDir().replaceAll("(\\\\)", "/"));\r
414 getProject().setProperty("PACKAGE_RELATIVE_DIR", packageId.getPackageRelativeDir().replaceAll("(\\\\)", "/"));\r
ff225cbb 415\r
a29c47e0 416 //\r
417 // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE\r
418 // MODULE_DIR, MODULE_RELATIVE_DIR\r
419 //\r
aca6c736 420 getProject().setProperty("MODULE", moduleId.getName());\r
83fba802 421 String baseName = saq.getModuleOutputFileBasename();\r
a29c47e0 422 if (baseName == null) {\r
aca6c736 423 getProject().setProperty("BASE_NAME", moduleId.getName());\r
82516887 424 } else {\r
aca6c736 425 getProject().setProperty("BASE_NAME", baseName);\r
a29c47e0 426 }\r
aca6c736 427 getProject().setProperty("GUID", moduleId.getGuid());\r
428 getProject().setProperty("FILE_GUID", moduleId.getGuid());\r
429 getProject().setProperty("VERSION", moduleId.getVersion());\r
430 getProject().setProperty("MODULE_TYPE", moduleId.getModuleType());\r
86f3fef0 431 File msaFile = moduleId.getMsaFile();\r
432 String msaFileName = msaFile.getName();\r
433 getProject().setProperty("MODULE_DIR", msaFile.getParent().replaceAll("(\\\\)", "/"));\r
434 getProject().setProperty("MODULE_RELATIVE_DIR", moduleId.getModuleRelativePath().replaceAll("(\\\\)", "/") \r
bc022470 435 + File.separatorChar + msaFileName.substring(0, msaFileName.lastIndexOf('.')));\r
ff225cbb 436\r
a29c47e0 437 //\r
438 // SUBSYSTEM\r
439 //\r
440 String[][] subsystemMap = { { "BASE", "EFI_BOOT_SERVICE_DRIVER"},\r
ff225cbb 441 { "SEC", "EFI_BOOT_SERVICE_DRIVER" },\r
442 { "PEI_CORE", "EFI_BOOT_SERVICE_DRIVER" },\r
443 { "PEIM", "EFI_BOOT_SERVICE_DRIVER" },\r
a29c47e0 444 { "DXE_CORE", "EFI_BOOT_SERVICE_DRIVER" },\r
ff225cbb 445 { "DXE_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
446 { "DXE_RUNTIME_DRIVER", "EFI_RUNTIME_DRIVER" },\r
447 { "DXE_SAL_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
448 { "DXE_SMM_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
449 { "TOOL", "EFI_BOOT_SERVICE_DRIVER" },\r
a29c47e0 450 { "UEFI_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },\r
ff225cbb 451 { "UEFI_APPLICATION", "EFI_APPLICATION" },\r
452 { "USER_DEFINED", "EFI_BOOT_SERVICE_DRIVER"} };\r
453\r
a29c47e0 454 String subsystem = "EFI_BOOT_SERVICE_DRIVER";\r
455 for (int i = 0; i < subsystemMap.length; i++) {\r
456 if (moduleId.getModuleType().equalsIgnoreCase(subsystemMap[i][0])) {\r
457 subsystem = subsystemMap[i][1];\r
458 break ;\r
878ddf1f 459 }\r
460 }\r
aca6c736 461 getProject().setProperty("SUBSYSTEM", subsystem);\r
ff225cbb 462\r
a29c47e0 463 //\r
464 // ENTRYPOINT\r
465 //\r
466 if (arch.equalsIgnoreCase("EBC")) {\r
aca6c736 467 getProject().setProperty("ENTRYPOINT", "EfiStart");\r
82516887 468 } else {\r
aca6c736 469 getProject().setProperty("ENTRYPOINT", "_ModuleEntryPoint");\r
878ddf1f 470 }\r
ff225cbb 471\r
aca6c736 472 getProject().setProperty("OBJECTS", "");\r
878ddf1f 473 }\r
474\r
a29c47e0 475 private void getCompilerFlags(String target, String toolchain, FpdModuleIdentification fpdModuleId) throws EdkException {\r
476 String[] cmd = GlobalData.getToolChainInfo().getCommands();\r
477 for ( int m = 0; m < cmd.length; m++) {\r
878ddf1f 478 //\r
a29c47e0 479 // Set cmd, like CC, DLINK\r
878ddf1f 480 //\r
a29c47e0 481 String[] key = new String[]{target, toolchain, fpdModuleId.getArch(), cmd[m], null};\r
4a6a5026 482 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_PATH;\r
a29c47e0 483 String cmdPath = GlobalData.getCommandSetting(key, fpdModuleId);\r
4a6a5026 484 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_NAME;\r
a29c47e0 485 String cmdName = GlobalData.getCommandSetting(key, fpdModuleId);\r
1549f516 486 if (cmdName.length() == 0) {\r
fd6c41f5 487 EdkLog.log(this, EdkLog.EDK_VERBOSE, "Warning: " + cmd[m] + " hasn't been defined!");\r
488 getProject().setProperty(cmd[m], "");\r
1549f516 489 continue;\r
490 }\r
a29c47e0 491 File cmdFile = new File(cmdPath + File.separatorChar + cmdName);\r
aca6c736 492 getProject().setProperty(cmd[m], cmdFile.getPath().replaceAll("(\\\\)", "/"));\r
ff225cbb 493\r
878ddf1f 494 //\r
a29c47e0 495 // set CC_FLAGS\r
878ddf1f 496 //\r
4a6a5026 497 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FLAGS;\r
a29c47e0 498 String cmdFlags = GlobalData.getCommandSetting(key, fpdModuleId);\r
e04a8a9a 499 if (cmdFlags != null) \r
500 {\r
e04a8a9a 501 getProject().setProperty(cmd[m] + "_FLAGS", cmdFlags);\r
502 } \r
503 else \r
504 {\r
505 getProject().setProperty(cmd[m] + "_FLAGS", "");\r
506 }\r
507\r
878ddf1f 508 //\r
a29c47e0 509 // Set CC_EXT\r
878ddf1f 510 //\r
4a6a5026 511 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_EXT;\r
a29c47e0 512 String extName = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 513 if ( extName != null && ! extName.equalsIgnoreCase("")) {\r
aca6c736 514 getProject().setProperty(cmd[m] + "_EXT", extName);\r
82516887 515 } else {\r
aca6c736 516 getProject().setProperty(cmd[m] + "_EXT", "");\r
878ddf1f 517 }\r
ff225cbb 518\r
878ddf1f 519 //\r
a29c47e0 520 // set CC_FAMILY\r
878ddf1f 521 //\r
4a6a5026 522 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_FAMILY;\r
a29c47e0 523 String toolChainFamily = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 524 if (toolChainFamily != null) {\r
aca6c736 525 getProject().setProperty(cmd[m] + "_FAMILY", toolChainFamily);\r
878ddf1f 526 }\r
ff225cbb 527\r
878ddf1f 528 //\r
a29c47e0 529 // set CC_SPATH\r
878ddf1f 530 //\r
4a6a5026 531 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_SPATH;\r
a29c47e0 532 String spath = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 533 if (spath != null) {\r
aca6c736 534 getProject().setProperty(cmd[m] + "_SPATH", spath.replaceAll("(\\\\)", "/"));\r
82516887 535 } else {\r
aca6c736 536 getProject().setProperty(cmd[m] + "_SPATH", "");\r
878ddf1f 537 }\r
ff225cbb 538\r
878ddf1f 539 //\r
a29c47e0 540 // set CC_DPATH\r
878ddf1f 541 //\r
4a6a5026 542 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_DPATH;\r
a29c47e0 543 String dpath = GlobalData.getCommandSetting(key, fpdModuleId);\r
a29c47e0 544 if (dpath != null) {\r
aca6c736 545 getProject().setProperty(cmd[m] + "_DPATH", dpath.replaceAll("(\\\\)", "/"));\r
82516887 546 } else {\r
aca6c736 547 getProject().setProperty(cmd[m] + "_DPATH", "");\r
878ddf1f 548 }\r
c639781e 549 \r
550 //\r
551 // Set CC_LIBPATH\r
552 //\r
553 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_LIBPATH;\r
554 String libpath = GlobalData.getCommandSetting(key, fpdModuleId);\r
555 if (libpath != null) {\r
556 getProject().setProperty(cmd[m] + "_LIBPATH", libpath.replaceAll("(\\\\)", "/"));\r
557 } else {\r
558 getProject().setProperty(cmd[m] + "_LIBPATH", "");\r
559 }\r
560 \r
561 //\r
562 // Set CC_INCLUDEPATH\r
563 //\r
564 key[4] = ToolDefinitions.TOOLS_DEF_ATTRIBUTE_INCLUDEPATH;\r
565 String includepath = GlobalData.getCommandSetting(key, fpdModuleId);\r
566 if (dpath != null) {\r
567 getProject().setProperty(cmd[m] + "_INCLUDEPATH", includepath.replaceAll("(\\\\)", "/"));\r
568 } else {\r
569 getProject().setProperty(cmd[m] + "_INCLUDEPATH", "");\r
570 }\r
878ddf1f 571 }\r
a29c47e0 572 }\r
ff225cbb 573\r
a29c47e0 574 public void setMsaFile(File msaFile) {\r
575 this.msaFile = msaFile;\r
878ddf1f 576 }\r
577\r
578 /**\r
ff225cbb 579 Method is for ANT to initialize MSA file.\r
580\r
a29c47e0 581 @param msaFilename MSA file name\r
878ddf1f 582 **/\r
a29c47e0 583 public void setMsaFile(String msaFilename) {\r
584 String moduleDir = getProject().getProperty("MODULE_DIR");\r
ff225cbb 585\r
a29c47e0 586 //\r
587 // If is Single Module Build, then use the Base Dir defined in build.xml\r
588 //\r
589 if (moduleDir == null) {\r
590 moduleDir = getProject().getBaseDir().getPath();\r
878ddf1f 591 }\r
a29c47e0 592 msaFile = new File(moduleDir + File.separatorChar + msaFilename);\r
593 }\r
ff225cbb 594\r
a29c47e0 595 public void addConfiguredModuleItem(ModuleItem moduleItem) {\r
596 PackageIdentification packageId = new PackageIdentification(moduleItem.getPackageGuid(), moduleItem.getPackageVersion());\r
597 ModuleIdentification moduleId = new ModuleIdentification(moduleItem.getModuleGuid(), moduleItem.getModuleVersion());\r
598 moduleId.setPackage(packageId);\r
599 this.moduleId = moduleId;\r
600 }\r
ff225cbb 601\r
a29c47e0 602 /**\r
ff225cbb 603 Add a property.\r
604\r
a29c47e0 605 @param p property\r
606 **/\r
607 public void addProperty(Property p) {\r
608 properties.addElement(p);\r
609 }\r
610\r
611 public void setType(String type) {\r
612 this.type = type;\r
613 }\r
ff225cbb 614\r
892b0e7a 615 private void applyBuild(String buildTarget, String buildTagname, FpdModuleIdentification fpdModuleId) throws EdkException {\r
a29c47e0 616 //\r
83fba802 617 // Call AutoGen to generate AutoGen.c and AutoGen.h\r
a29c47e0 618 //\r
2eb7d78d 619 AutoGen autogen = new AutoGen(getProject().getProperty("FV_DIR"), getProject().getProperty("DEST_DIR_DEBUG"), fpdModuleId.getModule(),fpdModuleId.getArch(), saq, parentId);\r
136adffc 620 autogen.genAutogen();\r
ff225cbb 621\r
a29c47e0 622 //\r
623 // Get compiler flags\r
624 //\r
82516887 625 try {\r
626 getCompilerFlags(buildTarget, buildTagname, fpdModuleId);\r
627 }\r
628 catch (EdkException ee) {\r
629 throw new BuildException(ee.getMessage());\r
630 }\r
631 \r
a29c47e0 632 //\r
633 // Prepare LIBS\r
634 //\r
83fba802 635 ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());\r
a29c47e0 636 String propertyLibs = "";\r
637 for (int i = 0; i < libinstances.length; i++) {\r
498e9021 638 propertyLibs += getProject().getProperty("BIN_DIR") + File.separatorChar + libinstances[i].getName() + ".lib" + " ";\r
878ddf1f 639 }\r
aca6c736 640 getProject().setProperty("LIBS", propertyLibs.replaceAll("(\\\\)", "/"));\r
ff225cbb 641\r
bf3a7173 642 //\r
643 // Get all includepath and set to INCLUDE_PATHS\r
644 //\r
645 String[] includes = prepareIncludePaths(fpdModuleId);\r
646 \r
a29c47e0 647 //\r
648 // if it is CUSTOM_BUILD\r
649 // then call the exist BaseName_build.xml directly.\r
650 //\r
98840b10 651 String buildFilename = "";\r
652 if ((buildFilename = GetCustomizedBuildFile(fpdModuleId.getArch())) != "") {\r
653 EdkLog.log(this, "Call user-defined " + buildFilename);\r
82516887 654 \r
98840b10 655 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + buildFilename;\r
82516887 656 antCall(antFilename, null);\r
657 \r
a29c47e0 658 return ;\r
878ddf1f 659 }\r
ff225cbb 660\r
878ddf1f 661 //\r
a29c47e0 662 // Generate ${BASE_NAME}_build.xml\r
663 // TBD\r
878ddf1f 664 //\r
83fba802 665 String ffsKeyword = saq.getModuleFfsKeyword();\r
666 ModuleBuildFileGenerator fileGenerator = new ModuleBuildFileGenerator(getProject(), ffsKeyword, fpdModuleId, includes, saq);\r
98840b10 667 buildFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
a29c47e0 668 fileGenerator.genBuildFile(buildFilename);\r
ff225cbb 669\r
a29c47e0 670 //\r
671 // Ant call ${BASE_NAME}_build.xml\r
672 //\r
82516887 673 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
674 antCall(antFilename, null);\r
a29c47e0 675 }\r
ff225cbb 676\r
e3cc4061 677 private void applyNonBuildTarget(FpdModuleIdentification fpdModuleId){\r
678 //\r
679 // if it is CUSTOM_BUILD\r
680 // then call the exist BaseName_build.xml directly.\r
681 //\r
682 if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
683 EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml");\r
684 \r
685 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";\r
686 antCall(antFilename, this.type);\r
687 \r
688 return ;\r
689 }\r
690\r
691 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
692 antCall(antFilename, this.type);\r
693 }\r
694\r
a29c47e0 695 private void applyClean(FpdModuleIdentification fpdModuleId){\r
696 //\r
697 // if it is CUSTOM_BUILD\r
698 // then call the exist BaseName_build.xml directly.\r
699 //\r
700 if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
d965d1f6 701 EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml");\r
82516887 702 \r
703 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";\r
704 antCall(antFilename, "clean");\r
705 \r
a29c47e0 706 return ;\r
878ddf1f 707 }\r
ff225cbb 708\r
82516887 709 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
710 antCall(antFilename, "clean");\r
a29c47e0 711 }\r
ff225cbb 712\r
a29c47e0 713 private void applyCleanall(FpdModuleIdentification fpdModuleId){\r
714 //\r
715 // if it is CUSTOM_BUILD\r
716 // then call the exist BaseName_build.xml directly.\r
717 //\r
718 if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {\r
d965d1f6 719 EdkLog.log(this, "Calling user-defined " + moduleId.getName() + "_build.xml");\r
82516887 720\r
721 String antFilename = getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml";\r
722 antCall(antFilename, "cleanall");\r
723 \r
a29c47e0 724 return ;\r
878ddf1f 725 }\r
82516887 726 \r
727 String antFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";\r
728 antCall(antFilename, "cleanall");\r
729 }\r
ff225cbb 730\r
82516887 731 private void antCall(String antFilename, String target) {\r
a29c47e0 732 Ant ant = new Ant();\r
733 ant.setProject(getProject());\r
82516887 734 ant.setAntfile(antFilename);\r
735 if (target != null) {\r
736 ant.setTarget(target);\r
737 }\r
a29c47e0 738 ant.setInheritAll(true);\r
739 ant.init();\r
740 ant.execute();\r
878ddf1f 741 }\r
742\r
de4bb9f6 743 public void setSingleModuleBuild(boolean isSingleModuleBuild) {\r
744 this.isSingleModuleBuild = isSingleModuleBuild;\r
745 }\r
bf3a7173 746 \r
892b0e7a 747 private String[] prepareIncludePaths(FpdModuleIdentification fpdModuleId) throws EdkException{\r
bf3a7173 748 //\r
749 // Prepare the includes: PackageDependencies and Output debug direactory\r
750 //\r
751 Set<String> includes = new LinkedHashSet<String>();\r
752 String arch = fpdModuleId.getArch();\r
753 \r
754 //\r
755 // WORKSPACE\r
756 //\r
757 includes.add("${WORKSPACE_DIR}" + File.separatorChar);\r
758 \r
759 //\r
760 // Module iteself\r
761 //\r
762 includes.add("${MODULE_DIR}");\r
763 includes.add("${MODULE_DIR}" + File.separatorChar + archDir(arch));\r
764 \r
765 //\r
766 // Packages in PackageDenpendencies\r
767 //\r
83fba802 768 PackageIdentification[] packageDependencies = saq.getDependencePkg(fpdModuleId.getArch());\r
bf3a7173 769 for (int i = 0; i < packageDependencies.length; i++) {\r
770 GlobalData.refreshPackageIdentification(packageDependencies[i]);\r
771 File packageFile = packageDependencies[i].getSpdFile();\r
772 includes.add(packageFile.getParent() + File.separatorChar + "Include");\r
773 includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));\r
774 }\r
775\r
776 //\r
777 // All Dependency Library Instance's PackageDependencies\r
778 //\r
83fba802 779 ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());\r
bf3a7173 780 for (int i = 0; i < libinstances.length; i++) {\r
83fba802 781 saq.push(GlobalData.getDoc(libinstances[i], fpdModuleId.getArch()));\r
782 PackageIdentification[] libraryPackageDependencies = saq.getDependencePkg(fpdModuleId.getArch());\r
bf3a7173 783 for (int j = 0; j < libraryPackageDependencies.length; j++) {\r
784 GlobalData.refreshPackageIdentification(libraryPackageDependencies[j]);\r
785 File packageFile = libraryPackageDependencies[j].getSpdFile();\r
786 includes.add(packageFile.getParent() + File.separatorChar + "Include");\r
787 includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));\r
788 }\r
83fba802 789 saq.pop();\r
bf3a7173 790 }\r
791 \r
792 \r
793 //\r
794 // The package which the module belongs to\r
795 // TBD\r
796 includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include");\r
797 includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include" + File.separatorChar + archDir(arch));\r
798\r
799 //\r
800 // Debug files output directory\r
801 //\r
802 includes.add("${DEST_DIR_DEBUG}");\r
803 \r
804 //\r
805 // set to INCLUDE_PATHS property\r
806 //\r
807 Iterator<String> iter = includes.iterator();\r
808 StringBuffer includePaths = new StringBuffer();\r
809 while (iter.hasNext()) {\r
810 includePaths.append(iter.next());\r
811 includePaths.append("; ");\r
812 }\r
aca6c736 813 getProject().setProperty("INCLUDE_PATHS", getProject().replaceProperties(includePaths.toString()).replaceAll("(\\\\)", "/"));\r
bf3a7173 814 \r
815 return includes.toArray(new String[includes.size()]);\r
816 }\r
817 \r
818 /**\r
819 Return the name of the directory that corresponds to the architecture.\r
820 This is a translation from the XML Schema tag to a directory that\r
821 corresponds to our directory name coding convention.\r
822 \r
823 **/\r
824 private String archDir(String arch) {\r
825 return arch.replaceFirst("X64", "x64")\r
826 .replaceFirst("IPF", "Ipf")\r
827 .replaceFirst("IA32", "Ia32")\r
828 .replaceFirst("ARM", "Arm")\r
829 .replaceFirst("EBC", "Ebc");\r
19bf6b15 830 }\r
831 \r
832 \r
833 public void setExternalProperties(Vector<Property> v) {\r
834 this.properties = v;\r
835 }\r
98840b10 836\r
837 private String GetCustomizedBuildFile(String arch) {\r
838 String[][] files = saq.getSourceFiles(arch);\r
839 for (int i = 0; i < files.length; ++i) {\r
840 if (files[i][1].endsWith("build.xml")) {\r
841 return files[i][1];\r
842 }\r
843 }\r
844\r
845 return "";\r
846 }\r
878ddf1f 847}\r