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