| 1 | /** @file\r |
| 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 |
| 5 | ANT script build.xml, then call the the ANT script to build the module.\r |
| 6 | \r |
| 7 | Copyright (c) 2006, Intel Corporation\r |
| 8 | All rights reserved. This program and the accompanying materials\r |
| 9 | are licensed and made available under the terms and conditions of the BSD License\r |
| 10 | which accompanies this distribution. The full text of the license may be found at\r |
| 11 | http://opensource.org/licenses/bsd-license.php\r |
| 12 | \r |
| 13 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r |
| 14 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r |
| 15 | **/\r |
| 16 | package org.tianocore.build;\r |
| 17 | \r |
| 18 | import java.io.File;\r |
| 19 | import java.util.HashMap;\r |
| 20 | import java.util.HashSet;\r |
| 21 | import java.util.Iterator;\r |
| 22 | import java.util.LinkedHashSet;\r |
| 23 | import java.util.List;\r |
| 24 | import java.util.Map;\r |
| 25 | import java.util.Set;\r |
| 26 | import java.util.Vector;\r |
| 27 | import java.util.regex.Matcher;\r |
| 28 | import java.util.regex.Pattern;\r |
| 29 | \r |
| 30 | import javax.xml.parsers.DocumentBuilder;\r |
| 31 | import javax.xml.parsers.DocumentBuilderFactory;\r |
| 32 | import javax.xml.transform.OutputKeys;\r |
| 33 | import javax.xml.transform.Result;\r |
| 34 | import javax.xml.transform.Source;\r |
| 35 | import javax.xml.transform.Transformer;\r |
| 36 | import javax.xml.transform.TransformerFactory;\r |
| 37 | import javax.xml.transform.dom.DOMSource;\r |
| 38 | import javax.xml.transform.stream.StreamResult;\r |
| 39 | \r |
| 40 | import org.apache.tools.ant.BuildException;\r |
| 41 | import org.apache.tools.ant.Project;\r |
| 42 | import org.apache.tools.ant.Task;\r |
| 43 | import org.apache.tools.ant.taskdefs.Ant;\r |
| 44 | import org.apache.xmlbeans.XmlObject;\r |
| 45 | import org.w3c.dom.Comment;\r |
| 46 | import org.w3c.dom.Document;\r |
| 47 | import org.w3c.dom.Element;\r |
| 48 | import org.w3c.dom.Node;\r |
| 49 | \r |
| 50 | import org.tianocore.build.autogen.AutoGen;\r |
| 51 | import org.tianocore.build.autogen.CommonDefinition;\r |
| 52 | import org.tianocore.build.fpd.FpdParserTask;\r |
| 53 | import org.tianocore.build.global.GlobalData;\r |
| 54 | import org.tianocore.build.global.OutputManager;\r |
| 55 | import org.tianocore.build.global.SurfaceAreaQuery;\r |
| 56 | import org.tianocore.build.toolchain.ToolChainFactory;\r |
| 57 | import org.tianocore.FilenameDocument;\r |
| 58 | import org.tianocore.MsaHeaderDocument;\r |
| 59 | import org.tianocore.MsaLibHeaderDocument;\r |
| 60 | \r |
| 61 | /**\r |
| 62 | <p>\r |
| 63 | <code>GenBuildTask</code> is an ANT task that can be used in ANT build\r |
| 64 | system. The main function of this task is to parse module's surface area,\r |
| 65 | then generate the corresponding <em>BaseName_build.xml</em> (the real ANT\r |
| 66 | build script) and call this to build the module.\r |
| 67 | </p>\r |
| 68 | \r |
| 69 | <p>\r |
| 70 | The usage is (take module <em>HelloWorld</em> for example):\r |
| 71 | </p>\r |
| 72 | \r |
| 73 | <pre>\r |
| 74 | <GenBuild baseName="HelloWorld" \r |
| 75 | mbdFilename="${MODULE_DIR}/HelloWorld.mbd" \r |
| 76 | msaFilename="${MODULE_DIR}/HelloWorld.msa"/>\r |
| 77 | </pre>\r |
| 78 | \r |
| 79 | <p>\r |
| 80 | This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and\r |
| 81 | <em>AutoGen.h</em>. The task also parses the development environment\r |
| 82 | configuration files, such as collecting package information, setting compiler\r |
| 83 | flags and so on.\r |
| 84 | </p>\r |
| 85 | \r |
| 86 | \r |
| 87 | @since GenBuild 1.0\r |
| 88 | **/\r |
| 89 | public class GenBuildTask extends Task {\r |
| 90 | \r |
| 91 | ///\r |
| 92 | /// Module surface area file.\r |
| 93 | ///\r |
| 94 | File msaFilename;\r |
| 95 | \r |
| 96 | ///\r |
| 97 | /// Module build description file.\r |
| 98 | ///\r |
| 99 | File mbdFilename;\r |
| 100 | \r |
| 101 | ///\r |
| 102 | /// Module surface area information after overrided.\r |
| 103 | ///\r |
| 104 | public Map<String, XmlObject> map = new HashMap<String, XmlObject>();\r |
| 105 | \r |
| 106 | ///\r |
| 107 | /// Module's base name.\r |
| 108 | ///\r |
| 109 | private String baseName;\r |
| 110 | \r |
| 111 | ///\r |
| 112 | /// Current build Arch, such as IA32, X64, IPF and so on.\r |
| 113 | ///\r |
| 114 | private String arch;\r |
| 115 | \r |
| 116 | ///\r |
| 117 | /// Module's GUID (Globally Unique Identifier).\r |
| 118 | ///\r |
| 119 | private String guid;\r |
| 120 | \r |
| 121 | ///\r |
| 122 | /// Module's component type, such as SEC, LIBRARY, BS_DRIVER and so on.\r |
| 123 | ///\r |
| 124 | private String componentType;\r |
| 125 | \r |
| 126 | ///\r |
| 127 | /// This value is used in build time. Override module's component type. When\r |
| 128 | /// search FFS (Sections information) in common file, buildtype instead of\r |
| 129 | /// component type.\r |
| 130 | ///\r |
| 131 | private String buildType;\r |
| 132 | \r |
| 133 | ///\r |
| 134 | /// List all required includes for current build module.\r |
| 135 | ///\r |
| 136 | public Set<String> includes = new LinkedHashSet<String>();\r |
| 137 | \r |
| 138 | ///\r |
| 139 | /// List all libraries for current build module.\r |
| 140 | ///\r |
| 141 | public Set<String> libraries = new LinkedHashSet<String>();\r |
| 142 | \r |
| 143 | ///\r |
| 144 | /// List all source files for current build module.\r |
| 145 | ///\r |
| 146 | public Set<String> sourceFiles = new LinkedHashSet<String>();\r |
| 147 | \r |
| 148 | ///\r |
| 149 | /// Flag to identify what surface area files are specified. Current value is\r |
| 150 | /// <em>NO_SA</em>, <em>ONLY_MSA</em>, <em>ONLY_LIBMSA</em>,\r |
| 151 | /// <em>MSA_AND_MBD</em> or <em>LIBMSA_AND_LIBMBD</em>.\r |
| 152 | /// \r |
| 153 | /// @see org.tianocore.build.global.GlobaData\r |
| 154 | ///\r |
| 155 | private int flag = GlobalData.NO_SA;\r |
| 156 | \r |
| 157 | ///\r |
| 158 | /// The information at the header of <em>build.xml</em>.\r |
| 159 | ///\r |
| 160 | private String info = "====================================================================\n"\r |
| 161 | + "DO NOT EDIT \n"\r |
| 162 | + "File auto-generated by build utility\n"\r |
| 163 | + "\n"\r |
| 164 | + "Abstract:\n"\r |
| 165 | + "Auto-generated ANT build file for building of EFI Modules/Platforms\n"\r |
| 166 | + "=====================================================================";\r |
| 167 | \r |
| 168 | /**\r |
| 169 | Public construct method. It is necessary for ANT task.\r |
| 170 | **/\r |
| 171 | public GenBuildTask() {\r |
| 172 | }\r |
| 173 | \r |
| 174 | /**\r |
| 175 | ANT task's entry point, will be called after init(). The main steps is described\r |
| 176 | as following: \r |
| 177 | <ul>\r |
| 178 | <li> Judge current build mode (MODULE | PACKAGE | PLATFORM). This step will execute\r |
| 179 | only once in whole build process; </li>\r |
| 180 | <li> Initialize global information (Framework DB, SPD files and all MSA files \r |
| 181 | listed in SPD). This step will execute only once in whole build process; </li>\r |
| 182 | <li> Restore some important ANT property. If current build is single module \r |
| 183 | build, here will set many default values; </li>\r |
| 184 | <li> Get the current module's overridded surface area information from \r |
| 185 | global data; </li> \r |
| 186 | <li> Set up the output directories, including BIN_DIR, DEST_DIR_OUTPUT and\r |
| 187 | DEST_DIR_DEBUG; </li>\r |
| 188 | <li> Get module dependent library instances and include pathes; </li>\r |
| 189 | <li> Judge whether current module is built. If yes, skip it; </li>\r |
| 190 | <li> Call AutoGen and PCD to generate AutoGen.c & AutoGen.h </li>\r |
| 191 | <li> Set up the compile flags; </li>\r |
| 192 | <li> Generate BaseName_build.xml; </li>\r |
| 193 | <li> Call to BaseName_build.xml, and build the current module. </li>\r |
| 194 | </ul>\r |
| 195 | \r |
| 196 | <p>Build is dependent on BuildMacro.xml which define many macro. </p> \r |
| 197 | \r |
| 198 | @throws BuildException\r |
| 199 | From module build, exception from module surface area invalid.\r |
| 200 | **/\r |
| 201 | public void execute() throws BuildException {\r |
| 202 | System.out.println("Module [" + baseName + "] start.");\r |
| 203 | OutputManager.update(getProject());\r |
| 204 | GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db",\r |
| 205 | getProject().getProperty("WORKSPACE_DIR"));\r |
| 206 | recallFixedProperties();\r |
| 207 | arch = getProject().getProperty("ARCH");\r |
| 208 | arch = arch.toUpperCase();\r |
| 209 | map = GlobalData.getDoc(baseName);\r |
| 210 | //\r |
| 211 | // Initialize SurfaceAreaQuery\r |
| 212 | //\r |
| 213 | SurfaceAreaQuery.setDoc(map);\r |
| 214 | //\r |
| 215 | // Setup Output Management\r |
| 216 | //\r |
| 217 | String[] outdir = SurfaceAreaQuery.getOutputDirectory();\r |
| 218 | OutputManager.update(getProject(), outdir[1], outdir[0]);\r |
| 219 | \r |
| 220 | updateIncludesAndLibraries();\r |
| 221 | \r |
| 222 | if (GlobalData.isModuleBuilt(baseName, arch)) {\r |
| 223 | return;\r |
| 224 | } else {\r |
| 225 | GlobalData.registerBuiltModule(baseName, arch);\r |
| 226 | }\r |
| 227 | //\r |
| 228 | // Call AutoGen\r |
| 229 | //\r |
| 230 | AutoGen autogen = new AutoGen(getProject().getProperty("DEST_DIR_DEBUG"), baseName, arch);\r |
| 231 | autogen.genAutogen();\r |
| 232 | //\r |
| 233 | // Update parameters\r |
| 234 | //\r |
| 235 | updateParameters();\r |
| 236 | //\r |
| 237 | // Update flags like CC_FLAGS, LIB_FLAGS etc.\r |
| 238 | //\r |
| 239 | flagsSetup();\r |
| 240 | GlobalData.addLibrary(baseName, arch, getProject().getProperty("BIN_DIR") + File.separatorChar + baseName + ".lib");\r |
| 241 | GlobalData.addModuleLibrary(baseName, arch, libraries);\r |
| 242 | //\r |
| 243 | // If ComponentType is USER_DEFINED,\r |
| 244 | // then call the exist BaseName_build.xml directly.\r |
| 245 | //\r |
| 246 | if (buildType.equalsIgnoreCase("CUSTOM_BUILD")) {\r |
| 247 | System.out.println("Call user-defined " + baseName + "_build.xml");\r |
| 248 | Ant ant = new Ant();\r |
| 249 | ant.setProject(getProject());\r |
| 250 | ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + baseName + "_build.xml");\r |
| 251 | ant.setInheritAll(true);\r |
| 252 | ant.init();\r |
| 253 | ant.execute();\r |
| 254 | return;\r |
| 255 | }\r |
| 256 | //\r |
| 257 | // Generate ${BASE_NAME}_build.xml file\r |
| 258 | //\r |
| 259 | System.out.println("Generate " + baseName + "_build.xml");\r |
| 260 | genBuildFile();\r |
| 261 | System.out.println("Call the " + baseName + "_build.xml");\r |
| 262 | Ant ant = new Ant();\r |
| 263 | ant.setProject(getProject());\r |
| 264 | ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName + "_build.xml");\r |
| 265 | ant.setInheritAll(true);\r |
| 266 | ant.init();\r |
| 267 | ant.execute();\r |
| 268 | }\r |
| 269 | \r |
| 270 | /**\r |
| 271 | Return the name of the directory that corresponds to the architecture.\r |
| 272 | This is a translation from the XML Schema tag to a directory that\r |
| 273 | corresponds to our directory name coding convention.\r |
| 274 | \r |
| 275 | **/\r |
| 276 | private String archDir(String arch) {\r |
| 277 | return arch.replaceFirst("X64", "x64")\r |
| 278 | .replaceFirst("IPF", "Ipf")\r |
| 279 | .replaceFirst("IA32", "Ia32")\r |
| 280 | .replaceFirst("ARM", "Arm")\r |
| 281 | .replaceFirst("EBC", "Ebc");\r |
| 282 | }\r |
| 283 | \r |
| 284 | /**\r |
| 285 | Get the dependent library instances and include package name from \r |
| 286 | surface area, and initialize module include pathes. \r |
| 287 | \r |
| 288 | **/\r |
| 289 | private void updateIncludesAndLibraries() {\r |
| 290 | List<String> rawIncludes = SurfaceAreaQuery.getIncludePackageName(arch);\r |
| 291 | if (rawIncludes != null) {\r |
| 292 | Iterator iter = rawIncludes.iterator();\r |
| 293 | while (iter.hasNext()) {\r |
| 294 | String packageName = (String) iter.next();\r |
| 295 | includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)\r |
| 296 | + File.separatorChar + "Include");\r |
| 297 | includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)\r |
| 298 | + File.separatorChar + "Include" + File.separatorChar + archDir(arch));\r |
| 299 | }\r |
| 300 | }\r |
| 301 | includes.add("${DEST_DIR_DEBUG}");\r |
| 302 | List<String> rawLibraries = SurfaceAreaQuery.getLibraryInstance(this.arch, CommonDefinition.AlwaysConsumed);\r |
| 303 | if (rawLibraries != null) {\r |
| 304 | Iterator iter = rawLibraries.iterator();\r |
| 305 | while (iter.hasNext()) {\r |
| 306 | libraries.add((String) iter.next());\r |
| 307 | }\r |
| 308 | }\r |
| 309 | normalize();\r |
| 310 | }\r |
| 311 | \r |
| 312 | /**\r |
| 313 | Normalize all dependent library instance and include pathes' format. \r |
| 314 | \r |
| 315 | **/\r |
| 316 | private void normalize() {\r |
| 317 | String[] includesArray = includes.toArray(new String[includes.size()]);\r |
| 318 | includes.clear();\r |
| 319 | for (int i = 0; i < includesArray.length; i++) {\r |
| 320 | includes.add((new File(includesArray[i])).getPath());\r |
| 321 | }\r |
| 322 | String[] librariesArray = libraries.toArray(new String[libraries.size()]);\r |
| 323 | libraries.clear();\r |
| 324 | for (int i = 0; i < librariesArray.length; i++) {\r |
| 325 | libraries.add((new File(librariesArray[i])).getPath());\r |
| 326 | }\r |
| 327 | }\r |
| 328 | \r |
| 329 | /**\r |
| 330 | Restore some important ANT property. If current build is single module \r |
| 331 | build, here will set many default values.\r |
| 332 | \r |
| 333 | <p> If current build is single module build, then the default <code>ARCH</code>\r |
| 334 | is <code>IA32</code>. Also set up the properties <code>PACKAGE</code>, \r |
| 335 | <code>PACKAGE_DIR</code>, <code>TARGET</code> and <code>MODULE_DIR</code></p>\r |
| 336 | \r |
| 337 | <p> Note that for package build, package name is stored in <code>PLATFORM</code>\r |
| 338 | and package directory is stored in <code>PLATFORM_DIR</code>. </p> \r |
| 339 | \r |
| 340 | @see org.tianocore.build.global.OutputManager\r |
| 341 | **/\r |
| 342 | private void recallFixedProperties() {\r |
| 343 | //\r |
| 344 | // If build is for module build\r |
| 345 | //\r |
| 346 | if (getProject().getProperty("PACKAGE_DIR") == null) {\r |
| 347 | ToolChainFactory toolChainFactory = new ToolChainFactory(getProject());\r |
| 348 | toolChainFactory.setupToolChain();\r |
| 349 | //\r |
| 350 | // PACKAGE PACKAGE_DIR ARCH (Default) COMMON_FILE BUILD_MACRO\r |
| 351 | //\r |
| 352 | if (getProject().getProperty("ARCH") == null) {\r |
| 353 | getProject().setProperty("ARCH", "IA32");\r |
| 354 | }\r |
| 355 | String packageName = GlobalData.getPackageNameForModule(baseName);\r |
| 356 | getProject().setProperty("PACKAGE", packageName);\r |
| 357 | \r |
| 358 | String packageDir = GlobalData.getPackagePath(packageName);\r |
| 359 | getProject().setProperty("PACKAGE_DIR",\r |
| 360 | getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + packageDir);\r |
| 361 | \r |
| 362 | getProject().setProperty("TARGET", toolChainFactory.getCurrentTarget());\r |
| 363 | \r |
| 364 | getProject().setProperty("MODULE_DIR",\r |
| 365 | getProject().replaceProperties(getProject().getProperty("MODULE_DIR")));\r |
| 366 | }\r |
| 367 | if (OutputManager.PLATFORM != null) {\r |
| 368 | getProject().setProperty("PLATFORM", OutputManager.PLATFORM);\r |
| 369 | }\r |
| 370 | if (OutputManager.PLATFORM_DIR != null) {\r |
| 371 | getProject().setProperty("PLATFORM_DIR", OutputManager.PLATFORM_DIR);\r |
| 372 | }\r |
| 373 | }\r |
| 374 | \r |
| 375 | /**\r |
| 376 | The whole BaseName_build.xml is composed of seven part. \r |
| 377 | <ul>\r |
| 378 | <li> ANT properties; </li>\r |
| 379 | <li> Dependent module (dependent library instances in most case); </li>\r |
| 380 | <li> Source files; </li>\r |
| 381 | <li> Sections if module is not library; </li>\r |
| 382 | <li> Output (different for library module and driver module); </li>\r |
| 383 | <li> Clean; </li>\r |
| 384 | <li> Clean all. </li>\r |
| 385 | </ul>\r |
| 386 | \r |
| 387 | @throws BuildException\r |
| 388 | Error throws during BaseName_build.xml generating. \r |
| 389 | **/\r |
| 390 | private void genBuildFile() throws BuildException {\r |
| 391 | FfsProcess fp = new FfsProcess();\r |
| 392 | DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();\r |
| 393 | try {\r |
| 394 | DocumentBuilder dombuilder = domfac.newDocumentBuilder();\r |
| 395 | Document document = dombuilder.newDocument();\r |
| 396 | Comment rootComment = document.createComment(info);\r |
| 397 | //\r |
| 398 | // create root element and its attributes\r |
| 399 | //\r |
| 400 | Element root = document.createElement("project");\r |
| 401 | //\r |
| 402 | // root.setAttribute("name", base_name);\r |
| 403 | //\r |
| 404 | root.setAttribute("default", "main");\r |
| 405 | root.setAttribute("basedir", ".");\r |
| 406 | //\r |
| 407 | // element for External ANT tasks\r |
| 408 | //\r |
| 409 | root.appendChild(document.createComment("Apply external ANT tasks"));\r |
| 410 | Element ele = document.createElement("taskdef");\r |
| 411 | ele.setAttribute("resource", "frameworktasks.tasks");\r |
| 412 | root.appendChild(ele);\r |
| 413 | ele = document.createElement("taskdef");\r |
| 414 | ele.setAttribute("resource", "cpptasks.tasks");\r |
| 415 | root.appendChild(ele);\r |
| 416 | ele = document.createElement("typedef");\r |
| 417 | ele.setAttribute("resource", "cpptasks.types");\r |
| 418 | root.appendChild(ele);\r |
| 419 | ele = document.createElement("taskdef");\r |
| 420 | ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");\r |
| 421 | root.appendChild(ele);\r |
| 422 | //\r |
| 423 | // elements for Properties\r |
| 424 | //\r |
| 425 | root.appendChild(document.createComment("All Properties"));\r |
| 426 | ele = document.createElement("property");\r |
| 427 | ele.setAttribute("name", "BASE_NAME");\r |
| 428 | ele.setAttribute("value", baseName);\r |
| 429 | root.appendChild(ele);\r |
| 430 | //\r |
| 431 | // Generate the default target,\r |
| 432 | // which depends on init, sections and output target\r |
| 433 | //\r |
| 434 | root.appendChild(document.createComment("Default target"));\r |
| 435 | ele = document.createElement("target");\r |
| 436 | ele.setAttribute("name", "main");\r |
| 437 | ele.setAttribute("depends", "libraries, sourcefiles, sections, output");\r |
| 438 | root.appendChild(ele);\r |
| 439 | //\r |
| 440 | // compile all source files\r |
| 441 | //\r |
| 442 | root.appendChild(document.createComment("Compile all dependency Library instances."));\r |
| 443 | ele = document.createElement("target");\r |
| 444 | ele.setAttribute("name", "libraries");\r |
| 445 | //\r |
| 446 | // Parse all sourfiles but files specified in sections\r |
| 447 | //\r |
| 448 | applyLibraryInstance(document, ele);\r |
| 449 | root.appendChild(ele);\r |
| 450 | //\r |
| 451 | // compile all source files\r |
| 452 | //\r |
| 453 | root.appendChild(document.createComment("sourcefiles target"));\r |
| 454 | ele = document.createElement("target");\r |
| 455 | ele.setAttribute("name", "sourcefiles");\r |
| 456 | //\r |
| 457 | // Parse all sourfiles but files specified in sections\r |
| 458 | //\r |
| 459 | applyCompileElement(document, ele);\r |
| 460 | root.appendChild(ele);\r |
| 461 | //\r |
| 462 | // generate the init target\r |
| 463 | // main purpose is create all nessary pathes\r |
| 464 | // generate the sections target\r |
| 465 | //\r |
| 466 | root.appendChild(document.createComment("sections target"));\r |
| 467 | ele = document.createElement("target");\r |
| 468 | ele.setAttribute("name", "sections");\r |
| 469 | applySectionsElement(document, ele, fp);\r |
| 470 | root.appendChild(ele);\r |
| 471 | //\r |
| 472 | // generate the output target\r |
| 473 | //\r |
| 474 | root.appendChild(document.createComment("output target"));\r |
| 475 | ele = document.createElement("target");\r |
| 476 | ele.setAttribute("name", "output");\r |
| 477 | applyOutputElement(document, ele, fp);\r |
| 478 | root.appendChild(ele);\r |
| 479 | //\r |
| 480 | // generate the clean target\r |
| 481 | //\r |
| 482 | root.appendChild(document.createComment("clean target"));\r |
| 483 | ele = document.createElement("target");\r |
| 484 | ele.setAttribute("name", "clean");\r |
| 485 | applyCleanElement(document, ele);\r |
| 486 | root.appendChild(ele);\r |
| 487 | //\r |
| 488 | // generate the Clean All target\r |
| 489 | //\r |
| 490 | root.appendChild(document.createComment("Clean All target"));\r |
| 491 | ele = document.createElement("target");\r |
| 492 | ele.setAttribute("name", "cleanall");\r |
| 493 | applyDeepcleanElement(document, ele);\r |
| 494 | root.appendChild(ele);\r |
| 495 | //\r |
| 496 | // add the root element to the document\r |
| 497 | //\r |
| 498 | document.appendChild(rootComment);\r |
| 499 | document.appendChild(root);\r |
| 500 | //\r |
| 501 | // Prepare the DOM document for writing\r |
| 502 | //\r |
| 503 | Source source = new DOMSource(document);\r |
| 504 | //\r |
| 505 | // Prepare the output file\r |
| 506 | //\r |
| 507 | File file = new File(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName\r |
| 508 | + "_build.xml");\r |
| 509 | //\r |
| 510 | // generate all directory path\r |
| 511 | //\r |
| 512 | (new File(file.getParent())).mkdirs();\r |
| 513 | Result result = new StreamResult(file);\r |
| 514 | //\r |
| 515 | // Write the DOM document to the file\r |
| 516 | //\r |
| 517 | Transformer xformer = TransformerFactory.newInstance().newTransformer();\r |
| 518 | xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");\r |
| 519 | xformer.setOutputProperty(OutputKeys.INDENT, "yes");\r |
| 520 | xformer.transform(source, result);\r |
| 521 | } catch (Exception ex) {\r |
| 522 | throw new BuildException("Module [" + baseName + "] generating build file failed.\n" + ex.getMessage());\r |
| 523 | }\r |
| 524 | }\r |
| 525 | \r |
| 526 | /**\r |
| 527 | Generate the clean elements for BaseName_build.xml. \r |
| 528 | \r |
| 529 | @param document current BaseName_build.xml XML document\r |
| 530 | @param root Root element for current\r |
| 531 | **/\r |
| 532 | private void applyCleanElement(Document document, Node root) {\r |
| 533 | String[] libinstances = libraries.toArray(new String[libraries.size()]);\r |
| 534 | for (int i = 0; i < libinstances.length; i++) {\r |
| 535 | File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");\r |
| 536 | \r |
| 537 | Element ifEle = document.createElement("if");\r |
| 538 | Element availableEle = document.createElement("available");\r |
| 539 | availableEle.setAttribute("file", file.getPath());\r |
| 540 | ifEle.appendChild(availableEle);\r |
| 541 | Element elseEle = document.createElement("then");\r |
| 542 | \r |
| 543 | Element ele = document.createElement("ant");\r |
| 544 | ele.setAttribute("antfile", file.getPath());\r |
| 545 | ele.setAttribute("inheritAll", "false");\r |
| 546 | ele.setAttribute("target", libinstances[i] + "_clean");\r |
| 547 | //\r |
| 548 | // Workspace_DIR\r |
| 549 | //\r |
| 550 | Element property = document.createElement("property");\r |
| 551 | property.setAttribute("name", "WORKSPACE_DIR");\r |
| 552 | property.setAttribute("value", "${WORKSPACE_DIR}");\r |
| 553 | ele.appendChild(property);\r |
| 554 | //\r |
| 555 | // Package Dir\r |
| 556 | //\r |
| 557 | property = document.createElement("property");\r |
| 558 | property.setAttribute("name", "PACKAGE_DIR");\r |
| 559 | property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar\r |
| 560 | + GlobalData.getPackagePathForModule(libinstances[i]));\r |
| 561 | ele.appendChild(property);\r |
| 562 | //\r |
| 563 | // ARCH\r |
| 564 | //\r |
| 565 | property = document.createElement("property");\r |
| 566 | property.setAttribute("name", "ARCH");\r |
| 567 | property.setAttribute("value", "${ARCH}");\r |
| 568 | ele.appendChild(property);\r |
| 569 | //\r |
| 570 | // TARGET\r |
| 571 | //\r |
| 572 | property = document.createElement("property");\r |
| 573 | property.setAttribute("name", "TARGET");\r |
| 574 | property.setAttribute("value", "${TARGET}");\r |
| 575 | ele.appendChild(property);\r |
| 576 | //\r |
| 577 | // PACKAGE\r |
| 578 | //\r |
| 579 | property = document.createElement("property");\r |
| 580 | property.setAttribute("name", "PACKAGE");\r |
| 581 | property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));\r |
| 582 | ele.appendChild(property);\r |
| 583 | \r |
| 584 | elseEle.appendChild(ele);\r |
| 585 | ifEle.appendChild(elseEle);\r |
| 586 | root.appendChild(ifEle);\r |
| 587 | }\r |
| 588 | }\r |
| 589 | \r |
| 590 | /**\r |
| 591 | Generate the cleanall elements for BaseName_build.xml. \r |
| 592 | \r |
| 593 | @param document current BaseName_build.xml XML document\r |
| 594 | @param root Root element for current\r |
| 595 | **/\r |
| 596 | private void applyDeepcleanElement(Document document, Node root) {\r |
| 597 | String[] libinstances = libraries.toArray(new String[libraries.size()]);\r |
| 598 | for (int i = 0; i < libinstances.length; i++) {\r |
| 599 | File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");\r |
| 600 | \r |
| 601 | Element ifEle = document.createElement("if");\r |
| 602 | Element availableEle = document.createElement("available");\r |
| 603 | availableEle.setAttribute("file", file.getPath());\r |
| 604 | ifEle.appendChild(availableEle);\r |
| 605 | Element elseEle = document.createElement("then");\r |
| 606 | \r |
| 607 | Element ele = document.createElement("ant");\r |
| 608 | ele.setAttribute("antfile", file.getPath());\r |
| 609 | ele.setAttribute("inheritAll", "false");\r |
| 610 | ele.setAttribute("target", libinstances[i] + "_cleanall");\r |
| 611 | //\r |
| 612 | // Workspace_DIR\r |
| 613 | //\r |
| 614 | Element property = document.createElement("property");\r |
| 615 | property.setAttribute("name", "WORKSPACE_DIR");\r |
| 616 | property.setAttribute("value", "${WORKSPACE_DIR}");\r |
| 617 | ele.appendChild(property);\r |
| 618 | //\r |
| 619 | // Package Dir\r |
| 620 | //\r |
| 621 | property = document.createElement("property");\r |
| 622 | property.setAttribute("name", "PACKAGE_DIR");\r |
| 623 | property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar\r |
| 624 | + GlobalData.getPackagePathForModule(libinstances[i]));\r |
| 625 | ele.appendChild(property);\r |
| 626 | //\r |
| 627 | // ARCH\r |
| 628 | //\r |
| 629 | property = document.createElement("property");\r |
| 630 | property.setAttribute("name", "ARCH");\r |
| 631 | property.setAttribute("value", "${ARCH}");\r |
| 632 | ele.appendChild(property);\r |
| 633 | //\r |
| 634 | // TARGET\r |
| 635 | //\r |
| 636 | property = document.createElement("property");\r |
| 637 | property.setAttribute("name", "TARGET");\r |
| 638 | property.setAttribute("value", "${TARGET}");\r |
| 639 | ele.appendChild(property);\r |
| 640 | //\r |
| 641 | // PACKAGE\r |
| 642 | //\r |
| 643 | property = document.createElement("property");\r |
| 644 | property.setAttribute("name", "PACKAGE");\r |
| 645 | property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));\r |
| 646 | ele.appendChild(property);\r |
| 647 | \r |
| 648 | elseEle.appendChild(ele);\r |
| 649 | ifEle.appendChild(elseEle);\r |
| 650 | root.appendChild(ifEle);\r |
| 651 | }\r |
| 652 | }\r |
| 653 | \r |
| 654 | /**\r |
| 655 | Generate the dependent library instances elements for BaseName_build.xml. \r |
| 656 | \r |
| 657 | @param document current BaseName_build.xml XML document\r |
| 658 | @param root Root element for current\r |
| 659 | **/\r |
| 660 | private void applyLibraryInstance(Document document, Node root) {\r |
| 661 | String[] libinstances = libraries.toArray(new String[libraries.size()]);\r |
| 662 | for (int i = 0; i < libinstances.length; i++) {\r |
| 663 | Element ele = document.createElement("ant");\r |
| 664 | File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");\r |
| 665 | ele.setAttribute("antfile", file.getPath());\r |
| 666 | ele.setAttribute("inheritAll", "false");\r |
| 667 | ele.setAttribute("target", libinstances[i]);\r |
| 668 | //\r |
| 669 | // Workspace_DIR\r |
| 670 | //\r |
| 671 | Element property = document.createElement("property");\r |
| 672 | property.setAttribute("name", "WORKSPACE_DIR");\r |
| 673 | property.setAttribute("value", "${WORKSPACE_DIR}");\r |
| 674 | ele.appendChild(property);\r |
| 675 | //\r |
| 676 | // Package Dir\r |
| 677 | //\r |
| 678 | property = document.createElement("property");\r |
| 679 | property.setAttribute("name", "PACKAGE_DIR");\r |
| 680 | property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar\r |
| 681 | + GlobalData.getPackagePathForModule(libinstances[i]));\r |
| 682 | ele.appendChild(property);\r |
| 683 | //\r |
| 684 | // ARCH\r |
| 685 | //\r |
| 686 | property = document.createElement("property");\r |
| 687 | property.setAttribute("name", "ARCH");\r |
| 688 | property.setAttribute("value", "${ARCH}");\r |
| 689 | ele.appendChild(property);\r |
| 690 | //\r |
| 691 | // TARGET\r |
| 692 | //\r |
| 693 | property = document.createElement("property");\r |
| 694 | property.setAttribute("name", "TARGET");\r |
| 695 | property.setAttribute("value", "${TARGET}");\r |
| 696 | ele.appendChild(property);\r |
| 697 | //\r |
| 698 | // PACKAGE\r |
| 699 | //\r |
| 700 | property = document.createElement("property");\r |
| 701 | property.setAttribute("name", "PACKAGE");\r |
| 702 | property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));\r |
| 703 | ele.appendChild(property);\r |
| 704 | root.appendChild(ele);\r |
| 705 | }\r |
| 706 | Element expand = document.createElement("Expand");\r |
| 707 | root.appendChild(expand);\r |
| 708 | }\r |
| 709 | \r |
| 710 | /**\r |
| 711 | Generate the build source files elements for BaseName_build.xml. \r |
| 712 | \r |
| 713 | @param document current BaseName_build.xml XML document\r |
| 714 | @param root Root element for current\r |
| 715 | **/\r |
| 716 | private void applyCompileElement(Document document, Node root) {\r |
| 717 | FileProcess fileProcess = new FileProcess();\r |
| 718 | fileProcess.init(getProject(), includes, sourceFiles, document);\r |
| 719 | Node[] files = this.getSourceFiles();\r |
| 720 | //\r |
| 721 | // Parse all unicode files\r |
| 722 | //\r |
| 723 | for (int i = 0; i < files.length; i++) {\r |
| 724 | String filetype = getFiletype(files[i]);\r |
| 725 | if (filetype != null) {\r |
| 726 | fileProcess.parseFile(getFilename(files[i]), filetype, root, true);\r |
| 727 | } else {\r |
| 728 | fileProcess.parseFile(getFilename(files[i]), root, true);\r |
| 729 | }\r |
| 730 | }\r |
| 731 | if (fileProcess.isUnicodeExist()) {\r |
| 732 | Element ele = document.createElement("Build_Unicode_Database");\r |
| 733 | ele.setAttribute("FILEPATH", ".");\r |
| 734 | ele.setAttribute("FILENAME", "${BASE_NAME}");\r |
| 735 | root.appendChild(ele);\r |
| 736 | }\r |
| 737 | \r |
| 738 | //\r |
| 739 | // Parse AutoGen.c & AutoGen.h\r |
| 740 | //\r |
| 741 | if (!baseName.equalsIgnoreCase("Shell")) {\r |
| 742 | fileProcess.parseFile(getProject().getProperty("DEST_DIR_DEBUG") + File.separatorChar + "AutoGen.c", root,\r |
| 743 | false);\r |
| 744 | }\r |
| 745 | //\r |
| 746 | // Parse all source files\r |
| 747 | //\r |
| 748 | for (int i = 0; i < files.length; i++) {\r |
| 749 | String filetype = getFiletype(files[i]);\r |
| 750 | if (filetype != null) {\r |
| 751 | fileProcess.parseFile(getFilename(files[i]), filetype, root, false);\r |
| 752 | } else {\r |
| 753 | fileProcess.parseFile(getFilename(files[i]), root, false);\r |
| 754 | }\r |
| 755 | }\r |
| 756 | //\r |
| 757 | // root.appendChild(parallelEle);\r |
| 758 | //\r |
| 759 | Iterator iter = sourceFiles.iterator();\r |
| 760 | String str = "";\r |
| 761 | while (iter.hasNext()) {\r |
| 762 | str += " " + (String) iter.next();\r |
| 763 | }\r |
| 764 | getProject().setProperty("SOURCE_FILES", str);\r |
| 765 | }\r |
| 766 | \r |
| 767 | /**\r |
| 768 | Generate the section elements for BaseName_build.xml. Library module will\r |
| 769 | skip this process. \r |
| 770 | \r |
| 771 | @param document current BaseName_build.xml XML document\r |
| 772 | @param root Root element for current\r |
| 773 | **/\r |
| 774 | private void applySectionsElement(Document document, Node root, FfsProcess fp) {\r |
| 775 | if (fp.initSections(buildType, getProject())) {\r |
| 776 | String targetFilename = guid + "-" + baseName + FpdParserTask.getSuffix(componentType);\r |
| 777 | String[] list = fp.getGenSectionElements(document, baseName, guid, targetFilename);\r |
| 778 | \r |
| 779 | for (int i = 0; i < list.length; i++) {\r |
| 780 | Element ele = document.createElement(list[i]);\r |
| 781 | ele.setAttribute("FILEPATH", ".");\r |
| 782 | ele.setAttribute("FILENAME", "${BASE_NAME}");\r |
| 783 | root.appendChild(ele);\r |
| 784 | }\r |
| 785 | }\r |
| 786 | }\r |
| 787 | \r |
| 788 | /**\r |
| 789 | Generate the output elements for BaseName_build.xml. If module is library,\r |
| 790 | call the <em>LIB</em> command, else call the <em>GenFfs</em> command. \r |
| 791 | \r |
| 792 | @param document current BaseName_build.xml XML document\r |
| 793 | @param root Root element for current\r |
| 794 | **/\r |
| 795 | private void applyOutputElement(Document document, Node root, FfsProcess fp) {\r |
| 796 | if (flag == GlobalData.ONLY_LIBMSA || flag == GlobalData.LIBMSA_AND_LIBMBD) {\r |
| 797 | //\r |
| 798 | // call Lib command\r |
| 799 | //\r |
| 800 | Element cc = document.createElement("Build_Library");\r |
| 801 | cc.setAttribute("FILENAME", baseName);\r |
| 802 | root.appendChild(cc);\r |
| 803 | }\r |
| 804 | //\r |
| 805 | // if it is a module but library\r |
| 806 | //\r |
| 807 | else {\r |
| 808 | if (fp.getFfsNode() != null) {\r |
| 809 | root.appendChild(fp.getFfsNode());\r |
| 810 | }\r |
| 811 | }\r |
| 812 | }\r |
| 813 | \r |
| 814 | /**\r |
| 815 | Get file name from node. If some wrong, return string with zero length. \r |
| 816 | \r |
| 817 | @param node Filename node of MSA/MBD or specified in each Section\r |
| 818 | @return File name\r |
| 819 | **/\r |
| 820 | private String getFilename(Node node) {\r |
| 821 | String path = null;\r |
| 822 | String filename = "${MODULE_DIR}" + File.separatorChar;\r |
| 823 | String str = "";\r |
| 824 | try {\r |
| 825 | FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);\r |
| 826 | str = file.getFilename().getStringValue().trim();\r |
| 827 | path = file.getFilename().getPath();\r |
| 828 | } catch (Exception e) {\r |
| 829 | str = "";\r |
| 830 | }\r |
| 831 | if (path != null) {\r |
| 832 | filename += path + File.separatorChar + str;\r |
| 833 | } else {\r |
| 834 | filename += str;\r |
| 835 | }\r |
| 836 | return getProject().replaceProperties(filename);\r |
| 837 | }\r |
| 838 | \r |
| 839 | /**\r |
| 840 | Get file type from node. If some wrong or not specified, return \r |
| 841 | <code>null</code>. \r |
| 842 | \r |
| 843 | @param node Filename node of MSA/MBD or specified in each Section\r |
| 844 | @return File type\r |
| 845 | **/\r |
| 846 | private String getFiletype(Node node) {\r |
| 847 | String str = null;\r |
| 848 | try {\r |
| 849 | FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);\r |
| 850 | str = file.getFilename().getFileType();\r |
| 851 | } catch (Exception e) {\r |
| 852 | str = null;\r |
| 853 | }\r |
| 854 | return str;\r |
| 855 | }\r |
| 856 | \r |
| 857 | /**\r |
| 858 | Return all source files but AutoGen.c.\r |
| 859 | \r |
| 860 | @return source files Node array\r |
| 861 | **/\r |
| 862 | public Node[] getSourceFiles() {\r |
| 863 | XmlObject[] files = SurfaceAreaQuery.getSourceFiles(arch);\r |
| 864 | if (files == null) {\r |
| 865 | return new Node[0];\r |
| 866 | }\r |
| 867 | Vector<Node> vector = new Vector<Node>();\r |
| 868 | for (int i = 0; i < files.length; i++) {\r |
| 869 | vector.addElement(files[i].getDomNode());\r |
| 870 | }\r |
| 871 | //\r |
| 872 | // To be consider sourcefiles from Sections\r |
| 873 | //\r |
| 874 | return vector.toArray(new Node[vector.size()]);\r |
| 875 | }\r |
| 876 | \r |
| 877 | /**\r |
| 878 | Get current module's base name. \r |
| 879 | \r |
| 880 | @return base name\r |
| 881 | **/\r |
| 882 | public String getBaseName() {\r |
| 883 | return baseName;\r |
| 884 | }\r |
| 885 | \r |
| 886 | /**\r |
| 887 | Set MBD surface area file. For ANT use.\r |
| 888 | \r |
| 889 | @param mbdFilename Surface Area file\r |
| 890 | **/\r |
| 891 | public void setMbdFilename(File mbdFilename) {\r |
| 892 | this.mbdFilename = mbdFilename;\r |
| 893 | }\r |
| 894 | \r |
| 895 | /**\r |
| 896 | Set MSA surface area file. For ANT use.\r |
| 897 | \r |
| 898 | @param msaFilename Surface Area file\r |
| 899 | **/\r |
| 900 | public void setMsaFilename(File msaFilename) {\r |
| 901 | this.msaFilename = msaFilename;\r |
| 902 | }\r |
| 903 | \r |
| 904 | /**\r |
| 905 | Compile flags setup. \r |
| 906 | \r |
| 907 | <p> Take command <code>CC</code> and arch <code>IA32</code> for example, \r |
| 908 | Those flags are from <code>ToolChainFactory</code>: </p>\r |
| 909 | <ul>\r |
| 910 | <li> IA32_CC </li>\r |
| 911 | <li> IA32_CC_STD_FLAGS </li>\r |
| 912 | <li> IA32_CC_GLOBAL_FLAGS </li>\r |
| 913 | <li> IA32_CC_GLOBAL_ADD_FLAGS </li>\r |
| 914 | <li> IA32_CC_GLOBAL_SUB_FLAGS </li>\r |
| 915 | </ul>\r |
| 916 | Those flags can user-define: \r |
| 917 | <ul>\r |
| 918 | <li> IA32_CC_PROJ_FLAGS </li>\r |
| 919 | <li> IA32_CC_PROJ_ADD_FLAGS </li>\r |
| 920 | <li> IA32_CC_PROJ_SUB_FLAGS </li>\r |
| 921 | <li> CC_PROJ_FLAGS </li>\r |
| 922 | <li> CC_PROJ_ADD_FLAGS </li>\r |
| 923 | <li> CC_PROJ_SUB_FLAGS </li>\r |
| 924 | <li> CC_FLAGS </li>\r |
| 925 | <li> IA32_CC_FLAGS </li>\r |
| 926 | </ul>\r |
| 927 | \r |
| 928 | <p> The final flags is composed of STD, GLOBAL and PROJ. If CC_FLAGS or\r |
| 929 | IA32_CC_FLAGS is specified, STD, GLOBAL and PROJ will not affect. </p>\r |
| 930 | \r |
| 931 | Note that the <code>ToolChainFactory</code> executes only once \r |
| 932 | during whole build process. \r |
| 933 | **/\r |
| 934 | private void flagsSetup() {\r |
| 935 | Project project = getProject();\r |
| 936 | //\r |
| 937 | // If ToolChain has been set up before, do nothing.\r |
| 938 | //\r |
| 939 | ToolChainFactory toolChainFactory = new ToolChainFactory(project);\r |
| 940 | toolChainFactory.setupToolChain();\r |
| 941 | \r |
| 942 | String[] cmd = ToolChainFactory.commandType;\r |
| 943 | Set<String> addSet = new HashSet<String>(40);\r |
| 944 | Set<String> subSet = new HashSet<String>(40);\r |
| 945 | for (int i = 0; i < cmd.length; i++) {\r |
| 946 | String str = ToolChainFactory.getValue(arch + "_" + cmd[i]);\r |
| 947 | //\r |
| 948 | // Command line path+command name\r |
| 949 | //\r |
| 950 | if (str != null) {\r |
| 951 | project.setProperty(cmd[i], str);\r |
| 952 | }\r |
| 953 | //\r |
| 954 | // ARCH_CMD_STD_FLAGS\r |
| 955 | //\r |
| 956 | str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_STD_FLAGS");\r |
| 957 | if (str != null) {\r |
| 958 | putFlagsToSet(addSet, str);\r |
| 959 | project.setProperty(cmd[i] + "_STD_FLAGS", str);\r |
| 960 | }\r |
| 961 | //\r |
| 962 | // ARCH_CMD_GLOBAL_FLAGS\r |
| 963 | //\r |
| 964 | str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_FLAGS");\r |
| 965 | if (str != null) {\r |
| 966 | putFlagsToSet(addSet, str);\r |
| 967 | }\r |
| 968 | //\r |
| 969 | // ARCH_CMD_GLOBAL_ADD_FLAGS\r |
| 970 | //\r |
| 971 | str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_ADD_FLAGS");\r |
| 972 | if (str != null) {\r |
| 973 | putFlagsToSet(addSet, str);\r |
| 974 | }\r |
| 975 | //\r |
| 976 | // ARCH_CMD_GLOBAL_SUB_FLAGS\r |
| 977 | //\r |
| 978 | str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_SUB_FLAGS");\r |
| 979 | if (str != null) {\r |
| 980 | putFlagsToSet(subSet, str);\r |
| 981 | }\r |
| 982 | //\r |
| 983 | // ARCH_CMD_PROJ_FLAGS\r |
| 984 | //\r |
| 985 | str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_FLAGS");\r |
| 986 | if (str != null) {\r |
| 987 | putFlagsToSet(addSet, str);\r |
| 988 | }\r |
| 989 | //\r |
| 990 | // ARCH_CMD_PROG_FLAGS\r |
| 991 | //\r |
| 992 | str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_ADD_FLAGS");\r |
| 993 | if (str != null) {\r |
| 994 | putFlagsToSet(addSet, str);\r |
| 995 | }\r |
| 996 | //\r |
| 997 | // ARCH_CMD_PROG_FLAGS\r |
| 998 | //\r |
| 999 | str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_SUB_FLAGS");\r |
| 1000 | if (str != null) {\r |
| 1001 | putFlagsToSet(subSet, str);\r |
| 1002 | }\r |
| 1003 | //\r |
| 1004 | // CMD_PROJ_FLAGS\r |
| 1005 | //\r |
| 1006 | str = project.getProperty(cmd[i] + "_PROJ_FLAGS");\r |
| 1007 | if (str != null) {\r |
| 1008 | putFlagsToSet(addSet, str);\r |
| 1009 | }\r |
| 1010 | //\r |
| 1011 | // CMD_PROG_FLAGS\r |
| 1012 | //\r |
| 1013 | str = project.getProperty(cmd[i] + "_PROJ_ADD_FLAGS");\r |
| 1014 | if (str != null) {\r |
| 1015 | putFlagsToSet(addSet, str);\r |
| 1016 | }\r |
| 1017 | //\r |
| 1018 | // CMD_PROG_FLAGS\r |
| 1019 | //\r |
| 1020 | str = project.getProperty(cmd[i] + "_PROJ_SUB_FLAGS");\r |
| 1021 | if (str != null) {\r |
| 1022 | putFlagsToSet(subSet, str);\r |
| 1023 | }\r |
| 1024 | //\r |
| 1025 | // If IA32_CC_FLAGS or IA32_LIB_FLAGS .. has defined in BuildOptions\r |
| 1026 | //\r |
| 1027 | if ((str = project.getProperty(arch + "_" + cmd[i] + "_FLAGS")) != null) {\r |
| 1028 | project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));\r |
| 1029 | addSet.clear();\r |
| 1030 | subSet.clear();\r |
| 1031 | putFlagsToSet(addSet, project.replaceProperties(str));\r |
| 1032 | project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));\r |
| 1033 | addSet.clear();\r |
| 1034 | subSet.clear();\r |
| 1035 | }\r |
| 1036 | //\r |
| 1037 | // If CC_FLAGS or LIB_FLAGS .. has defined in BuildOptions\r |
| 1038 | //\r |
| 1039 | else if ((str = project.getProperty(cmd[i] + "_FLAGS")) != null) {\r |
| 1040 | project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));\r |
| 1041 | addSet.clear();\r |
| 1042 | subSet.clear();\r |
| 1043 | putFlagsToSet(addSet, project.replaceProperties(str));\r |
| 1044 | project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));\r |
| 1045 | addSet.clear();\r |
| 1046 | subSet.clear();\r |
| 1047 | } else {\r |
| 1048 | project.setProperty(cmd[i] + "_FLAGS", getFlags(addSet, subSet));\r |
| 1049 | addSet.clear();\r |
| 1050 | subSet.clear();\r |
| 1051 | }\r |
| 1052 | }\r |
| 1053 | project.setProperty("C_FLAGS", project.getProperty("CC_FLAGS"));\r |
| 1054 | }\r |
| 1055 | \r |
| 1056 | /**\r |
| 1057 | Initialize some properties will be used in current module build, including\r |
| 1058 | user-defined option from <em>Option</em> of <em>BuildOptions</em> in \r |
| 1059 | surface area. \r |
| 1060 | **/\r |
| 1061 | private void updateParameters() {\r |
| 1062 | getProject().setProperty("OBJECTS", "");\r |
| 1063 | getProject().setProperty("SDB_FILES", "");\r |
| 1064 | getProject().setProperty("BASE_NAME", baseName);\r |
| 1065 | if (map.get("MsaHeader") != null) {\r |
| 1066 | flag = GlobalData.MSA_AND_MBD;\r |
| 1067 | MsaHeaderDocument.MsaHeader header = ((MsaHeaderDocument) map.get("MsaHeader")).getMsaHeader();\r |
| 1068 | guid = header.getGuid().getStringValue();\r |
| 1069 | componentType = header.getComponentType().toString();\r |
| 1070 | } \r |
| 1071 | \r |
| 1072 | else if (map.get("MsaLibHeader") != null) {\r |
| 1073 | flag = GlobalData.LIBMSA_AND_LIBMBD;\r |
| 1074 | MsaLibHeaderDocument.MsaLibHeader header = ((MsaLibHeaderDocument) map.get("MsaLibHeader"))\r |
| 1075 | .getMsaLibHeader();\r |
| 1076 | guid = header.getGuid().getStringValue();\r |
| 1077 | componentType = header.getComponentType().toString();\r |
| 1078 | }\r |
| 1079 | \r |
| 1080 | if (componentType != null) {\r |
| 1081 | getProject().setProperty("COMPONENT_TYPE", componentType);\r |
| 1082 | }\r |
| 1083 | \r |
| 1084 | if (guid != null) {\r |
| 1085 | getProject().setProperty("FILE_GUID", guid);\r |
| 1086 | }\r |
| 1087 | //\r |
| 1088 | // Get all options and set to properties\r |
| 1089 | //\r |
| 1090 | String[][] options = SurfaceAreaQuery.getOptions(arch);\r |
| 1091 | for (int i = 0; i < options.length; i++) {\r |
| 1092 | if (options[i][0] != null && options[i][1] != null) {\r |
| 1093 | getProject().setProperty(options[i][0], getProject().replaceProperties(options[i][1]));\r |
| 1094 | }\r |
| 1095 | }\r |
| 1096 | \r |
| 1097 | buildType = getProject().getProperty("BUILD_TYPE");\r |
| 1098 | if (buildType == null) {\r |
| 1099 | buildType = componentType;\r |
| 1100 | }\r |
| 1101 | \r |
| 1102 | }\r |
| 1103 | \r |
| 1104 | /**\r |
| 1105 | Separate the string and instore in set.\r |
| 1106 | \r |
| 1107 | <p> String is separated by Java Regulation Expression \r |
| 1108 | "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>\r |
| 1109 | \r |
| 1110 | <p>For example: </p>\r |
| 1111 | \r |
| 1112 | <pre>\r |
| 1113 | "/nologo", "/W3", "/WX"\r |
| 1114 | "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""\r |
| 1115 | </pre>\r |
| 1116 | \r |
| 1117 | @param set store the separated string\r |
| 1118 | @param str string to separate\r |
| 1119 | **/\r |
| 1120 | private void putFlagsToSet(Set<String> set, String str) {\r |
| 1121 | Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");\r |
| 1122 | Matcher matcher = myPattern.matcher(str + " ");\r |
| 1123 | while (matcher.find()) {\r |
| 1124 | String item = str.substring(matcher.start(1), matcher.end(1));\r |
| 1125 | if (!set.contains(item)) {\r |
| 1126 | set.add(item);\r |
| 1127 | }\r |
| 1128 | }\r |
| 1129 | }\r |
| 1130 | \r |
| 1131 | /**\r |
| 1132 | Generate the final flags string will be used by compile command. \r |
| 1133 | \r |
| 1134 | @param add the add flags set\r |
| 1135 | @param sub the sub flags set\r |
| 1136 | @return final flags after add set substract sub set\r |
| 1137 | **/\r |
| 1138 | private String getFlags(Set<String> add, Set<String> sub) {\r |
| 1139 | String result = "";\r |
| 1140 | add.removeAll(sub);\r |
| 1141 | Iterator iter = add.iterator();\r |
| 1142 | while (iter.hasNext()) {\r |
| 1143 | String str = getProject().replaceProperties((String) iter.next());\r |
| 1144 | result += str.substring(1, str.length() - 1) + " ";\r |
| 1145 | }\r |
| 1146 | return result;\r |
| 1147 | }\r |
| 1148 | \r |
| 1149 | /**\r |
| 1150 | Generate the flags string with original format. The format is defined by \r |
| 1151 | Java Regulation Expression "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>\r |
| 1152 | \r |
| 1153 | <p>For example: </p>\r |
| 1154 | \r |
| 1155 | <pre>\r |
| 1156 | "/nologo", "/W3", "/WX"\r |
| 1157 | "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""\r |
| 1158 | </pre>\r |
| 1159 | \r |
| 1160 | @param add the add flags set\r |
| 1161 | @param sub the sub flags set\r |
| 1162 | @return flags with original format\r |
| 1163 | **/\r |
| 1164 | private String getRawFlags(Set<String> add, Set<String> sub) {\r |
| 1165 | String result = "";\r |
| 1166 | add.removeAll(sub);\r |
| 1167 | Iterator iter = add.iterator();\r |
| 1168 | while (iter.hasNext()) {\r |
| 1169 | String str = getProject().replaceProperties((String) iter.next());\r |
| 1170 | result += "\"" + str.substring(1, str.length() - 1) + "\", ";\r |
| 1171 | }\r |
| 1172 | return result;\r |
| 1173 | }\r |
| 1174 | \r |
| 1175 | /**\r |
| 1176 | Set base name. For ANT use.\r |
| 1177 | \r |
| 1178 | @param baseName Base name\r |
| 1179 | **/\r |
| 1180 | public void setBaseName(String baseName) {\r |
| 1181 | this.baseName = baseName;\r |
| 1182 | }\r |
| 1183 | \r |
| 1184 | }\r |