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