1 /*
   2  * Copyright (c) 2013, 2016, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /**
  27  * The main build script for JavaFX.
  28  *
  29  * MUST FIX tasks to complete:
  30  *  - build check -- making sure the final artifact has the right bits
  31  *      - some things worth automatically sanity checking:
  32  *          - are there images in the javadocs?
  33  *          - are all of the expected dylibs etc there?
  34  *          - is jfxrt.jar there?
  35  *          - does jfxrt.jar contain stuff it shouldn't (doc-files, iml, etc)
  36  *          - does jfxrt.jar contain stuff it should (bss files, etc)
  37  *  - Perform sanity checking to make sure a JDK exists with javac, javah, etc
  38  *  - Support building with no known JDK location, as long as javac, javah, etc are on the path
  39  *  - Check all of the native flags. We're adding weight to some libs that don't need it, and so forth.
  40  *
  41  * Additional projects to work on as we go:
  42  *  - Add "developer debug". This is where the natives do not have debug symbols, but the Java code does
  43  *  - The genVSproperties.bat doesn't find the directory where RC.exe lives. So it is hard coded. Might be a problem.
  44  *  - special tasks for common needs, such as:
  45  *      - updating copyright headers
  46  *      - stripping trailing whitespace (?)
  47  *  - checkstyle
  48  *  - findbugs
  49  *  - re needs?
  50  *  - sqe testing
  51  *  - API change check
  52  *  - Pushing results to a repo?
  53  *  - ServiceWithSecurityManagerTest fails to complete when run from gradle.
  54  *  - Integrate Parfait reports for C code
  55  *  - FXML Project tests are not running
  56  */
  57 defaultTasks = ["sdk"]
  58 
  59 import java.util.concurrent.CountDownLatch
  60 import java.util.concurrent.ExecutorService
  61 import java.util.concurrent.Executors
  62 import java.util.concurrent.Future
  63 
  64 /******************************************************************************
  65  *                              Utility methods                               *
  66  *****************************************************************************/
  67 
  68 /**
  69  * If the given named property is not defined, then this method will define
  70  * it with the given defaultValue. Any properties defined by this method can
  71  * be substituted on the command line by using -P, or by specifying a
  72  * gradle.properties file in the user home dir
  73  *
  74  * @param name The name of the property to define
  75  * @param defaultValue The default value to assign the property
  76  */
  77 void defineProperty(String name, String defaultValue) {
  78     if (!project.hasProperty(name)) {
  79         project.ext.set(name, defaultValue);
  80     }
  81 }
  82 
  83 /**
  84  * If the given named property is not defined, then this method will attempt to
  85  * look up the property in the props map, and use the defaultValue if it cannot be found.
  86  *
  87  * @param name The name of the property to look up and/or define
  88  * @param props The properties to look for the named property in, if it has not already been defined
  89  * @param defaultValue The default value if the property has not been defined and the
  90  *                     props map does not contain the named property
  91  */
  92 void defineProperty(String name, Properties props, String defaultValue) {
  93     if (!project.hasProperty(name)) {
  94         project.ext.set(name, props.getProperty(name, defaultValue));
  95     }
  96 }
  97 
  98 /**
  99  * Converts cygwin style paths to windows style paths, but with a forward slash.
 100  * This method is safe to call from any platform, and will only do work if
 101  * called on Windows (in all other cases it simply returns the supplied path.
 102  *
 103  * @param path the path to convert
 104  * @return the path converted to windows style, if on windows, otherwise it
 105  *         is the supplied path.
 106  */
 107 String cygpath(String path) {
 108     if (!IS_WINDOWS) return path;
 109     if (path == null || "".equals(path)) return path;
 110     String ret = path.replaceAll('\\\\', '/')
 111     logger.info("Converting path '$path' via cygpath to "+ret)
 112     return ret
 113 }
 114 
 115 void loadProperties(String sourceFileName) {
 116     def config = new Properties()
 117     def propFile = new File(sourceFileName)
 118     if (propFile.canRead()) {
 119         config.load(new FileInputStream(propFile))
 120         for (java.util.Map.Entry property in config) {
 121             def keySplit = property.key.split("\\.");
 122             def key = keySplit[0];
 123             for (int i = 1; i < keySplit.length; i++) {
 124                 key = key + keySplit[i].capitalize();
 125             }
 126             ext[key] = property.value;
 127         }
 128     }
 129 }
 130 
 131 /**
 132  * Struct used to contain some information passed to the closure
 133  * passed to compileTargets.
 134  */
 135 class CompileTarget {
 136     String name;
 137     String upper;
 138     String capital;
 139 }
 140 
 141 /**
 142  * Iterates over each of the compile targets, passing the given closure
 143  * a CompileTarget instance.
 144  *
 145  * @param c The closure to call
 146  */
 147 void compileTargets(Closure c) {
 148     if (COMPILE_TARGETS == "") {
 149         return
 150     }
 151     COMPILE_TARGETS.split(",").each { target ->
 152         CompileTarget ct = new CompileTarget();
 153         ct.name = target;
 154         ct.upper = target.trim().toUpperCase(Locale.ROOT)
 155         ct.capital = target.trim().capitalize()
 156         c(ct)
 157     }
 158 }
 159 
 160 /**
 161  * Manages the execution of some closure which is responsible for producing
 162  * content for a properties file built at build time and stored in the
 163  * root project's $buildDir, and then loading that properties file and
 164  * passing it to the processor closure.
 165  *
 166  * This is used on windows to produce a properties file containing all the
 167  * windows visual studio paths and environment variables, and on Linux
 168  * for storing the results of pkg-config calls.
 169  *
 170  * @param name the name of the file to produce
 171  * @param loader a closure which is invoked, given the properties file. This
 172  *        closure is invoked only if the properties file needs to be created
 173  *        and is responsible for populating the properties file.
 174  * @param processor a closure which is invoked every time this method is
 175  *        called and which will be given a Properties object, fully populated.
 176  *        The processor is then responsible for doing whatever it is that it
 177  *        must do with those properties (such as setting up environment
 178  *        variables used in subsequent native builds, or whatnot).
 179  */
 180 void setupTools(String name, Closure loader, Closure processor) {
 181     // Check to see whether $buildDir/$name.properties file exists. If not,
 182     // then generate it. Once generated, we need to read the properties file to
 183     // help us define the defaults for this block of properties
 184     File propFile = file("$buildDir/${name}.properties");
 185     if (!propFile.exists()) {
 186         // Create the properties file
 187         propFile.getParentFile().mkdirs();
 188         propFile.createNewFile();
 189         loader(propFile);
 190     }
 191 
 192     // Try reading the properties in order to define the properties. If the property file cannot
 193     // be located, then we will throw an exception because we cannot guess these values
 194     InputStream propStream = null;
 195     try {
 196         Properties properties = new Properties();
 197         propStream = new FileInputStream(propFile);
 198         properties.load(propStream);
 199         processor(properties);
 200     } finally {
 201         try { propStream.close() } catch (Exception e) { }
 202     }
 203 }
 204 
 205 String[] parseJavaVersion(String jRuntimeVersion) {
 206     def jVersion = jRuntimeVersion.split("[-\\+]")[0]
 207     def tmpBuildNumber = "0"
 208     if (jVersion.startsWith("1.")) {
 209         // This is a pre-JEP-223 version string
 210         def dashbIdx = jRuntimeVersion.lastIndexOf("-b")
 211         if (dashbIdx != -1) {
 212             tmpBuildNumber = jRuntimeVersion.substring(dashbIdx + 2)
 213         }
 214     } else {
 215         // This is a post-JEP-223 version string
 216         def plusIdx = jRuntimeVersion.indexOf("+")
 217         if (plusIdx != -1) {
 218             tmpBuildNumber = jRuntimeVersion.substring(plusIdx + 1)
 219         }
 220     }
 221     def jBuildNumber = tmpBuildNumber.split("[-\\+]")[0]
 222     def versionInfo = new String[2];
 223     versionInfo[0] = jVersion
 224     versionInfo[1] = jBuildNumber
 225     return versionInfo
 226 }
 227 
 228 /**
 229  * Fails the build with the specified error message
 230  *
 231  * @param msg the reason for the failure
 232  */
 233 void fail(String msg) {
 234     throw new GradleException("FAIL: " + msg);
 235 }
 236 
 237 /******************************************************************************
 238  *                                                                            *
 239  *                   Definition of project properties                         *
 240  *                                                                            *
 241  *  All properties defined using ext. are immediately available throughout    *
 242  *  the script as variables that can be used. These variables are attached    *
 243  *  to the root project (whereas if they were defined as def variables then   *
 244  *  they would only be available within the root project scope).              *
 245  *                                                                            *
 246  *  All properties defined using the "defineProperty" method can be replaced  *
 247  *  on the command line by using the -P flag. For example, to override the    *
 248  *  location of the binary plug, you would specify -PBINARY_PLUG=some/where   *
 249  *                                                                            *
 250  *****************************************************************************/
 251 
 252 // If the ../rt-closed directory exists, then we are doing a closed build.
 253 // In this case, build and property files will be read from
 254 // ../rt-closed/closed-build.gradle and ../rt-closed/closed-properties.gradle
 255 // respectively
 256 
 257 def closedDir = file("../rt-closed")
 258 def buildClosed = closedDir.isDirectory()
 259 ext.BUILD_CLOSED = buildClosed
 260 
 261 // These variables indicate what platform is running the build. Is
 262 // this build running on a Mac, Windows, or Linux machine? 32 or 64 bit?
 263 ext.OS_NAME = System.getProperty("os.name").toLowerCase()
 264 ext.OS_ARCH = System.getProperty("os.arch")
 265 ext.IS_64 = OS_ARCH.toLowerCase().contains("64")
 266 ext.IS_MAC = OS_NAME.contains("mac") || OS_NAME.contains("darwin")
 267 ext.IS_WINDOWS = OS_NAME.contains("windows")
 268 ext.IS_LINUX = OS_NAME.contains("linux")
 269 
 270 // Verify that the architecture & OS are supported configurations. Note that
 271 // at present building on PI is not supported, but we would only need to make
 272 // some changes on assumptions on what should be built (like SWT / Swing) and
 273 // such and we could probably make it work.
 274 if (!IS_MAC && !IS_WINDOWS && !IS_LINUX) fail("Unsupported build OS ${OS_NAME}")
 275 if (IS_WINDOWS && OS_ARCH != "x86" && OS_ARCH != "amd64") {
 276     fail("Unknown and unsupported build architecture: $OS_ARCH")
 277 } else if (IS_MAC && OS_ARCH != "x86_64") {
 278     fail("Unknown and unsupported build architecture: $OS_ARCH")
 279 } else if (IS_LINUX && OS_ARCH != "i386" && OS_ARCH != "amd64") {
 280     fail("Unknown and unsupported build architecture: $OS_ARCH")
 281 }
 282 
 283 
 284 // Get the JDK_HOME automatically based on the version of Java used to execute gradle. Or, if specified,
 285 // use a user supplied JDK_HOME, STUB_RUNTIME, JAVAC, and/or JAVAH, all of which may be specified
 286 // independently (or we'll try to get the right one based on other supplied info). Sometimes the
 287 // JRE might be the thing that is being used instead of the JRE embedded in the JDK, such as:
 288 //    c:\Program Files (x86)\Java\jdk1.8.0\jre
 289 //    c:\Program Files (x86)\Java\jre8\
 290 // Because of this, you may sometimes get the jdk's JRE (in which case the logic we used to have here
 291 // was correct and consistent with all other platforms), or it might be the standalone JRE (for the love!).
 292 def envJavaHome = cygpath(System.getenv("JDK_HOME"))
 293 if (envJavaHome == null || envJavaHome.equals("")) envJavaHome = cygpath(System.getenv("JAVA_HOME"))
 294 def javaHome = envJavaHome == null || envJavaHome.equals("") ? System.getProperty("java.home") : envJavaHome
 295 def javaHomeFile = file(javaHome)
 296 defineProperty("JDK_HOME",
 297         javaHomeFile.name == "jre" ?
 298         javaHomeFile.getParent().toString() :
 299         javaHomeFile.name.startsWith("jre") ?
 300         new File(javaHomeFile.getParent(), "jdk1.${javaHomeFile.name.substring(3)}.0").toString() :
 301         javaHome) // we have to bail and set it to something and this is as good as any!
 302 ext.JAVA_HOME = JDK_HOME
 303 
 304 // Check whether JIGSAW_HOME is set. If it is, then it points to a JDK9
 305 // jigsaw build with modularization enabled and can be used for testing
 306 def envJigsawHome = cygpath(System.getenv("JIGSAW_HOME"))
 307 defineProperty("JIGSAW_HOME", envJigsawHome);
 308 
 309 if (JIGSAW_HOME == null || JIGSAW_HOME == "") {
 310     logger.warn("JIGSAW_HOME is not set");
 311     ext.USE_JIGSAW = false
 312 } else {
 313     ext.USE_JIGSAW = true
 314 }
 315 
 316 defineProperty("JAVA", cygpath("$JDK_HOME/bin/java${IS_WINDOWS ? '.exe' : ''}"))
 317 defineProperty("JIGSAW_JAVA", cygpath("$JIGSAW_HOME/bin/java${IS_WINDOWS ? '.exe' : ''}"))
 318 defineProperty("JAVAC", cygpath("$JDK_HOME/bin/javac${IS_WINDOWS ? '.exe' : ''}"))
 319 defineProperty("JIGSAW_JAVAC", cygpath("$JIGSAW_HOME/bin/javac${IS_WINDOWS ? '.exe' : ''}"))
 320 defineProperty("JAVAH", cygpath("$JDK_HOME/bin/javah${IS_WINDOWS ? '.exe' : ''}"))
 321 defineProperty("JAVADOC", cygpath("$JDK_HOME/bin/javadoc${IS_WINDOWS ? '.exe' : ''}"))
 322 defineProperty("JDK_DOCS", "https://docs.oracle.com/javase/8/docs/api/")
 323 defineProperty("JIGSAW_MODULES", cygpath(System.getenv("JIGSAW_MODULES")) ?: cygpath(System.getenv("JIGSAW_HOME") + "/jmods"))
 324 
 325 defineProperty("javaRuntimeVersion", System.getProperty("java.runtime.version"))
 326 def javaVersionInfo = parseJavaVersion(javaRuntimeVersion)
 327 defineProperty("javaVersion", javaVersionInfo[0])
 328 defineProperty("javaBuildNumber", javaVersionInfo[1])
 329 
 330 loadProperties("$projectDir/build.properties")
 331 
 332 // Look for stub runtime in either old (JDK 8u) or new (JDK 9) dir layout
 333 
 334 def cachesSdkRtDir = file("../caches/sdk/rt")
 335 def hasRtDir = cachesSdkRtDir.isDirectory()
 336 def String closedCacheStubRuntime = cygpath("$projectDir") + "/../caches/sdk" + (hasRtDir ? "/rt" : "")
 337 
 338 def jdkHomeJreDir = file("$JDK_HOME/jre")
 339 def hasJreDir = jdkHomeJreDir.isDirectory()
 340 def String jreStubRuntime = cygpath("$JDK_HOME") + (hasJreDir ? "/jre" : "")
 341 
 342 defineProperty("STUB_RUNTIME", BUILD_CLOSED ? closedCacheStubRuntime : jreStubRuntime)
 343 
 344 defineProperty("LIBRARY_STUB", IS_MAC ? "$STUB_RUNTIME/lib" :
 345                                IS_WINDOWS ? "$STUB_RUNTIME/bin" :
 346                                "$STUB_RUNTIME/lib/$OS_ARCH")
 347 defineProperty("UPDATE_STUB_CACHE", (STUB_RUNTIME.equals(closedCacheStubRuntime) ? 'true' : 'false'))
 348 
 349 def supplementalPreBuildFile = file("$closedDir/closed-pre-build.gradle");
 350 def supplementalBuildFile = file("$closedDir/closed-build.gradle");
 351 
 352 if (BUILD_CLOSED) {
 353     apply from: supplementalPreBuildFile
 354 }
 355 
 356 // GRADLE_VERSION_CHECK specifies whether to fail the build if the
 357 // gradle version check fails
 358 defineProperty("GRADLE_VERSION_CHECK", "true")
 359 ext.IS_GRADLE_VERSION_CHECK = Boolean.parseBoolean(GRADLE_VERSION_CHECK)
 360 
 361 // COMPILE_WEBKIT specifies whether to build all of webkit.
 362 defineProperty("COMPILE_WEBKIT", "false")
 363 ext.IS_COMPILE_WEBKIT = Boolean.parseBoolean(COMPILE_WEBKIT)
 364 
 365 // COMPILE_MEDIA specifies whether to build all of media.
 366 defineProperty("COMPILE_MEDIA", "false")
 367 ext.IS_COMPILE_MEDIA = Boolean.parseBoolean(COMPILE_MEDIA)
 368 
 369 // COMPILE_PANGO specifies whether to build javafx_font_pango.
 370 defineProperty("COMPILE_PANGO", "${IS_LINUX}")
 371 ext.IS_COMPILE_PANGO = Boolean.parseBoolean(COMPILE_PANGO)
 372 
 373 // COMPILE_HARFBUZZ specifies whether to use Harfbuzz.
 374 defineProperty("COMPILE_HARFBUZZ", "false")
 375 ext.IS_COMPILE_HARFBUZZ = Boolean.parseBoolean(COMPILE_HARFBUZZ)
 376 
 377 // COMPILE_PARFAIT specifies whether to build parfait
 378 defineProperty("COMPILE_PARFAIT", "false")
 379 ext.IS_COMPILE_PARFAIT = Boolean.parseBoolean(COMPILE_PARFAIT)
 380 
 381 // FIXME: update the default when using 9 (pre-jigsaw) as boot jdk
 382 // COMPILE_JFR specifies whether to build code that logs to JRockit Flight Recorder
 383 defineProperty("COMPILE_JFR", Boolean.toString(file("$JDK_HOME/jre/lib/jfr.jar").exists()))
 384 ext.IS_COMPILE_JFR = Boolean.parseBoolean(COMPILE_JFR)
 385 
 386 // BUILD_FXPACKAGER enables building the packager modules and native code
 387 defineProperty("BUILD_FXPACKAGER", "false")
 388 ext.IS_BUILD_FXPACKAGER = Boolean.parseBoolean(BUILD_FXPACKAGER)
 389 
 390 // RETAIN_PACKAGER_TESTS specifies whether the tests in fxpackager should
 391 // keep generated files instead of attempting to automatically delete them
 392 defineProperty("RETAIN_PACKAGER_TESTS", "false")
 393 ext.IS_RETAIN_PACKAGER_TESTS = Boolean.parseBoolean(RETAIN_PACKAGER_TESTS)
 394 
 395 // TEST_PACKAGER_DMG whether tests that create DMG files via hdiutil
 396 // should be run.  On OSX 10.7 this tends to hang automated builds
 397 defineProperty("TEST_PACKAGER_DMG", "false")
 398 ext.IS_TEST_PACKAGER_DMG = Boolean.parseBoolean(TEST_PACKAGER_DMG)
 399 
 400 // Define the SWT.jar that we are going to have to download during the build process based
 401 // on what platform we are compiling from (not based on our target).
 402 ext.SWT_FILE_NAME = IS_MAC ? "org.eclipse.swt.cocoa.macosx.x86_64_3.7.2.v3740f" :
 403     IS_WINDOWS && IS_64 ? "org.eclipse.swt.win32.win32.x86_64_3.7.2.v3740f" :
 404     IS_WINDOWS && !IS_64 ? "org.eclipse.swt.win32.win32.x86_3.7.2.v3740f" :
 405     IS_LINUX && IS_64 ? "org.eclipse.swt.gtk.linux.x86_64_3.7.2.v3740f" :
 406     IS_LINUX && !IS_64 ? "org.eclipse.swt.gtk.linux.x86_3.7.2.v3740f" : ""
 407 
 408 // Build javadocs only if BUILD_JAVADOC=true
 409 defineProperty("BUILD_JAVADOC", "false")
 410 ext.IS_BUILD_JAVADOC = Boolean.parseBoolean(BUILD_JAVADOC)
 411 
 412 // Specifies whether to build the javafx-src bundle
 413 defineProperty("BUILD_SRC_ZIP", "false")
 414 ext.IS_BUILD_SRC_ZIP = Boolean.parseBoolean(BUILD_SRC_ZIP)
 415 
 416 // Specifies whether to build the javafx-exports bundle
 417 defineProperty("BUILD_MODULE_ZIP", "true")
 418 ext.IS_BUILD_MODULE_ZIP = Boolean.parseBoolean(BUILD_MODULE_ZIP)
 419 
 420 // Specifies whether to run full tests (true) or smoke tests (false)
 421 defineProperty("FULL_TEST", "false")
 422 ext.IS_FULL_TEST = Boolean.parseBoolean(FULL_TEST);
 423 
 424 defineProperty("JIGSAW_TEST", "true")
 425 ext.IS_JIGSAW_TEST = Boolean.parseBoolean(JIGSAW_TEST) && USE_JIGSAW
 426 
 427 defineProperty("FORCE_TESTS", "false")
 428 ext.IS_FORCE_TESTS = Boolean.parseBoolean(FORCE_TESTS);
 429 
 430 // Specifies whether to run robot-based visual tests (only used when FULL_TEST is also enabled)
 431 defineProperty("USE_ROBOT", "false")
 432 ext.IS_USE_ROBOT = Boolean.parseBoolean(USE_ROBOT);
 433 
 434 // Specified whether to run tests in headless mode
 435 defineProperty("HEADLESS_TEST", "false")
 436 ext.IS_HEADLESS_TEST = Boolean.parseBoolean(HEADLESS_TEST);
 437 
 438 // Specifies whether to run system tests that depend on AWT (only used when FULL_TEST is also enabled)
 439 defineProperty("AWT_TEST", "true")
 440 ext.IS_AWT_TEST = Boolean.parseBoolean(AWT_TEST);
 441 
 442 // Specifies whether to run system tests that depend on SWT (only used when FULL_TEST is also enabled)
 443 defineProperty("SWT_TEST", "true")
 444 ext.IS_SWT_TEST = Boolean.parseBoolean(SWT_TEST);
 445 
 446 // Specifies whether to run unstable tests (true) - tests that don't run well with Hudson builds
 447 // These tests should be protected with :
 448 //    assumeTrue(Boolean.getBoolean("unstable.test"));
 449 defineProperty("UNSTABLE_TEST", "false")
 450 ext.IS_UNSTABLE_TEST = Boolean.parseBoolean(UNSTABLE_TEST);
 451 
 452 // Toggle diagnostic output from the Gradle workaround and the Sandbox test apps.
 453 defineProperty("WORKER_DEBUG", "false")
 454 ext.IS_WORKER_DEBUG = Boolean.parseBoolean(WORKER_DEBUG);
 455 
 456 // Specify the build configuration (Release, Debug, or DebugNative)
 457 defineProperty("CONF", "Debug")
 458 ext.IS_DEBUG_JAVA = CONF == "Debug" || CONF == "DebugNative"
 459 ext.IS_DEBUG_NATIVE = CONF == "DebugNative"
 460 
 461 // Defines the compiler warning levels to use. If empty, then no warnings are generated. If
 462 // not empty, then the expected syntax is as a space or comma separated list of names, such
 463 // as defined in the javac documentation.
 464 defineProperty("LINT", "none")
 465 ext.IS_LINT = LINT != "none"
 466 
 467 defineProperty("DOC_LINT", "none")
 468 ext.IS_DOC_LINT = DOC_LINT != "none"
 469 
 470 // Specifies whether to use the "useDepend" option when compiling Java sources
 471 defineProperty("USE_DEPEND", "true")
 472 ext.IS_USE_DEPEND = Boolean.parseBoolean(USE_DEPEND)
 473 
 474 // Specifies whether to use the "incremental" option when compiling Java sources
 475 defineProperty("INCREMENTAL", "false")
 476 ext.IS_INCREMENTAL = Boolean.parseBoolean(INCREMENTAL)
 477 
 478 // Specifies whether to include the Null3D pipeline (for perf debugging)
 479 defineProperty("INCLUDE_NULL3D", "false")
 480 ext.IS_INCLUDE_NULL3D = Boolean.parseBoolean(INCLUDE_NULL3D)
 481 
 482 // Specifies whether to include the ES2 pipeline if available
 483 defineProperty("INCLUDE_ES2", IS_WINDOWS ? "false" : "true")
 484 ext.IS_INCLUDE_ES2 = Boolean.parseBoolean(INCLUDE_ES2)
 485 
 486 // Specifies whether to generate code coverage statistics when running tests
 487 defineProperty("JCOV", "false")
 488 ext.DO_JCOV = Boolean.parseBoolean(JCOV)
 489 
 490 // Define the number of threads to use when compiling (specifically for native compilation)
 491 // On Mac we limit it to 1 by default due to problems running gcc in parallel
 492 if (IS_MAC) {
 493     defineProperty("NUM_COMPILE_THREADS", "1")
 494 } else {
 495     defineProperty("NUM_COMPILE_THREADS", "${Runtime.runtime.availableProcessors()}")
 496 }
 497 
 498 //
 499 // The next three sections of properties are used to generate the
 500 // VersionInfo class, and the Windows DLL manifest.
 501 //
 502 
 503 // The following properties should be left alone by developers and set only from Hudson.
 504 defineProperty("HUDSON_JOB_NAME", "not_hudson")
 505 defineProperty("HUDSON_BUILD_NUMBER","0000")
 506 defineProperty("PROMOTED_BUILD_NUMBER", "0")
 507 
 508 // The following properties define the product name for Oracle JDK and OpenJDK
 509 // for VersionInfo and the DLL manifest.
 510 if (BUILD_CLOSED) {
 511     defineProperty("PRODUCT_NAME", "Java(TM)")
 512     defineProperty("COMPANY_NAME", "Oracle Corporation")
 513     defineProperty("PLATFORM_NAME", "Platform SE")
 514 } else {
 515     defineProperty("PRODUCT_NAME", "OpenJFX")
 516     defineProperty("COMPANY_NAME", "N/A")
 517     defineProperty("PLATFORM_NAME", "Platform")
 518 }
 519 
 520 // The following properties are set based on properties defined in
 521 // build.properties. The release version and suffix should be updated
 522 // in that file.
 523 def relVer = 0
 524 if (jfxReleasePatchVersion == "0") {
 525     if (jfxReleaseSecurityVersion == "0") {
 526         if (jfxReleaseMinorVersion == "0") {
 527             relVer = "${jfxReleaseMajorVersion}"
 528         } else {
 529             relVer = "${jfxReleaseMajorVersion}.${jfxReleaseMinorVersion}"
 530         }
 531     } else {
 532         relVer = "${jfxReleaseMajorVersion}.${jfxReleaseMinorVersion}.${jfxReleaseSecurityVersion}"
 533     }
 534 } else {
 535     relVer = "${jfxReleaseMajorVersion}.${jfxReleaseMinorVersion}.${jfxReleaseSecurityVersion}.${jfxReleasePatchVersion}"
 536 }
 537 defineProperty("RELEASE_VERSION", relVer)
 538 defineProperty("RELEASE_VERSION_PADDED", "${jfxReleaseMajorVersion}.${jfxReleaseMinorVersion}.${jfxReleaseSecurityVersion}.${jfxReleasePatchVersion}")
 539 
 540 def buildDate = new java.util.Date()
 541 def buildTimestamp = new java.text.SimpleDateFormat("yyyy-MM-dd-HHmmss").format(buildDate)
 542 defineProperty("BUILD_TIMESTAMP", buildTimestamp)
 543 def relSuffix = ""
 544 def relOpt = ""
 545 if (HUDSON_JOB_NAME == "not_hudson") {
 546     relSuffix = "-internal"
 547     relOpt = "-${buildTimestamp}"
 548 } else {
 549     relSuffix = jfxReleaseSuffix
 550 }
 551 defineProperty("RELEASE_SUFFIX", relSuffix)
 552 defineProperty("RELEASE_VERSION_SHORT", "${RELEASE_VERSION}${RELEASE_SUFFIX}")
 553 defineProperty("RELEASE_VERSION_LONG", "${RELEASE_VERSION_SHORT}+${PROMOTED_BUILD_NUMBER}${relOpt}")
 554 
 555 // Check whether the COMPILE_TARGETS property has been specified (if so, it was done by
 556 // the user and not by this script). If it has not been defined then default
 557 // to building the normal desktop build for this machine
 558 project.ext.set("defaultHostTarget", IS_MAC ? "mac" : IS_WINDOWS ? "win" : IS_LINUX ? "linux" : "");
 559 defineProperty("COMPILE_TARGETS", "$defaultHostTarget")
 560 
 561 // Flag indicating whether to import cross compile tools
 562 def importCrossTools = BUILD_CLOSED ? true : false;
 563 if (!importCrossTools && hasProperty("IMPORT_CROSS_TOOLS")) {
 564     importCrossTools = Boolean.parseBoolean(IMPORT_CROSS_TOOLS);
 565 }
 566 ext.IS_IMPORT_CROSS_TOOLS = importCrossTools
 567 
 568 // Location of the cross compile tools
 569 def crossToolsDir = "../crosslibs"
 570 if (hasProperty("CROSS_TOOLS_DIR")) {
 571     crossToolsDir = CROSS_TOOLS_DIR
 572 }
 573 ext.CROSS_TOOLS_DIR = file(crossToolsDir)
 574 
 575 // Specifies whether to run tests with the present jfxrt.jar instead of compiling the new one
 576 defineProperty("BUILD_SDK_FOR_TEST", "true")
 577 ext.DO_BUILD_SDK_FOR_TEST = Boolean.parseBoolean(BUILD_SDK_FOR_TEST)
 578 
 579 // Specifies the location to point at SDK build when DO_BUILD_SDK_FOR_TEST set to false
 580 // Used to get location of jfxrt.jar, ant-javafx.jar and javafx-mx.jar
 581 defineProperty("TEST_SDK", JDK_HOME)
 582 ext.TEST_SDK_DIR = file(TEST_SDK)
 583 
 584 def rtDir = TEST_SDK_DIR
 585 ext.jfxrtJarFromSdk = new File(rtDir, "lib/jfxrt.jar").absolutePath
 586 if (!DO_BUILD_SDK_FOR_TEST && !file(jfxrtJarFromSdk).exists()) {
 587     fail ("BUILD_SDK_FOR_TEST is set to false, but there\'s no jfxrt.jar at the expected paths in TEST_SDK($TEST_SDK_DIR)\n"
 588             + "TEST_SDK should point at either JavaFX SDK location or JDK location\n"
 589             + "Please, set the correct TEST_SDK")
 590 }
 591 
 592 // These tasks would be disabled when running with DO_BUILD_SDK_FOR_TEST=false as they're unneeded for running tests
 593 def disabledTasks = DO_BUILD_SDK_FOR_TEST ? [] : ["compileJava", "processResources", "classes", // all projects
 594          "generateDecoraShaders", "generatePrismShaders",
 595          "compilePrismCompilers", "compilePrismJavaShaders", "compileDecoraCompilers", // :graphics
 596          "processDecoraShaders", "processPrismShaders"]
 597 
 598 /**
 599  * Fetch/Check that external tools are present for the build. This method
 600  * will conditionally download the packages from project defined ivy repositories
 601  * and unpack them into the specified destdir
 602  *
 603  * @param configName A unique name to distinguish the configuration (ie "ARMSFV6")
 604  * @param packages A list of required packages (with extensions .tgz, .zip)
 605  * @param destdir where the packages should be unpacked
 606  * @param doFetch if true, the named packages will be download
 607  */
 608 void fetchExternalTools(String configName, List packages, File destdir, boolean doFetch) {
 609     if (doFetch) {
 610         // create a unique configuration for this fetch
 611         def String fetchToolsConfig = "fetchTools$configName"
 612         rootProject.configurations.create(fetchToolsConfig)
 613 
 614         def List<String> fetchedPackages = []
 615         def int fetchCount = 0
 616 
 617         packages.each { pkgname->
 618             def int dotdex = pkgname.lastIndexOf('.')
 619             def int dashdex = pkgname.lastIndexOf('-')
 620             def String basename = pkgname.substring(0,dashdex)
 621             def String ver = pkgname.substring(dashdex+1,dotdex)
 622             def String ext = pkgname.substring(dotdex+1)
 623             def File pkgdir = file("$destdir/$basename-$ver")
 624 
 625             if (!pkgdir.isDirectory()) {
 626                 rootProject.dependencies.add(fetchToolsConfig, "javafx:$basename:$ver", {
 627                     artifact {
 628                         name = basename
 629                         version = ver
 630                         type = ext
 631                     }
 632                 })
 633                 println "adding $pkgname as a downloadable item did not find $pkgdir"
 634                 fetchedPackages.add(pkgname)
 635                 fetchCount++
 636             }
 637         }
 638 
 639         //fetch all the missing packages
 640         if (fetchedPackages.size > 0) {
 641             destdir.mkdirs()
 642 
 643             logger.quiet "fetching missing packages $fetchedPackages"
 644             copy {
 645                 from rootProject.configurations[fetchToolsConfig]
 646                 into destdir
 647             }
 648 
 649             // unpack the fetched packages
 650             fetchedPackages.each { pkgname->
 651                 logger.quiet "expanding the package $pkgname"
 652                 def srcball = file("${destdir}/${pkgname}")
 653 
 654                 if (!srcball.exists()) {
 655                     throw new GradleException("Failed to fetch $pkgname");
 656                 }
 657 
 658                 def String basename = pkgname.substring(0,pkgname.lastIndexOf("."))
 659                 def File pkgdir = file("$destdir/$basename")
 660 
 661                 if (pkgname.endsWith(".tgz")) {
 662                     if (IS_LINUX || IS_MAC) {
 663                         // use native tar to support symlinks
 664                         pkgdir.mkdirs()
 665                         exec {
 666                             workingDir pkgdir
 667                             commandLine "tar", "zxf", "${srcball}"
 668                          }
 669                     } else {
 670                         copy {
 671                             from tarTree(resources.gzip("${srcball}"))
 672                             into pkgdir
 673                         }
 674                     }
 675                 } else if (pkgname.endsWith(".zip")) {
 676                      copy {
 677                          from zipTree("${srcball}")
 678                          into pkgdir
 679                      }
 680                 } else {
 681                     throw new GradleException("Unhandled package type for compile package ${pkgname}")
 682                 }
 683                 srcball.deleteOnExit();
 684             }
 685         } else {
 686             logger.quiet "all tool packages are present $packages"
 687         }
 688     } else { // !doFetch - so just check they are present
 689         // check that all the dirs are really there
 690         def List<String> errors = []
 691         packages.each { pkgname->
 692             def String basename = pkgname.substring(0,pkgname.lastIndexOf("."))
 693             def File pkgdir = file("$destdir/$basename")
 694 
 695             if (!pkgdir.isDirectory()) {
 696                 errors.add(pkgname)
 697             }
 698         }
 699         if (errors.size > 0) {
 700             throw new GradleException("Error: missing tool packages: $errors")
 701         } else {
 702             logger.quiet "all tool packages are present $packages"
 703         }
 704     }
 705 }
 706 
 707 // Now we need to define the native compilation tasks. The set of parameters to
 708 // native compilation depends on the target platform (and also to some extent what platform
 709 // you are compiling on). These settings are contained in various gradle files
 710 // such as mac.gradle and linux.gradle and armhf.gradle. Additionally, the developer
 711 // can specify COMPILE_FLAGS_FILE to be a URL or path to a different gradle file
 712 // that will contain the appropriate flags.
 713 defineProperty("COMPILE_FLAGS_FILES", COMPILE_TARGETS.split(",").collect {"buildSrc/${it.trim()}.gradle"}.join(","))
 714 if (COMPILE_TARGETS == "all") {
 715     def tmp = []
 716     File buildSrcDir = file("buildSrc")
 717     buildSrcDir.listFiles().each { File f ->
 718         if (f.isFile() && f.name.endsWith(".gradle") && !f.name.equals("build.gradle")) {
 719             def target = f.name.substring(0, f.name.lastIndexOf('.gradle')).toUpperCase(Locale.ROOT)
 720             apply from: f
 721             if (project.ext["${target}"].canBuild) {
 722                 tmp.add(target)
 723             }
 724         }
 725     }
 726     COMPILE_FLAGS_FILES = tmp.collect { "buildSrc/${it}.gradle"}.join(",")
 727     COMPILE_TARGETS = tmp.collect { "${it.toLowerCase()}"}.join(",")
 728 } else {
 729     COMPILE_FLAGS_FILES.split(",").each {
 730         logger.info("Applying COMPILE_FLAGS_FILE '$it'")
 731         apply from: it
 732     }
 733 }
 734 
 735 if (COMPILE_TARGETS != "") {
 736     def tmp = []
 737     COMPILE_TARGETS.split(",").each {target ->
 738         if (project.ext["${target.toUpperCase(Locale.ROOT)}"].canBuild) {
 739             tmp.add(target)
 740         }
 741     }
 742     COMPILE_TARGETS = tmp.collect { "${it.toLowerCase()}"}.join(",")
 743 }
 744 
 745 // Sanity check the expected properties all exist
 746 compileTargets { t ->
 747     // Every platform must define these variables
 748     if (!project.hasProperty(t.upper)) throw new Exception("ERROR: Incorrectly configured compile flags file, missing ${t.name} property")
 749     def props = project.ext[t.upper];
 750     ["compileSwing", "compileSWT", "compileFXPackager", "libDest"].each { prop ->
 751         if (!props.containsKey(prop)) throw new Exception("ERROR: Incorrectly configured compile flags file, missing ${prop} property on ${t.name}")
 752     }
 753 }
 754 
 755 // Various build flags may be set by the different target files, such as
 756 // whether to build Swing, SWT, FXPackager, etc. We iterate over all
 757 // compile targets and look for these settings in our properties. Note that
 758 // these properties cannot be set from the command line, but are set by
 759 // the target build files such as armv6hf.gradle or mac.gradle.
 760 ext.COMPILE_SWING = false;
 761 ext.COMPILE_SWT = false;
 762 ext.COMPILE_FXPACKAGER = false;
 763 compileTargets { t ->
 764     def targetProperties = project.rootProject.ext[t.upper]
 765 
 766     if (targetProperties.compileSwing) COMPILE_SWING = true
 767     if (targetProperties.compileSWT) COMPILE_SWT = true
 768     if (IS_BUILD_FXPACKAGER && JIGSAW_HOME && targetProperties.compileFXPackager) COMPILE_FXPACKAGER = true
 769 
 770     if (!targetProperties.containsKey('compileWebnodeNative')) {
 771         // unless specified otherwise, we will compile native Webnode if IS_COMPILE_WEBKIT
 772         targetProperties.compileWebnodeNative = true
 773     }
 774 
 775     if (!targetProperties.containsKey('compileMediaNative')) {
 776         // unless specified otherwise, we will compile native Media if IS_COMPILE_MEDIA
 777         targetProperties.compileMediaNative = true
 778     }
 779 
 780     if (!targetProperties.containsKey('includeSWT')) targetProperties.includeSWT = true
 781     if (!targetProperties.containsKey('includeSwing')) targetProperties.includeSwing = true
 782     if (!targetProperties.containsKey('includeNull3d')) targetProperties.includeNull3d = true
 783     if (!targetProperties.containsKey('includeLens')) targetProperties.includeLens = false
 784     if (!targetProperties.containsKey('includeMonocle')) targetProperties.includeMonocle = false
 785     if (!targetProperties.containsKey('includeEGL')) targetProperties.includeEGL = false
 786 
 787     if (!targetProperties.containsKey('includeGTK')) targetProperties.includeGTK = IS_LINUX
 788 
 789     // This value is used as a prefix for various directories under ./build,
 790     // such as sdk, to allow for a common name for the hosted build
 791     // (for use when building apps) and a unique name for cross builds.
 792     if (rootProject.defaultHostTarget.equals(t.name)) {
 793         // use a simple common default for the "host" build
 794         targetProperties.platformPrefix=""
 795     } else {
 796         // and a more complex one for cross builds
 797         targetProperties.platformPrefix="${t.name}-"
 798     }
 799 }
 800 
 801 /******************************************************************************
 802  *                                                                            *
 803  *                         Build Setup Sanity Checks                          *
 804  *                                                                            *
 805  *  Here we do a variety of checks so that if the version of Java you are     *
 806  *  building with is misconfigured, or you are using the wrong version of     *
 807  *  gradle, etc you will get some kind of helpful error / warning message     *
 808  *                                                                            *
 809  *****************************************************************************/
 810 
 811 // Sanity check that we actually have a list of compile targets to execute
 812 if (COMPILE_TARGETS == null || COMPILE_TARGETS == "") {
 813     throw new Exception("Unable to determine compilation platform, must specify valid COMPILE_TARGETS!")
 814 }
 815 
 816 // Make sure JDK_HOME/bin/java exists
 817 if (!file(JAVA).exists()) throw new Exception("Missing or incorrect path to 'java': '$JAVA'. Perhaps bad JDK_HOME? $JDK_HOME")
 818 if (!file(JIGSAW_JAVA).exists()) logger.warn("Missing or incorrect path to JIGSAW 'java': '$JIGSAW_JAVA'. Perhaps bad JIGSAW_HOME? $JIGSAW_HOME")
 819 if (!file(JAVAC).exists()) throw new Exception("Missing or incorrect path to 'javac': '$JAVAC'. Perhaps bad JDK_HOME? $JDK_HOME")
 820 if (!file(JIGSAW_JAVAC).exists()) logger.warn("Missing or incorrect path to JIGSAW 'javac': '$JIGSAW_JAVAC'. Perhaps bad JIGSAW_HOME? $JIGSAW_HOME")
 821 if (!file(JAVAH).exists()) throw new Exception("Missing or incorrect path to 'javah': '$JAVAH'. Perhaps bad JDK_HOME? $JDK_HOME")
 822 if (!file(JAVADOC).exists()) throw new Exception("Missing or incorrect path to 'javadoc': '$JAVADOC'. Perhaps bad JDK_HOME? $JDK_HOME")
 823 
 824 // Determine the verion of Java in JDK_HOME. It looks like this:
 825 //
 826 // $ java -version
 827 // java version "1.7.0_45"
 828 // Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
 829 // Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
 830 //
 831 // We need to parse the second line
 832 def inStream = new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.ProcessBuilder(JAVA, "-fullversion").start().getErrorStream()));
 833 try {
 834     String v = inStream.readLine().trim();
 835     if (v != null) {
 836         int ib = v.indexOf("full version \"");
 837         if (ib != -1) {
 838             String str = v.substring(ib);
 839             String ver = str.substring(str.indexOf("\"") + 1, str.size() - 1);
 840 
 841             defineProperty("jdkRuntimeVersion", ver)
 842             def jdkVersionInfo = parseJavaVersion(ver)
 843             defineProperty("jdkVersion", jdkVersionInfo[0])
 844             defineProperty("jdkBuildNumber", jdkVersionInfo[1])
 845         }
 846     }
 847 } finally {
 848     inStream.close();
 849 }
 850 if (!project.hasProperty("jdkRuntimeVersion")) throw new Exception("Unable to determine the version of Java in JDK_HOME at $JDK_HOME");
 851 
 852 
 853 
 854 // Verify that CONF is something useful
 855 if (CONF != "Release" && CONF != "Debug" && CONF != "DebugNative") {
 856     logger.warn("Unknown configuration CONF='$CONF'. Treating as 'Release'")
 857 }
 858 
 859 // If the number of compile threads is less than 1 then we have a problem!
 860 if (Integer.parseInt(NUM_COMPILE_THREADS.toString()) < 1) {
 861     logger.warn("NUM_COMPILE_THREADS was specified as '$NUM_COMPILE_THREADS' which is less than the minimum value of 1. " +
 862             "Building with a value of 1 instead.")
 863     NUM_COMPILE_THREADS = 1
 864 }
 865 
 866 // Check that Gradle 2.11 is in use, error if < 2.11.
 867 if (gradle.gradleVersion != "2.11") {
 868     def ver = gradle.gradleVersion.split("[\\.]");
 869     def gradleMajor = Integer.parseInt(ver[0]);
 870     def gradleMinor = Integer.parseInt(ver[1]);
 871     def err = "";
 872     if (gradleMajor == 1 || gradleMajor == 2 && gradleMinor < 11) {
 873         err = "Gradle version too old: ${gradle.gradleVersion}; must be at least 2.11"
 874     }
 875 
 876     if (IS_GRADLE_VERSION_CHECK && err != "") {
 877         fail(err);
 878     }
 879 
 880     logger.warn("*****************************************************************");
 881     logger.warn("Unsupported gradle version $gradle.gradleVersion in use.");
 882     logger.warn("Only version 2.11 is supported. Use this version at your own risk");
 883     if ( err != "") logger.warn(err);
 884     logger.warn("*****************************************************************");
 885 }
 886 
 887 /******************************************************************************
 888  *                                                                            *
 889  *                      Logging of Properties and Settings                    *
 890  *                                                                            *
 891  *  Log some of the settings we've determined. We could log more here, it     *
 892  *  doesn't really hurt.                                                      *
 893  *                                                                            *
 894  *****************************************************************************/
 895 
 896 logger.quiet("gradle.gradleVersion: $gradle.gradleVersion")
 897 logger.quiet("OS_NAME: $OS_NAME")
 898 logger.quiet("OS_ARCH: $OS_ARCH")
 899 logger.quiet("JAVA_HOME: $JAVA_HOME")
 900 logger.quiet("JDK_HOME: $JDK_HOME")
 901 logger.quiet("JIGSAW_HOME: $JIGSAW_HOME")
 902 logger.quiet("java.runtime.version: ${javaRuntimeVersion}")
 903 logger.quiet("java version: ${javaVersion}")
 904 logger.quiet("java build number: ${javaBuildNumber}")
 905 logger.quiet("jdk.runtime.version: ${jdkRuntimeVersion}")
 906 logger.quiet("jdk version: ${jdkVersion}")
 907 logger.quiet("jdk build number: ${jdkBuildNumber}")
 908 logger.quiet("minimum jdk version: ${jfxBuildJdkVersionMin}")
 909 logger.quiet("minimum jdk build number: ${jfxBuildJdkBuildnumMin}")
 910 logger.quiet("STUB_RUNTIME: $STUB_RUNTIME")
 911 logger.quiet("CONF: $CONF")
 912 logger.quiet("NUM_COMPILE_THREADS: $NUM_COMPILE_THREADS")
 913 logger.quiet("COMPILE_TARGETS: $COMPILE_TARGETS")
 914 logger.quiet("COMPILE_FLAGS_FILES: $COMPILE_FLAGS_FILES")
 915 logger.quiet("HUDSON_JOB_NAME: $HUDSON_JOB_NAME")
 916 logger.quiet("HUDSON_BUILD_NUMBER: $HUDSON_BUILD_NUMBER")
 917 logger.quiet("PROMOTED_BUILD_NUMBER: $PROMOTED_BUILD_NUMBER")
 918 logger.quiet("PRODUCT_NAME: $PRODUCT_NAME")
 919 logger.quiet("RELEASE_VERSION: $RELEASE_VERSION")
 920 logger.quiet("RELEASE_SUFFIX: $RELEASE_SUFFIX")
 921 logger.quiet("RELEASE_VERSION_SHORT: $RELEASE_VERSION_SHORT")
 922 logger.quiet("RELEASE_VERSION_LONG: $RELEASE_VERSION_LONG")
 923 logger.quiet("RELEASE_VERSION_PADDED: $RELEASE_VERSION_PADDED")
 924 
 925 if (UPDATE_STUB_CACHE) {
 926     logger.quiet("UPDATE_STUB_CACHE: $UPDATE_STUB_CACHE")
 927 }
 928 
 929 /******************************************************************************
 930  *                                                                            *
 931  *                Definition of Native Code Compilation Tasks                 *
 932  *                                                                            *
 933  *    - JavaHeaderTask is used to run javah. The JAVAH property will point at *
 934  *      the version of javah to be used (i.e.: a path to javah)               *
 935  *    - CCTask compiles native code. Specifically it will compile .m, .c,     *
 936  *      .cpp, or .cc files. It uses the headers provided by the               *
 937  *      JavaHeaderTask plus additional platform specific headers. It will     *
 938  *      compile into .obj files.                                              *
 939  *    - LinkTask will perform native linking and create the .dll / .so /      *
 940  *      .dylib as necessary.                                                  *
 941  *                                                                            *
 942  *****************************************************************************/
 943 
 944 // Save a reference to the buildSrc.jar file because we need it for actually
 945 // compiling things, not just for the sake of this build script
 946 // (such as generating the JSL files, etc)
 947 ext.BUILD_SRC = rootProject.files("buildSrc/build/libs/buildSrc.jar")
 948 
 949 /**
 950  * Convenience method for creating javah, cc, link, and "native" tasks in the given project. These
 951  * tasks are parameterized by name, so that we can produce, for example, javahGlass, ccGlass, etc
 952  * named tasks.
 953  *
 954  * @param project The project to add tasks to
 955  * @param name The name of the project, such as "prism-common". This name is used
 956  *        in the name of the generated task, such as ccPrismCommon, and also
 957  *        in the name of the final library, such as libprism-common.dylib.
 958  */
 959 void addNative(Project project, String name) {
 960     // TODO if we want to handle 32/64 bit windows in the same build,
 961     // Then we will need to modify the win compile target to be win32 or win64
 962     def capitalName = name.split("-").collect{it.capitalize()}.join()
 963     def nativeTask = project.task("native$capitalName", group: "Build") {
 964         description = "Generates JNI headers, compiles, and builds native dynamic library for $name for all compile targets"
 965     }
 966     def cleanTask = project.task("cleanNative$capitalName", type: Delete, group: "Build") {
 967         description = "Clean native objects for $name"
 968     }
 969     if (project.hasProperty("nativeAllTask")) project.nativeAllTask.dependsOn nativeTask
 970     project.assemble.dependsOn(nativeTask)
 971     if (project.hasProperty("cleanNativeAllTask")) project.cleanNativeAllTask.dependsOn cleanTask
 972 
 973     // Each of the different compile targets will be placed in a sub directory
 974     // of these root dirs, with the name of the dir being the name of the target
 975     def headerRootDir = project.file("$project.buildDir/gensrc/headers/$name")
 976     def nativeRootDir = project.file("$project.buildDir/native/$name")
 977     def libRootDir = project.file("$project.buildDir/libs/$name")
 978     // For each compile target, create a javah / cc / link triplet
 979     compileTargets { t ->
 980         def targetProperties = project.rootProject.ext[t.upper]
 981         def library = targetProperties.library
 982         def properties = targetProperties.get(name)
 983         def nativeDir = file("$nativeRootDir/${t.name}")
 984         def headerDir = file("$headerRootDir/${t.name}")
 985 
 986         // If there is not a library clause in the properties, assume it is not wanted
 987         if (!targetProperties.containsKey(name)) {
 988             println("Ignoring native library ${name}. Not defined in ${t.name} project properties");
 989             return
 990         }
 991 
 992         // check for the property disable${name} = true
 993         def String disableKey = "disable${name}"
 994         def boolean disabled = targetProperties.containsKey(disableKey) ? targetProperties.get(disableKey) : false
 995         if (disabled) {
 996             println("Native library ${name} disabled in ${t.name} project properties");
 997             return
 998         }
 999 
1000         def javahTask = project.task("javah${t.capital}${capitalName}", type: JavaHeaderTask, dependsOn: project.classes, group: "Build") {
1001             description = "Generates JNI Headers for ${name} for ${t.name}"
1002             if (properties.javahSource == null) {
1003                 source(project.sourceSets.main.output.classesDir)
1004             } else {
1005                 source(properties.javahSource)
1006             }
1007             if (properties.javahClasspath == null) {
1008                 classpath = project.files(project.sourceSets.main.output.classesDir)
1009                 classpath += project.sourceSets.main.compileClasspath
1010             } else {
1011                 classpath = project.files(properties.javahClasspath)
1012             }
1013             output = headerDir
1014             include(properties.javahInclude)
1015             cleanTask.delete headerDir
1016         }
1017 
1018         def variants = properties.containsKey("variants") ? properties.variants : [""];
1019         variants.each { variant ->
1020             def variantProperties = variant == "" ? properties : properties.get(variant)
1021             def capitalVariant = variant.capitalize()
1022             def ccOutput = variant == "" ? nativeDir : file("$nativeDir/$variant")
1023             def ccTask = project.task("cc${t.capital}$capitalName$capitalVariant", type: CCTask, dependsOn: javahTask, group: "Build") {
1024                 description = "Compiles native sources for ${name} for ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}"
1025                 matches = ".*\\.c|.*\\.cpp|.*\\.m|.*\\.cc"
1026                 headers = headerDir
1027                 output(ccOutput)
1028                 params.addAll(variantProperties.ccFlags)
1029                 compiler = variantProperties.compiler
1030                 source(variantProperties.nativeSource)
1031                 cleanTask.delete ccOutput
1032             }
1033             def linkTask = project.task("link${t.capital}$capitalName$capitalVariant", type: LinkTask, dependsOn: ccTask, group: "Build") {
1034                 description = "Creates native dynamic library for $name for ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}"
1035                 objectDir = ccOutput
1036                 linkParams.addAll(variantProperties.linkFlags)
1037                 lib = file("$libRootDir/${t.name}/${variant == '' ? library(properties.lib) : library(variantProperties.lib)}")
1038                 linker = variantProperties.linker
1039                 cleanTask.delete "$libRootDir/${t.name}"
1040             }
1041             nativeTask.dependsOn(linkTask)
1042             if (IS_WINDOWS && t.name == "win") {
1043                 def rcTask = project.task("rc$capitalName$capitalVariant", type: CompileResourceTask, dependsOn: javahTask, group: "Build") {
1044                     description = "Compiles native sources for $name"
1045                     matches = ".*\\.rc"
1046                     compiler = variantProperties.rcCompiler
1047                     source(variantProperties.rcSource)
1048                     if (variantProperties.rcFlags) {
1049                         rcParams.addAll(variantProperties.rcFlags)
1050                     }
1051                     output(ccOutput)
1052                 }
1053                 linkTask.dependsOn rcTask;
1054             }
1055         }
1056 
1057         def useLipo = targetProperties.containsKey('useLipo') ? targetProperties.useLipo : false
1058         if (useLipo) {
1059             def lipoTask = project.task("lipo${t.capital}$capitalName", type: LipoTask, dependsOn: javahTask, group: "Build") {
1060                 description = "Creates native fat library for $name for ${t.name}"
1061                 libDir = file("$libRootDir/${t.name}")
1062                 lib = file("$libRootDir/${t.name}/${library(properties.lib)}")
1063             }
1064             nativeTask.dependsOn(lipoTask)
1065         }
1066     }
1067 }
1068 
1069 void addJSL(Project project, String name, String pkg, Closure compile) {
1070     def lowerName = name.toLowerCase()
1071 
1072     def compileCompilers = project.task("compile${name}Compilers", type: JavaCompile, dependsOn: project.compileJava) {
1073         description = "Compile the $name JSL Compilers"
1074         classpath = project.files(project.sourceSets.main.output.classesDir) +
1075                project.files(project.sourceSets.jslc.output.classesDir) +
1076                project.configurations.antlr
1077         source = [project.file("src/main/jsl-$lowerName")]
1078         destinationDir = project.file("$project.buildDir/classes/jsl-compilers/$lowerName")
1079     }
1080 
1081     def generateShaders = project.task("generate${name}Shaders", dependsOn: compileCompilers) {
1082         description = "Generate $name shaders from JSL"
1083         def sourceDir = project.file("src/main/jsl-$lowerName")
1084         def destinationDir = project.file("$project.buildDir/gensrc/jsl-$lowerName")
1085         inputs.dir sourceDir
1086         outputs.dir destinationDir
1087         doLast {
1088             compile(sourceDir, destinationDir)
1089         }
1090     }
1091 
1092     def compileHLSLShaders = project.task("compile${name}HLSLShaders", dependsOn: generateShaders, type: CompileHLSLTask) {
1093         enabled = IS_WINDOWS
1094         description = "Compile $name HLSL files into .obj files"
1095         matches = ".*\\.hlsl"
1096         output project.file("$project.buildDir/hlsl/$name/$pkg")
1097         source project.file("$project.buildDir/gensrc/jsl-$lowerName/$pkg")
1098     }
1099 
1100     def processShaders = project.task("process${name}Shaders", dependsOn: [generateShaders, compileHLSLShaders], type: Copy, description: "Copy hlsl / frag shaders to build/resources/jsl-$lowerName") {
1101         from("$project.buildDir/hlsl/$name") {
1102             include "**/*.obj"
1103         }
1104         from("$project.buildDir/gensrc/jsl-$lowerName") {
1105             include("**/*.frag")
1106         }
1107         into project.sourceSets.main.output.resourcesDir
1108     }
1109 
1110     project.processShaders.dependsOn(processShaders)
1111     project.sourceSets.shaders.output.dir("$project.buildDir/gensrc/jsl-$lowerName", builtBy: processShaders )
1112 
1113 }
1114 
1115 /**
1116  * Parses a JDK version string. The string must be in one of the following
1117  * two formats:
1118  *
1119  *     major.minor.subminor
1120  * or
1121  *     major.minor.subminor_update
1122  *
1123  * In both cases a list of 4 integers is returned, with element 3 set to
1124  * 0 in the former case.
1125  */
1126 List parseJdkVersion(String version) {
1127     def arr = version.split("[_\\.]");
1128     def intArr = [];
1129     arr.each { s -> intArr += Integer.parseInt(s); }
1130     while (intArr.size() < 4) intArr += 0;
1131     return intArr;
1132 }
1133 
1134 /**
1135  * Returns -1, 0, or 1 depending on whether JDK version "a" is less than,
1136  * equal to, or grater than version "b".
1137  */
1138 int compareJdkVersion(String a, String b) {
1139     def aIntArr = parseJdkVersion(a);
1140     def bIntArr = parseJdkVersion(b);
1141 
1142     for (int i = 0; i < 4; i++) {
1143         if (aIntArr[i] < bIntArr[i]) return -1;
1144         if (aIntArr[i] > bIntArr[i]) return  1;
1145     }
1146     return 0;
1147 }
1148 
1149 // Task to verify the minimum level of Java needed to build JavaFX
1150 task verifyJava() {
1151     doLast {
1152         def status = compareJdkVersion(jdkVersion, jfxBuildJdkVersionMin);
1153         if (status < 0) {
1154             fail("java version mismatch: JDK version (${jdkVersion}) < minimum version (${jfxBuildJdkVersionMin})")
1155         } else if (status == 0) {
1156             def buildNum = Integer.parseInt(jdkBuildNumber)
1157             def minBuildNum = Integer.parseInt(jfxBuildJdkBuildnumMin)
1158             if (buildNum != 0 && buildNum < minBuildNum) {
1159                 fail("JDK build number ($buildNum) < minimum build number ($minBuildNum)")
1160             }
1161         }
1162     }
1163 }
1164 
1165 // Task to check whether jfxrt.jar is present in the JDK
1166 task checkJfxrtJar {
1167     doLast {
1168         // The following path is correct when using 8u as boot jdk
1169         def jfxrtFile = new File("$JDK_HOME/jre/lib/ext/jfxrt.jar");
1170         if (jfxrtFile.exists()) {
1171             fail("$jfxrtFile must be removed before building sdk")
1172         }
1173         // The following path is correct when using 9 (pre-jigsaw) as boot jdk
1174         jfxrtFile = new File("$JDK_HOME/lib/jfxrt.jar");
1175         if (jfxrtFile.exists()) {
1176             fail("$jfxrtFile must be removed before building sdk")
1177         }
1178     }
1179 }
1180 
1181 task updateCacheIfNeeded() {
1182     // an empty task we can add to as needed for UPDATE_STUB_CACHE
1183 }
1184 
1185 /*****************************************************************************
1186 *        Project definitions (dependencies, etc)                             *
1187 *****************************************************************************/
1188 
1189 void addJCov(p, test) {
1190     test.doFirst {
1191         def jcovJVMArgument =
1192                 "include=javafx," +
1193                 "include=com.sun.javafx," +
1194                 "include=com.sun.glass," +
1195                 "include=com.sun.openpisces," +
1196                 "include=com.sun.pisces," +
1197                 "include=com.sun.prism," +
1198                 "include=com.sun.scenario," +
1199                 "include=com.sun.webkit," +
1200                 "exclude=com," +
1201                 "exclude=java," +
1202                 "exclude=javax," +
1203                 "exclude=\"**.test\"," +
1204                 "exclude=\"**.*Test\"," +
1205                 "file=build/reports/jcov/report.xml," +
1206                 "merge=merge";
1207         test.jvmArgs("-javaagent:${p.configurations.testCompile.files.find { it.name.startsWith('jcov') }}=$jcovJVMArgument");
1208         p.mkdir p.file("build/reports/jcov")
1209     }
1210     test.doLast {
1211         def reportFile = p.file("build/reports/jcov/report.xml")
1212         if (reportFile.exists()) {
1213             p.javaexec {
1214                 workingDir = p.file("build/reports/jcov")
1215                 classpath = p.files(p.configurations.testCompile.files.find { it.name.startsWith('jcov') })
1216                 main = "com.sun.tdk.jcov.Helper"
1217                 args = [
1218                         "RepGen",
1219                         "-exclude", "\"**.test\"",
1220                         "-exclude", "\"**.*Test\"",
1221                         "-output", ".",
1222                         "-source", p.sourceSets.main.java.srcDirs.collect{p.file(it)}.join(":"),
1223                         "report.xml"
1224                 ]
1225             }
1226         }
1227     }
1228 }
1229 
1230 allprojects {
1231     // We want to configure all projects as java projects and use the same compile settings
1232     // etc, except for the root project which we just want to ignore (and for now media)
1233     if (project == rootProject) {
1234        return
1235     }
1236     if (project.path.startsWith(":apps")) {
1237         // Lets handle the apps tree differently, as it is a collection of ant builds,
1238         // and the ant importer collides with the 'apply plugin:java'
1239         return
1240     }
1241     // All of our projects are java projects
1242     apply plugin: "java"
1243     sourceCompatibility = 1.8
1244 
1245     // Setup the repositories that we'll download libraries from. Maven Central is
1246     // just easy for most things. The custom "ivy" repo is for downloading SWT. The way it
1247     // works is to setup the download URL such that it will resolve to the actual jar file
1248     // to download. See SWT_FILE_NAME for the name of the jar that will be used as the
1249     // "artifact" in the pattern below. Note that the closed builds use different repositories
1250     // so if you are debugging a closed-build artifact related build issue, check out the
1251     // closed gradle file instead.
1252     if (!BUILD_CLOSED) {
1253         repositories {
1254             mavenCentral()
1255             ivy {
1256                 url "http://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/plugins/"
1257                 layout "pattern", {
1258                     artifact "[artifact].[ext]"
1259                 }
1260             }
1261         }
1262     }
1263 
1264     // By default all of our projects require junit for testing so we can just
1265     // setup this dependency here.
1266     dependencies {
1267         testCompile group: "junit", name: "junit", version: "4.8.2"
1268         if (BUILD_CLOSED && DO_JCOV)  {
1269             testCompile name: "jcov"
1270         }
1271     }
1272 
1273     compileJava.dependsOn verifyJava
1274     compileJava.dependsOn checkJfxrtJar
1275 
1276     // Compile and run tests against the jfxrt.jar in the built sdk of the host machine
1277     def sdkDir = "${rootProject.buildDir}/sdk"
1278     def jfxrtJar = "$sdkDir/lib/jfxrt.jar"
1279     def testJfxrtJar = DO_BUILD_SDK_FOR_TEST ? jfxrtJar : jfxrtJarFromSdk
1280 
1281     // At the moment the ASM library shipped with Gradle that is used to
1282     // discover the different test classes fails on Java 8, so in order
1283     // to have sourceCompatibility set to 1.8 I have to also turn scanForClasses off
1284     // and manually specify the includes / excludes. At the moment we use
1285     // Java 7 but when we switch to 8 this will be needed, and probably again when
1286     // we start building with Java 9.
1287     test {
1288         executable = JAVA;
1289         enableAssertions = true;
1290         testLogging.exceptionFormat = "full";
1291         scanForTestClasses = false;
1292         include("**/*Test.*");
1293         if (BUILD_CLOSED && DO_JCOV) {
1294             addJCov(project, test)
1295         }
1296         classpath = files(testJfxrtJar) + classpath
1297         if (IS_HEADLESS_TEST) {
1298             systemProperty 'glass.platform', 'Monocle'
1299             systemProperty 'monocle.platform', 'Headless'
1300             systemProperty 'prism.order', 'sw'
1301             systemProperty 'com.sun.javafx.gestures.zoom', 'true'
1302             systemProperty 'com.sun.javafx.gestures.rotate', 'true'
1303             systemProperty 'com.sun.javafx.gestures.scroll', 'true'
1304         }
1305 
1306         systemProperty 'unstable.test', IS_UNSTABLE_TEST
1307 
1308         if (project.hasProperty("EXTRA_TEST_ARGS")) {
1309             jvmArgs EXTRA_TEST_ARGS.split(' ')
1310         }
1311     }
1312 
1313     compileTestJava {
1314         classpath = files(testJfxrtJar) + classpath
1315     }
1316 
1317     // Exclude any non-public-API classes from having javadoc generated. This block is used
1318     // when generating JavaDocs for a specific project. When generating the JavaDocs for the
1319     // entire SDK, a different javadoc command is used (see the javadoc task on the top level)
1320     javadoc {
1321         enabled = IS_BUILD_JAVADOC
1322         exclude("com/**/*", "Compile*", "javafx/builder/**/*", "javafx/scene/accessibility/**/*");
1323         executable = JAVADOC;
1324         options.windowTitle("JavaFX Project ${project.name} ${RELEASE_VERSION}")
1325         if (BUILD_CLOSED) {
1326             options.linksOffline(JDK_DOCS, JDK_DOCS_CLOSED);
1327         } else {
1328             options.links(JDK_DOCS);
1329         }
1330         options.addBooleanOption("XDignore.symbol.file").setValue(true);
1331         options.addBooleanOption("Xdoclint:none").setValue(!IS_DOC_LINT);
1332         options.addBooleanOption("javafx").setValue(true);
1333         options.addBooleanOption("use").setValue(true);
1334         // All doc-files are located in src/main/docs because Gradle's javadoc doesn't copy
1335         // over the doc-files if they are embedded with the sources. I find this arrangement
1336         // somewhat cleaner anyway (never was a fan of mixing javadoc files with the sources)
1337         doLast {
1338             copy {
1339                 from "src/main/docs"
1340                 into "$buildDir/docs/javadoc"
1341             }
1342         }
1343     }
1344 }
1345 
1346 // The "base" project is our first module and the most basic one required for
1347 // all other modules. It is useful even for non-GUI applications.
1348 project(":base") {
1349     project.ext.buildModule = true
1350     project.ext.moduleRuntime = true
1351     project.ext.moduleName = "javafx.base"
1352 
1353     Set<String> testInclude = [ "test/**" ]
1354     configureJigsawTests(project, null,
1355         null, testInclude,
1356         project.projectDir.path + "/src/test/addExports"
1357         )
1358 
1359     dependencies {
1360     }
1361 
1362     // We need to take the VersionInfo.java file and replace the various
1363     // properties within it
1364     def replacements = [
1365         "BUILD_TIMESTAMP": BUILD_TIMESTAMP,
1366         "HUDSON_JOB_NAME": HUDSON_JOB_NAME,
1367         "HUDSON_BUILD_NUMBER": HUDSON_BUILD_NUMBER,
1368         "PROMOTED_BUILD_NUMBER": PROMOTED_BUILD_NUMBER,
1369         "PRODUCT_NAME": PRODUCT_NAME,
1370         "RELEASE_VERSION": RELEASE_VERSION,
1371         "RELEASE_SUFFIX": RELEASE_SUFFIX];
1372     task processVersionInfo(type: Copy, description: "Replace params in VersionInfo and copy file to destination") {
1373         doFirst { mkdir "$buildDir/gensrc/java" }
1374         from "src/main/version-info"
1375         into "$buildDir/gensrc/java/com/sun/javafx/runtime"
1376         filter {line->
1377             replacements.each() {k, v ->
1378                 line = line.replace("@$k@", v.toString());
1379             }
1380             line
1381         }
1382     }
1383 
1384     if (IS_COMPILE_JFR) {
1385         sourceSets.main.java.srcDirs += "src/main/java-jfr"
1386     }
1387 
1388     // Make sure to include $buildDir/gensrc/java that we previously created.
1389     // We DO NOT want to include src/main/version-info
1390 
1391     sourceSets.main.java.srcDirs += "$buildDir/gensrc/java"
1392 
1393     compileJava.dependsOn processVersionInfo
1394 }
1395 
1396 // The graphics module is needed for any graphical JavaFX application. It requires
1397 // the base module and includes the scene graph, layout, css, prism, windowing, etc.
1398 // This is a fairly complicated module. There are many different types of native components
1399 // that all need to be compiled.
1400 project(":graphics") {
1401 
1402     apply plugin: 'antlr'
1403 
1404     sourceSets {
1405         antlr  // antlr sources for JSLC
1406         jslc   // JSLC gramar subset
1407         main
1408         shaders // generated shaders (prism & decora)
1409         test
1410         stub
1411     }
1412 
1413     project.ext.buildModule = true
1414     project.ext.moduleRuntime = true
1415     project.ext.moduleName = "javafx.graphics"
1416 
1417     Set<String> testInclude = [ "test/**" ]
1418     configureJigsawTests(project, [ "base" ],
1419         null, testInclude,
1420         project.projectDir.path + "/src/test/addExports"
1421         )
1422 
1423     dependencies {
1424         compile project(":base")
1425         stubCompile group: "junit", name: "junit", version: "4.8.2",
1426         project(":base").sourceSets.test.output, sourceSets.main.output
1427 
1428         jslcCompile  group: "org.antlr", name: "antlr-complete", version: "3.5.2"
1429 
1430         antlr  group: "org.antlr", name: "antlr-complete", version: "3.5.2"
1431     }
1432 
1433     compileJslcJava.dependsOn(generateGrammarSource)
1434     compileJava.dependsOn(compileJslcJava)
1435 
1436     /*
1437     Graphics compilation is "complicated" by the generated shaders.
1438 
1439     We have two shader groups - Decora and Prism.
1440 
1441     The shader groups each will generate a custom compiler that
1442     then genarates the shader code. These compilers rely on the JSLC
1443     gramar parser which is antlr generated and compile separately.
1444 
1445     The decora compiler relies on compileJava - which is sourceSet.main.java
1446     It also accesses module private packages, so will need add-exports
1447 
1448     Once the shader java code is generated, we can compileFullJava
1449 
1450     After that, we can generate the required native header and then build the native code
1451     */
1452 
1453     project.task("processShaders") {
1454         // an empty task to hang the prism and decora shaders on
1455    }
1456 
1457     project.task("compileFullJava", type: JavaCompile, dependsOn: processShaders) {
1458         description = "Compile all of the graphics java classes - main and shaders"
1459         classpath = configurations.compile
1460         source = project.sourceSets.main.java.srcDirs
1461         source += project.sourceSets.shaders.output
1462         destinationDir = project.sourceSets.main.output.classesDir
1463     }
1464     classes.dependsOn(compileFullJava)
1465 
1466     // Create a single "native" task which will depend on all the individual native tasks for graphics
1467     project.ext.nativeAllTask = task("native", group: "Build", description: "Compiles and Builds all native libraries for Graphics");
1468     project.ext.cleanNativeAllTask = task("cleanNative", group: "Build", description: "Clean all native libraries and objects for Graphics");
1469 
1470     // Add tasks for native compilation
1471     addNative(project, "glass");
1472     addNative(project, "prism")
1473     addNative(project, "prismSW")
1474     addNative(project, "font")
1475     addNative(project, "iio")
1476     addNative(project, "prismES2")
1477 
1478     if (IS_COMPILE_PANGO) {
1479         addNative(project, "fontFreetype")
1480         addNative(project, "fontPango")
1481     }
1482 
1483     if (IS_WINDOWS) {
1484         addNative(project, "prismD3D")
1485         // TODO need to hook this up to be executed only if PassThroughVS.h is missing or PassThroughVS.hlsl is changed
1486         task generateD3DHeaders(group: "Build") {
1487             enabled = IS_WINDOWS
1488             dependsOn javahWinPrismD3D
1489             inputs.file "src/main/native-prism-d3d/hlsl/Mtl1PS.hlsl"
1490             inputs.file "src/main/native-prism-d3d/hlsl/Mtl1VS.hlsl"
1491             inputs.file "src/main/native-prism-d3d/PassThroughVS.hlsl"
1492             outputs.dir "$buildDir/headers/PrismD3D/"
1493             outputs.dir "$buildDir/headers/PrismD3D/hlsl/"
1494             description = "Generate headers by compiling hlsl files"
1495             doLast {
1496                 mkdir file("$buildDir/headers/PrismD3D/hlsl")
1497                 def PS_3D_SRC = file("src/main/native-prism-d3d/hlsl/Mtl1PS.hlsl")
1498                 def VS_3D_SRC = file("src/main/native-prism-d3d/hlsl/Mtl1VS.hlsl")
1499                 def PASSTHROUGH_VS_SRC = file("src/main/native-prism-d3d/PassThroughVS.hlsl")
1500                 def jobs = [
1501                         ["$FXC", "/nologo", "/T", "vs_3_0", "/Fh", "$buildDir/headers/PrismD3D/PassThroughVS.h", "/E", "passThrough", "$PASSTHROUGH_VS_SRC"],
1502                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS.h", "/DSpec=0", "/DSType=0", "$PS_3D_SRC"],
1503                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_i.h", "/DSpec=0", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"],
1504                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1n.h", "/DSpec=1", "/DSType=0", "$PS_3D_SRC"],
1505                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2n.h", "/DSpec=2", "/DSType=0", "$PS_3D_SRC"],
1506                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3n.h", "/DSpec=3", "/DSType=0", "$PS_3D_SRC"],
1507                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1t.h", "/DSpec=1", "/DSType=1", "$PS_3D_SRC"],
1508                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2t.h", "/DSpec=2", "/DSType=1", "$PS_3D_SRC"],
1509                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3t.h", "/DSpec=3", "/DSType=1", "$PS_3D_SRC"],
1510                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1c.h", "/DSpec=1", "/DSType=2", "$PS_3D_SRC"],
1511                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2c.h", "/DSpec=2", "/DSType=2", "$PS_3D_SRC"],
1512                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3c.h", "/DSpec=3", "/DSType=2", "$PS_3D_SRC"],
1513                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1m.h", "/DSpec=1", "/DSType=3", "$PS_3D_SRC"],
1514                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2m.h", "/DSpec=2", "/DSType=3", "$PS_3D_SRC"],
1515                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3m.h", "/DSpec=3", "/DSType=3", "$PS_3D_SRC"],
1516                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1n.h", "/DSpec=1", "/DSType=0", "/DBump=1", "$PS_3D_SRC"],
1517                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2n.h", "/DSpec=2", "/DSType=0", "/DBump=1", "$PS_3D_SRC"],
1518                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3n.h", "/DSpec=3", "/DSType=0", "/DBump=1", "$PS_3D_SRC"],
1519                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1t.h", "/DSpec=1", "/DSType=1", "/DBump=1", "$PS_3D_SRC"],
1520                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2t.h", "/DSpec=2", "/DSType=1", "/DBump=1", "$PS_3D_SRC"],
1521                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3t.h", "/DSpec=3", "/DSType=1", "/DBump=1", "$PS_3D_SRC"],
1522                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1c.h", "/DSpec=1", "/DSType=2", "/DBump=1", "$PS_3D_SRC"],
1523                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2c.h", "/DSpec=2", "/DSType=2", "/DBump=1", "$PS_3D_SRC"],
1524                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3c.h", "/DSpec=3", "/DSType=2", "/DBump=1", "$PS_3D_SRC"],
1525                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1m.h", "/DSpec=1", "/DSType=3", "/DBump=1", "$PS_3D_SRC"],
1526                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2m.h", "/DSpec=2", "/DSType=3", "/DBump=1", "$PS_3D_SRC"],
1527                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3m.h", "/DSpec=3", "/DSType=3", "/DBump=1", "$PS_3D_SRC"],
1528                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1ni.h", "/DSpec=1", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"],
1529                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2ni.h", "/DSpec=2", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"],
1530                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3ni.h", "/DSpec=3", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"],
1531                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1ti.h", "/DSpec=1", "/DSType=1", "/DIllumMap=1", "$PS_3D_SRC"],
1532                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2ti.h", "/DSpec=2", "/DSType=1", "/DIllumMap=1", "$PS_3D_SRC"],
1533                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3ti.h", "/DSpec=3", "/DSType=1", "/DIllumMap=1", "$PS_3D_SRC"],
1534                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1ci.h", "/DSpec=1", "/DSType=2", "/DIllumMap=1", "$PS_3D_SRC"],
1535                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2ci.h", "/DSpec=2", "/DSType=2", "/DIllumMap=1", "$PS_3D_SRC"],
1536                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3ci.h", "/DSpec=3", "/DSType=2", "/DIllumMap=1", "$PS_3D_SRC"],
1537                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1mi.h", "/DSpec=1", "/DSType=3", "/DIllumMap=1", "$PS_3D_SRC"],
1538                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2mi.h", "/DSpec=2", "/DSType=3", "/DIllumMap=1", "$PS_3D_SRC"],
1539                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3mi.h", "/DSpec=3", "/DSType=3", "/DIllumMap=1", "$PS_3D_SRC"],
1540                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1ni.h", "/DSpec=1", "/DSType=0", "/DBump=1", "/DIllumMap=1", "$PS_3D_SRC"],
1541                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2ni.h", "/DSpec=2", "/DSType=0", "/DBump=1", "/DIllumMap=1", "$PS_3D_SRC"],
1542                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3ni.h", "/DSpec=3", "/DSType=0", "/DBump=1", "/DIllumMap=1", "$PS_3D_SRC"],
1543                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1ti.h", "/DSpec=1", "/DSType=1", "/DBump=1", "/DIllumMap=1", "$PS_3D_SRC"],
1544                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2ti.h", "/DSpec=2", "/DSType=1", "/DBump=1", "/DIllumMap=1", "$PS_3D_SRC"],
1545                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3ti.h", "/DSpec=3", "/DSType=1", "/DBump=1", "/DIllumMap=1", "$PS_3D_SRC"],
1546                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1ci.h", "/DSpec=1", "/DSType=2", "/DBump=1", "/DIllumMap=1", "$PS_3D_SRC"],
1547                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2ci.h", "/DSpec=2", "/DSType=2", "/DBump=1", "/DIllumMap=1", "$PS_3D_SRC"],
1548                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3ci.h", "/DSpec=3", "/DSType=2", "/DBump=1", "/DIllumMap=1", "$PS_3D_SRC"],
1549                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1mi.h", "/DSpec=1", "/DSType=3", "/DBump=1", "/DIllumMap=1", "$PS_3D_SRC"],
1550                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2mi.h", "/DSpec=2", "/DSType=3", "/DBump=1", "/DIllumMap=1", "$PS_3D_SRC"],
1551                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3mi.h", "/DSpec=3", "/DSType=3", "/DBump=1", "/DIllumMap=1", "$PS_3D_SRC"],
1552                         ["$FXC", "/nologo", "/T", "vs_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1VS_Obj.h", "/DVertexType=ObjVertex", "$VS_3D_SRC"]
1553                 ]
1554                 final ExecutorService executor = Executors.newFixedThreadPool(Integer.parseInt(project.NUM_COMPILE_THREADS.toString()));
1555                 final CountDownLatch latch = new CountDownLatch(jobs.size());
1556                 List futures = new ArrayList<Future>();
1557                 jobs.each { cmd ->
1558                     futures.add(executor.submit(new Runnable() {
1559                         @Override public void run() {
1560                             try {
1561                                 exec {
1562                                     commandLine cmd
1563                                 }
1564                             } finally {
1565                                 latch.countDown();
1566                             }
1567                         }
1568                     }));
1569                 }
1570                 latch.await();
1571                 // Looking for whether an exception occurred while executing any of the futures.
1572                 // By calling "get()" on each future an exception will be thrown if one had occurred
1573                 // on the background thread.
1574                 futures.each {it.get();}
1575             }
1576         }
1577 
1578         ccWinPrismD3D.dependsOn generateD3DHeaders
1579     }
1580 
1581     // The Decora and Prism JSL files have to be generated in a very specific set of steps.
1582     //      1) Compile the *Compile.java classes. These live in src/main/jsl-* and will be
1583     //         output to $buildDir/classes/jsl-compilers/* (where * == decora or prism).
1584     //      2) Generate source files from the JSL files contained in src/main/jsl-*. These
1585     //         will be output to $buildDir/gensrc/jsl-*
1586     //      3) Compile the JSL Java sources in $buildDir/gensrc/jsl-* and put the output
1587     //         into classes/jsl-*
1588     //      4) Compile the native JSL sources in $buildDir/gensrc/jsl-* and put the obj
1589     //         files into native/jsl-* and the resulting library into libs/jsl-*.dll|so|dylib
1590     //      5) Modify the jar step to include classes/jsl-*
1591     // The native library must be copied over during SDK creation time in the "sdk" task. In
1592     // addition to these steps, the clean task is created. Note that I didn't bother to create
1593     // a new task for each of the decora files, preferring instead just to create a rule?? Also
1594     // need "clean" tasks for each compile task.
1595 
1596     addJSL(project, "Decora", "com/sun/scenario/effect/impl/hw/d3d/hlsl") { sourceDir, destinationDir ->
1597         [[fileName: "ColorAdjust", generator: "CompileJSL", outputs: "-all"],
1598          [fileName: "Brightpass", generator: "CompileJSL", outputs: "-all"],
1599          [fileName: "SepiaTone", generator: "CompileJSL", outputs: "-all"],
1600          [fileName: "PerspectiveTransform", generator: "CompileJSL", outputs: "-all"],
1601          [fileName: "DisplacementMap", generator: "CompileJSL", outputs: "-all"],
1602          [fileName: "InvertMask", generator: "CompileJSL", outputs: "-all"],
1603          [fileName: "Blend", generator: "CompileBlend", outputs: "-all"],
1604          [fileName: "PhongLighting", generator: "CompilePhong", outputs: "-all"],
1605          [fileName: "LinearConvolve", generator: "CompileLinearConvolve", outputs: "-hw"],
1606          [fileName: "LinearConvolveShadow", generator: "CompileLinearConvolve", outputs: "-hw"]].each { settings ->
1607             javaexec {
1608                 executable = JAVA
1609                 workingDir = project.projectDir
1610                 main = settings.generator
1611                 classpath = configurations.compile + configurations.antlr
1612                 classpath += files(project.sourceSets.jslc.output.classesDir)
1613 
1614                 //classpath += files(project.sourceSets.jslc.resources) // not quite right..
1615                 classpath += files("${project.projectDir}/src/jslc/resources")
1616 
1617                 classpath += files("$buildDir/classes/main")
1618                 classpath += files("$buildDir/classes/jsl-compilers/decora")
1619                 args = ["-i", sourceDir, "-o", destinationDir, "-t", "-pkg", "com/sun/scenario/effect", "$settings.outputs", "$settings.fileName"]
1620             }
1621         }
1622     }
1623 
1624     task generateDecoraNativeHeaders(type: JavaHeaderTask, dependsOn: compileFullJava) {
1625         description = "Generates JNI Headers for Decora SSE Natives"
1626         source file("$buildDir/classes/main")
1627         include("com/sun/scenario/effect/impl/sw/sse/*");
1628         classpath = files("$buildDir/classes/main")
1629         classpath += files(project.sourceSets.jslc.output.classesDir)
1630         output = file("$buildDir/gensrc/headers/jsl-decora")
1631     }
1632 
1633     task nativeDecora(dependsOn: compileDecoraHLSLShaders, group: "Build") {
1634         description = "Generates JNI headers, compiles, and builds native dynamic library for Decora"
1635     }
1636     task cleanNativeDecora(type: Delete, group: "Build") {
1637         description = "Clean native objects for Decora"
1638     }
1639 
1640     def headerDir = file("$buildDir/gensrc/headers/jsl-decora")
1641     def nativeRootDir = project.file("$project.buildDir/native/jsl-decora")
1642     def libRootDir = project.file("$project.buildDir/libs/jsl-decora")
1643     // For each compile target, create cc and link tasks
1644     compileTargets { t ->
1645         def target = t.name
1646         def upperTarget = t.upper
1647         def capitalTarget = t.capital
1648         def targetProperties = rootProject.ext[upperTarget];
1649         def library = targetProperties.library
1650         def properties = targetProperties.get('decora')
1651         def nativeDir = file("$nativeRootDir/$target");
1652 
1653         def variants = properties.containsKey("variants") ? properties.variants : [""];
1654         variants.each { variant ->
1655             def variantProperties = variant == "" ? properties : properties.get(variant)
1656             def capitalVariant = variant.capitalize()
1657             def ccOutput = variant == "" ? nativeDir : file("$nativeDir/$variant")
1658 
1659             def ccTask = task("compileDecoraNativeShaders$capitalTarget$capitalVariant", type: CCTask, dependsOn: generateDecoraNativeHeaders) {
1660                 description = "Compiles Decora SSE natives for ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}"
1661                 matches = ".*\\.cc"
1662                 source file("$buildDir/gensrc/jsl-decora")
1663                 source file(project.projectDir.path + "/src/main/native-decora")
1664                 headers = headerDir
1665                 params.addAll(variantProperties.ccFlags)
1666                 output(ccOutput)
1667                 compiler = variantProperties.compiler
1668                 cleanNativeDecora.delete ccOutput
1669             }
1670 
1671             def linkTask = task("linkDecoraNativeShaders$capitalTarget$capitalVariant", type: LinkTask, dependsOn: ccTask) {
1672                 description = "Creates native dynamic library for Decora SSE ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}"
1673                 objectDir = ccOutput
1674                 linkParams.addAll(variantProperties.linkFlags)
1675                 lib = file("$libRootDir/$t.name/${library(variantProperties.lib)}")
1676                 linker = variantProperties.linker
1677                 cleanNativeDecora.delete "$libRootDir/$t.name/"
1678             }
1679 
1680             if (IS_WINDOWS && target == "win") {
1681                 def rcTask = project.task("rcDecoraNativeShaders$capitalTarget$capitalVariant", type: CompileResourceTask, dependsOn: generateDecoraNativeHeaders) {
1682                     description = "Compiles native sources for Decora SSE"
1683                     matches = ".*\\.rc"
1684                     compiler = variantProperties.rcCompiler
1685                     source(variantProperties.rcSource)
1686                     if (variantProperties.rcFlags) {
1687                         rcParams.addAll(variantProperties.rcFlags)
1688                     }
1689                     output(ccOutput)
1690                 }
1691                 linkTask.dependsOn rcTask;
1692             }
1693 
1694             nativeDecora.dependsOn(linkTask)
1695         }
1696     }
1697 
1698     // Prism JSL
1699     addJSL(project, "Prism", "com/sun/prism/d3d/hlsl") { sourceDir, destinationDir ->
1700         def inputFiles = fileTree(dir: sourceDir)
1701         inputFiles.include "**/*.jsl"
1702         inputFiles.each { file ->
1703             javaexec {
1704                 executable = JAVA
1705                 workingDir = project.projectDir
1706                 main = "CompileJSL"
1707                 classpath = configurations.compile + configurations.antlr
1708                 classpath += files(project.sourceSets.jslc.output.classesDir)
1709                 classpath += files(project.sourceSets.jslc.resources)
1710                 classpath += files("$buildDir/classes/jsl-compilers/prism",
1711                     project.projectDir.path + "/src/main/jsl-prism") // for the .stg
1712                 args = ["-i", sourceDir, "-o", destinationDir, "-t", "-pkg", "com/sun/prism", "-d3d", "-es2", "-name", "$file"]
1713             }
1714         }
1715     }
1716 
1717     nativePrism.dependsOn compilePrismHLSLShaders;
1718 
1719     project.nativeAllTask.dependsOn nativeDecora
1720     project.cleanNativeAllTask.dependsOn cleanNativeDecora
1721     assemble.dependsOn nativeDecora
1722     processResources.dependsOn processDecoraShaders, processPrismShaders
1723 
1724     test {
1725         def cssDir = file("$buildDir/classes/main/javafx")
1726         jvmArgs "-Djavafx.toolkit=test.com.sun.javafx.pgstub.StubToolkit",
1727             "-DCSS_META_DATA_TEST_DIR=$cssDir"
1728         enableAssertions = true
1729         testLogging.exceptionFormat = "full"
1730         scanForTestClasses = false
1731         include "**/*Test.*"
1732         if (BUILD_CLOSED && DO_JCOV) {
1733             addJCov(project, test)
1734         }
1735     }
1736 
1737     // To enable the IDEs to all be happy (no red squiggles) we need to have the libraries
1738     // available in some known location. Maybe in the future the Gradle plugins to each
1739     // of the IDEs will be good enough that we won't need this hack anymore.
1740     classes << {
1741         // Copy all of the download libraries to the libs directory for the sake of the IDEs
1742         File libsDir = rootProject.file("build/libs");
1743 
1744         // In some IDEs (Eclipse for example), touching these libraries
1745         // cauese a full build within the IDE. When gradle is used
1746         // outside of the IDE, for example to build the native code,
1747         // a full rebuild is caused within the IDE. The fix is to check
1748         // for the presence of the target files in the lib directory
1749         // and not copy the files if all are present.
1750 
1751         libsDir.mkdirs();
1752 
1753         def allLibsPresent = true
1754         def libNames = ["antlr-3.1.3.jar", "stringtemplate-3.2.jar", "antlr-runtime-3.1.3.jar"]
1755         libNames.each { name ->
1756             File f = new File(libsDir, name)
1757             if (!f.exists()) allLibsPresent = false
1758         }
1759         if (allLibsPresent) return;
1760 
1761         for (File f : [configurations.compile.files, configurations.antlr.files].flatten()) {
1762             copy {
1763                 into libsDir
1764                 from f.getParentFile()
1765                 include "**/antlr-complete-3.5.2.jar"
1766                 includeEmptyDirs = false
1767             }
1768         }
1769     }
1770 }
1771 
1772 project(":controls") {
1773     project.ext.buildModule = true
1774     project.ext.moduleRuntime = true
1775     project.ext.moduleName = "javafx.controls"
1776 
1777     Set<String> testInclude = [ "test/**" ]
1778     configureJigsawTests(project, [ "base", "graphics" ],
1779         null, testInclude,
1780         project.projectDir.path + "/src/test/addExports"
1781     )
1782 
1783     dependencies {
1784         compile project(":base"), project(":graphics")
1785         // TODO not sure how to specify this? processResources project(":base"), project(":graphics")
1786         testCompile project(":graphics").sourceSets.test.output
1787         testCompile project(":base").sourceSets.test.output
1788     }
1789 
1790     test {
1791         def cssDir = file("$buildDir/classes/main/javafx")
1792         jvmArgs "-Djavafx.toolkit=test.com.sun.javafx.pgstub.StubToolkit",
1793             "-DCSS_META_DATA_TEST_DIR=$cssDir"
1794     }
1795 
1796     // TODO Css2Bin really should be moved out and put into buildSrc if it can be
1797     // TODO could change script to dynamically locate all .css files and create bss for them, probably better
1798     // TODO also not sure there is any benefit to having css files in the jfxrt.jar at all
1799     processResources << {
1800         ["$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/caspian.css",
1801         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/caspian-no-transparency.css",
1802         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/embedded-qvga.css",
1803         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/embedded.css",
1804         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/fxvk.css",
1805         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/highcontrast.css",
1806         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/modena/modena.css",
1807         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/modena/modena-no-transparency.css",
1808         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/modena/touch.css"].each { css ->
1809             javaexec {
1810                 executable = JAVA
1811                 workingDir = project.projectDir
1812                 classpath files("$buildDir/classes/main",
1813                         project(":graphics").sourceSets.main.output,
1814                         project(":base").sourceSets.main.output)
1815                 main = "com.sun.javafx.css.parser.Css2Bin"
1816                 args css
1817             }
1818         }
1819     }
1820 }
1821 
1822 project(":swing") {
1823     /* should not be built, but needed in JMX
1824     tasks.all {
1825         if (!COMPILE_SWING) it.enabled = false
1826     }
1827     */
1828     project.ext.buildModule = COMPILE_SWING
1829     project.ext.moduleRuntime = true
1830     project.ext.moduleName = "javafx.swing"
1831 
1832     dependencies {
1833         compile project(":base"), project(":graphics")
1834     }
1835 
1836     Set<String> testInclude = [ "test/**" ]
1837     configureJigsawTests(project, [ "base", "graphics", "controls" ],
1838         null, testInclude,
1839         null // no addExports
1840     )
1841 
1842     test {
1843         enabled = IS_FULL_TEST && IS_AWT_TEST
1844     }
1845 }
1846 
1847 project(":swt") {
1848     tasks.all {
1849         if (!COMPILE_SWT) it.enabled = false
1850     }
1851 
1852     // javafx.swt is an automatic module
1853     project.ext.buildModule = false
1854 
1855     dependencies {
1856         compile project(":base"), project(":graphics")
1857         compile name: SWT_FILE_NAME
1858     }
1859     classes << {
1860         // Copy all of the download libraries to libs directory for the sake of the IDEs
1861         File libsDir = rootProject.file("build/libs");
1862         File swtLib = new File(libsDir, "swt-debug.jar")
1863         libsDir.mkdirs();
1864 
1865         // Skip copy if file is present.
1866         if (swtLib.exists()) return;
1867 
1868         for (File f : configurations.compile.files) {
1869             // Have to rename the swt jar because it is some platform specific name but
1870             // for the sake of the IDEs we need to have a single stable name that works
1871             // on every platform
1872             copy {
1873                 into libsDir
1874                 from f.getParentFile()
1875                 include "**/*swt*.jar"
1876                 includeEmptyDirs = false
1877                 rename ".*swt.*jar", "swt-debug\\.jar"
1878             }
1879         }
1880     }
1881 
1882     test {
1883         if (IS_JIGSAW_TEST) {
1884             enabled = false // FIXME: JIGSAW -- support this with modules
1885             logger.info("JIGSAW Testing disabled for swt")
1886         } else {
1887             enabled = IS_FULL_TEST && IS_SWT_TEST
1888             if (IS_MAC) {
1889                 enabled = false
1890                 logger.info("SWT tests are disabled on MAC, because Gradle test runner does not handle -XstartOnFirstThread properly (https://issues.gradle.org/browse/GRADLE-3290).")
1891             }
1892         }
1893     }
1894 }
1895 
1896 project(":fxml") {
1897     project.ext.buildModule = true
1898     project.ext.moduleRuntime = true
1899     project.ext.moduleName = "javafx.fxml"
1900 
1901     Set<String> testInclude = [ "test/**" ]
1902     configureJigsawTests(project, [ "base", "graphics" ],
1903         null, testInclude,
1904         project.projectDir.path + "/src/test/addExports"
1905     )
1906 
1907     dependencies {
1908         compile project(":base"),
1909                 project(":graphics"),
1910                 project(":controls")
1911         testCompile project(":graphics").sourceSets.test.output
1912     }
1913     test {
1914         // StubToolkit is not *really* needed here, but because some code inadvertently invokes performance
1915         // tracker and this attempts to fire up the toolkit and this looks for native libraries and fails,
1916         // we have to use the stub toolkit for now.
1917         jvmArgs "-Djavafx.toolkit=test.com.sun.javafx.pgstub.StubToolkit"
1918         // FIXME: change this to also allow JDK 9 boot jdk
1919         classpath += files("$JDK_HOME/jre/lib/ext/nashorn.jar")
1920     }
1921 }
1922 
1923 project(":jmx") {
1924     project.ext.buildModule = false // true
1925     project.ext.moduleRuntime = false
1926     project.ext.moduleName = "javafx.jmx"
1927     dependencies {
1928         compile project(":base")
1929         compile project(":graphics")
1930         compile project(":swing")
1931         compile project(":media")
1932     }
1933 
1934     // Tests are disabled until RT-33926 can be fixed
1935     test.enabled = false
1936 
1937     if (!DO_BUILD_SDK_FOR_TEST) {
1938        def javafxMxJar = new File(TEST_SDK_DIR, "lib/javafx-mx.jar")
1939        [test, compileTestJava].each {
1940            it.classpath = files(javafxMxJar) + it.classpath
1941        }
1942     }
1943 }
1944 
1945 project(":fxpackagerservices") {
1946     project.ext.buildModule = COMPILE_FXPACKAGER
1947     project.ext.moduleRuntime = false
1948     project.ext.moduleName = "jdk.packager.services"
1949     tasks.all {
1950         if (!COMPILE_FXPACKAGER) it.enabled = false
1951     }
1952 
1953     test {
1954         if (IS_JIGSAW_TEST) {
1955             enabled = false // FIXME: JIGSAW -- support this with modules
1956             logger.info("JIGSAW Testing disabled for fxpackagerservices")
1957         }
1958     }
1959 }
1960 
1961 project(":fxpackager") {
1962     project.ext.buildModule = COMPILE_FXPACKAGER
1963     project.ext.moduleRuntime = false
1964     project.ext.moduleName = "jdk.packager"
1965     manifest {
1966         attributes(
1967                 "Main-Class": "com.sun.javafx.tools.packager.Main"
1968         )
1969     }
1970     tasks.all {
1971         if (!COMPILE_FXPACKAGER) it.enabled = false
1972     }
1973 
1974     sourceSets {
1975         main
1976         antplugin {
1977             java {
1978                 compileClasspath += main.output
1979                 runtimeClasspath += main.output
1980             }
1981         }
1982         test
1983     }
1984 
1985     // fxpackager has a dependency on ant in order to build the ant jar,
1986     // and as such needs to point to the apache binary repository
1987     if (!BUILD_CLOSED) {
1988         repositories {
1989             maven {
1990                 url "https://repository.apache.org"
1991             }
1992         }
1993     }
1994 
1995     dependencies {
1996         compile project(":fxpackagerservices")
1997         antpluginCompile group: "org.apache.ant", name: "ant", version: "1.8.2"
1998         testCompile project(":controls")
1999     }
2000 
2001     // When producing the ant-javafx.jar, we need to relocate a few class files
2002     // from their normal location to a resources/classes or resources/web-files
2003     // location
2004     task antpluginJar(type: Jar, dependsOn: [ compileJava, jar, compileAntpluginJava ]) {
2005         includeEmptyDirs = false
2006         archiveName = "ant-javafx.jar"
2007 
2008         from (sourceSets.antplugin.output) {
2009             eachFile { FileCopyDetails details ->
2010                 if (details.path.startsWith("com/javafx/main")) {
2011                     details.path = "resources/classes/$details.path"
2012                 }
2013             }
2014         }
2015 
2016         from (sourceSets.main.output.resourcesDir) {
2017             includes = [ "resources/web-files/**", "com/sun/javafx/tools/ant/antlib.xml" ]
2018         }
2019     }
2020 
2021     assemble.dependsOn(antpluginJar)
2022 
2023     // The "man" task will create a $buildDir/man containing the man
2024     // files for the system being built
2025     task man(type: Copy) {
2026         includeEmptyDirs = false
2027         enabled = (IS_LINUX || IS_MAC) && COMPILE_FXPACKAGER
2028         from "src/main/man"
2029         into "$buildDir/man"
2030         exclude "**/*.html"
2031         if (IS_MAC) exclude "**/ja_JP.UTF-8/**"
2032     }
2033     processResources.dependsOn man
2034 
2035     // Compile the native launchers. These are included in jdk.packager.jmod.
2036     if (IS_WINDOWS && COMPILE_FXPACKAGER) {
2037         task buildWinLauncher(type: CCTask, group: "Build") {
2038             description = "Compiles native sources for the application co-bundle launcher";
2039             matches = "WinLauncher\\.cpp";
2040             params.addAll(WIN.launcher.ccFlags);
2041             output(file("$buildDir/native/WinLauncher"));
2042             source(file("src/main/native/launcher/win"));
2043             compiler = WIN.launcher.compiler
2044             exe = true;
2045             linkerOptions.addAll(WIN.launcher.linkFlags);
2046             doLast {
2047                 copy {
2048                     from "$buildDir/native/WinLauncher/WinLauncher.exe"
2049                     from "$MSVCR"
2050                     from "$MSVCP"
2051                     into "$buildDir/classes/main/com/oracle/tools/packager/windows"
2052                 }
2053             }
2054         }
2055         task compileWinLibrary(type: CCTask, group: "Build") {
2056             description = "Compiles native sources for the application co-bundle launcher library";
2057             matches = ".*\\.cpp"
2058             source(file("src/main/native/library/common"));
2059             params.addAll(WIN.launcherlibrary.ccFlags)
2060             output(file("$buildDir/native/WinLauncher/obj"));
2061             compiler = WIN.launcherlibrary.compiler
2062         }
2063         task linkWinLibrary(type: LinkTask, group: "Build", dependsOn: compileWinLibrary) {
2064             description = "Links native sources for the application co-bundle launcher library";
2065             objectDir = file("$buildDir/native/WinLauncher/obj")
2066             linkParams.addAll(WIN.launcherlibrary.linkFlags);
2067             lib = file("$buildDir/native/WinLauncher/packager.dll")
2068             linker = WIN.launcherlibrary.linker
2069             doLast {
2070                 copy {
2071                     from "$buildDir/native/WinLauncher/packager.dll"
2072                     into "$buildDir/classes/main/com/oracle/tools/packager/windows"
2073                 }
2074             }
2075         }
2076         task buildWinLauncherSvc(type: CCTask, group: "Build") {
2077             description = "Compiles native sources for the application co-bundle launcher";
2078             matches = "WinLauncherSvc\\.cpp";
2079             params.addAll(WIN.launcher.ccFlags);
2080             output(file("$buildDir/native/WinLauncherSvc"));
2081             source(file("src/main/native/service/win"));
2082             compiler = WIN.launcher.compiler
2083             exe = true;
2084             linkerOptions.addAll(WIN.launcher.linkFlags);
2085             doLast {
2086                 copy {
2087                     from "$buildDir/native/WinLauncherSvc/WinLauncherSvc.exe"
2088                     into "$buildDir/classes/main/com/oracle/tools/packager/windows"
2089                 }
2090             }
2091         }
2092         task buildIconSwap(type: CCTask, group: "Build") {
2093             description = "Compiles native sources for the application co-bundle launcher"
2094             matches = "IconSwap\\.cpp"
2095             params.addAll(WIN.iconLauncher.ccFlags)
2096             output(file("$buildDir/native/IconSwap"))
2097             source file("src/main/native/tools/win/iconswap")
2098             compiler = WIN.launcher.compiler
2099             exe = true
2100             linkerOptions.addAll(WIN.iconLauncher.linkFlags)
2101             doLast {
2102                 copy {
2103                     from "$buildDir/native/IconSwap/IconSwap.exe"
2104                     into "$buildDir/classes/main/com/oracle/tools/packager/windows"
2105                 }
2106             }
2107         }
2108         task compileVersionInfoSwap(type: CCTask, group: "Build") {
2109             description = "Compiles native sources for the VersionInfoSwap tool";
2110             matches = ".*\\.cpp"
2111             source(file("src/main/native/tools/win/versioninfoswap"));
2112             params.addAll(WIN.versionInfoLauncher.ccFlags)
2113             output(file("$buildDir/native/VersionInfoSwap/obj"));
2114             compiler = WIN.versionInfoLauncher.compiler
2115         }
2116         task linkVersionInfoSwap(type: LinkTask, group: "Build", dependsOn: compileVersionInfoSwap) {
2117             description = "Links native sources for the VersionInfoSwap tool";
2118             objectDir = file("$buildDir/native/VersionInfoSwap/obj")
2119             linkParams.addAll(WIN.versionInfoLauncher.linkFlags);
2120             lib = file("$buildDir/native/VersionInfoSwap/VersionInfoSwap.exe")
2121             linker = WIN.versionInfoLauncher.linker
2122             doLast {
2123                 copy {
2124                     from "$buildDir/native/VersionInfoSwap/VersionInfoSwap.exe"
2125                     into "$buildDir/classes/main/com/oracle/tools/packager/windows"
2126                 }
2127             }
2128         }
2129         task compileLauncher(dependsOn: [buildWinLauncher, linkWinLibrary, buildWinLauncherSvc, buildIconSwap, linkVersionInfoSwap])
2130         jar.dependsOn compileLauncher;
2131     } else if (IS_MAC && COMPILE_FXPACKAGER) {
2132         task buildMacLauncher(type: CCTask, group: "Build") {
2133             description = "Compiles native sources for the application co-bundle launcher"
2134             matches = ".*\\.m"
2135             source file("src/main/native/launcher/mac")
2136             params.addAll(MAC.launcher.ccFlags)
2137             compiler = MAC.launcher.compiler
2138             output(file("$buildDir/classes/main/com/oracle/tools/packager/mac"))
2139             outputs.file(file("$buildDir/classes/main/com/oracle/tools/packager/mac/JavaAppLauncher"))
2140             eachOutputFile = { f ->
2141                 return new File(f.getParent(), "JavaAppLauncher")
2142             }
2143         }
2144         task compileMacLibrary(type: CCTask, group: "Build") {
2145             description = "Compiles native sources for the application co-bundle launcher library"
2146             matches = ".*\\.cpp|.*\\.mm"
2147             source file("src/main/native/library/common");
2148             params.addAll(MAC.launcherlibrary.ccFlags)
2149             compiler = MAC.launcherlibrary.compiler
2150             output(file("$buildDir/native/maclauncher/obj"))
2151         }
2152         task linkMacLibrary(type: LinkTask, group: "Build", dependsOn: compileMacLibrary) {
2153             description = "Links native sources for the application co-bundle launcher library"
2154             objectDir = file("$buildDir/native/maclauncher/obj")
2155             linkParams.addAll(MAC.launcherlibrary.linkFlags)
2156             linker = MAC.launcherlibrary.linker
2157             lib = file("$buildDir/classes/main/com/oracle/tools/packager/mac/libpackager.dylib")
2158         }
2159         task compileLauncher(dependsOn: [buildMacLauncher, linkMacLibrary])
2160         jar.dependsOn compileLauncher;
2161     } else if (IS_LINUX && COMPILE_FXPACKAGER) {
2162         task compileLinuxLauncher(type: CCTask, group: "Build") {
2163             description = "Compiles native sources for the application co-bundle launcher"
2164             matches = ".*\\.cpp"
2165             source file("src/main/native/launcher/linux")
2166             params.addAll(LINUX.launcher.ccFlags)
2167             compiler = LINUX.launcher.compiler
2168             output(file("$buildDir/native/linuxlauncher/launcherobj"))
2169         }
2170         task linkLinuxLauncher(type: LinkTask, dependsOn: compileLinuxLauncher, group: "Build") {
2171             description = "Links native dynamic library for the application co-bundle launcher"
2172             objectDir = file("$buildDir/native/linuxlauncher/launcherobj")
2173             linkParams.addAll(LINUX.launcher.linkFlags)
2174             linker = LINUX.launcher.linker
2175             lib = file("$buildDir/classes/main/com/oracle/tools/packager/linux/JavaAppLauncher")
2176         }
2177         task compileLinuxLibrary(type: CCTask, group: "Build") {
2178             description = "Compiles native sources for the application co-bundle launcher library"
2179             matches = ".*\\.cpp"
2180             source file("src/main/native/library/common")
2181             params.addAll(LINUX.launcherlibrary.ccFlags)
2182             compiler = LINUX.launcherlibrary.compiler
2183             output(file("$buildDir/native/linuxlauncher/obj"))
2184         }
2185         task linkLinuxLibrary(type: LinkTask, dependsOn: compileLinuxLibrary, group: "Build") {
2186             description = "Links native dynamic library for the application co-bundle launcher library"
2187             objectDir = file("$buildDir/native/linuxlauncher/obj")
2188             linkParams.addAll(LINUX.launcherlibrary.linkFlags)
2189             linker = LINUX.launcherlibrary.linker
2190             lib = file("$buildDir/classes/main/com/oracle/tools/packager/linux/libpackager.so")
2191         }
2192         task compileLauncher(dependsOn: [linkLinuxLauncher, linkLinuxLibrary])
2193         jar.dependsOn compileLauncher;
2194     }
2195 
2196     // Builds the javapackager executable. For everything other than windows,
2197     // this is simply moving the existing shell script and ensuring it has proper
2198     // permissions. For Windows, this includes compiling the native executable
2199     if (IS_WINDOWS && COMPILE_FXPACKAGER){
2200         task buildJavaPackager(type: CCTask, group: "Build") {
2201             description = "Compiles native sources for javapackager.exe"
2202             matches = "javapackager\\.cpp"
2203             params.addAll(WIN.fxpackager.ccFlags)
2204             compiler = WIN.fxpackager.compiler
2205             output(file("$buildDir/native/javapackager"))
2206             source WIN.fxpackager.nativeSource
2207             doFirst {
2208                 copy {
2209                     mkdir "$buildDir/native"
2210                     mkdir "$buildDir/native/javapackager"
2211                     from file("src/main/native/javapackager/win/javapackager.manifest")
2212                     into file("$buildDir/native/javapackager")
2213                     filter { line->
2214                         line = line.replace("FXVERSION", RELEASE_VERSION_PADDED)
2215                     }
2216                 }
2217             }
2218             doLast {
2219                 mkdir "$buildDir/native"
2220                 exec {
2221                     environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2222                     commandLine(WIN.fxpackager.rcCompiler)
2223                     args(WIN.fxpackager.rcFlags)
2224                     args("/fo$buildDir/native/javapackager/javapackager.res")
2225                     args(WIN.fxpackager.rcSource)
2226                 }
2227             }
2228             doLast {
2229                 mkdir "$buildDir/javapackager"
2230                 exec({
2231                     commandLine("$WIN.fxpackager.linker", "/nologo", "/opt:REF", "/incremental:no", "/manifest", "kernel32.lib", "advapi32.lib",
2232                             "/out:$buildDir/native/javapackager/javapackager.exe",
2233                             "$buildDir/native/javapackager/javapackager.obj",
2234                             "$buildDir/native/javapackager/javapackager.res")
2235                     environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2236                 })
2237             }
2238             doLast {
2239                 exec({
2240                     commandLine("$MC", "-manifest",
2241                                        "$buildDir/native/javapackager/javapackager.manifest",
2242                                        "-outputresource:$buildDir/native/javapackager/javapackager.exe")
2243                     environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2244                 })
2245                 copy {
2246                     from file("$buildDir/native/javapackager/javapackager.exe")
2247                     into file("$buildDir/javapackager")
2248                 }
2249             }
2250         }
2251     } else {
2252         task buildJavaPackager(group: "Build") {
2253             enabled = COMPILE_FXPACKAGER
2254             doLast {
2255                 copy {
2256                     from "src/main/native/javapackager/shell"
2257                     into "$buildDir/javapackager"
2258                     fileMode = 0755
2259                 }
2260             }
2261         }
2262     }
2263 
2264     jar.dependsOn buildJavaPackager
2265 
2266     classes << {
2267         // Copy all of the download libraries to libs directory for the sake of the IDEs
2268         File libsDir = rootProject.file("build/libs");
2269         File antLib = new File(libsDir, "ant-1.8.2.jar")
2270         libsDir.mkdirs();
2271 
2272         // Skip copy if file is present.
2273         if (antLib.exists()) return;
2274 
2275         for (File f : configurations.compile.files) {
2276             copy {
2277                 into libsDir
2278                 from f.getParentFile()
2279                 include "**/ant-1.8.2.jar"
2280                 includeEmptyDirs = false
2281             }
2282         }
2283     }
2284 
2285     task packagerFakeJar(type: Jar) {
2286         dependsOn compileTestJava
2287         from compileTestJava.destinationDir
2288         include "hello/**"
2289 
2290         destinationDir project.file("build/tmp/tests/appResources")
2291         archiveName "mainApp.jar"
2292 
2293         manifest {
2294             attributes(
2295                     "Main-Class": "hello.HelloRectangle",
2296                     "Custom-Attribute": " Is it stripped?"
2297             )
2298         }
2299 
2300         doFirst {
2301             copy {
2302                 from "$projectDir/src/main/resources/com/oracle/tools/packager/linux/javalogo_white_48.png"
2303                 from "$projectDir/src/main/resources/com/oracle/tools/packager/mac/GenericAppHiDPI.icns"
2304                 from "$projectDir/src/main/resources/com/oracle/tools/packager/windows/javalogo_white_48.ico"
2305                 from "$projectDir/src/test/resources/hello/java-logo2.gif"
2306                 from "$projectDir/src/test/resources/hello/small.ico"
2307                 from "$projectDir/src/test/resources/hello/test.icns"
2308                 from "$projectDir/src/test/resources/hello/LICENSE-RTF.rtf"
2309                 from "$projectDir/../../LICENSE"
2310                 into project.file("$projectDir/build/tmp/tests/appResources")
2311             }
2312             copy {
2313                 from "$projectDir/../../LICENSE"
2314                 into project.file("$projectDir/build/tmp/tests/appResources")
2315                 rename '(.*)LICENSE', '$1LICENSE2'
2316             }
2317         }
2318     }
2319 
2320     task packagerFXPackagedJar(type: Jar) {
2321         dependsOn packagerFakeJar
2322         from compileTestJava.destinationDir
2323         include "hello/**"
2324 
2325         destinationDir project.file("build/tmp/tests/appResources")
2326         archiveName "packagedMainApp.jar"
2327 
2328         manifest {
2329             attributes(
2330                 "JavaFX-Application-Class": "hello.TestPackager",
2331             )
2332         }
2333     }
2334 
2335     if (!DO_BUILD_SDK_FOR_TEST) {
2336         def antJavafxJar = new File(TEST_SDK_DIR, "lib/ant-javafx.jar")
2337         [compileTestJava, test].each {
2338             it.classpath = files(antJavafxJar) + it.classpath
2339         }
2340     }
2341 
2342     test {
2343         if (IS_JIGSAW_TEST) {
2344             enabled = false // FIXME: JIGSAW -- support this with modules
2345             logger.info("JIGSAW Testing disabled for fxpackager")
2346         }
2347 
2348         dependsOn packagerFXPackagedJar
2349         systemProperty "RETAIN_PACKAGER_TESTS", RETAIN_PACKAGER_TESTS
2350         systemProperty "TEST_PACKAGER_DMG", TEST_PACKAGER_DMG
2351         systemProperty "FULL_TEST", FULL_TEST
2352         executable = JIGSAW_JAVA;
2353     }
2354 
2355     def packagerDevOpts = []
2356     try {
2357         packagerDevOpts.addAll(PACKAGER_DEV_OPTS.split(' '))
2358     } catch (MissingPropertyException ignore) {
2359         packagerDevOpts.addAll("image")
2360     }
2361 
2362     task packagerDev(dependsOn: [jar, testClasses, packagerFakeJar], type:JavaExec) {
2363         workingDir = project.file("build/tmp/tests/appResources/")
2364         executable = JIGSAW_JAVA
2365         classpath = project.files("build/libs/ant-javafx.jar", "build/classes/test", "build/resources/test")
2366         main = "hello.SimpleBundle"
2367         args = [
2368                 '--module-path', JIGSAW_MODULES,
2369                 '-o', "$projectDir/build/dev",
2370                 '-all',
2371                 packagerDevOpts
2372         ].flatten()
2373     }
2374 
2375     task buildRedistributableFiles() {
2376         def projectDir = "tools/java/redistributable-files"
2377         def sourceDir = "src/$projectDir"
2378         def buildDir = "build/$projectDir"
2379 
2380         doLast {
2381             exec {
2382                 commandLine(JIGSAW_JAVAC)
2383                 args("-d")
2384                 args("$buildDir")
2385                 args("$sourceDir/RedistributableFiles.java")
2386             }
2387         }
2388     }
2389 
2390     task runRedistributableFiles() {
2391         def projectDir = "tools/java/redistributable-files"
2392         def sourceDir = "src/$projectDir"
2393         def buildDir = "build/$projectDir"
2394         def resourceDir = "build/resources/main/jdk/packager/internal/resources/tools/redistributable-files"
2395 
2396         doLast {
2397             def fxmodules = ""
2398 
2399             if (!file("$JIGSAW_MODULES/jdk.packager.jmod").exists()) {
2400                 moduleProjList.each { project ->
2401                     if (fxmodules.isEmpty()) {
2402                         fxmodules = project.ext.moduleName
2403                     }
2404                     else {
2405                         fxmodules += "," + project.ext.moduleName
2406                     }
2407                 }
2408             }
2409 
2410             exec {
2411                 commandLine(JIGSAW_JAVA)
2412                 args("-classpath")
2413                 args("$buildDir")
2414                 args("RedistributableFiles")
2415                 args("--module-path")
2416                 args("$JIGSAW_MODULES")
2417                 args("--exclude-filelist")
2418                 args("$sourceDir/exclude_modules.list")
2419                 args("--out-file")
2420                 args("$resourceDir/redistributable.list")
2421 
2422                 if (!fxmodules.isEmpty()) {
2423                     args("--add-modules")
2424                     args("$fxmodules")
2425                 }
2426             }
2427         }
2428     }
2429 
2430     runRedistributableFiles.dependsOn buildRedistributableFiles
2431     processResources.dependsOn runRedistributableFiles
2432 }
2433 
2434 project(":media") {
2435     configurations {
2436         media
2437     }
2438 
2439     project.ext.buildModule = true
2440     project.ext.moduleRuntime = true
2441     project.ext.moduleName = "javafx.media"
2442 
2443     dependencies {
2444         compile project(":base"), project(":graphics")
2445     }
2446 
2447     compileJava.dependsOn updateCacheIfNeeded
2448 
2449     sourceSets {
2450         tools {
2451             java.srcDir "src/tools/java"
2452         }
2453     }
2454 
2455     compileToolsJava {
2456         enabled = IS_COMPILE_MEDIA
2457         classpath = sourceSets.main.output;
2458     }
2459 
2460     project.ext.makeJobsFlag = IS_WINDOWS && IS_DEBUG_NATIVE ? "-j1" : "-j5";
2461     project.ext.buildType = IS_DEBUG_NATIVE ? "Debug" : "Release";
2462 
2463     def nativeSrcDir = file("${projectDir}/src/main/native")
2464     def generatedHeadersDir = file("${buildDir}/gensrc/headers")
2465 
2466     task generateHeaders(dependsOn: compileJava) {
2467         enabled = IS_COMPILE_MEDIA
2468         doLast {
2469             def classpath = sourceSets.main.output;
2470             mkdir generatedHeadersDir;
2471 
2472             def classesList = ["com.sun.media.jfxmedia.logging.Logger",
2473                              "com.sun.media.jfxmedia.track.AudioTrack",
2474                              "com.sun.media.jfxmedia.control.VideoDataBuffer",
2475                              "com.sun.media.jfxmedia.control.VideoFormat\$FormatTypes",
2476                              "com.sun.media.jfxmediaimpl.NativeAudioClip",
2477                              "com.sun.media.jfxmediaimpl.NativeMediaPlayer",
2478                              "com.sun.media.jfxmediaimpl.NativeVideoBuffer",
2479                              "com.sun.media.jfxmediaimpl.platform.gstreamer.GSTPlatform",
2480                              "com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMedia",
2481                              "com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMediaPlayer",
2482                              "com.sun.media.jfxmediaimpl.NativeAudioEqualizer",
2483                              "com.sun.media.jfxmediaimpl.NativeEqualizerBand",
2484                              "com.sun.media.jfxmediaimpl.NativeAudioSpectrum"]
2485             if (IS_MAC) {
2486                 classesList.addAll( ["com.sun.media.jfxmediaimpl.platform.osx.OSXPlatform",
2487                                      "com.sun.media.jfxmediaimpl.platform.osx.OSXMedia",
2488                                      "com.sun.media.jfxmediaimpl.platform.osx.OSXMediaPlayer"] );
2489             }
2490             exec {
2491                 commandLine ("${JAVAH}", "-d", "${generatedHeadersDir}", "-classpath", "${classpath.asPath}");
2492                 args classesList;
2493             }
2494         }
2495     }
2496 
2497     task generateMediaErrorHeader(dependsOn: [compileToolsJava, compileJava]) {
2498         enabled = IS_COMPILE_MEDIA
2499         doLast {
2500             def classpath = files(sourceSets.main.output, sourceSets.tools.output);
2501             def sourcepath = sourceSets.main.java.srcDirs;
2502             def headerpath = file("$generatedHeadersDir/jfxmedia_errors.h");
2503             def srcRoot = (sourcepath.toArray())[0];
2504 
2505             mkdir generatedHeadersDir;
2506 
2507             exec {
2508                 commandLine("$JAVA", "-classpath", "${classpath.asPath}");
2509                 args("headergen.HeaderGen", "$headerpath", "$srcRoot");
2510             }
2511         }
2512     }
2513 
2514     task buildNativeTargets {
2515         enabled = IS_COMPILE_MEDIA
2516     }
2517 
2518     compileTargets { t->
2519         def targetProperties = project.rootProject.ext[t.upper]
2520         def nativeOutputDir = file("${buildDir}/native/${t.name}")
2521         def projectDir = t.name.startsWith("arm") ? "linux" : t.name
2522         def mediaProperties = targetProperties.media
2523         // Makefile for OSX needs to know if we're building for parfait
2524         def compileParfait = IS_COMPILE_PARFAIT ? "true" : "false"
2525 
2526         def buildNative = task("build${t.capital}Native", dependsOn: [generateHeaders, generateMediaErrorHeader]) {
2527             enabled = targetProperties.compileMediaNative
2528             if (!targetProperties.compileMediaNative) {
2529                 println("Not compiling native Media for ${t.name} per configuration request");
2530             }
2531 
2532             doLast {
2533                 exec {
2534                     commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/jfxmedia/projects/${projectDir}")
2535                     args("JAVA_HOME=${JDK_HOME}", "GENERATED_HEADERS_DIR=${generatedHeadersDir}",
2536                          "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=jfxmedia",
2537                          "COMPILE_PARFAIT=${compileParfait}",
2538                          IS_64 ? "ARCH=x64" : "ARCH=x32",
2539                         "CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}")
2540 
2541                     if (t.name == "win") {
2542                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2543                         args( "RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.jfxmediaRcFile}")
2544                     } else {
2545                         if (t.name.startsWith("arm")) {
2546                             args("EXTRA_CFLAGS=${mediaProperties.extra_cflags}", "EXTRA_LDFLAGS=${mediaProperties.extra_ldflags}")
2547                         } else {
2548                             args("HOST_COMPILE=1")
2549                         }
2550                     }
2551                 }
2552             }
2553         }
2554 
2555         // check for the property disable${name} = true
2556         def boolean disabled = targetProperties.containsKey('disableMedia') ? targetProperties.get('disableMedia') : false
2557         if (!disabled) {
2558             // Building GStreamer
2559             def buildGStreamer = task("build${t.capital}GStreamer") {
2560                 enabled = IS_COMPILE_MEDIA
2561                 doLast {
2562                     exec {
2563                         commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/gstreamer-lite")
2564                         args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=gstreamer-lite",
2565                              IS_64 ? "ARCH=x64" : "ARCH=x32", "CC=${mediaProperties.compiler}",
2566                              "AR=${mediaProperties.ar}", "LINKER=${mediaProperties.linker}")
2567 
2568                         if (t.name == "win") {
2569                             environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2570                             args("RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.gstreamerRcFile}")
2571                         }
2572                     }
2573                 }
2574             }
2575 
2576             def buildPlugins = task("build${t.capital}Plugins", dependsOn: buildGStreamer) {
2577                 enabled = IS_COMPILE_MEDIA
2578 
2579                 if (!project.ext.properties.containsKey("ON2_SRCDIR")) {
2580                     project.ext.ON2_SRCDIR = "";
2581                 }
2582 
2583                 if (!project.ext.properties.containsKey("ON2_LIB")) {
2584                     project.ext.ON2_LIB = "";
2585                 }
2586 
2587                 doLast {
2588                     exec {
2589                         commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/fxplugins")
2590                         args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=fxplugins",
2591                              "ON2_SRCDIR=${project.ext.ON2_SRCDIR}", "ON2_LIB=${project.ext.ON2_LIB}",
2592                              IS_64 ? "ARCH=x64" : "ARCH=x32",
2593                              "CC=${mediaProperties.compiler}", "AR=${mediaProperties.ar}", "LINKER=${mediaProperties.linker}")
2594 
2595                         if (t.name == "win") {
2596                             Map winEnv = new HashMap(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2597 
2598                             String sdkDir = System.getenv("BASECLASSES_SDK_DIR");
2599                             if (sdkDir == null) {
2600                                 sdkDir = "C:/Program Files/Microsoft SDKs/Windows/v7.1" // Default value
2601                                 winEnv["BASECLASSES_SDK_DIR"] = sdkDir
2602                             }
2603                             environment(winEnv)
2604 
2605                             args("RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.fxpluginsRcFile}")
2606                         }
2607                     }
2608                 }
2609             }
2610 
2611             buildNative.dependsOn buildPlugins
2612 
2613             if (t.name == "linux") {
2614                 def buildAVPlugin = task( "buildAVPlugin", dependsOn: [buildPlugins]) {
2615                     enabled = IS_COMPILE_MEDIA
2616 
2617                     doLast {
2618                         if (project.ext.properties.containsKey("libav")) {
2619                             project.ext.libav.versions.each { version ->
2620                                 def libavDir = "${project.ext.libav.basedir}-${version}"
2621                                 File dir = file(libavDir)
2622                                 if (dir.exists()) {
2623                                     exec {
2624                                         commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/linux/avplugin")
2625                                         args("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}",
2626                                              "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}",
2627                                              "BASE_NAME=avplugin", "VERSION=${version}", "LIBAV_DIR=${libavDir}",
2628                                              "SUFFIX=", IS_64 ? "ARCH=x64" : "ARCH=x32")
2629                                     }
2630                                 }
2631                             }
2632 
2633                             project.ext.libav.ffmpeg.versions.each { version ->
2634                                 def libavDir = "${project.ext.libav.ffmpeg.basedir}-${version}"
2635                                 File dir = file(libavDir)
2636                                 if (dir.exists()) {
2637                                     exec {
2638                                         commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/linux/avplugin")
2639                                         args("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}",
2640                                              "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}",
2641                                              "BASE_NAME=avplugin", "VERSION=${version}", "LIBAV_DIR=${libavDir}",
2642                                              "SUFFIX=-ffmpeg", IS_64 ? "ARCH=x64" : "ARCH=x32")
2643                                     }
2644                                 }
2645                             }
2646                         } else {
2647                             // Building fxavcodec plugin (libav plugin)
2648                             exec {
2649                                 commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/linux/avplugin")
2650                                 args("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}",
2651                                      "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}",
2652                                      "BASE_NAME=avplugin", IS_64 ? "ARCH=x64" : "ARCH=x32")
2653                             }
2654                         }
2655                     }
2656                 }
2657                 buildNative.dependsOn buildAVPlugin
2658             }
2659 
2660             if (t.name == "win") {
2661                 def buildResources = task("buildResources") << {
2662                     def rcOutputDir = "${nativeOutputDir}/${buildType}"
2663                     mkdir rcOutputDir
2664                     exec {
2665                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2666                         commandLine (WIN.media.rcCompiler)
2667                         args(WIN.media.glibRcFlags)
2668                         args("/Fo${rcOutputDir}/${WIN.media.glibRcFile}", WIN.media.rcSource)
2669                     }
2670 
2671                     exec {
2672                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2673                         commandLine (WIN.media.rcCompiler)
2674                         args(WIN.media.gstreamerRcFlags)
2675                         args("/Fo${rcOutputDir}/${WIN.media.gstreamerRcFile}", WIN.media.rcSource)
2676                     }
2677 
2678                     exec {
2679                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2680                         commandLine (WIN.media.rcCompiler)
2681                         args(WIN.media.fxpluginsRcFlags)
2682                         args("/Fo${rcOutputDir}/${WIN.media.fxpluginsRcFile}", WIN.media.rcSource)
2683                     }
2684 
2685                     exec {
2686                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2687                         commandLine (WIN.media.rcCompiler)
2688                         args(WIN.media.jfxmediaRcFlags)
2689                         args("/Fo${rcOutputDir}/${WIN.media.jfxmediaRcFile}", WIN.media.rcSource)
2690                     }
2691                 }
2692 
2693                 def buildGlib = task("build${t.capital}Glib", dependsOn: [buildResources]) {
2694                     enabled = IS_COMPILE_MEDIA
2695                     doLast {
2696                         exec {
2697                             environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2698                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/glib-lite")
2699                             args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=glib-lite",
2700                                  IS_64 ? "ARCH=x64" : "ARCH=x32", "RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.glibRcFile}",
2701                                  "CC=${mediaProperties.compiler}", "AR=${mediaProperties.ar}", "LINKER=${mediaProperties.linker}")
2702                         }
2703                     }
2704                 }
2705                 buildGStreamer.dependsOn buildGlib
2706 
2707             } else if (t.name == "mac") {
2708                 def buildGlib = task("build${t.capital}Glib") {
2709                     enabled = IS_COMPILE_MEDIA
2710                     doLast {
2711                         exec {
2712                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/libffi")
2713                             args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=ffi")
2714                             args ("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}", "AR=${mediaProperties.ar}")
2715                         }
2716 
2717                         exec {
2718                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/glib-lite")
2719                             args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=glib-lite")
2720                             args ("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}")
2721                         }
2722                     }
2723                 }
2724                 buildGStreamer.dependsOn buildGlib
2725             }
2726         }
2727 
2728         buildNativeTargets.dependsOn buildNative
2729     }
2730 
2731     jar {
2732         exclude("headergen/**")
2733 
2734         dependsOn compileJava
2735         if (IS_COMPILE_MEDIA) {
2736             dependsOn buildNativeTargets
2737         }
2738     }
2739 }
2740 
2741 project(":web") {
2742     configurations {
2743         webkit
2744     }
2745     project.ext.buildModule = true
2746     project.ext.moduleRuntime = true
2747     project.ext.moduleName = "javafx.web"
2748 
2749     Set<String> testInclude = [ "test/**" ]
2750     configureJigsawTests(project, [ "base", "graphics" ],
2751         null, testInclude,
2752         project.projectDir.path + "/src/test/addExports"
2753         )
2754 
2755     dependencies {
2756         compile project(":base"), project(":graphics"), project(":controls"), project(":media")
2757     }
2758 
2759     compileJava.dependsOn updateCacheIfNeeded
2760 
2761     task webArchiveJar(type: Jar) {
2762         from (project.file("$projectDir/src/test/resources/test/html")) {
2763             include "**/archive-*.*"
2764         }
2765         archiveName = "webArchiveJar.jar"
2766         destinationDir = file("$buildDir/testing/resources")
2767     }
2768 
2769     test {
2770         if (!IS_JIGSAW_TEST) {
2771         //TODO: support this in Jake
2772         // Run web tests in headless mode
2773         systemProperty 'glass.platform', 'Monocle'
2774         systemProperty 'monocle.platform', 'Headless'
2775         systemProperty 'prism.order', 'sw'
2776         }
2777         dependsOn webArchiveJar
2778         def testResourceDir = file("$buildDir/testing/resources")
2779         jvmArgs "-DWEB_ARCHIVE_JAR_TEST_DIR=$testResourceDir"
2780     }
2781 
2782     if (!IS_COMPILE_WEBKIT) {
2783         // Include wrapper classes that are otherwise generated by native build
2784         sourceSets.main.java.srcDirs += "src/main/java-wrappers"
2785     }
2786 
2787     task generateHeaders(dependsOn: compileJava) {
2788         doLast {
2789             def classpath = files("$buildDir/classes/main",
2790                                   project(":graphics").sourceSets.main.output.classesDir)
2791             def dest = file("$buildDir/gensrc/headers");
2792             mkdir dest;
2793             exec {
2794                 commandLine("$JAVAH", "-d", "$dest",
2795                             "-classpath", "${classpath.asPath}");
2796                 args("java.lang.Character",
2797                      "java.net.IDN",
2798                      "com.sun.webkit.ContextMenu",
2799                      "com.sun.webkit.ContextMenuItem",
2800                      "com.sun.webkit.CursorManager",
2801                      "com.sun.webkit.PageCache",
2802                      "com.sun.webkit.PopupMenu",
2803                      "com.sun.webkit.SharedBuffer",
2804                      "com.sun.webkit.WatchdogTimer",
2805                      "com.sun.webkit.WebPage",
2806                      "com.sun.webkit.LoadListenerClient",
2807                      "com.sun.webkit.event.WCFocusEvent",
2808                      "com.sun.webkit.event.WCKeyEvent",
2809                      "com.sun.webkit.event.WCMouseEvent",
2810                      "com.sun.webkit.event.WCMouseWheelEvent",
2811                      "com.sun.webkit.graphics.GraphicsDecoder",
2812                      "com.sun.webkit.graphics.RenderMediaControls",
2813                      "com.sun.webkit.graphics.RenderTheme",
2814                      "com.sun.webkit.graphics.ScrollBarTheme",
2815                      "com.sun.webkit.graphics.WCMediaPlayer",
2816                      "com.sun.webkit.graphics.WCGraphicsManager",
2817                      "com.sun.webkit.graphics.WCRenderQueue",
2818                      "com.sun.webkit.graphics.WCPath",
2819                      "com.sun.webkit.graphics.WCPathIterator",
2820                      "com.sun.webkit.Timer",
2821                      "com.sun.webkit.WCFrameView",
2822                      "com.sun.webkit.WCPasteboard",
2823                      "com.sun.webkit.WCPluginWidget",
2824                      "com.sun.webkit.dom.JSObject",
2825                      "com.sun.webkit.network.SocketStreamHandle",
2826                      "com.sun.webkit.network.URLLoader",
2827                      "com.sun.webkit.text.TextBreakIterator",
2828                      "com.sun.webkit.text.TextNormalizer");
2829             }
2830         }
2831     }
2832 
2833     task compileGenerated()
2834 
2835     compileTargets { t ->
2836         def targetProperties = project.rootProject.ext[t.upper]
2837         def classifier = (t.name != "linux" && t.name != "win") ? t.name :
2838                           IS_64 ? "${t.name}-amd64" : "${t.name}-i586"
2839         dependencies {
2840             webkit group: "com.sun.webkit", name: "webview-deps",
2841                    version: "1.3.1", classifier: "$classifier", ext: "zip"
2842         }
2843 
2844         def webkitOutputDir = cygpath("$buildDir/${t.name}")
2845         def webkitConfig = IS_DEBUG_NATIVE ? "Debug" : "Release"
2846 
2847         def compileNativeTask = task("compileNative${t.capital}", dependsOn: generateHeaders) << {
2848             println "Building Webkit configuration /$webkitConfig/ into $webkitOutputDir"
2849 
2850             def dependencyFile = configurations.webkit.filter(
2851                     { File f -> f.getName().contains(classifier) }
2852                 ).getSingleFile()
2853             ant.unzip(src:  dependencyFile,
2854                       dest: webkitOutputDir)
2855 
2856             exec {
2857                 workingDir("$projectDir/src/main/native")
2858                 commandLine("perl", "Tools/Scripts/set-webkit-configuration", "--$webkitConfig")
2859                 environment(["WEBKIT_OUTPUTDIR" : webkitOutputDir])
2860             }
2861 
2862             exec {
2863                 workingDir("$projectDir/src/main/native")
2864                 def cmakeArgs = "-DENABLE_TOOLS=1"
2865                 if (t.name == "win") {
2866                     String parfaitPath = IS_COMPILE_PARFAIT ? System.getenv().get("PARFAIT_PATH") + ";" : "";
2867                     Map environmentSettings = new HashMap(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2868                     environmentSettings["PATH"] = parfaitPath + "$WINDOWS_VS_PATH"
2869                     /* To build with ICU:
2870                     1. Download http://javaweb.us.oracle.com/jcg/fx-webrevs/RT-17164/WebKitLibrariesICU.zip
2871                     and unzip it to WebKitLibraries folder.
2872                     2. Copy DLLs from
2873                     WebKitLibrariesICU.zip\WebKitLibraries\import\runtime
2874                     to %windir%\system32
2875                     3. Uncomment the line below
2876                      */
2877                     // args("--icu-unicode")
2878                 } else if (t.name == "mac") {
2879                     // Add any osx specific flags.
2880                 } else if (t.name == "linux") {
2881                     if (!IS_64) {
2882                         cmakeArgs = "-DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32"
2883                     }
2884                 } else if (t.name.startsWith("arm")) {
2885                     fail("ARM target is not supported as of now.")
2886                 }
2887 
2888                 if (IS_COMPILE_PARFAIT) {
2889                     environment([
2890                         "COMPILE_PARFAIT" : "true"
2891                     ])
2892                     cmakeArgs = "-DCMAKE_C_COMPILER=parfait-gcc -DCMAKE_CXX_COMPILER=parfait-g++"
2893                 }
2894 
2895                 environment([
2896                     "JAVA_HOME"       : JDK_HOME,
2897                     "WEBKIT_OUTPUTDIR" : webkitOutputDir,
2898                 ])
2899 
2900                 def targetCpuBitDepthSwitch = ""
2901                 if (IS_64) {
2902                     targetCpuBitDepthSwitch = "--64-bit"
2903                 } else {
2904                     targetCpuBitDepthSwitch = "--32-bit"
2905                 }
2906 
2907                 commandLine("perl", "Tools/Scripts/build-webkit",
2908                     "--java", "--icu-unicode", targetCpuBitDepthSwitch,
2909                     "--cmakeargs=${cmakeArgs}")
2910             }
2911 
2912             def library = rootProject.ext[t.upper].library
2913             copy {
2914                 from "$webkitOutputDir/$webkitConfig/lib/${library('jfxwebkit')}"
2915                 into "$buildDir/libs/${t.name}"
2916             }
2917             copy {
2918                 from "$webkitOutputDir/$webkitConfig/lib/${library('DumpRenderTreeJava')}"
2919                 into "$buildDir/test/${t.name}"
2920             }
2921         }
2922 
2923         if (IS_WINDOWS && t.name == "win") {
2924             def webkitProperties = project.rootProject.ext[t.upper].webkit
2925             def rcTask = project.task("rc${t.capital}", type: CompileResourceTask) {
2926                 compiler = webkitProperties.rcCompiler
2927                 source(webkitProperties.rcSource)
2928                 if (webkitProperties.rcFlags) {
2929                     rcParams.addAll(webkitProperties.rcFlags)
2930                 }
2931                 output(file("$webkitOutputDir/$webkitConfig/WebCore/obj"))
2932             }
2933             compileNativeTask.dependsOn rcTask
2934         }
2935 
2936         def compileGeneratedTask = task("compileGenerated${t.capital}", type: JavaCompile, dependsOn: compileNativeTask) {
2937             def gensrcDir = "$webkitOutputDir/$webkitConfig/DerivedSources/WebCore/nativeJava/java"
2938             doFirst {
2939                 copy {
2940                     from "$projectDir/src/main/java-wrappers/com/sun/webkit/dom/EventListenerImpl.java"
2941                     into "$gensrcDir/com/sun/webkit/dom"
2942                 }
2943             }
2944             classpath = files(project.sourceSets.main.output.classesDir)
2945             source gensrcDir
2946             destinationDir = file("$buildDir/classes/main")
2947         }
2948 
2949         compileGenerated.dependsOn compileGeneratedTask
2950 
2951         if (!targetProperties.compileWebnodeNative) {
2952             println("Not compiling native Webkit for ${t.name} per configuration request");
2953             compileNativeTask.enabled = false
2954         }
2955     }
2956 
2957     def drtClasses = "com/sun/javafx/webkit/drt/**"
2958     jar.exclude(drtClasses)
2959     task drtJar(type: Jar, dependsOn: compileJava) {
2960         archiveName = "drt.jar"
2961         destinationDir = file("$buildDir/test")
2962         from "$buildDir/classes/main"
2963         include drtClasses
2964     }
2965 
2966     if (IS_COMPILE_WEBKIT) {
2967         jar.dependsOn compileGenerated, drtJar
2968     }
2969 }
2970 
2971 // This project is for system tests that need to run with a full SDK.
2972 // Most of them display a stage or do other things that preclude running
2973 // them in a shared JVM or as part of the "smoke test" run (which must
2974 // not pop up any windows or use audio). As such, they are only enabled
2975 // when FULL_TEST is specified, and each test runs in its own JVM
2976 project(":systemTests") {
2977 
2978     dependencies {
2979         testCompile project(":graphics").sourceSets.test.output
2980         testCompile project(":base").sourceSets.test.output
2981         testCompile project(":controls").sourceSets.test.output
2982         testCompile project(":swing").sourceSets.test.output
2983     }
2984 
2985     Set<String> testInclude = [ "test/**" ]
2986     configureJigsawTests(project, [ "base", "graphics", "controls", "swing", "fxml", "web" ],
2987         null, testInclude,
2988         project.projectDir.path + "/src/test/addExports"
2989     )
2990 
2991     test {
2992         enabled = IS_FULL_TEST
2993         if (!IS_USE_ROBOT) {
2994             // Disable all robot-based visual tests
2995             exclude("test/robot/**");
2996         }
2997         if (!IS_AWT_TEST) {
2998             // Disable all AWT-based tests
2999             exclude("**/javafx/embed/swing/*.*");
3000             exclude("**/com/sun/javafx/application/Swing*.*");
3001         }
3002 
3003         forkEvery = 1
3004     }
3005 }
3006 
3007 allprojects {
3008     // The following block is a workaround for the fact that presently Gradle
3009     // can't set the -XDignore.symbol.file flag, because it appears that the
3010     // javac API is lacking support for it. So what we'll do is find any Compile
3011     // task and manually provide the options necessary to fire up the
3012     // compiler with the right settings.
3013     //
3014     // Also, we need to remove jfxrt.jar from the ext classpath (if it is there)
3015     tasks.withType(JavaCompile) { compile ->
3016         if (compile.options.hasProperty("useAnt")) {
3017             compile.options.useAnt = true
3018             compile.options.useDepend = IS_USE_DEPEND
3019         } else if (compile.options.hasProperty("incremental")) {
3020             compile.options.incremental = IS_INCREMENTAL
3021         }
3022         compile.options.debug = true // we always generate debugging info in the class files
3023         compile.options.debugOptions.debugLevel = IS_DEBUG_JAVA ? "source,lines,vars" : "source,lines"
3024         compile.options.fork = true
3025         compile.options.forkOptions.executable = JAVAC
3026         compile.options.warnings = IS_LINT
3027         compile.options.compilerArgs = ["-XDignore.symbol.file", "-encoding", "UTF-8"]
3028         if (!DO_BUILD_SDK_FOR_TEST) {
3029             compile.classpath = files(jfxrtJarFromSdk) + compile.classpath
3030         }
3031 
3032         // Add in the -Xlint options
3033         if (IS_LINT) {
3034             LINT.split("[, ]").each { s ->
3035                 compile.options.compilerArgs += "-Xlint:$s"
3036             }
3037         }
3038     }
3039 
3040     // Some tasks should be disabled not to compile SDK, when running only the tests
3041     disabledTasks.each {
3042         project.getTasksByName(it, false)*.enabled = false
3043     }
3044 }
3045 
3046 // fxpackager requires JDK 9 to compile
3047 project(":fxpackager") {
3048     tasks.withType(JavaCompile) { compile ->
3049         compile.options.forkOptions.executable = JIGSAW_JAVAC
3050         compile.options.compilerArgs = [
3051                 "--add-exports", "java.base/sun.security.pkcs=ALL-UNNAMED",
3052                 "--add-exports", "java.base/sun.security.timestamp=ALL-UNNAMED",
3053                 "--add-exports", "java.base/sun.security.x509=ALL-UNNAMED",
3054                 "-encoding", "UTF-8"]
3055     }
3056 }
3057 
3058 // fxpackagerservices requires JDK 9 to compile
3059 project(":fxpackagerservices") {
3060     tasks.withType(JavaCompile) { compile ->
3061         compile.options.forkOptions.executable = JIGSAW_JAVAC
3062         compile.options.compilerArgs = [
3063                 "-encoding", "UTF-8"]
3064     }
3065 }
3066 
3067 /******************************************************************************
3068  *                                                                            *
3069  *                             Top Level Tasks                                *
3070  *                                                                            *
3071  *  These are the tasks which are defined only for the top level project and  *
3072  *  not for any sub projects. These are generally the entry point that is     *
3073  *  used by Hudson and by the continuous build system.                        *
3074  *                                                                            *
3075  *****************************************************************************/
3076 
3077 task clean() {
3078     group = "Basic"
3079     description = "Deletes the build directory and the build directory of all sub projects"
3080     getSubprojects().each { subProject ->
3081         dependsOn(subProject.getTasksByName("clean", true));
3082     }
3083     doLast {
3084         delete(buildDir);
3085     }
3086 }
3087 
3088 task cleanAll() {
3089     group = "Basic"
3090     description = "Scrubs the repo of build artifacts"
3091     dependsOn(clean)
3092     doLast {
3093         //delete(".gradle"); This causes problems on windows.
3094         delete("buildSrc/build");
3095     }
3096 }
3097 
3098 task javadoc(type: Javadoc) {
3099     enabled = IS_BUILD_JAVADOC
3100     group = "Basic"
3101     description = "Generates the JavaDoc for all the public API"
3102     executable = JAVADOC
3103     def projectsToDocument = [
3104             project(":base"), project(":graphics"), project(":controls"), project(":media"),
3105             project(":swing"), /*project(":swt"),*/ project(":fxml"), project(":web")]
3106     source(projectsToDocument.collect({
3107         [it.sourceSets.main.java]
3108     }));
3109     setDestinationDir(new File(buildDir, 'javadoc'));
3110     // FIXME: The following is a workaround for JDK-8151191; it should be
3111     // reverted once that bug is fixed
3112     classpath += files(projectsToDocument.collect { project ->
3113         project.sourceSets.main.java.srcDirs
3114     });
3115     /*
3116     // Might need a classpath
3117     classpath = files(projectsToDocument.collect { project ->
3118         project.sourceSets.main.compileClasspath
3119     });
3120     classpath += files(projectsToDocument.collect { project ->
3121         project.sourceSets.main.output
3122     });
3123     */
3124     exclude("com/**/*", "Compile*", "javafx/builder/**/*", "javafx/scene/accessibility/**/*");
3125     options.windowTitle("${javadocTitle}")
3126     options.header("${javadocHeader}")
3127     options.bottom("${javadocBottom}")
3128     if (BUILD_CLOSED) {
3129         options.linksOffline(JDK_DOCS, JDK_DOCS_CLOSED);
3130     } else {
3131         options.links(JDK_DOCS);
3132     }
3133     options.addBooleanOption("XDignore.symbol.file").setValue(true);
3134     options.addBooleanOption("Xdoclint:none").setValue(!IS_DOC_LINT);
3135     options.addBooleanOption("javafx").setValue(true);
3136     options.addBooleanOption("use").setValue(true);
3137     doLast {
3138         projectsToDocument.each { p ->
3139             copy {
3140                 from "$p.projectDir/src/main/docs"
3141                 into "$buildDir/javadoc"
3142             }
3143         }
3144     }
3145 
3146     dependsOn(projectsToDocument.collect { project -> project.getTasksByName("classes", true)});
3147 }
3148 
3149 task jfxrt() {
3150     if (DO_BUILD_SDK_FOR_TEST) {
3151         rootProject.getTasksByName("compileTestJava", true).each { t ->
3152             if (t.enabled) t.dependsOn(jfxrt)
3153         }
3154     }
3155 }
3156 
3157 task sdk() {
3158     if (DO_BUILD_SDK_FOR_TEST) {
3159         rootProject.getTasksByName("test", true).each { t ->
3160             if (t.enabled) t.dependsOn(sdk)
3161         }
3162     }
3163 }
3164 
3165 task appsjar() {
3166     dependsOn(sdk)
3167     // Note: the jar dependencies get added elsewhere see project(":apps")
3168 }
3169 
3170 // these are empty tasks, allowing us to depend on the task, which may have other
3171 // real work items added later.
3172 task copyAppsArtifacts() {
3173     dependsOn(appsjar)
3174 }
3175 
3176 task apps() {
3177     dependsOn(sdk)
3178     dependsOn(appsjar)
3179     dependsOn(copyAppsArtifacts)
3180 }
3181 
3182 task findbugs() {
3183     dependsOn(sdk)
3184 
3185     doLast {
3186         if (!BUILD_CLOSED) {
3187             println "findbugs task is only run for a closed build"
3188         }
3189     }
3190 }
3191 
3192 // The following tasks are for the closed build only. They are a no-op for the open build
3193 
3194 task checkCache() {
3195     dependsOn(updateCacheIfNeeded)
3196 }
3197 
3198 // TODO: consider moving the "public-sdk" portion of this task here
3199 task publicExports() {
3200     doFirst {
3201         if (BUILD_CLOSED && !IS_BUILD_JAVADOC) {
3202             fail("publicExports task requires: -PBUILD_JAVADOC=true")
3203         }
3204     }
3205     dependsOn(sdk)
3206 }
3207 
3208 task perf() {
3209     dependsOn(sdk,apps)
3210     doLast {
3211         if (!BUILD_CLOSED) {
3212             println "perf task is only run for a closed build"
3213         }
3214     }
3215 }
3216 
3217 task zips() {
3218     doFirst {
3219         if (BUILD_CLOSED && !IS_BUILD_JAVADOC) {
3220             fail("zips task requires: -PBUILD_JAVADOC=true")
3221         }
3222     }
3223     dependsOn(sdk,publicExports,apps,perf)
3224 }
3225 
3226 task copySources(type: Copy) {
3227     enabled = IS_BUILD_SRC_ZIP
3228     def projectsToCopy = [
3229             project(":base"), project(":graphics"), project(":controls"),
3230             project(":swing"), project(":swt"), project(":fxml"),
3231             project(":media"), project(":web")]
3232     from(projectsToCopy.collect({ proj ->
3233         files(proj.sourceSets.main.java.srcDirs)
3234     }))
3235     include "**/*.java"
3236     into "${buildDir}/javafx-src"
3237 }
3238 
3239 task zipSources(type: Zip) {
3240     enabled = IS_BUILD_SRC_ZIP
3241     dependsOn(copySources)
3242     archiveName = "javafx-src.zip"
3243     destinationDir = file("$buildDir")
3244     includeEmptyDirs = false
3245     from "${buildDir}/javafx-src"
3246 }
3247 
3248 task src {
3249     enabled = IS_BUILD_SRC_ZIP
3250     description = "Created the javafx-src.zip bundle"
3251     dependsOn(zipSources)
3252 }
3253 
3254 task all() {
3255     dependsOn(sdk,publicExports,apps,perf,zips)
3256 }
3257 
3258 
3259 // Construct list of subprojects that are modules
3260 ext.moduleProjList = []
3261 subprojects {
3262     if (project.hasProperty("buildModule") && project.ext.buildModule) {
3263         rootProject.ext.moduleProjList += project
3264         println "module: $project (buildModule=YES)"
3265     } else {
3266         println "module: $project (buildModule=NO)"
3267     }
3268 }
3269 
3270 
3271 // Create the legacy sdk from the modular-sdk
3272 
3273 compileTargets { t ->
3274     def targetProperties = project.ext[t.upper]
3275     def platformPrefix = targetProperties.platformPrefix
3276     def sdkDirName = "${platformPrefix}sdk"
3277     def modularSdkDirName = "${platformPrefix}modular-sdk"
3278     def modularSdkDir = "${rootProject.buildDir}/${modularSdkDirName}"
3279     def modulesDir = "${modularSdkDir}/modules"
3280     def modulesCmdsDir = "${modularSdkDir}/modules_cmds"
3281     def modulesLibsDir = "${modularSdkDir}/modules_libs"
3282 
3283     // The jfxrt task is responsible for creating the legacy jfxrt.jar. A developer may
3284     // have multiple SDK's on their system at any one time, depending on which
3285     // cross compiles they have done. For example, I might have:
3286     //      build/ios-sdk/lib/jfxrt.jar
3287     //      build/armhf-sdk/lib/jfxrt.jar
3288     // and so forth. The default host build will always install into 'sdk'
3289     // allowing for uses where a known sdk path is needed (like IDEs)
3290     //      build/sdk/lib/jfxrt.jar
3291     // This arrangement allows for multiple independent SDKs to
3292     // exist on a developer's system.
3293     def jfxrtTask = task("jfxrt$t.capital", type: Jar) {
3294         group = "Basic"
3295         description = "Creates the jfxrt.jar for the $t.name target"
3296         archiveName = "build/${sdkDirName}/lib/jfxrt.jar";
3297         includeEmptyDirs = false
3298 
3299         moduleProjList.each { project ->
3300             if (project.ext.moduleRuntime) {
3301                 from("${modulesDir}/${project.ext.moduleName}");
3302             }
3303         }
3304 
3305         dependsOn(subprojects.collect { project -> project.getTasksByName("assemble", true)});
3306     }
3307 
3308     def jfxrtIndexTask = task("jfxrtIndex$t.capital") {
3309         //the following is a workaround for the lack of indexing in gradle 1.4 through 1.7
3310         dependsOn(jfxrtTask)
3311 
3312         doLast() {
3313             ant.jar (update: true, index: true, destfile: jfxrtTask.archiveName)
3314         }
3315     }
3316     jfxrt.dependsOn(jfxrtIndexTask)
3317 
3318     def javafxSwtTask = task("javafxSwt$t.capital", type: Jar) {
3319         enabled = COMPILE_SWT
3320         group = "Basic"
3321         description = "Creates the javafx-swt.jar for the $t.name target"
3322         archiveName = "${project(":swt").buildDir}/libs/javafx-swt.jar";
3323         includeEmptyDirs = false
3324         from("${project(":swt").buildDir}/classes/main");
3325         include("**/javafx/embed/swt/**")
3326 
3327         dependsOn(subprojects.collect { project -> project.getTasksByName("assemble", true)});
3328     }
3329 
3330     def javafxSwtIndexTask = task("javafxSwtIndex$t.capital") {
3331         //the following is a workaround for the lack of indexing in gradle 1.4 through 1.7
3332         dependsOn(javafxSwtTask)
3333 
3334         doLast() {
3335             ant.jar (update: true, index: true, destfile: javafxSwtTask.archiveName)
3336         }
3337     }
3338     jfxrt.dependsOn(javafxSwtIndexTask)
3339 
3340     def jmxTask = task ("jmx${t.capital}", type: Jar) {
3341         group = "Basic"
3342         description = "Creates the javafx-mx.jar"
3343         archiveName = "build/${sdkDirName}/lib/javafx-mx.jar";
3344         includeEmptyDirs = false
3345         from project(":jmx").buildDir.path + "/classes/main"
3346         from project(":jmx").buildDir.path + "/resources/main"
3347         dependsOn project(":jmx").assemble
3348     }
3349 
3350     // The 'sdk' task will build the rest of the legacy SDK, and depends
3351     // on the 'jfxrtTask' task. After executing this task the sdk bundle for
3352     // the current COMPILE_TARGETS will be fully created.
3353     def sdkTask = task("sdk$t.capital") {
3354         group = "Basic"
3355         description = "Creates the SDK for $t.name"
3356         doLast {
3357             copy {
3358                 moduleProjList.each { project ->
3359                     from "${modulesLibsDir}/${project.ext.moduleName}"
3360                 }
3361                 into "build/${sdkDirName}/lib"
3362             }
3363 
3364             copy {
3365                 moduleProjList.each { project ->
3366                     from "${modulesCmdsDir}/${project.ext.moduleName}"
3367                 }
3368                 into "build/${sdkDirName}/bin"
3369             }
3370 
3371             // FIXME: JIGSAW -- update this for modules
3372             // Copy over the javadocs that were generated. This is done rather than just generating
3373             // the docs into the "right place" because for a cross-compile you only need one set of
3374             // docs but need to have a copy in each created sdk
3375             if (IS_BUILD_JAVADOC) {
3376                 copy {
3377                     from "build/javadoc"
3378                     into "build/${sdkDirName}/docs/api"
3379                 }
3380             }
3381 
3382             // FIXME: JIGSAW -- update this for modules
3383             // Copy over the javafx-src bundle
3384             if (IS_BUILD_SRC_ZIP) {
3385                 copy {
3386                     from "build/javafx-src.zip"
3387                     into "build/${sdkDirName}"
3388                 }
3389             }
3390 
3391             // FIXME: JIGSAW -- update this for modules
3392             // Copy over the javapackager man files
3393             copy {
3394                 from "${project(":fxpackager").buildDir}/man"
3395                 into "build/${sdkDirName}/man"
3396             }
3397         }
3398         dependsOn(jmxTask);
3399         dependsOn(jfxrtIndexTask)
3400         dependsOn(javafxSwtIndexTask)
3401         dependsOn(javadoc)
3402         dependsOn(src)
3403     }
3404 
3405     def generateSymbols = targetProperties.containsKey('generateSymbols') ? targetProperties.generateSymbols : false
3406     if (generateSymbols) {
3407         def exportedSymbolsTask = project.task("exportedSymbols${t.capital}", type: ExportedSymbolsTask, dependsOn: sdkTask, group: "Build") {
3408             description = "Generates exported symbols file for iOS build (from .a libraries)"
3409             def libDirName = "build/${sdkDirName}/$targetProperties.libDest"
3410             libDir = file("$libDirName")
3411             outputFile = file("$libDirName/exported.symbols")
3412             excludes = targetProperties.generateSymbolsExcludes
3413         }
3414         sdk.dependsOn(exportedSymbolsTask)
3415     }
3416 
3417     sdk.dependsOn(sdkTask)
3418 }
3419 
3420 /*
3421  * This clause changes the way we handle a build.gradle within ./apps
3422  * It does a few things:
3423  *   modifies the classpath used to include the built runttime classes
3424  *   provides for copying the build applications to the artifacts tree
3425  *
3426  * The applications to be built will be under ./apps, but also must
3427  * be listed in the applications listed in the setting variable: JFXApplications
3428  */
3429 ext.JFXRT_CP =
3430     files(
3431         project(":base").sourceSets.main.output.classesDir,
3432         project(":graphics").sourceSets.main.output.classesDir,
3433         project(":controls").sourceSets.main.output.classesDir,
3434         project(":fxml").sourceSets.main.output.classesDir,
3435         project(":swing").sourceSets.main.output.classesDir, //NOTE - used by 3Dviewer
3436         "${project(":media").buildDir}/classes/main",
3437         "${project(":web").buildDir}/classes/main",
3438     )
3439 
3440 project(":apps") {
3441     // The apps build is Ant based, and gradle lets us "import" ant build.xml
3442     // into our configuration.
3443 
3444     ant.importBuild 'build.xml'
3445 
3446     compileTargets { t ->
3447         // The apps build is Ant based, and gradle lets us "import" ant apps/build.xml
3448         // into our configuration.
3449 
3450         // override the apps build.xml with an explicit pointer to our jar.
3451         def platformPrefix = rootProject.ext[t.upper].platformPrefix
3452         def sdkDirName = "${platformPrefix}sdk"
3453         def jfxrtJar = "${rootProject.buildDir}/${sdkDirName}/lib/jfxrt.jar"
3454 
3455         def appsJar = project.task("appsJar${t.capital}") {
3456             dependsOn(sdk)
3457             doLast() {
3458               ant.properties['targetBld'] = "$t.name"
3459               if (!rootProject.ext[t.upper].compileSwing) {
3460                 ant.properties['JFX_CORE_ONLY'] = 'true'
3461               }
3462               ant.properties['jfxbuild.jfxrt.jar'] = jfxrtJar
3463               ant.properties['platforms.JDK_1.8.home'] = "${rootProject.ext.JDK_HOME}"
3464               ant.project.executeTarget("sampleAppsJar")
3465               ant.project.executeTarget("scenebuilderSampleAppsJar")
3466               if (!t.name.startsWith("arm")) {
3467                 ant.project.executeTarget("scenebuilderAppJar")
3468               }
3469             }
3470         }
3471         rootProject.appsjar.dependsOn(appsJar)
3472 
3473         def appsClean = project.task("appsClean${t.capital}") {
3474             doLast() {
3475               ant.properties['targetBld'] = "$t.name"
3476               ant.properties['platforms.JDK_1.8.home'] = "${rootProject.ext.JDK_HOME}"
3477               ant.project.executeTarget("sampleAppsClean")
3478               ant.project.executeTarget("scenebuilderSampleAppsClean")
3479               if (!t.name.startsWith("arm")) {
3480                 ant.project.executeTarget("scenebuilderAppClean")
3481               }
3482             }
3483         }
3484         rootProject.clean.dependsOn(appsClean)
3485     }
3486 }
3487 
3488 
3489 /******************************************************************************
3490  *                                                                            *
3491  *                               Modules                                      *
3492  *                                                                            *
3493  *****************************************************************************/
3494 
3495 ext.moduleDependencies = [file("dependencies")]
3496 
3497 task buildModules {
3498 }
3499 
3500 // Combine the classes, lib, and bin for each module
3501 compileTargets { t ->
3502     def targetProperties = project.ext[t.upper]
3503 
3504     def platformPrefix = targetProperties.platformPrefix
3505     def modularSdkDirName = "${platformPrefix}modular-sdk"
3506     def modularSdkDir = "${rootProject.buildDir}/${modularSdkDirName}"
3507     def modulesDir = "${modularSdkDir}/modules"
3508     def modulesCmdsDir = "${modularSdkDir}/modules_cmds"
3509     def modulesLibsDir = "${modularSdkDir}/modules_libs"
3510     def modulesSrcDir = "${modularSdkDir}/modules_src"
3511     def modulesConfDir = "${modularSdkDir}/modules_conf"
3512     def modulesMakeDir = "${modularSdkDir}/make"
3513     final File patchmoduleFile = file("${rootProject.buildDir}/patchmodule.args")
3514 
3515     project.files(patchmoduleFile);
3516 
3517     def zipTask = project.task("buildModuleZip$t.capital", type: Zip, group: "Build") {
3518         enabled = IS_BUILD_MODULE_ZIP
3519 
3520         // FIXME: JIGSAW -- this should be moved to a sub-directory so we can keep the same name
3521         def jfxBundle = "${platformPrefix}javafx-exports.zip"
3522 
3523         doFirst() {
3524             file("${rootProject.buildDir}/${jfxBundle}").delete()
3525         }
3526 
3527         archiveName = jfxBundle
3528         destinationDir = file("${rootProject.buildDir}")
3529         includeEmptyDirs = false
3530         from "${modularSdkDir}"
3531     }
3532     buildModules.dependsOn(zipTask)
3533 
3534     def buildModulesTask = task("buildModules$t.capital", group: "Build") {
3535         doLast {
3536             moduleProjList.each { project ->
3537 
3538                 // Copy classes, bin, and lib directories
3539 
3540                 def moduleName = project.ext.moduleName
3541                 def buildDir = project.buildDir
3542 
3543                 def srcClassesDir = "${buildDir}/${platformPrefix}module-classes"
3544                 def dstClassesDir = "${modulesDir}/${moduleName}"
3545                 copy {
3546                     from srcClassesDir
3547                     into dstClassesDir
3548                 }
3549 
3550                 def srcCmdsDir = "${buildDir}/${platformPrefix}module-bin"
3551                 def dstCmdsDir = "${modulesCmdsDir}/${moduleName}"
3552                 copy {
3553                     from srcCmdsDir
3554                     into dstCmdsDir
3555                 }
3556 
3557                 def srcLibsDir = "${buildDir}/${platformPrefix}module-lib"
3558                 def dstLibsDir = "${modulesLibsDir}/${moduleName}"
3559                 copy {
3560                     from srcLibsDir
3561                     into dstLibsDir
3562                 }
3563 
3564                 // Copy module-info.java
3565                 def srcModuleInfoDir = "${project.projectDir}/src/main/module-info"
3566                 def dstModuleInfoDir = "${modulesSrcDir}/${moduleName}"
3567                 copy {
3568                     from srcModuleInfoDir
3569                     into dstModuleInfoDir
3570                     if (!IS_COMPILE_JFR && project.name.equals("base")) {
3571                         filter { line-> line.contains("requires jdk.jfr;") ? "" : line }
3572                     }
3573                 }
3574 
3575                 // Copy make/build.properties
3576                 def srcMakeDir = "${project.projectDir}/make"
3577                 def dstMakeDir = "${modulesMakeDir}/${moduleName}"
3578                 copy {
3579                     from srcMakeDir
3580                     into dstMakeDir
3581                 }
3582             }
3583 
3584             // Copy dependencies/*/module-info.java.extra
3585             def dependencyRoots = moduleDependencies
3586             if (rootProject.hasProperty("closedModuleDepedencies")) {
3587                 dependencyRoots = [dependencyRoots, closedModuleDepedencies].flatten()
3588             }
3589             copy {
3590                 dependencyRoots.each { root ->
3591                     from root
3592                 }
3593                 into modulesSrcDir
3594             }
3595 
3596             // concatecate java.policy files into a single file
3597             //
3598             def outputPolicyDir = "${modulesConfDir}/java.base/security"
3599             def outputPolicyFile = file("${outputPolicyDir}/java.policy.extra")
3600             mkdir outputPolicyDir
3601             outputPolicyFile.delete()
3602             moduleProjList.each { project ->
3603                 def policyDir = "${project.projectDir}/src/main/conf/security"
3604                 def policyFile = file("${policyDir}/java.policy")
3605                 if (policyFile.exists()) outputPolicyFile << policyFile.text
3606             }
3607         }
3608     }
3609     zipTask.dependsOn(buildModulesTask);
3610     buildModules.dependsOn(buildModulesTask)
3611 
3612     def buildModulesPatchTask = task("buildModulesPatch$t.capital", group: "Build") {
3613         doLast() {
3614             patchmoduleFile.delete()
3615 
3616             logger.info("Creating patchmodule.args file ${patchmoduleFile}")
3617             String thepath=cygpath("${rootProject.buildDir}/sdk/${targetProperties.libDest}")
3618 
3619             patchmoduleFile <<  "-Djava.library.path=${thepath}\n"
3620             moduleProjList.each { project ->
3621                 def moduleName = project.ext.moduleName
3622                 def dstModuleDir = cygpath("${modulesDir}/${moduleName}")
3623                 patchmoduleFile <<  "--patch-module ${moduleName}=\"${dstModuleDir}\"\n"
3624             }
3625         }
3626     }
3627 
3628     buildModulesPatchTask.dependsOn(buildModulesTask)
3629     buildModules.dependsOn(buildModulesPatchTask)
3630 
3631     def isWindows = IS_WINDOWS && t.name == "win";
3632     def isMac = IS_MAC && t.name == "mac";
3633 
3634     // Create layout for modular classes
3635     moduleProjList.each { project ->
3636         def buildModuleClassesTask = project.task("buildModule$t.capital", group: "Build") {
3637             dependsOn(project.assemble)
3638             def buildDir = project.buildDir
3639             def sourceBuildDirs = [
3640                 "${buildDir}/classes/main",
3641                 "${buildDir}/resources/main"
3642             ]
3643             doLast {
3644                 def moduleClassesDir = "$buildDir/${platformPrefix}module-classes"
3645                 copy {
3646                     includeEmptyDirs = false
3647                     sourceBuildDirs.each { d ->
3648                         from d
3649                     }
3650                     into moduleClassesDir
3651 
3652                     // Exclude obsolete, experimental, or non-shipping code
3653                     exclude("version.rc")
3654                     exclude("com/sun/glass/ui/swt")
3655                     exclude("com/sun/javafx/tools/ant")
3656                     exclude("com/javafx/main")
3657                     if (!IS_INCLUDE_NULL3D) {
3658                         exclude ("com/sun/prism/null3d")
3659                     }
3660                     if (!IS_INCLUDE_ES2) {
3661                            exclude("com/sun/prism/es2",
3662                                    "com/sun/scenario/effect/impl/es2")
3663                     }
3664 
3665                     // Exclude platform-specific classes for other platforms
3666 
3667                     if (!isMac) {
3668                         exclude ("com/sun/media/jfxmediaimpl/platform/osx",
3669                                  "com/sun/prism/es2/MacGL*",
3670                                  "com/sun/glass/events/mac",
3671                                  "com/sun/glass/ui/mac",
3672                                  )
3673                     }
3674 
3675                     if (!isWindows) {
3676                         exclude ("**/*.hlsl",
3677                                  "com/sun/glass/ui/win",
3678                                  "com/sun/prism/d3d",
3679                                  "com/sun/prism/es2/WinGL*",
3680                                  "com/sun/scenario/effect/impl/hw/d3d"
3681                                  )
3682                     }
3683 
3684                     if (!targetProperties.includeGTK) { //usually IS_LINUX
3685                         exclude (
3686                                  "com/sun/glass/ui/gtk",
3687                                  "com/sun/prism/es2/EGL*",
3688                                  "com/sun/prism/es2/X11GL*"
3689                                  )
3690                     }
3691 
3692                     if (!targetProperties.includeEGL) {
3693                         exclude ("com/sun/prism/es2/EGL*")
3694                     }
3695 
3696                     if (!targetProperties.includeLens) {
3697                         exclude ("com/sun/glass/ui/lens")
3698                     }
3699 
3700                     // FIXME: JIGSAW -- Figure out what to do with Monocle
3701                     /*
3702                     if (!targetProperties.includeMonocle) {
3703                         exclude ("com/sun/glass/ui/monocle")
3704                         exclude("com/sun/prism/es2/Monocle*")
3705                     }
3706                     */
3707 
3708                     if (t.name != 'ios') {
3709                         exclude ("com/sun/media/jfxmediaimpl/platform/ios",
3710                                  "com/sun/glass/ui/ios",
3711                                  "com/sun/prism/es2/IOS*"
3712                                  )
3713                     }
3714 
3715                     if (t.name != 'android' && t.name != 'dalvik') {
3716                         exclude ("com/sun/glass/ui/android")
3717                     }
3718 
3719                     // Filter out other platform-specific classes
3720                     if (targetProperties.containsKey('jfxrtJarExcludes')) {
3721                         exclude(targetProperties.jfxrtJarExcludes)
3722                     }
3723 
3724                     /* FIXME: JIGSAW -- handle this in the module itself
3725                     String webbld = project(":web").buildDir.path
3726                     String ctrlbld = project(":controls").buildDir.path
3727                     if (t.name == 'android') {
3728                         from ("${webbld}/classes/android",
3729                               "${webbld}/resources/android",
3730                               "${ctrlbld}/classes/android",
3731                               "${ctrlbld}/resources/android")
3732                     } else if (t.name == 'ios') {
3733                         from ("${webbld}/classes/ios",
3734                               "${webbld}/resources/ios",
3735                               "modules/extensions/build/classes/ios")
3736                     } else {
3737                         from ("${webbld}/classes/main",
3738                               "${webbld}resources/main")
3739                     }
3740                     */
3741                 }
3742             }
3743         }
3744         buildModulesTask.dependsOn(buildModuleClassesTask)
3745     }
3746 
3747 
3748     def buildModuleLibsTask = task("buildModuleLibs$t.capital") {
3749         group = "Basic"
3750 
3751         def graphicsProject = project(":graphics");
3752         dependsOn(graphicsProject.assemble)
3753 
3754         def mediaProject = project(":media");
3755         dependsOn(mediaProject.assemble)
3756 
3757         def webProject = project(":web");
3758         dependsOn(webProject.assemble)
3759 
3760         def swtProject = project(":swt");
3761         if (COMPILE_SWT) {
3762             def javafxSwtIndexTask = tasks.getByName("javafxSwtIndex${t.capital}");
3763             dependsOn(javafxSwtIndexTask)
3764         }
3765 
3766         def packagerProject = project(":fxpackager");
3767         //dependsOn(packagerProject.assemble)
3768         dependsOn(packagerProject.jar)
3769         dependsOn(project(":fxpackagerservices").jar)
3770 
3771         doLast {
3772 
3773             def library = targetProperties.library
3774 
3775             // javafx.base (lib/javafx.properties)
3776 
3777             def baseProject = project(":base");
3778             def moduleLibDir = "${baseProject.buildDir}/${platformPrefix}module-lib"
3779             mkdir moduleLibDir
3780             final File javafxProperties = file("${moduleLibDir}/javafx.properties")
3781             javafxProperties.delete()
3782             javafxProperties << "javafx.version=$RELEASE_VERSION_SHORT";
3783             javafxProperties << "\n"
3784             javafxProperties << "javafx.runtime.version=$RELEASE_VERSION_LONG";
3785             javafxProperties << "\n"
3786             javafxProperties << "javafx.runtime.build=$PROMOTED_BUILD_NUMBER";
3787             javafxProperties << "\n"
3788             // Include any properties that have been defined (most likely in
3789             // one of the various platform gradle files)
3790             if (targetProperties.containsKey("javafxProperties")) {
3791                 javafxProperties << targetProperties.javafxProperties
3792                 javafxProperties << "\n"
3793             }
3794 
3795             // Embedded builds define this file as well
3796             if (targetProperties.containsKey("javafxPlatformProperties")) {
3797                 final File javafxPlatformProperties = file("${moduleLibDir}/javafx.platform.properties")
3798                 javafxPlatformProperties.delete()
3799                 javafxPlatformProperties << targetProperties.javafxPlatformProperties
3800                 javafxPlatformProperties << "\n"
3801             }
3802 
3803 
3804             def useLipo = targetProperties.containsKey('useLipo') ? targetProperties.useLipo : false
3805             def libDest = targetProperties.libDest
3806             def moduleNativeDirName = "${platformPrefix}module-$libDest"
3807 
3808             // javafx.graphics native libraries
3809 
3810             copy {
3811                 into "${graphicsProject.buildDir}/${moduleNativeDirName}"
3812 
3813                 from("${graphicsProject.buildDir}/libs/jsl-decora/${t.name}/${library(targetProperties.decora.lib)}")
3814                 def libs = ['font', 'prism', 'prismSW', 'glass', 'iio']
3815                 if (IS_INCLUDE_ES2) {
3816                     libs += ['prismES2'];
3817                 }
3818                 if (IS_COMPILE_PANGO) {
3819                     libs += ['fontFreetype', 'fontPango'];
3820                 }
3821                 libs.each { lib ->
3822                     def variants = targetProperties[lib].containsKey('variants') && !useLipo ? targetProperties[lib].variants : [null]
3823                     variants.each { variant ->
3824                         def variantProperties = variant ? targetProperties[lib][variant] : targetProperties[lib]
3825                         from ("${graphicsProject.buildDir}/libs/$lib/$t.name/${library(variantProperties.lib)}")
3826                     }
3827                 }
3828                 if (IS_WINDOWS) {
3829                     from ("${graphicsProject.buildDir}/libs/prismD3D/${t.name}/${library(targetProperties.prismD3D.lib)}");
3830                 }
3831             }
3832 
3833 
3834             // javafx.media native libraries
3835 
3836             copy {
3837                 into "${mediaProject.buildDir}/${moduleNativeDirName}"
3838 
3839                 def mediaBuildType = project(":media").ext.buildType
3840                 if (IS_COMPILE_MEDIA) {
3841                     [ "fxplugins", "gstreamer-lite", "jfxmedia" ].each { name ->
3842                         from ("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}/${library(name)}") }
3843 
3844                     if (t.name == "mac") {
3845                         // OSX media natives
3846                         [ "jfxmedia_qtkit", "jfxmedia_avf", "glib-lite" ].each { name ->
3847                             from ("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}/${library(name)}") }
3848                     } else if (t.name == "linux") {
3849                         from("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}") { include "libavplugin*.so" }
3850                     } else from ("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}/${library("glib-lite")}")
3851                 } else {
3852                     if (t.name != "android"  && t.name != "dalvik" ) {
3853                         [ "fxplugins", "gstreamer-lite", "jfxmedia" ].each { name ->
3854                             from ("$LIBRARY_STUB/${library(name)}") }
3855                     }
3856 
3857                     if (t.name == "mac") {
3858                         // copy libjfxmedia_{avf,qtkit}.dylib if they exist
3859                         [ "jfxmedia_qtkit", "jfxmedia_avf", "glib-lite" ].each { name ->
3860                             from ("$LIBRARY_STUB/${library(name)}") }
3861                     } else if (t.name == "linux") {
3862                         from(LIBRARY_STUB) { include "libavplugin*.so" }
3863                     }
3864                     else if (t.name != "android"  && t.name != "dalvik" ) {
3865                         from ("$LIBRARY_STUB/${library("glib-lite")}")
3866                     }
3867                 }
3868             }
3869 
3870 
3871             // javafx.web native libraries
3872 
3873             copy {
3874                 into "${webProject.buildDir}/${moduleNativeDirName}"
3875 
3876                 if (IS_COMPILE_WEBKIT) {
3877                     from ("${webProject.buildDir}/libs/${t.name}/${library('jfxwebkit')}")
3878                 } else {
3879                     if (t.name != "android" && t.name != "ios" && t.name != "dalvik") {
3880                         from ("$LIBRARY_STUB/${library('jfxwebkit')}")
3881                     }
3882                 }
3883             }
3884 
3885             // FIXME: the following is a hack to workaround the fact that there
3886             // is no way to deliver javafx-swt.jar other than in one of the
3887             // existing runtime modules.
3888             if (COMPILE_SWT) {
3889                 // Copy javafx-swt.jar to the javafx-graphics module lib dir
3890                 copy {
3891                     from "${swtProject.buildDir}/libs/javafx-swt.jar"
3892                     into "${graphicsProject.buildDir}/${platformPrefix}module-lib"
3893                 }
3894             }
3895 
3896             // javafx.packager libraries and executable
3897 
3898             // Copy over the javapackager libs
3899             copy {
3900                 from "${packagerProject.buildDir}/libs"
3901                 into "${packagerProject.buildDir}/${platformPrefix}module-lib"
3902             }
3903 
3904             // Copy over the javapackager executable
3905             if (t.name == "win" || t.name == "linux" || t.name == "mac") {
3906                 copy {
3907                     from "${packagerProject.buildDir}/javapackager"
3908                     into "${packagerProject.buildDir}/${platformPrefix}module-bin"
3909                 }
3910             }
3911 
3912         }
3913     }
3914     buildModulesTask.dependsOn(buildModuleLibsTask)
3915 
3916     def sdkTask = tasks.getByName("sdk${t.capital}");
3917     sdkTask.dependsOn(buildModulesTask)
3918 }
3919 sdk.dependsOn(buildModules)
3920 
3921 void configureJigsawTests(
3922         Project p,
3923         List<String> moduleDeps,
3924         Set<String> patchInc,
3925         Set<String> testsInc,
3926         String addExportsFile
3927         ) {
3928 
3929     if(!IS_JIGSAW_TEST) {
3930         return
3931     }
3932 
3933     p.configurations {
3934         jigsawTest
3935     }
3936 
3937     p.dependencies {
3938         jigsawTest group: "junit", name: "junit", version: "4.8.2"
3939     }
3940 
3941     compileTargets { t ->
3942 
3943         def targetProperties = project.rootProject.ext[t.upper]
3944 
3945         def modularSdkDirName = "${targetProperties.platformPrefix}modular-sdk"
3946         def modularSdkDir = "${rootProject.buildDir}/${modularSdkDirName}"
3947         def modulesDir = "${modularSdkDir}/modules"
3948 
3949         boolean useModule = true
3950         String moduleName
3951         if(!p.hasProperty('moduleName')) {
3952             useModule = false
3953             moduleName = "systemTests"
3954         } else {
3955             moduleName = p.moduleName
3956         }
3957 
3958         logger.info("configuring $p.name for modular test copy");
3959 
3960         def testingDir = "${rootProject.buildDir}/${targetProperties.platformPrefix}testing";
3961         def patchesDir = new File("${testingDir}/modules");
3962         File patchPolicyFile = new File("${testingDir}/java.patch.policy");
3963         File patchmoduleFile = new File("${testingDir}/patchmodule.args");
3964 
3965         String javaLibraryPath = "${rootProject.buildDir}/sdk/$targetProperties.libDest"
3966 
3967         def jigsawPatchesBaseDir = new File("${testingDir}/modules/$moduleName");
3968         def jigsawPatchesTestDir = new File("${testingDir}/tests/$moduleName");
3969 
3970         p.files(patchPolicyFile);
3971         p.files(patchmoduleFile);
3972 
3973         def srcClassesDir = "${p.buildDir}/${targetProperties.platformPrefix}module-classes"
3974         Task classes =  p.task("jigsawCopyClasses${t.capital}", type: Copy, dependsOn: [p.classes]) {
3975 
3976             enabled = useModule
3977 
3978             from srcClassesDir
3979             into jigsawPatchesBaseDir
3980         }
3981 
3982         Task shims =  p.task("jigsawCopyShims${t.capital}", type: Copy, dependsOn: [p.testClasses]) {
3983             //from p.sourceSets.test.output.classesDir
3984 
3985             enabled = useModule
3986 
3987             from p.sourceSets.test.output
3988             into jigsawPatchesBaseDir
3989             if (patchInc != null) {
3990                 include patchInc
3991             } else {
3992                 include "**/*"
3993             }
3994             if (testsInc != null) {
3995                 exclude testsInc
3996             }
3997             includeEmptyDirs = false
3998             doLast() {
3999                 logger.info("project $p.name finished jigsawCopyShims to $jigsawPatchesBaseDir");
4000             }
4001         }
4002 
4003         Task alltests =  p.task("jigsawCopyTests${t.capital}", type: Copy, dependsOn: [p.testClasses]) {
4004             from p.sourceSets.test.output
4005             into jigsawPatchesTestDir
4006             if (patchInc != null) {
4007                 exclude patchInc
4008             }
4009             if (testsInc != null) {
4010                 include testsInc
4011             } else {
4012                 include "**/*"
4013             }
4014             includeEmptyDirs = false
4015             doLast() {
4016                 logger.info("project $p.name finished jigsawCopyTests to $jigsawPatchesTestDir");
4017             }
4018         }
4019 
4020         // create & use just one of these per platform
4021         String nameis = "moduleTestPatchPolicy${t.capital}"
4022         Task patchPerms = null
4023         if (rootProject.hasProperty(nameis)) {
4024             patchPerms = rootProject.tasks[nameis]
4025         } else {
4026             patchPerms = rootProject.task(nameis) {
4027                 outputs.file(patchPolicyFile)
4028                 outputs.file(patchmoduleFile)
4029                 doLast() {
4030                     logger.info("Creating test patch.policy file ${patchPolicyFile}")
4031                     logger.info("Creating test patch.policy file ${patchmoduleFile}")
4032 
4033                     delete(patchPolicyFile)
4034                     delete(patchmoduleFile)
4035                     mkdir(testingDir)
4036                     String thepath=cygpath("${rootProject.buildDir}/sdk/${targetProperties.libDest}")
4037 
4038                     patchmoduleFile <<  "-Djava.library.path=${thepath}\n"
4039                     moduleProjList.each { project ->
4040                         String themod = file("${patchesDir}/${project.ext.moduleName}").toURI()
4041                         patchPolicyFile <<  "grant codeBase \"${themod}\" {\n" +
4042                         "    permission java.security.AllPermission;\n" +
4043                         "};\n"
4044 
4045                         def dstModuleDir = cygpath("${patchesDir}/${project.ext.moduleName}")
4046                         patchmoduleFile <<  "--patch-module ${project.ext.moduleName}=\"${dstModuleDir}\"\n"
4047                     }
4048                 }
4049             }
4050         }
4051 
4052         Task jigsawTestsTask =  p.task("jigsawTests${t.capital}", dependsOn: [classes, shims, alltests, patchPerms ]) {
4053             doLast() {
4054                 logger.info("project $p.name finished jigsawTests${t.capital}");
4055             }
4056         }
4057 
4058         FileCollection testclasspath = p.files(p.configurations.jigsawTest)
4059 
4060         p.test.dependsOn jigsawTestsTask
4061 
4062         if (moduleDeps != null) {
4063             moduleDeps.each() {s->
4064                 logger.info("adding dep to project $p.name $s");
4065                 Project pdep = rootProject.project(s);
4066                 def jigsawTask = pdep.tasks.getByName("jigsawTests${t.capital}");
4067                 jigsawTestsTask.dependsOn jigsawTask;
4068 
4069                 testclasspath += p.files(pdep.ext.jigsawPatchesTestDir);
4070             }
4071         }
4072 
4073         testclasspath += p.files(jigsawPatchesTestDir);
4074 
4075         p.ext.jigsawTestClasspath = testclasspath
4076         p.ext.jigsawPatchesTestDir = jigsawPatchesTestDir
4077         p.ext.jigsawTestClasses = jigsawTestsTask
4078 
4079         p.ext.argclasspathFile = "$testingDir/classpath_"+p.name+".txt"
4080 
4081         p.test {
4082             if (IS_FORCE_TESTS) {
4083                 dependsOn 'cleanTest'
4084             }
4085 
4086             scanForTestClasses = false
4087             include("**/*Test.*")
4088 
4089             if (IS_JIGSAW_TEST) {
4090                 dependsOn jigsawTestsTask
4091 
4092                 doFirst {
4093                     classpath = testclasspath
4094                     p.sourceSets.test.runtimeClasspath = testclasspath
4095                 }
4096 
4097                 String bcp = "-Xbootclasspath/a:" + rootProject.projectDir.path + "/buildSrc/build/libs/buildSrc.jar"
4098 
4099                 systemProperties 'worker.debug': IS_WORKER_DEBUG
4100                 systemProperties 'worker.patchmodule.file': cygpath(patchmoduleFile.path)
4101                 if (addExportsFile != null) {
4102                     systemProperties 'worker.exports.file': cygpath(addExportsFile)
4103                 }
4104                 systemProperties 'worker.classpath.file': cygpath(p.ext.argclasspathFile)
4105                 systemProperties 'worker.java.cmd': JIGSAW_JAVA
4106 
4107                 systemProperties 'worker.isJigsaw': true
4108 
4109                 systemProperties 'worker.patch.policy': cygpath(patchPolicyFile.path)
4110 
4111                 //systemProperties 'prism.order': 'sw'
4112                 //systemProperties 'glass.platform': 'Monocle'
4113                 //systemProperties
'glass.len': 'headless'
4114 
4115                 jvmArgs bcp, "workaround.GradleJUnitWorker"
4116 
4117                 environment("JDK_HOME", JIGSAW_HOME);
4118                 executable (JIGSAW_JAVA);
4119 
4120               }
4121         }
4122 
4123     }
4124 
4125 }
4126 
4127 task checkrepo() {
4128     doLast {
4129         logger.info("checking for whitespace (open)");
4130         exec {
4131             if (IS_WINDOWS) {
4132                 commandLine  'bash', 'tools/scripts/checkWhiteSpace'
4133             } else {
4134                 commandLine  'bash', 'tools/scripts/checkWhiteSpace', '-x'
4135             }
4136         }
4137     }
4138 }
4139 
4140 task checkrepoall() {
4141     doLast {
4142         logger.info("checking for all whitespace (open)");
4143         exec {
4144             if (IS_WINDOWS) {
4145                 commandLine  'bash', 'tools/scripts/checkWhiteSpace', '-a'
4146             } else {
4147                 commandLine  'bash', 'tools/scripts/checkWhiteSpace', '-x', '-a'
4148             }
4149         }
4150     }
4151 }
4152 
4153 /******************************************************************************
4154  *                                                                            *
4155  *                              BUILD_CLOSED                                  *
4156  *                                                                            *
4157  * This next section should remain at the end of the build script. It allows  *
4158  * for a "supplemental" gradle file to be used to extend the normal build     *
4159  * structure. For example, this is used for passing a supplemental gradle     *
4160  * file for producing official JavaFX builds.                                 *
4161  *                                                                            *
4162  *****************************************************************************/
4163 
4164 if (BUILD_CLOSED) {
4165     apply from: supplementalBuildFile
4166 }
4167 
4168 task showFlags {
4169 }
4170 
4171 compileTargets { t ->
4172     // Every platform must define these variables
4173     def props = project.ext[t.upper];
4174     showFlags.dependsOn(
4175         project.task("showFlags$t.upper") {
4176             doLast() {
4177                 println "Properties set for $t.upper"
4178                 props.each { println it }
4179             }
4180         }
4181     )
4182 
4183 }
4184