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