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