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