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