1 /* 2 * Copyright (c) 2005, 2018, 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 package build.tools.projectcreator; 26 27 import java.util.Enumeration; 28 import java.util.Hashtable; 29 import java.util.Vector; 30 31 class BuildConfig { 32 @SuppressWarnings("rawtypes") 33 Hashtable vars; 34 Vector<String> basicNames, basicPaths; 35 String[] context; 36 37 static CompilerInterface ci; 38 static CompilerInterface getCI() { 39 if (ci == null) { 40 String comp = (String)getField(null, "CompilerVersion"); 41 try { 42 ci = (CompilerInterface)Class.forName("build.tools.projectcreator.CompilerInterface" + comp).newInstance(); 43 } catch (Exception cnfe) { 44 System.err.println("Cannot find support for compiler " + comp); 45 throw new RuntimeException(cnfe.toString()); 46 } 47 } 48 return ci; 49 } 50 51 @SuppressWarnings("rawtypes") 52 protected void initNames(String flavour, String build, String outDll) { 53 if (vars == null) vars = new Hashtable(); 54 55 String flavourBuild = flavour + "_" + build; 56 String platformName = getFieldString(null, "PlatformName"); 57 System.out.println(); 58 System.out.println(flavourBuild); 59 60 put("Name", getCI().makeCfgName(flavourBuild, platformName)); 61 put("Flavour", flavour); 62 put("Build", build); 63 put("PlatformName", platformName); 64 65 // ones mentioned above were needed to expand format 66 String buildBase = expandFormat(getFieldString(null, "BuildBase")); 67 String sourceBase = getFieldString(null, "SourceBase"); 68 String buildSpace = getFieldString(null, "BuildSpace"); 69 String outDir = buildBase; 70 String jdkTargetRoot = getFieldString(null, "JdkTargetRoot"); 71 String makeBinary = getFieldString(null, "MakeBinary"); 72 String makeOutput = expandFormat(getFieldString(null, "MakeOutput")); 73 74 put("Id", flavourBuild); 75 put("OutputDir", outDir); 76 put("SourceBase", sourceBase); 77 put("BuildBase", buildBase); 78 put("BuildSpace", buildSpace); 79 put("OutputDll", outDir + Util.sep + outDll); 80 put("JdkTargetRoot", jdkTargetRoot); 81 put("MakeBinary", makeBinary); 82 put("MakeOutput", makeOutput); 83 84 context = new String [] {flavourBuild, flavour, build, null}; 85 } 86 87 protected void init(Vector<String> includes, Vector<String> defines) { 88 initDefaultDefines(defines); 89 initDefaultCompilerFlags(includes); 90 initDefaultLinkerFlags(); 91 //handleDB(); 92 } 93 94 95 protected void initDefaultCompilerFlags(Vector<String> includes) { 96 Vector compilerFlags = new Vector(); 97 98 compilerFlags.addAll(getCI().getBaseCompilerFlags(getV("Define"), 99 includes, 100 get("OutputDir"))); 101 102 put("CompilerFlags", compilerFlags); 103 } 104 105 protected void initDefaultLinkerFlags() { 106 Vector linkerFlags = new Vector(); 107 108 linkerFlags.addAll(getCI().getBaseLinkerFlags( get("OutputDir"), get("OutputDll"), get("PlatformName"))); 109 110 put("LinkerFlags", linkerFlags); 111 } 112 113 public boolean matchesIgnoredPath(String path) { 114 Vector<String> rv = new Vector<String>(); 115 collectRelevantVectors(rv, "IgnorePath"); 116 for (String pathPart : rv) { 117 if (path.contains(pathPart)) { 118 return true; 119 } 120 } 121 return false; 122 } 123 124 public boolean matchesHidePath(String path) { 125 Vector<String> rv = new Vector<String>(); 126 collectRelevantVectors(rv, "HidePath"); 127 for (String pathPart : rv) { 128 if (path.contains(Util.normalize(pathPart))) { 129 return true; 130 } 131 } 132 return false; 133 } 134 135 public Vector<String> matchesAdditionalGeneratedPath(String fullPath) { 136 Vector<String> rv = new Vector<String>(); 137 Hashtable<String, String> v = (Hashtable<String, String>)BuildConfig.getField(this.toString(), "AdditionalGeneratedFile"); 138 if (v != null) { 139 for (Enumeration<String> e=v.keys(); e.hasMoreElements(); ) { 140 String key = e.nextElement(); 141 String val = v.get(key); 142 143 if (fullPath.endsWith(expandFormat(key))) { 144 rv.add(expandFormat(val)); 145 } 146 } 147 } 148 return rv; 149 } 150 151 // Returns true if the specified path refers to a relative alternate 152 // source file. RelativeAltSrcInclude is usually "src\closed". 153 public static boolean matchesRelativeAltSrcInclude(String path) { 154 String relativeAltSrcInclude = 155 getFieldString(null, "RelativeAltSrcInclude"); 156 Vector<String> v = getFieldVector(null, "AltRelativeInclude"); 157 if (v != null) { 158 for (String pathPart : v) { 159 if (path.contains(relativeAltSrcInclude + Util.sep + pathPart)) { 160 return true; 161 } 162 } 163 } 164 return false; 165 } 166 167 // Returns the relative alternate source file for the specified path. 168 // Null is returned if the specified path does not have a matching 169 // alternate source file. 170 public static String getMatchingRelativeAltSrcFile(String path) { 171 Vector<String> v = getFieldVector(null, "RelativeAltSrcFileList"); 172 if (v == null) { 173 return null; 174 } 175 for (String pathPart : v) { 176 if (path.endsWith(pathPart)) { 177 String relativeAltSrcInclude = 178 getFieldString(null, "RelativeAltSrcInclude"); 179 return relativeAltSrcInclude + Util.sep + pathPart; 180 } 181 } 182 return null; 183 } 184 185 // Returns true if the specified path has a matching alternate 186 // source file. 187 public static boolean matchesRelativeAltSrcFile(String path) { 188 return getMatchingRelativeAltSrcFile(path) != null; 189 } 190 191 // Track the specified alternate source file. The source file is 192 // tracked without the leading .*<sep><RelativeAltSrcFileList><sep> 193 // part to make matching regular source files easier. 194 public static void trackRelativeAltSrcFile(String path) { 195 String pattern = getFieldString(null, "RelativeAltSrcInclude") + 196 Util.sep; 197 int altSrcInd = path.indexOf(pattern); 198 if (altSrcInd == -1) { 199 // not an AltSrc path 200 return; 201 } 202 203 altSrcInd += pattern.length(); 204 if (altSrcInd >= path.length()) { 205 // not a valid AltSrc path 206 return; 207 } 208 209 String altSrcFile = path.substring(altSrcInd); 210 Vector v = getFieldVector(null, "RelativeAltSrcFileList"); 211 if (v == null || !v.contains(altSrcFile)) { 212 addFieldVector(null, "RelativeAltSrcFileList", altSrcFile); 213 } 214 } 215 216 void addTo(Hashtable ht, String key, String value) { 217 ht.put(expandFormat(key), expandFormat(value)); 218 } 219 220 void initDefaultDefines(Vector defines) { 221 Vector sysDefines = new Vector(); 222 sysDefines.add("WIN32"); 223 sysDefines.add("_WINDOWS"); 224 sysDefines.add("HOTSPOT_BUILD_USER=\\\""+System.getProperty("user.name")+"\\\""); 225 sysDefines.add("HOTSPOT_BUILD_TARGET=\\\""+get("Build")+"\\\""); 226 sysDefines.add("INCLUDE_JFR=1"); 227 sysDefines.add("_JNI_IMPLEMENTATION_"); 228 if (vars.get("PlatformName").equals("Win32")) { 229 sysDefines.add("HOTSPOT_LIB_ARCH=\\\"i386\\\""); 230 } else { 231 sysDefines.add("HOTSPOT_LIB_ARCH=\\\"amd64\\\""); 232 } 233 sysDefines.add("DEBUG_LEVEL=\\\"" + get("Build")+"\\\""); 234 sysDefines.addAll(defines); 235 236 put("Define", sysDefines); 237 } 238 239 String get(String key) { 240 return (String)vars.get(key); 241 } 242 243 Vector getV(String key) { 244 return (Vector)vars.get(key); 245 } 246 247 Object getO(String key) { 248 return vars.get(key); 249 } 250 251 Hashtable getH(String key) { 252 return (Hashtable)vars.get(key); 253 } 254 255 Object getFieldInContext(String field) { 256 for (int i=0; i<context.length; i++) { 257 Object rv = getField(context[i], field); 258 if (rv != null) { 259 return rv; 260 } 261 } 262 return null; 263 } 264 265 Object lookupHashFieldInContext(String field, String key) { 266 for (int i=0; i<context.length; i++) { 267 Hashtable ht = (Hashtable)getField(context[i], field); 268 if (ht != null) { 269 Object rv = ht.get(key); 270 if (rv != null) { 271 return rv; 272 } 273 } 274 } 275 return null; 276 } 277 278 void put(String key, String value) { 279 vars.put(key, value); 280 } 281 282 void put(String key, Vector vvalue) { 283 vars.put(key, vvalue); 284 } 285 286 void add(String key, Vector vvalue) { 287 getV(key).addAll(vvalue); 288 } 289 290 String flavour() { 291 return get("Flavour"); 292 } 293 294 String build() { 295 return get("Build"); 296 } 297 298 Object getSpecificField(String field) { 299 return getField(get("Id"), field); 300 } 301 302 void putSpecificField(String field, Object value) { 303 putField(get("Id"), field, value); 304 } 305 306 void collectRelevantVectors(Vector rv, String field) { 307 for (String ctx : context) { 308 Vector<String> v = getFieldVector(ctx, field); 309 if (v != null) { 310 for (String val : v) { 311 rv.add(expandFormat(val).replace('/', '\\')); 312 } 313 } 314 } 315 } 316 317 void collectRelevantHashes(Hashtable rv, String field) { 318 for (String ctx : context) { 319 Hashtable v = (Hashtable)getField(ctx, field); 320 if (v != null) { 321 for (Enumeration e=v.keys(); e.hasMoreElements(); ) { 322 String key = (String)e.nextElement(); 323 String val = (String)v.get(key); 324 addTo(rv, key, val); 325 } 326 } 327 } 328 } 329 330 331 Vector getDefines() { 332 Vector rv = new Vector(); 333 collectRelevantVectors(rv, "Define"); 334 return rv; 335 } 336 337 Vector getIncludes() { 338 Vector rv = new Vector(); 339 collectRelevantVectors(rv, "AbsoluteInclude"); 340 rv.addAll(getSourceIncludes()); 341 return rv; 342 } 343 344 private Vector getSourceIncludes() { 345 Vector<String> rv = new Vector<String>(); 346 String sourceBase = getFieldString(null, "SourceBase"); 347 348 // add relative alternate source include values: 349 String relativeAltSrcInclude = 350 getFieldString(null, "RelativeAltSrcInclude"); 351 Vector<String> asri = new Vector<String>(); 352 collectRelevantVectors(asri, "AltRelativeInclude"); 353 for (String f : asri) { 354 rv.add(sourceBase + Util.sep + relativeAltSrcInclude + 355 Util.sep + f); 356 } 357 358 Vector<String> ri = new Vector<String>(); 359 collectRelevantVectors(ri, "RelativeInclude"); 360 for (String f : ri) { 361 rv.add(sourceBase + Util.sep + f); 362 } 363 return rv; 364 } 365 366 static Hashtable cfgData = new Hashtable(); 367 static Hashtable globalData = new Hashtable(); 368 369 static boolean appliesToTieredBuild(String cfg) { 370 return (cfg != null && 371 cfg.startsWith("server")); 372 } 373 374 // Filters out the IgnoreFile and IgnorePaths since they are 375 // handled specially for tiered builds. 376 static boolean appliesToTieredBuild(String cfg, String key) { 377 return (appliesToTieredBuild(cfg))&& (key != null && !key.startsWith("Ignore")); 378 } 379 380 static String getTieredBuildCfg(String cfg) { 381 assert appliesToTieredBuild(cfg) : "illegal configuration " + cfg; 382 return "server"; 383 } 384 385 static Object getField(String cfg, String field) { 386 if (cfg == null) { 387 return globalData.get(field); 388 } 389 390 Hashtable ht = (Hashtable)cfgData.get(cfg); 391 return ht == null ? null : ht.get(field); 392 } 393 394 static String getFieldString(String cfg, String field) { 395 return (String)getField(cfg, field); 396 } 397 398 static Vector getFieldVector(String cfg, String field) { 399 return (Vector)getField(cfg, field); 400 } 401 402 static void putField(String cfg, String field, Object value) { 403 putFieldImpl(cfg, field, value); 404 if (appliesToTieredBuild(cfg, field)) { 405 putFieldImpl(getTieredBuildCfg(cfg), field, value); 406 } 407 } 408 409 private static void putFieldImpl(String cfg, String field, Object value) { 410 if (cfg == null) { 411 globalData.put(field, value); 412 return; 413 } 414 415 Hashtable ht = (Hashtable)cfgData.get(cfg); 416 if (ht == null) { 417 ht = new Hashtable(); 418 cfgData.put(cfg, ht); 419 } 420 421 ht.put(field, value); 422 } 423 424 static Object getFieldHash(String cfg, String field, String name) { 425 Hashtable ht = (Hashtable)getField(cfg, field); 426 427 return ht == null ? null : ht.get(name); 428 } 429 430 static void putFieldHash(String cfg, String field, String name, Object val) { 431 putFieldHashImpl(cfg, field, name, val); 432 if (appliesToTieredBuild(cfg, field)) { 433 putFieldHashImpl(getTieredBuildCfg(cfg), field, name, val); 434 } 435 } 436 437 private static void putFieldHashImpl(String cfg, String field, String name, Object val) { 438 Hashtable ht = (Hashtable)getField(cfg, field); 439 440 if (ht == null) { 441 ht = new Hashtable(); 442 putFieldImpl(cfg, field, ht); 443 } 444 445 ht.put(name, val); 446 } 447 448 static void addFieldVector(String cfg, String field, String element) { 449 addFieldVectorImpl(cfg, field, element); 450 if (appliesToTieredBuild(cfg, field)) { 451 addFieldVectorImpl(getTieredBuildCfg(cfg), field, element); 452 } 453 } 454 455 private static void addFieldVectorImpl(String cfg, String field, String element) { 456 Vector v = (Vector)getField(cfg, field); 457 458 if (v == null) { 459 v = new Vector(); 460 putFieldImpl(cfg, field, v); 461 } 462 463 v.add(element); 464 } 465 466 String expandFormat(String format) { 467 if (format == null) { 468 return null; 469 } 470 471 if (format.indexOf('%') == -1) { 472 return format; 473 } 474 475 StringBuffer sb = new StringBuffer(); 476 int len = format.length(); 477 for (int i=0; i<len; i++) { 478 char ch = format.charAt(i); 479 if (ch == '%') { 480 char ch1 = format.charAt(i+1); 481 switch (ch1) { 482 case '%': 483 sb.append(ch1); 484 break; 485 case 'b': 486 sb.append(build()); 487 break; 488 case 'f': 489 sb.append(flavour()); 490 break; 491 default: 492 sb.append(ch); 493 sb.append(ch1); 494 } 495 i++; 496 } else { 497 sb.append(ch); 498 } 499 } 500 501 return sb.toString(); 502 } 503 } 504 505 abstract class GenericDebugConfig extends BuildConfig { 506 abstract String getOptFlag(); 507 508 protected void init(Vector includes, Vector defines) { 509 defines.add("_DEBUG"); 510 defines.add("ASSERT"); 511 512 super.init(includes, defines); 513 514 getV("CompilerFlags").addAll(getCI().getDebugCompilerFlags(getOptFlag(), get("PlatformName"))); 515 getV("LinkerFlags").addAll(getCI().getDebugLinkerFlags()); 516 } 517 } 518 519 abstract class GenericDebugNonKernelConfig extends GenericDebugConfig { 520 protected void init(Vector includes, Vector defines) { 521 super.init(includes, defines); 522 if (get("PlatformName").equals("Win32")) { 523 getCI().getAdditionalNonKernelLinkerFlags(getV("LinkerFlags")); 524 } 525 } 526 } 527 528 class C1DebugConfig extends GenericDebugNonKernelConfig { 529 String getOptFlag() { 530 return getCI().getNoOptFlag(); 531 } 532 533 C1DebugConfig() { 534 initNames("client", "debug", "jvm.dll"); 535 init(getIncludes(), getDefines()); 536 } 537 } 538 539 class C1FastDebugConfig extends GenericDebugNonKernelConfig { 540 String getOptFlag() { 541 return getCI().getOptFlag(); 542 } 543 544 C1FastDebugConfig() { 545 initNames("client", "fastdebug", "jvm.dll"); 546 init(getIncludes(), getDefines()); 547 } 548 } 549 550 class TieredDebugConfig extends GenericDebugNonKernelConfig { 551 String getOptFlag() { 552 return getCI().getNoOptFlag(); 553 } 554 555 TieredDebugConfig() { 556 initNames("server", "debug", "jvm.dll"); 557 init(getIncludes(), getDefines()); 558 } 559 } 560 561 class TieredFastDebugConfig extends GenericDebugNonKernelConfig { 562 String getOptFlag() { 563 return getCI().getOptFlag(); 564 } 565 566 TieredFastDebugConfig() { 567 initNames("server", "fastdebug", "jvm.dll"); 568 init(getIncludes(), getDefines()); 569 } 570 } 571 572 abstract class ProductConfig extends BuildConfig { 573 protected void init(Vector includes, Vector defines) { 574 defines.add("NDEBUG"); 575 defines.add("PRODUCT"); 576 577 super.init(includes, defines); 578 579 getV("CompilerFlags").addAll(getCI().getProductCompilerFlags()); 580 getV("LinkerFlags").addAll(getCI().getProductLinkerFlags()); 581 } 582 } 583 584 class C1ProductConfig extends ProductConfig { 585 C1ProductConfig() { 586 initNames("client", "product", "jvm.dll"); 587 init(getIncludes(), getDefines()); 588 } 589 } 590 591 class TieredProductConfig extends ProductConfig { 592 TieredProductConfig() { 593 initNames("server", "product", "jvm.dll"); 594 init(getIncludes(), getDefines()); 595 } 596 } 597 598 599 abstract class CompilerInterface { 600 abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir); 601 abstract Vector getBaseLinkerFlags(String outDir, String outDll, String platformName); 602 abstract Vector getDebugCompilerFlags(String opt, String platformName); 603 abstract Vector getDebugLinkerFlags(); 604 abstract void getAdditionalNonKernelLinkerFlags(Vector rv); 605 abstract Vector getProductCompilerFlags(); 606 abstract Vector getProductLinkerFlags(); 607 abstract String getOptFlag(); 608 abstract String getNoOptFlag(); 609 abstract String makeCfgName(String flavourBuild, String platformName); 610 611 void addAttr(Vector receiver, String attr, String value) { 612 receiver.add(attr); receiver.add(value); 613 } 614 void extAttr(Vector receiver, String attr, String value) { 615 int attr_pos=receiver.indexOf(attr) ; 616 if ( attr_pos == -1) { 617 // If attr IS NOT present in the Vector - add it 618 receiver.add(attr); receiver.add(value); 619 } else { 620 // If attr IS present in the Vector - append value to it 621 receiver.set(attr_pos+1,receiver.get(attr_pos+1)+value); 622 } 623 } 624 }