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