1 /* 2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 import java.util.*; 26 import java.io.File; 27 28 class BuildConfig { 29 Hashtable vars; 30 Vector basicNames, basicPaths; 31 String[] context; 32 33 static CompilerInterface ci; 34 static CompilerInterface getCI() { 35 if (ci == null) { 36 String comp = (String)getField(null, "CompilerVersion"); 37 try { 38 ci = (CompilerInterface)Class.forName("CompilerInterface" + comp).newInstance(); 39 } catch (Exception cnfe) { 40 System.err.println("Cannot find support for compiler " + comp); 41 throw new RuntimeException(cnfe.toString()); 42 } 43 } 44 return ci; 45 } 46 47 protected void initNames(String flavour, String build, String outDll) { 48 if (vars == null) vars = new Hashtable(); 49 50 String flavourBuild = flavour + "_" + build; 51 System.out.println(); 52 System.out.println(flavourBuild); 53 54 put("Name", getCI().makeCfgName(flavourBuild)); 55 put("Flavour", flavour); 56 put("Build", build); 57 58 // ones mentioned above were needed to expand format 59 String buildBase = expandFormat(getFieldString(null, "BuildBase")); 60 String jdkDir = getFieldString(null, "JdkTargetRoot"); 61 String sourceBase = getFieldString(null, "SourceBase"); 62 String outDir = buildBase; 63 64 put("Id", flavourBuild); 65 put("OutputDir", outDir); 66 put("SourceBase", sourceBase); 67 put("BuildBase", buildBase); 68 put("OutputDll", jdkDir + Util.sep + outDll); 69 70 context = new String [] {flavourBuild, flavour, build, null}; 71 } 72 73 protected void init(Vector includes, Vector defines) { 74 initDefaultDefines(defines); 75 initDefaultCompilerFlags(includes); 76 initDefaultLinkerFlags(); 77 handleDB(); 78 } 79 80 81 protected void initDefaultCompilerFlags(Vector includes) { 82 Vector compilerFlags = new Vector(); 83 84 compilerFlags.addAll(getCI().getBaseCompilerFlags(getV("Define"), 85 includes, 86 get("OutputDir"))); 87 88 put("CompilerFlags", compilerFlags); 89 } 90 91 protected void initDefaultLinkerFlags() { 92 Vector linkerFlags = new Vector(); 93 94 linkerFlags.addAll(getCI().getBaseLinkerFlags( get("OutputDir"), get("OutputDll"))); 95 96 put("LinkerFlags", linkerFlags); 97 } 98 99 DirectoryTree getSourceTree(String sourceBase, String startAt) { 100 DirectoryTree tree = new DirectoryTree(); 101 102 tree.addSubdirToIgnore("Codemgr_wsdata"); 103 tree.addSubdirToIgnore("deleted_files"); 104 tree.addSubdirToIgnore("SCCS"); 105 tree.setVerbose(true); 106 if (startAt != null) { 107 tree.readDirectory(sourceBase + File.separator + startAt); 108 } else { 109 tree.readDirectory(sourceBase); 110 } 111 112 return tree; 113 } 114 115 116 Vector getPreferredPaths(MacroDefinitions macros) { 117 Vector preferredPaths = new Vector(); 118 // In the case of multiple files with the same name in 119 // different subdirectories, prefer the versions specified in 120 // the platform file as the "os_family" and "arch" macros. 121 for (Iterator iter = macros.getMacros(); iter.hasNext(); ) { 122 Macro macro = (Macro) iter.next(); 123 if (macro.name.equals("os_family") || 124 macro.name.equals("arch")) { 125 preferredPaths.add(macro.contents); 126 } 127 } 128 // Also prefer "opto" over "adlc" for adlcVMDeps.hpp 129 preferredPaths.add("opto"); 130 131 return preferredPaths; 132 } 133 134 135 void handleDB() { 136 WinGammaPlatform platform = (WinGammaPlatform)getField(null, "PlatformObject"); 137 138 File incls = new File(get("OutputDir")+Util.sep+"incls"); 139 140 incls.mkdirs(); 141 142 MacroDefinitions macros = new MacroDefinitions(); 143 try { 144 macros.readFrom(getFieldString(null, "Platform"), false); 145 } catch (Exception e) { 146 throw new RuntimeException(e); 147 } 148 149 putSpecificField("AllFilesHash", computeAllFiles(platform, macros)); 150 } 151 152 153 private boolean matchesIgnoredPath(String prefixedName) { 154 Vector rv = new Vector(); 155 collectRelevantVectors(rv, "IgnorePath"); 156 for (Iterator i = rv.iterator(); i.hasNext(); ) { 157 String pathPart = (String) i.next(); 158 if (prefixedName.contains(Util.normalize(pathPart))) { 159 return true; 160 } 161 } 162 return false; 163 } 164 165 void addAll(Iterator i, Hashtable hash, 166 WinGammaPlatform platform, DirectoryTree tree, 167 Vector preferredPaths, Vector filesNotFound, Vector filesDuplicate) { 168 for (; i.hasNext(); ) { 169 String fileName = (String) i.next(); 170 if (lookupHashFieldInContext("IgnoreFile", fileName) == null) { 171 String prefixedName = platform.envVarPrefixedFileName(fileName, 172 0, /* ignored */ 173 tree, 174 preferredPaths, 175 filesNotFound, 176 filesDuplicate); 177 if (prefixedName != null) { 178 prefixedName = Util.normalize(prefixedName); 179 if (!matchesIgnoredPath(prefixedName)) { 180 addTo(hash, prefixedName, fileName); 181 } 182 } 183 } 184 } 185 } 186 187 void addTo(Hashtable ht, String key, String value) { 188 ht.put(expandFormat(key), expandFormat(value)); 189 } 190 191 Hashtable computeAllFiles(WinGammaPlatform platform, MacroDefinitions macros) { 192 Hashtable rv = new Hashtable(); 193 DirectoryTree tree = getSourceTree(get("SourceBase"), getFieldString(null, "StartAt")); 194 Vector preferredPaths = getPreferredPaths(macros); 195 196 // Hold errors until end 197 Vector filesNotFound = new Vector(); 198 Vector filesDuplicate = new Vector(); 199 200 Vector includedFiles = new Vector(); 201 202 // find all files 203 Vector dirs = getSourceIncludes(); 204 for (Iterator i = dirs.iterator(); i.hasNext(); ) { 205 String dir = (String)i.next(); 206 DirectoryTree subtree = getSourceTree(dir, null); 207 for (Iterator fi = subtree.getFileIterator(); fi.hasNext(); ) { 208 String name = ((File)fi.next()).getName(); 209 includedFiles.add(name); 210 } 211 } 212 addAll(includedFiles.iterator(), rv, 213 platform, tree, 214 preferredPaths, filesNotFound, filesDuplicate); 215 216 Vector addFiles = new Vector(); 217 collectRelevantVectors(addFiles, "AdditionalFile"); 218 addAll(addFiles.iterator(), rv, 219 platform, tree, 220 preferredPaths, filesNotFound, filesDuplicate); 221 222 collectRelevantHashes(rv, "AdditionalGeneratedFile"); 223 224 if ((filesNotFound.size() != 0) || 225 (filesDuplicate.size() != 0)) { 226 System.err.println("Error: some files were not found or " + 227 "appeared in multiple subdirectories of " + 228 "directory " + get("SourceBase") + " and could not " + 229 "be resolved with the os_family and arch " + 230 "macros in the platform file."); 231 if (filesNotFound.size() != 0) { 232 System.err.println("Files not found:"); 233 for (Iterator iter = filesNotFound.iterator(); 234 iter.hasNext(); ) { 235 System.err.println(" " + (String) iter.next()); 236 } 237 } 238 if (filesDuplicate.size() != 0) { 239 System.err.println("Duplicate files:"); 240 for (Iterator iter = filesDuplicate.iterator(); 241 iter.hasNext(); ) { 242 System.err.println(" " + (String) iter.next()); 243 } 244 } 245 throw new RuntimeException(); 246 } 247 248 return rv; 249 } 250 251 void initDefaultDefines(Vector defines) { 252 Vector sysDefines = new Vector(); 253 sysDefines.add("WIN32"); 254 sysDefines.add("_WINDOWS"); 255 sysDefines.add("HOTSPOT_BUILD_USER="+System.getProperty("user.name")); 256 sysDefines.add("HOTSPOT_BUILD_TARGET=\\\""+get("Build")+"\\\""); 257 sysDefines.add("_JNI_IMPLEMENTATION_"); 258 sysDefines.add("HOTSPOT_LIB_ARCH=\\\"i386\\\""); 259 260 sysDefines.addAll(defines); 261 262 put("Define", sysDefines); 263 } 264 265 String get(String key) { 266 return (String)vars.get(key); 267 } 268 269 Vector getV(String key) { 270 return (Vector)vars.get(key); 271 } 272 273 Object getO(String key) { 274 return vars.get(key); 275 } 276 277 Hashtable getH(String key) { 278 return (Hashtable)vars.get(key); 279 } 280 281 Object getFieldInContext(String field) { 282 for (int i=0; i<context.length; i++) { 283 Object rv = getField(context[i], field); 284 if (rv != null) { 285 return rv; 286 } 287 } 288 return null; 289 } 290 291 Object lookupHashFieldInContext(String field, String key) { 292 for (int i=0; i<context.length; i++) { 293 Hashtable ht = (Hashtable)getField(context[i], field); 294 if (ht != null) { 295 Object rv = ht.get(key); 296 if (rv != null) { 297 return rv; 298 } 299 } 300 } 301 return null; 302 } 303 304 void put(String key, String value) { 305 vars.put(key, value); 306 } 307 308 void put(String key, Vector vvalue) { 309 vars.put(key, vvalue); 310 } 311 312 void add(String key, Vector vvalue) { 313 getV(key).addAll(vvalue); 314 } 315 316 String flavour() { 317 return get("Flavour"); 318 } 319 320 String build() { 321 return get("Build"); 322 } 323 324 Object getSpecificField(String field) { 325 return getField(get("Id"), field); 326 } 327 328 void putSpecificField(String field, Object value) { 329 putField(get("Id"), field, value); 330 } 331 332 void collectRelevantVectors(Vector rv, String field) { 333 for (int i = 0; i < context.length; i++) { 334 Vector v = getFieldVector(context[i], field); 335 if (v != null) { 336 for (Iterator j=v.iterator(); j.hasNext(); ) { 337 String val = (String)j.next(); 338 rv.add(expandFormat(val)); 339 } 340 } 341 } 342 } 343 344 void collectRelevantHashes(Hashtable rv, String field) { 345 for (int i = 0; i < context.length; i++) { 346 Hashtable v = (Hashtable)getField(context[i], field); 347 if (v != null) { 348 for (Enumeration e=v.keys(); e.hasMoreElements(); ) { 349 String key = (String)e.nextElement(); 350 String val = (String)v.get(key); 351 addTo(rv, key, val); 352 } 353 } 354 } 355 } 356 357 358 Vector getDefines() { 359 Vector rv = new Vector(); 360 collectRelevantVectors(rv, "Define"); 361 return rv; 362 } 363 364 Vector getIncludes() { 365 Vector rv = new Vector(); 366 367 // for generated includes 368 rv.add(get("OutputDir")); 369 370 collectRelevantVectors(rv, "AbsoluteInclude"); 371 372 rv.addAll(getSourceIncludes()); 373 374 return rv; 375 } 376 377 private Vector getSourceIncludes() { 378 Vector rv = new Vector(); 379 Vector ri = new Vector(); 380 String sourceBase = getFieldString(null, "SourceBase"); 381 collectRelevantVectors(ri, "RelativeInclude"); 382 for (Iterator i = ri.iterator(); i.hasNext(); ) { 383 String f = (String)i.next(); 384 rv.add(sourceBase + Util.sep + f); 385 } 386 return rv; 387 } 388 389 static Hashtable cfgData = new Hashtable(); 390 static Hashtable globalData = new Hashtable(); 391 392 static boolean appliesToTieredBuild(String cfg) { 393 return (cfg != null && 394 (cfg.startsWith("compiler1") || 395 cfg.startsWith("compiler2"))); 396 } 397 398 // Filters out the IgnoreFile and IgnorePaths since they are 399 // handled specialy for tiered builds. 400 static boolean appliesToTieredBuild(String cfg, String key) { 401 return (appliesToTieredBuild(cfg) && 402 (key != null && 403 !key.startsWith("Ignore"))); 404 } 405 406 static String getTieredBuildCfg(String cfg) { 407 assert appliesToTieredBuild(cfg) : "illegal configuration " + cfg; 408 return "tiered" + cfg.substring(9); 409 } 410 411 static Object getField(String cfg, String field) { 412 if (cfg == null) { 413 return globalData.get(field); 414 } 415 416 Hashtable ht = (Hashtable)cfgData.get(cfg); 417 return ht == null ? null : ht.get(field); 418 } 419 420 static String getFieldString(String cfg, String field) { 421 return (String)getField(cfg, field); 422 } 423 424 static Vector getFieldVector(String cfg, String field) { 425 return (Vector)getField(cfg, field); 426 } 427 428 static void putField(String cfg, String field, Object value) { 429 putFieldImpl(cfg, field, value); 430 if (appliesToTieredBuild(cfg, field)) { 431 putFieldImpl(getTieredBuildCfg(cfg), field, value); 432 } 433 } 434 435 private static void putFieldImpl(String cfg, String field, Object value) { 436 if (cfg == null) { 437 globalData.put(field, value); 438 return; 439 } 440 441 Hashtable ht = (Hashtable)cfgData.get(cfg); 442 if (ht == null) { 443 ht = new Hashtable(); 444 cfgData.put(cfg, ht); 445 } 446 447 ht.put(field, value); 448 } 449 450 static Object getFieldHash(String cfg, String field, String name) { 451 Hashtable ht = (Hashtable)getField(cfg, field); 452 453 return ht == null ? null : ht.get(name); 454 } 455 456 static void putFieldHash(String cfg, String field, String name, Object val) { 457 putFieldHashImpl(cfg, field, name, val); 458 if (appliesToTieredBuild(cfg, field)) { 459 putFieldHashImpl(getTieredBuildCfg(cfg), field, name, val); 460 } 461 } 462 463 private static void putFieldHashImpl(String cfg, String field, String name, Object val) { 464 Hashtable ht = (Hashtable)getField(cfg, field); 465 466 if (ht == null) { 467 ht = new Hashtable(); 468 putFieldImpl(cfg, field, ht); 469 } 470 471 ht.put(name, val); 472 } 473 474 static void addFieldVector(String cfg, String field, String element) { 475 addFieldVectorImpl(cfg, field, element); 476 if (appliesToTieredBuild(cfg, field)) { 477 addFieldVectorImpl(getTieredBuildCfg(cfg), field, element); 478 } 479 } 480 481 private static void addFieldVectorImpl(String cfg, String field, String element) { 482 Vector v = (Vector)getField(cfg, field); 483 484 if (v == null) { 485 v = new Vector(); 486 putFieldImpl(cfg, field, v); 487 } 488 489 v.add(element); 490 } 491 492 String expandFormat(String format) { 493 if (format == null) { 494 return null; 495 } 496 497 if (format.indexOf('%') == -1) { 498 return format; 499 } 500 501 StringBuffer sb = new StringBuffer(); 502 int len = format.length(); 503 for (int i=0; i<len; i++) { 504 char ch = format.charAt(i); 505 if (ch == '%') { 506 char ch1 = format.charAt(i+1); 507 switch (ch1) { 508 case '%': 509 sb.append(ch1); 510 break; 511 case 'b': 512 sb.append(build()); 513 break; 514 case 'f': 515 sb.append(flavour()); 516 break; 517 default: 518 sb.append(ch); 519 sb.append(ch1); 520 } 521 i++; 522 } else { 523 sb.append(ch); 524 } 525 } 526 527 return sb.toString(); 528 } 529 } 530 531 abstract class GenericDebugConfig extends BuildConfig { 532 abstract String getOptFlag(); 533 534 protected void init(Vector includes, Vector defines) { 535 defines.add("_DEBUG"); 536 defines.add("ASSERT"); 537 538 super.init(includes, defines); 539 540 getV("CompilerFlags").addAll(getCI().getDebugCompilerFlags(getOptFlag())); 541 getV("LinkerFlags").addAll(getCI().getDebugLinkerFlags()); 542 } 543 } 544 545 class C1DebugConfig extends GenericDebugConfig { 546 String getOptFlag() { 547 return getCI().getNoOptFlag(); 548 } 549 550 C1DebugConfig() { 551 initNames("compiler1", "debug", "fastdebug\\jre\\bin\\client\\jvm.dll"); 552 init(getIncludes(), getDefines()); 553 } 554 } 555 556 class C1FastDebugConfig extends GenericDebugConfig { 557 String getOptFlag() { 558 return getCI().getOptFlag(); 559 } 560 561 C1FastDebugConfig() { 562 initNames("compiler1", "fastdebug", "fastdebug\\jre\\bin\\client\\jvm.dll"); 563 init(getIncludes(), getDefines()); 564 } 565 } 566 567 class C2DebugConfig extends GenericDebugConfig { 568 String getOptFlag() { 569 return getCI().getNoOptFlag(); 570 } 571 572 C2DebugConfig() { 573 initNames("compiler2", "debug", "fastdebug\\jre\\bin\\server\\jvm.dll"); 574 init(getIncludes(), getDefines()); 575 } 576 } 577 578 class C2FastDebugConfig extends GenericDebugConfig { 579 String getOptFlag() { 580 return getCI().getOptFlag(); 581 } 582 583 C2FastDebugConfig() { 584 initNames("compiler2", "fastdebug", "fastdebug\\jre\\bin\\server\\jvm.dll"); 585 init(getIncludes(), getDefines()); 586 } 587 } 588 589 class TieredDebugConfig extends GenericDebugConfig { 590 String getOptFlag() { 591 return getCI().getNoOptFlag(); 592 } 593 594 TieredDebugConfig() { 595 initNames("tiered", "debug", "fastdebug\\jre\\bin\\server\\jvm.dll"); 596 init(getIncludes(), getDefines()); 597 } 598 } 599 600 class TieredFastDebugConfig extends GenericDebugConfig { 601 String getOptFlag() { 602 return getCI().getOptFlag(); 603 } 604 605 TieredFastDebugConfig() { 606 initNames("tiered", "fastdebug", "fastdebug\\jre\\bin\\server\\jvm.dll"); 607 init(getIncludes(), getDefines()); 608 } 609 } 610 611 612 abstract class ProductConfig extends BuildConfig { 613 protected void init(Vector includes, Vector defines) { 614 defines.add("NDEBUG"); 615 defines.add("PRODUCT"); 616 617 super.init(includes, defines); 618 619 getV("CompilerFlags").addAll(getCI().getProductCompilerFlags()); 620 getV("LinkerFlags").addAll(getCI().getProductLinkerFlags()); 621 } 622 } 623 624 class C1ProductConfig extends ProductConfig { 625 C1ProductConfig() { 626 initNames("compiler1", "product", "jre\\bin\\client\\jvm.dll"); 627 init(getIncludes(), getDefines()); 628 } 629 } 630 631 class C2ProductConfig extends ProductConfig { 632 C2ProductConfig() { 633 initNames("compiler2", "product", "jre\\bin\\server\\jvm.dll"); 634 init(getIncludes(), getDefines()); 635 } 636 } 637 638 class TieredProductConfig extends ProductConfig { 639 TieredProductConfig() { 640 initNames("tiered", "product", "jre\\bin\\server\\jvm.dll"); 641 init(getIncludes(), getDefines()); 642 } 643 } 644 645 646 class CoreDebugConfig extends GenericDebugConfig { 647 String getOptFlag() { 648 return getCI().getNoOptFlag(); 649 } 650 651 CoreDebugConfig() { 652 initNames("core", "debug", "fastdebug\\jre\\bin\\core\\jvm.dll"); 653 init(getIncludes(), getDefines()); 654 } 655 } 656 657 658 class CoreFastDebugConfig extends GenericDebugConfig { 659 String getOptFlag() { 660 return getCI().getOptFlag(); 661 } 662 663 CoreFastDebugConfig() { 664 initNames("core", "fastdebug", "fastdebug\\jre\\bin\\core\\jvm.dll"); 665 init(getIncludes(), getDefines()); 666 } 667 } 668 669 670 class CoreProductConfig extends ProductConfig { 671 CoreProductConfig() { 672 initNames("core", "product", "jre\\bin\\core\\jvm.dll"); 673 init(getIncludes(), getDefines()); 674 } 675 } 676 677 class KernelDebugConfig extends GenericDebugConfig { 678 String getOptFlag() { 679 return getCI().getNoOptFlag(); 680 } 681 682 KernelDebugConfig() { 683 initNames("kernel", "debug", "fastdebug\\jre\\bin\\kernel\\jvm.dll"); 684 init(getIncludes(), getDefines()); 685 } 686 } 687 688 689 class KernelFastDebugConfig extends GenericDebugConfig { 690 String getOptFlag() { 691 return getCI().getOptFlag(); 692 } 693 694 KernelFastDebugConfig() { 695 initNames("kernel", "fastdebug", "fastdebug\\jre\\bin\\kernel\\jvm.dll"); 696 init(getIncludes(), getDefines()); 697 } 698 } 699 700 701 class KernelProductConfig extends ProductConfig { 702 KernelProductConfig() { 703 initNames("kernel", "product", "jre\\bin\\kernel\\jvm.dll"); 704 init(getIncludes(), getDefines()); 705 } 706 } 707 abstract class CompilerInterface { 708 abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir); 709 abstract Vector getBaseLinkerFlags(String outDir, String outDll); 710 abstract Vector getDebugCompilerFlags(String opt); 711 abstract Vector getDebugLinkerFlags(); 712 abstract Vector getProductCompilerFlags(); 713 abstract Vector getProductLinkerFlags(); 714 abstract String getOptFlag(); 715 abstract String getNoOptFlag(); 716 abstract String makeCfgName(String flavourBuild); 717 718 void addAttr(Vector receiver, String attr, String value) { 719 receiver.add(attr); receiver.add(value); 720 } 721 }