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