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