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 that Gradle 1.8 is in use.
 773 if (gradle.gradleVersion != "1.8") {
 774     def ver = gradle.gradleVersion.split("[\\.]");
 775     def gradleMajor = Integer.parseInt(ver[0]);
 776     def gradleMinor = Integer.parseInt(ver[1]);
 777     def err = "";
 778     if (gradleMajor == 1) {
 779         if (gradleMinor < 8) {
 780             err = "Gradle version too old: ${gradle.gradleVersion}; must be at least 1.8"
 781         }
 782 
 783         // Blacklisted versions of gradle
 784         if (gradleMinor == 11) {
 785             err = "JavaFX fails to build with Gradle ${gradle.gradleVersion}; supported version is 1.8"
 786         }
 787     }
 788 
 789     if (IS_GRADLE_VERSION_CHECK && err != "") {
 790         fail(err);
 791     }
 792 
 793     logger.warn("*****************************************************************");
 794     logger.warn("Unsupported gradle version $gradle.gradleVersion in use.");
 795     logger.warn("Only version 1.8 is supported. Use this version at your own risk");
 796     if ( err != "") logger.warn(err);
 797     logger.warn("*****************************************************************");
 798 }
 799 
 800 /******************************************************************************
 801  *                                                                            *
 802  *                      Logging of Properties and Settings                    *
 803  *                                                                            *
 804  *  Log some of the settings we've determined. We could log more here, it     *
 805  *  doesn't really hurt.                                                      *
 806  *                                                                            *
 807  *****************************************************************************/
 808 
 809 logger.quiet("OS_NAME: $OS_NAME")
 810 logger.quiet("OS_ARCH: $OS_ARCH")
 811 logger.quiet("JAVA_HOME: $JAVA_HOME")
 812 logger.quiet("JDK_HOME: $JDK_HOME")
 813 logger.quiet("java.runtime.version: ${javaRuntimeVersion}")
 814 logger.quiet("java version: ${javaVersion}")
 815 logger.quiet("java build number: ${javaBuildNumber}")
 816 logger.quiet("jdk.runtime.version: ${jdkRuntimeVersion}")
 817 logger.quiet("jdk version: ${jdkVersion}")
 818 logger.quiet("jdk build number: ${jdkBuildNumber}")
 819 logger.quiet("minimum java build number: ${jfxBuildJdkBuildnumMin}")
 820 logger.quiet("CONF: $CONF")
 821 logger.quiet("NUM_COMPILE_THREADS: $NUM_COMPILE_THREADS")
 822 logger.quiet("COMPILE_TARGETS: $COMPILE_TARGETS")
 823 logger.quiet("COMPILE_FLAGS_FILES: $COMPILE_FLAGS_FILES")
 824 logger.quiet("HUDSON_JOB_NAME: $HUDSON_JOB_NAME")
 825 logger.quiet("HUDSON_BUILD_NUMBER: $HUDSON_BUILD_NUMBER")
 826 logger.quiet("PROMOTED_BUILD_NUMBER: $PROMOTED_BUILD_NUMBER")
 827 logger.quiet("PRODUCT_NAME: $PRODUCT_NAME")
 828 logger.quiet("RAW_VERSION: $RAW_VERSION")
 829 logger.quiet("RELEASE_NAME: $RELEASE_NAME")
 830 logger.quiet("RELEASE_MILESTONE: $RELEASE_MILESTONE")
 831 
 832 if (UPDATE_STUB_CACHE) {
 833     logger.quiet("UPDATE_STUB_CACHE: $UPDATE_STUB_CACHE")
 834 }
 835 
 836 /******************************************************************************
 837  *                                                                            *
 838  *                Definition of Native Code Compilation Tasks                 *
 839  *                                                                            *
 840  *    - JavaHeaderTask is used to run javah. The JAVAH property will point at *
 841  *      the version of javah to be used (i.e.: a path to javah)               *
 842  *    - CCTask compiles native code. Specifically it will compile .m, .c,     *
 843  *      .cpp, or .cc files. It uses the headers provided by the               *
 844  *      JavaHeaderTask plus additional platform specific headers. It will     *
 845  *      compile into .obj files.                                              *
 846  *    - LinkTask will perform native linking and create the .dll / .so /      *
 847  *      .dylib as necessary.                                                  *
 848  *                                                                            *
 849  *****************************************************************************/
 850 
 851 // Save a reference to the buildSrc.jar file because we need it for actually
 852 // compiling things, not just for the sake of this build script
 853 // (such as generating the builders, JSL files, etc)
 854 ext.BUILD_SRC = rootProject.files("buildSrc/build/libs/buildSrc.jar")
 855 
 856 /**
 857  * Convenience method for creating javah, cc, link, and "native" tasks in the given project. These
 858  * tasks are parameterized by name, so that we can produce, for example, javahGlass, ccGlass, etc
 859  * named tasks.
 860  *
 861  * @param project The project to add tasks to
 862  * @param name The name of the project, such as "prism-common". This name is used
 863  *        in the name of the generated task, such as ccPrismCommon, and also
 864  *        in the name of the final library, such as libprism-common.dylib.
 865  */
 866 void addNative(Project project, String name) {
 867     // TODO if we want to handle 32/64 bit windows in the same build,
 868     // Then we will need to modify the win compile target to be win32 or win64
 869     def capitalName = name.split("-").collect{it.capitalize()}.join()
 870     def nativeTask = project.task("native$capitalName", group: "Build") {
 871         description = "Generates JNI headers, compiles, and builds native dynamic library for $name for all compile targets"
 872     }
 873     def cleanTask = project.task("cleanNative$capitalName", type: Delete, group: "Build") {
 874         description = "Clean native objects for $name"
 875     }
 876     if (project.hasProperty("nativeAllTask")) project.nativeAllTask.dependsOn nativeTask
 877     project.assemble.dependsOn(nativeTask)
 878     if (project.hasProperty("cleanNativeAllTask")) project.cleanNativeAllTask.dependsOn cleanTask
 879 
 880     // Each of the different compile targets will be placed in a sub directory
 881     // of these root dirs, with the name of the dir being the name of the target
 882     def headerRootDir = project.file("$project.buildDir/generated-src/headers/$name")
 883     def nativeRootDir = project.file("$project.buildDir/native/$name")
 884     def libRootDir = project.file("$project.buildDir/libs/$name")
 885     // For each compile target, create a javah / cc / link triplet
 886     compileTargets { t ->
 887         def targetProperties = project.rootProject.ext[t.upper]
 888         def library = targetProperties.library
 889         def properties = targetProperties.get(name)
 890         def nativeDir = file("$nativeRootDir/${t.name}")
 891         def headerDir = file("$headerRootDir/${t.name}")
 892 
 893         // If there is not a library clause in the properties, assume it is not wanted
 894         if (!targetProperties.containsKey(name)) {
 895             println("Ignoring native library ${name}. Not defined in ${t.name} project properties");
 896             return
 897         }
 898 
 899         // check for the property disable${name} = true
 900         def String disableKey = "disable${name}"
 901         def boolean disabled = targetProperties.containsKey(disableKey) ? targetProperties.get(disableKey) : false
 902         if (disabled) {
 903             println("Native library ${name} disabled in ${t.name} project properties");
 904             return
 905         }
 906 
 907         def javahTask = project.task("javah${t.capital}${capitalName}", type: JavaHeaderTask, dependsOn: project.classes, group: "Build") {
 908             description = "Generates JNI Headers for ${name} for ${t.name}"
 909             if (properties.javahSource == null) {
 910                 source(project.sourceSets.main.output.classesDir)
 911             } else {
 912                 source(properties.javahSource)
 913             }
 914             if (properties.javahClasspath == null) {
 915                 classpath = project.files(project.sourceSets.main.output.classesDir)
 916                 classpath += project.sourceSets.main.compileClasspath
 917             } else {
 918                 classpath = project.files(properties.javahClasspath)
 919             }
 920             output = headerDir
 921             include(properties.javahInclude)
 922             cleanTask.delete headerDir
 923         }
 924 
 925         def variants = properties.containsKey("variants") ? properties.variants : [""];
 926         variants.each { variant ->
 927             def variantProperties = variant == "" ? properties : properties.get(variant)
 928             def capitalVariant = variant.capitalize()
 929             def ccOutput = variant == "" ? nativeDir : file("$nativeDir/$variant")
 930             def ccTask = project.task("cc${t.capital}$capitalName$capitalVariant", type: CCTask, dependsOn: javahTask, group: "Build") {
 931                 description = "Compiles native sources for ${name} for ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}"
 932                 matches = ".*\\.c|.*\\.cpp|.*\\.m|.*\\.cc"
 933                 headers = headerDir
 934                 output(ccOutput)
 935                 params.addAll(variantProperties.ccFlags)
 936                 compiler = variantProperties.compiler
 937                 source(variantProperties.nativeSource)
 938                 cleanTask.delete ccOutput
 939             }
 940             def linkTask = project.task("link${t.capital}$capitalName$capitalVariant", type: LinkTask, dependsOn: ccTask, group: "Build") {
 941                 description = "Creates native dynamic library for $name for ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}"
 942                 objectDir = ccOutput
 943                 linkParams.addAll(variantProperties.linkFlags)
 944                 lib = file("$libRootDir/${t.name}/${variant == '' ? library(properties.lib) : library(variantProperties.lib)}")
 945                 linker = variantProperties.linker
 946                 cleanTask.delete "$libRootDir/${t.name}"
 947             }
 948             nativeTask.dependsOn(linkTask)
 949             if (IS_WINDOWS && t.name == "win") {
 950                 def rcTask = project.task("rc$capitalName$capitalVariant", type: CompileResourceTask, dependsOn: javahTask, group: "Build") {
 951                     description = "Compiles native sources for $name"
 952                     matches = ".*\\.rc"
 953                     compiler = variantProperties.rcCompiler
 954                     source(variantProperties.rcSource)
 955                     if (variantProperties.rcFlags) {
 956                         rcParams.addAll(variantProperties.rcFlags)
 957                     }
 958                     output(ccOutput)
 959                 }
 960                 linkTask.dependsOn rcTask;
 961             }
 962         }
 963 
 964         def useLipo = targetProperties.containsKey('useLipo') ? targetProperties.useLipo : false
 965         if (useLipo) {
 966             def lipoTask = project.task("lipo${t.capital}$capitalName", type: LipoTask, dependsOn: javahTask, group: "Build") {
 967                 description = "Creates native fat library for $name for ${t.name}"
 968                 libDir = file("$libRootDir/${t.name}")
 969                 lib = file("$libRootDir/${t.name}/${library(properties.lib)}")
 970             }
 971             nativeTask.dependsOn(lipoTask)
 972         }
 973     }
 974 }
 975 
 976 void addJSL(Project project, String name, String pkg, Closure compile) {
 977     def lowerName = name.toLowerCase()
 978 
 979     def compileCompilers = project.task("compile${name}Compilers", type: JavaCompile, dependsOn: project.compileJava) {
 980         description = "Compile the $name JSL Compilers"
 981         classpath = project.files(project.sourceSets.main.output.classesDir) +
 982                 rootProject.BUILD_SRC +
 983                 project.configurations.antlr3
 984         source = [project.file("src/main/jsl-$lowerName")]
 985         destinationDir = project.file("$project.buildDir/classes/jsl-compilers/$lowerName")
 986     }
 987 
 988     def generateShaders = project.task("generate${name}Shaders", dependsOn: compileCompilers) {
 989         description = "Generate $name shaders from JSL"
 990         def sourceDir = project.file("src/main/jsl-$lowerName")
 991         def destinationDir = project.file("$project.buildDir/generated-src/jsl-$lowerName")
 992         inputs.dir sourceDir
 993         outputs.dir destinationDir
 994         doLast {
 995             compile(sourceDir, destinationDir)
 996         }
 997     }
 998 
 999     project.task("compile${name}JavaShaders", type: JavaCompile, dependsOn: generateShaders) {
1000         description = "Compile the Java $name JSL shaders"
1001         classpath = project.files(project.sourceSets.main.output.classesDir) + rootProject.BUILD_SRC
1002         source = [project.file("$project.buildDir/generated-src/jsl-$lowerName")]
1003         destinationDir = project.file("$project.buildDir/classes/jsl-$lowerName")
1004     }
1005 
1006     def compileHLSLShaders = project.task("compile${name}HLSLShaders", dependsOn: generateShaders, type: CompileHLSLTask) {
1007         enabled = IS_WINDOWS
1008         description = "Compile $name HLSL files into .obj files"
1009         matches = ".*\\.hlsl"
1010         output project.file("$project.buildDir/hlsl/$name/$pkg")
1011         source project.file("$project.buildDir/generated-src/jsl-$lowerName/$pkg")
1012     }
1013 
1014     project.task("process${name}Shaders", dependsOn: [generateShaders, compileHLSLShaders], type: Copy, description: "Copy hlsl / frag shaders to build/resources/jsl-$lowerName") {
1015         from("$project.buildDir/hlsl/$name") {
1016             include "**/*.obj"
1017         }
1018         from("$project.buildDir/generated-src/jsl-$lowerName") {
1019             include("**/*.frag")
1020         }
1021         into "$project.buildDir/resources/jsl-$lowerName"
1022     }
1023 }
1024 
1025 /**
1026  * Parses a JDK version string. The string must be in one of the following
1027  * two formats:
1028  *
1029  *     major.minor.subminor
1030  * or
1031  *     major.minor.subminor_update
1032  *
1033  * In both cases a list of 4 integers is returned, with element 3 set to
1034  * 0 in the former case.
1035  */
1036 List parseJdkVersion(String version) {
1037     def arr = version.split("[_\\.]");
1038     def intArr = [];
1039     arr.each { s -> intArr += Integer.parseInt(s); }
1040     if (intArr.size() < 4) intArr += 0;
1041     return intArr;
1042 }
1043 
1044 /**
1045  * Returns -1, 0, or 1 depending on whether JDK version "a" is less than,
1046  * equal to, or grater than version "b".
1047  */
1048 int compareJdkVersion(String a, String b) {
1049     def aIntArr = parseJdkVersion(a);
1050     def bIntArr = parseJdkVersion(b);
1051 
1052     for (int i = 0; i < 4; i++) {
1053         if (aIntArr[i] < bIntArr[i]) return -1;
1054         if (aIntArr[i] > bIntArr[i]) return  1;
1055     }
1056     return 0;
1057 }
1058 
1059 // Task to verify the minimum level of Java needed to build JavaFX
1060 task verifyJava() {
1061     doLast {
1062         def status = compareJdkVersion(jdkVersion, jfxBuildJdkVersion);
1063         if (status < 0) {
1064             fail("java version mismatch: JDK version (${jdkVersion}) < minimum version (${jfxBuildJdkVersion})")
1065         } else if (status == 0) {
1066             def buildNum = Integer.parseInt(jdkBuildNumber)
1067             def minBuildNum = Integer.parseInt(jfxBuildJdkBuildnumMin)
1068             if (buildNum < minBuildNum) {
1069                 fail("JDK build number ($buildNum) < minimum build number ($minBuildNum)")
1070             }
1071         }
1072     }
1073 }
1074 
1075 // Task to check whether jfxrt.jar is present in the JDK
1076 task checkJfxrtJar {
1077     doLast {
1078         def jfxrtFile = new File("$JDK_HOME/jre/lib/ext/jfxrt.jar");
1079         if (jfxrtFile.exists()) {
1080             fail("$jfxrtFile must be removed before building sdk")
1081         }
1082     }
1083 }
1084 
1085 task updateCacheIfNeeded() {
1086     // an empty task we can add to as needed for UPDATE_STUB_CACHE
1087 }
1088 
1089 /*****************************************************************************
1090 *        Project definitions (dependencies, etc)                             *
1091 *****************************************************************************/
1092 
1093 void addJCov(p, test) {
1094     test.doFirst {
1095         def jcovJVMArgument =
1096                 "include=javafx," +
1097                 "include=com.sun.javafx," +
1098                 "include=com.sun.glass," +
1099                 "include=com.sun.openpisces," +
1100                 "include=com.sun.pisces," +
1101                 "include=com.sun.prism," +
1102                 "include=com.sun.scenario," +
1103                 "include=com.sun.webkit," +
1104                 "exclude=com," +
1105                 "exclude=java," +
1106                 "exclude=javax," +
1107                 "exclude=\"**.test\"," +
1108                 "exclude=\"**.*Test\"," +
1109                 "file=build/reports/jcov/report.xml," +
1110                 "merge=merge";
1111         test.jvmArgs("-javaagent:${p.configurations.testCompile.files.find { it.name.startsWith('jcov') }}=$jcovJVMArgument");
1112         p.mkdir p.file("build/reports/jcov")
1113     }
1114     test.doLast {
1115         def reportFile = p.file("build/reports/jcov/report.xml")
1116         if (reportFile.exists()) {
1117             p.javaexec {
1118                 workingDir = p.file("build/reports/jcov")
1119                 classpath = p.files(p.configurations.testCompile.files.find { it.name.startsWith('jcov') })
1120                 main = "com.sun.tdk.jcov.Helper"
1121                 args = [
1122                         "RepGen",
1123                         "-exclude", "\"**.test\"",
1124                         "-exclude", "\"**.*Test\"",
1125                         "-output", ".",
1126                         "-source", p.sourceSets.main.java.srcDirs.collect{p.file(it)}.join(":"),
1127                         "report.xml"
1128                 ]
1129             }
1130         }
1131     }
1132 }
1133 
1134 allprojects {
1135     // Setup the repositories that we'll download libraries from. Maven Central is
1136     // just easy for most things. The custom "ivy" repo is for downloading SWT. The way it
1137     // works is to setup the download URL such that it will resolve to the actual jar file
1138     // to download. See SWT_FILE_NAME for the name of the jar that will be used as the
1139     // "artifact" in the pattern below. Note that the closed builds use different repositories
1140     // so if you are debugging a closed-build artifact related build issue, check out the
1141     // closed gradle file instead.
1142     if (!BUILD_CLOSED) {
1143         repositories {
1144             mavenCentral()
1145             ivy {
1146                 url "http://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/plugins/"
1147                 layout "pattern", {
1148                     artifact "[artifact].[ext]"
1149                 }
1150             }
1151         }
1152     }
1153 
1154     // We want to configure all projects as java projects and use the same compile settings
1155     // etc, except for the root project which we just want to ignore (and for now media)
1156     if (project == rootProject) {
1157        return
1158     }
1159     if (project.path.startsWith(":apps")) {
1160         // Lets handle the apps tree differently, as it is a collection of ant builds,
1161         // and the ant importer collides with the 'apply plugin:java'
1162         return
1163     }
1164 
1165     // All of our projects are java projects
1166     apply plugin: "java"
1167     sourceCompatibility = 1.8
1168 
1169     // By default all of our projects require junit for testing so we can just
1170     // setup this dependency here.
1171     dependencies {
1172         testCompile group: "junit", name: "junit", version: "4.8.2"
1173         if (BUILD_CLOSED && DO_JCOV)  {
1174             testCompile name: "jcov"
1175         }
1176     }
1177 
1178     // Compile and run tests against the jfxrt.jar in the built sdk of the host machine
1179     def sdkDir = "${rootProject.buildDir}/sdk"
1180     def jfxrtJar = "$sdkDir/rt/lib/ext/jfxrt.jar"
1181     def testJfxrtJar = DO_BUILD_SDK_FOR_TEST ? jfxrtJar : jfxrtJarFromSdk
1182 
1183     // At the moment the ASM library shipped with Gradle that is used to
1184     // discover the different test classes fails on Java 8, so in order
1185     // to have sourceCompatibility set to 1.8 I have to also turn scanForClasses off
1186     // and manually specify the includes / excludes. At the moment we use
1187     // Java 7 but when we switch to 8 this will be needed, and probably again when
1188     // we start building with Java 9.
1189     test {
1190         jvmArgs("-Djava.ext.dirs=");
1191         executable = JAVA;
1192         enableAssertions = true;
1193         testLogging.exceptionFormat = "full";
1194         scanForTestClasses = false;
1195         include("**/*Test.*");
1196         if (BUILD_CLOSED && DO_JCOV) {
1197             addJCov(project, test)
1198         }
1199         classpath = files(testJfxrtJar) + classpath
1200         if (IS_HEADLESS_TEST) {
1201             systemProperty 'glass.platform', 'Monocle'
1202             systemProperty 'monocle.platform', 'Headless'
1203             systemProperty 'prism.order', 'sw'
1204             systemProperty 'com.sun.javafx.gestures.zoom', 'true'
1205             systemProperty 'com.sun.javafx.gestures.rotate', 'true'
1206             systemProperty 'com.sun.javafx.gestures.scroll', 'true'
1207         }
1208     }
1209 
1210     compileTestJava {
1211         classpath = files(testJfxrtJar) + classpath
1212     }
1213 
1214     // Exclude any non-public-API classes from having javadoc generated. This block is used
1215     // when generating JavaDocs for a specific project. When generating the JavaDocs for the
1216     // entire SDK, a different javadoc command is used (see the javadoc task on the top level)
1217     javadoc {
1218         enabled = IS_BUILD_JAVADOC
1219         exclude("com/**/*", "Compile*", "javafx/builder/**/*", "javafx/scene/accessibility/**/*");
1220         executable = JAVADOC;
1221         options.windowTitle("JavaFX Project ${project.name} ${RELEASE_NAME}")
1222         if (BUILD_CLOSED) {
1223             options.linksOffline(JDK_DOCS, JDK_DOCS_CLOSED);
1224         } else {
1225             options.links(JDK_DOCS);
1226         }
1227         options.addBooleanOption("XDignore.symbol.file").setValue(true);
1228         options.addBooleanOption("Xdoclint:none").setValue(!IS_DOC_LINT);
1229         options.addBooleanOption("javafx").setValue(true);
1230         options.addBooleanOption("use").setValue(true);
1231         // All doc-files are located in src/main/docs because Gradle's javadoc doesn't copy
1232         // over the doc-files if they are embedded with the sources. I find this arrangement
1233         // somewhat cleaner anyway (never was a fan of mixing javadoc files with the sources)
1234         doLast {
1235             copy {
1236                 from "src/main/docs"
1237                 into "$buildDir/docs/javadoc"
1238             }
1239         }
1240     }
1241 }
1242 
1243 // The "base" project is our first module and the most basic one required for
1244 // all other modules. It is useful even for non-GUI applications.
1245 project(":base") {
1246     dependencies {
1247         compile BUILD_SRC
1248     }
1249 
1250     // We need to take the VersionInfo.java file and replace the various
1251     // properties within it
1252     def replacements = [
1253         "BUILD_TIMESTAMP": new java.util.Date(),
1254         "HUDSON_JOB_NAME": HUDSON_JOB_NAME,
1255         "HUDSON_BUILD_NUMBER": HUDSON_BUILD_NUMBER,
1256         "PROMOTED_BUILD_NUMBER": PROMOTED_BUILD_NUMBER,
1257         "PRODUCT_NAME": PRODUCT_NAME,
1258         "RAW_VERSION": RAW_VERSION,
1259         "RELEASE_NAME": RELEASE_NAME,
1260         "RELEASE_MILESTONE": RELEASE_MILESTONE];
1261     task processVersionInfo(type: Copy, description: "Replace params in VersionInfo and copy file to destination") {
1262         doFirst { mkdir "$buildDir/generated-src/version-info" }
1263         from "src/main/version-info"
1264         into "$buildDir/generated-src/version-info/com/sun/javafx/runtime"
1265         filter {line->
1266             replacements.each() {k, v ->
1267                 line = line.replace("@$k@", v.toString());
1268             }
1269             line
1270         }
1271     }
1272 
1273     compileJava.dependsOn updateCacheIfNeeded
1274     compileJava.dependsOn verifyJava
1275 
1276     // Make sure to include $buildDir/generated-src/version-info that we previously created.
1277     // We DO NOT want to include src/main/version-info
1278     if (System.getProperty("jfx.build.jdk.defenders", "true").equals("true")) {
1279         sourceSets.main.java.srcDirs += "src/main/java8"
1280     } else {
1281         sourceSets.main.java.srcDirs += "src/main/java7"
1282     }
1283 
1284     if (IS_COMPILE_JFR) {
1285         sourceSets.main.java.srcDirs += "src/main/java-jfr"
1286     }
1287 
1288     sourceSets.main.java.srcDirs += "$buildDir/generated-src/version-info"
1289 
1290     compileJava.dependsOn processVersionInfo
1291 }
1292 
1293 // The graphics module is needed for any graphical JavaFX application. It requires
1294 // the base module and includes the scene graph, layout, css, prism, windowing, etc.
1295 // This is a fairly complicated module. There are many different types of native components
1296 // that all need to be compiled.
1297 project(":graphics") {
1298     // Workaround for lack of Antlr 3 support in Gradle. By defining a configuration,
1299     // we can then give it a class path and use that classpath to execute a java command
1300     getConfigurations().create("antlr3");
1301 
1302     sourceSets {
1303         main
1304         test
1305         stub
1306     }
1307 
1308     dependencies {
1309         compile project(":base"), BUILD_SRC
1310         compile name: SWT_FILE_NAME
1311         stubCompile group: "junit", name: "junit", version: "4.8.2",
1312         project(":base").sourceSets.test.output, sourceSets.main.output
1313         antlr3 group: "org.antlr", name: "antlr", version: "3.1.3"
1314         antlr3 group: "org.antlr", name: "antlr-runtime",  version: "3.1.3"
1315         antlr3 group: "org.antlr", name: "stringtemplate", version: "3.2"
1316     }
1317 
1318     // Create a single "native" task which will depend on all the individual native tasks for graphics
1319     project.ext.nativeAllTask = task("native", group: "Build", description: "Compiles and Builds all native libraries for Graphics");
1320     project.ext.cleanNativeAllTask = task("cleanNative", group: "Build", description: "Clean all native libraries and objects for Graphics");
1321 
1322     // Add tasks for native compilation
1323     addNative(project, "glass");
1324     addNative(project, "prism")
1325     addNative(project, "prismSW")
1326     addNative(project, "font")
1327     addNative(project, "iio")
1328     addNative(project, "prismES2")
1329 
1330     if (IS_COMPILE_PANGO) {
1331         addNative(project, "fontFreetype")
1332         addNative(project, "fontPango")
1333     }
1334 
1335     if (IS_WINDOWS) {
1336         addNative(project, "prismD3D")
1337         // TODO need to hook this up to be executed only if PassThroughVS.h is missing or PassThroughVS.hlsl is changed
1338         task generateD3DHeaders(group: "Build") {
1339             enabled = IS_WINDOWS
1340             dependsOn javahWinPrismD3D
1341             inputs.file "src/main/native-prism-d3d/hlsl/Mtl1PS.hlsl"
1342             inputs.file "src/main/native-prism-d3d/hlsl/Mtl1VS.hlsl"
1343             inputs.file "src/main/native-prism-d3d/PassThroughVS.hlsl"
1344             outputs.dir "$buildDir/headers/PrismD3D/"
1345             outputs.dir "$buildDir/headers/PrismD3D/hlsl/"
1346             description = "Generate headers by compiling hlsl files"
1347             doLast {
1348                 mkdir file("$buildDir/headers/PrismD3D/hlsl")
1349                 def PS_3D_SRC = file("src/main/native-prism-d3d/hlsl/Mtl1PS.hlsl")
1350                 def VS_3D_SRC = file("src/main/native-prism-d3d/hlsl/Mtl1VS.hlsl")
1351                 def PASSTHROUGH_VS_SRC = file("src/main/native-prism-d3d/PassThroughVS.hlsl")
1352                 def jobs = [
1353                         ["$FXC", "/nologo", "/T", "vs_3_0", "/Fh", "$buildDir/headers/PrismD3D/PassThroughVS.h", "/E", "passThrough", "$PASSTHROUGH_VS_SRC"],
1354                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS.h", "/DSpec=0", "/DSType=0", "$PS_3D_SRC"],
1355                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_i.h", "/DSpec=0", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"],
1356                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1n.h", "/DSpec=1", "/DSType=0", "$PS_3D_SRC"],
1357                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2n.h", "/DSpec=2", "/DSType=0", "$PS_3D_SRC"],
1358                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3n.h", "/DSpec=3", "/DSType=0", "$PS_3D_SRC"],
1359                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1t.h", "/DSpec=1", "/DSType=1", "$PS_3D_SRC"],
1360                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2t.h", "/DSpec=2", "/DSType=1", "$PS_3D_SRC"],
1361                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3t.h", "/DSpec=3", "/DSType=1", "$PS_3D_SRC"],
1362                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1c.h", "/DSpec=1", "/DSType=2", "$PS_3D_SRC"],
1363                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2c.h", "/DSpec=2", "/DSType=2", "$PS_3D_SRC"],
1364                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3c.h", "/DSpec=3", "/DSType=2", "$PS_3D_SRC"],
1365                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1m.h", "/DSpec=1", "/DSType=3", "$PS_3D_SRC"],
1366                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2m.h", "/DSpec=2", "/DSType=3", "$PS_3D_SRC"],
1367                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3m.h", "/DSpec=3", "/DSType=3", "$PS_3D_SRC"],
1368                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1n.h", "/DSpec=1", "/DSType=0", "/DBump=1", "$PS_3D_SRC"],
1369                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2n.h", "/DSpec=2", "/DSType=0", "/DBump=1", "$PS_3D_SRC"],
1370                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3n.h", "/DSpec=3", "/DSType=0", "/DBump=1", "$PS_3D_SRC"],
1371                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1t.h", "/DSpec=1", "/DSType=1", "/DBump=1", "$PS_3D_SRC"],
1372                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2t.h", "/DSpec=2", "/DSType=1", "/DBump=1", "$PS_3D_SRC"],
1373                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3t.h", "/DSpec=3", "/DSType=1", "/DBump=1", "$PS_3D_SRC"],
1374                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1c.h", "/DSpec=1", "/DSType=2", "/DBump=1", "$PS_3D_SRC"],
1375                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2c.h", "/DSpec=2", "/DSType=2", "/DBump=1", "$PS_3D_SRC"],
1376                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3c.h", "/DSpec=3", "/DSType=2", "/DBump=1", "$PS_3D_SRC"],
1377                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1m.h", "/DSpec=1", "/DSType=3", "/DBump=1", "$PS_3D_SRC"],
1378                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2m.h", "/DSpec=2", "/DSType=3", "/DBump=1", "$PS_3D_SRC"],
1379                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3m.h", "/DSpec=3", "/DSType=3", "/DBump=1", "$PS_3D_SRC"],
1380                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1ni.h", "/DSpec=1", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"],
1381                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2ni.h", "/DSpec=2", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"],
1382                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3ni.h", "/DSpec=3", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"],
1383                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1ti.h", "/DSpec=1", "/DSType=1", "/DIllumMap=1", "$PS_3D_SRC"],
1384                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2ti.h", "/DSpec=2", "/DSType=1", "/DIllumMap=1", "$PS_3D_SRC"],
1385                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3ti.h", "/DSpec=3", "/DSType=1", "/DIllumMap=1", "$PS_3D_SRC"],
1386                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1ci.h", "/DSpec=1", "/DSType=2", "/DIllumMap=1", "$PS_3D_SRC"],
1387                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2ci.h", "/DSpec=2", "/DSType=2", "/DIllumMap=1", "$PS_3D_SRC"],
1388                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3ci.h", "/DSpec=3", "/DSType=2", "/DIllumMap=1", "$PS_3D_SRC"],
1389                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1mi.h", "/DSpec=1", "/DSType=3", "/DIllumMap=1", "$PS_3D_SRC"],
1390                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2mi.h", "/DSpec=2", "/DSType=3", "/DIllumMap=1", "$PS_3D_SRC"],
1391                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3mi.h", "/DSpec=3", "/DSType=3", "/DIllumMap=1", "$PS_3D_SRC"],
1392                         ["$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"],
1393                         ["$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"],
1394                         ["$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"],
1395                         ["$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"],
1396                         ["$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"],
1397                         ["$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"],
1398                         ["$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"],
1399                         ["$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"],
1400                         ["$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"],
1401                         ["$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"],
1402                         ["$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"],
1403                         ["$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"],
1404                         ["$FXC", "/nologo", "/T", "vs_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1VS_Obj.h", "/DVertexType=ObjVertex", "$VS_3D_SRC"]
1405                 ]
1406                 final ExecutorService executor = Executors.newFixedThreadPool(Integer.parseInt(project.NUM_COMPILE_THREADS.toString()));
1407                 final CountDownLatch latch = new CountDownLatch(jobs.size());
1408                 List futures = new ArrayList<Future>();
1409                 jobs.each { cmd ->
1410                     futures.add(executor.submit(new Runnable() {
1411                         @Override public void run() {
1412                             try {
1413                                 exec {
1414                                     commandLine cmd
1415                                 }
1416                             } finally {
1417                                 latch.countDown();
1418                             }
1419                         }
1420                     }));
1421                 }
1422                 latch.await();
1423                 // Looking for whether an exception occurred while executing any of the futures.
1424                 // By calling "get()" on each future an exception will be thrown if one had occurred
1425                 // on the background thread.
1426                 futures.each {it.get();}
1427             }
1428         }
1429 
1430         ccWinPrismD3D.dependsOn generateD3DHeaders
1431     }
1432 
1433     // The Decora and Prism JSL files have to be generated in a very specific set of steps.
1434     //      1) Compile the *Compile.java classes. These live in src/main/jsl-* and will be
1435     //         output to $buildDir/classes/jsl-compilers/* (where * == decora or prism).
1436     //      2) Generate source files from the JSL files contained in src/main/jsl-*. These
1437     //         will be output to $buildDir/generated-src/jsl-*
1438     //      3) Compile the JSL Java sources in $buildDir/generated-src/jsl-* and put the output
1439     //         into classes/jsl-*
1440     //      4) Compile the native JSL sources in $buildDir/generated-src/jsl-* and put the obj
1441     //         files into native/jsl-* and the resulting library into libs/jsl-*.dll|so|dylib
1442     //      5) Modify the jar step to include classes/jsl-*
1443     // The native library must be copied over during SDK creation time in the "sdk" task. In
1444     // addition to these steps, the clean task is created. Note that I didn't bother to create
1445     // a new task for each of the decora files, preferring instead just to create a rule?? Also
1446     // need "clean" tasks for each compile task.
1447 
1448     addJSL(project, "Decora", "com/sun/scenario/effect/impl/hw/d3d/hlsl") { sourceDir, destinationDir ->
1449         [[fileName: "ColorAdjust", generator: "CompileJSL", outputs: "-all"],
1450          [fileName: "Brightpass", generator: "CompileJSL", outputs: "-all"],
1451          [fileName: "SepiaTone", generator: "CompileJSL", outputs: "-all"],
1452          [fileName: "PerspectiveTransform", generator: "CompileJSL", outputs: "-all"],
1453          [fileName: "DisplacementMap", generator: "CompileJSL", outputs: "-all"],
1454          [fileName: "InvertMask", generator: "CompileJSL", outputs: "-all"],
1455          [fileName: "Blend", generator: "CompileBlend", outputs: "-all"],
1456          [fileName: "PhongLighting", generator: "CompilePhong", outputs: "-all"],
1457          [fileName: "LinearConvolve", generator: "CompileLinearConvolve", outputs: "-hw"],
1458          [fileName: "LinearConvolveShadow", generator: "CompileLinearConvolve", outputs: "-hw"]].each { settings ->
1459             javaexec {
1460                 executable = JAVA
1461                 workingDir = "modules/graphics"
1462                 main = settings.generator
1463                 classpath = configurations.compile + configurations.antlr3
1464                 classpath += files("$buildDir/classes/main")
1465                 classpath += files("$buildDir/classes/jsl-compilers/decora")
1466                 args = ["-i", sourceDir, "-o", destinationDir, "-t", "-pkg", "com/sun/scenario/effect", "$settings.outputs", "$settings.fileName"]
1467                 jvmArgs "-Djava.ext.dirs="
1468             }
1469         }
1470     }
1471 
1472     task generateDecoraNativeHeaders(type: JavaHeaderTask, dependsOn: compileDecoraJavaShaders) {
1473         description = "Generates JNI Headers for Decora SSE Natives"
1474         source file("$buildDir/classes/jsl-decora")
1475         source file("$buildDir/classes/main")
1476         include("com/sun/scenario/effect/impl/sw/sse/*");
1477         classpath = files("$buildDir/classes/main", "$buildDir/classes/jsl-decora")
1478         output = file("$buildDir/generated-src/headers/jsl-decora")
1479     }
1480 
1481     task nativeDecora(dependsOn: compileDecoraHLSLShaders, group: "Build") {
1482         description = "Generates JNI headers, compiles, and builds native dynamic library for Decora"
1483     }
1484     task cleanNativeDecora(type: Delete, group: "Build") {
1485         description = "Clean native objects for Decora"
1486     }
1487 
1488     def headerDir = file("$buildDir/generated-src/headers/jsl-decora")
1489     def nativeRootDir = project.file("$project.buildDir/native/jsl-decora")
1490     def libRootDir = project.file("$project.buildDir/libs/jsl-decora")
1491     // For each compile target, create cc and link tasks
1492     compileTargets { t ->
1493         def target = t.name
1494         def upperTarget = t.upper
1495         def capitalTarget = t.capital
1496         def targetProperties = rootProject.ext[upperTarget];
1497         def library = targetProperties.library
1498         def properties = targetProperties.get('decora')
1499         def nativeDir = file("$nativeRootDir/$target");
1500 
1501         def variants = properties.containsKey("variants") ? properties.variants : [""];
1502         variants.each { variant ->
1503             def variantProperties = variant == "" ? properties : properties.get(variant)
1504             def capitalVariant = variant.capitalize()
1505             def ccOutput = variant == "" ? nativeDir : file("$nativeDir/$variant")
1506 
1507             def ccTask = task("compileDecoraNativeShaders$capitalTarget$capitalVariant", type: CCTask, dependsOn: generateDecoraNativeHeaders) {
1508                 description = "Compiles Decora SSE natives for ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}"
1509                 matches = ".*\\.cc"
1510                 source file("$buildDir/generated-src/jsl-decora")
1511                 source file("modules/graphics/src/main/native-decora")
1512                 headers = headerDir
1513                 params.addAll(variantProperties.ccFlags)
1514                 output(ccOutput)
1515                 compiler = variantProperties.compiler
1516                 cleanNativeDecora.delete ccOutput
1517             }
1518 
1519             def linkTask = task("linkDecoraNativeShaders$capitalTarget$capitalVariant", type: LinkTask, dependsOn: ccTask) {
1520                 description = "Creates native dynamic library for Decora SSE ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}"
1521                 objectDir = ccOutput
1522                 linkParams.addAll(variantProperties.linkFlags)
1523                 lib = file("$libRootDir/$t.name/${library(variantProperties.lib)}")
1524                 linker = variantProperties.linker
1525                 cleanNativeDecora.delete "$libRootDir/$t.name/"
1526             }
1527 
1528             if (IS_WINDOWS && target == "win") {
1529                 def rcTask = project.task("rcDecoraNativeShaders$capitalTarget$capitalVariant", type: CompileResourceTask, dependsOn: generateDecoraNativeHeaders) {
1530                     description = "Compiles native sources for Decora SSE"
1531                     matches = ".*\\.rc"
1532                     compiler = variantProperties.rcCompiler
1533                     source(variantProperties.rcSource)
1534                     if (variantProperties.rcFlags) {
1535                         rcParams.addAll(variantProperties.rcFlags)
1536                     }
1537                     output(ccOutput)
1538                 }
1539                 linkTask.dependsOn rcTask;
1540             }
1541 
1542             nativeDecora.dependsOn(linkTask)
1543         }
1544     }
1545 
1546     // Prism JSL
1547     addJSL(project, "Prism", "com/sun/prism/d3d/hlsl") { sourceDir, destinationDir ->
1548         def inputFiles = fileTree(dir: sourceDir)
1549         inputFiles.include "**/*.jsl"
1550         inputFiles.each { file ->
1551             javaexec {
1552                 executable = JAVA
1553                 workingDir = "modules/graphics"
1554                 main = "CompileJSL"
1555                 classpath = configurations.compile + configurations.antlr3
1556                 classpath += files("$buildDir/classes/jsl-compilers/prism", "modules/graphics/src/main/jsl-prism") // for the .stg
1557                 args = ["-i", sourceDir, "-o", destinationDir, "-t", "-pkg", "com/sun/prism", "-d3d", "-es2", "-name", "$file"]
1558                 jvmArgs "-Djava.ext.dirs="
1559             }
1560         }
1561     }
1562 
1563     classes.dependsOn compilePrismJavaShaders;
1564     nativePrism.dependsOn compilePrismHLSLShaders;
1565 
1566     project.nativeAllTask.dependsOn nativeDecora
1567     project.cleanNativeAllTask.dependsOn cleanNativeDecora
1568     assemble.dependsOn nativeDecora
1569     processResources.dependsOn processDecoraShaders, processPrismShaders
1570 
1571     test {
1572         def cssDir = file("$buildDir/classes/main/javafx")
1573         jvmArgs "-Djava.ext.dirs=", "-Djavafx.toolkit=com.sun.javafx.pgstub.StubToolkit",
1574             "-DCSS_META_DATA_TEST_DIR=$cssDir"
1575         enableAssertions = true
1576         testLogging.exceptionFormat = "full"
1577         scanForTestClasses = false
1578         include "**/*Test.*"
1579         if (BUILD_CLOSED && DO_JCOV) {
1580             addJCov(project, test)
1581         }
1582     }
1583 
1584     // To enable the IDEs to all be happy (no red squiggles) we need to have the libraries
1585     // available in some known location. Maybe in the future the Gradle plugins to each
1586     // of the IDEs will be good enough that we won't need this hack anymore.
1587     classes << {
1588         // Copy all of the download libraries to the libs directory for the sake of the IDEs
1589         File libsDir = rootProject.file("build/libs");
1590 
1591         // In some IDEs (Eclipse for example), touching these libraries cauese a full build
1592         // within the IDE.  When gradle is used outside of the IDE, for example to build the
1593         // native code, a full rebuild is caused within the IDE.  The fix is to check for the
1594         // lib directory and not copy the files
1595         //
1596         // This means that in order to update the dependent libraries for the IDE's, a clean
1597         // build is required
1598         //
1599         if (libsDir.exists()) return;
1600         libsDir.mkdirs();
1601         for (File f : [configurations.compile.files, configurations.antlr3.files].flatten()) {
1602             copy {
1603                 into libsDir
1604                 from f.getParentFile()
1605                 include "**/antlr-3.1.3.jar"
1606                 include "**/stringtemplate-3.2.jar"
1607                 include "**/antlr-runtime-3.1.3.jar"
1608                 includeEmptyDirs = false
1609             }
1610             // Have to rename the swt jar because it is some platform specific name but
1611             // for the sake of the IDEs we need to have a single stable name that works
1612             // on every platform
1613             copy {
1614                 into libsDir
1615                 from f.getParentFile()
1616                 include "**/*swt*.jar"
1617                 includeEmptyDirs = false
1618                 rename ".*swt.*jar", "swt-debug\\.jar"
1619             }
1620         }
1621     }
1622 }
1623 
1624 project(":controls") {
1625     dependencies {
1626         compile BUILD_SRC, project(":base"), project(":graphics")
1627         // TODO not sure how to specify this? processResources project(":base"), project(":graphics")
1628         testCompile project(":graphics").sourceSets.test.output
1629         testCompile project(":base").sourceSets.test.output
1630     }
1631 
1632     test {
1633         def cssDir = file("$buildDir/classes/main/javafx")
1634         jvmArgs "-Djavafx.toolkit=com.sun.javafx.pgstub.StubToolkit",
1635             "-DCSS_META_DATA_TEST_DIR=$cssDir"
1636     }
1637 
1638     // TODO Css2Bin really should be moved out and put into buildSrc if it can be
1639     // TODO could change script to dynamically locate all .css files and create bss for them, probably better
1640     // TODO also not sure there is any benefit to having css files in the jfxrt.jar at all
1641     processResources << {
1642         ["$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/caspian.css",
1643         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/caspian-no-transparency.css",
1644         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/embedded-qvga.css",
1645         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/embedded.css",
1646         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/fxvk.css",
1647         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/highcontrast.css",
1648         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/modena/modena.css",
1649         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/modena/modena-no-transparency.css",
1650         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/modena/touch.css"].each { css ->
1651             javaexec {
1652                 executable = JAVA
1653                 workingDir = "modules/controls"
1654                 classpath files("$buildDir/classes/main",
1655                         project(":graphics").sourceSets.main.output,
1656                         project(":base").sourceSets.main.output)
1657                 main = "com.sun.javafx.css.parser.Css2Bin"
1658                 args css
1659                 jvmArgs "-Djava.ext.dirs="
1660             }
1661         }
1662     }
1663 }
1664 
1665 project(":extensions") {
1666     dependencies {
1667         compile BUILD_SRC, project(":base"), project(":graphics")
1668     }
1669 }
1670 
1671 project(":swing") {
1672     /* should not be built, but needed in builders and JMX
1673     tasks.all {
1674         if (!COMPILE_SWING) it.enabled = false
1675     }
1676     */
1677     dependencies {
1678         compile BUILD_SRC, project(":base"), project(":graphics")
1679     }
1680     test {
1681         enabled = IS_FULL_TEST && IS_AWT_TEST
1682     }
1683 }
1684 
1685 project(":swt") {
1686     tasks.all {
1687         if (!COMPILE_SWT) it.enabled = false
1688     }
1689     dependencies {
1690         compile BUILD_SRC, project(":base"), project(":graphics")
1691         compile name: SWT_FILE_NAME
1692     }
1693 }
1694 
1695 project(":fxml") {
1696     dependencies {
1697         compile BUILD_SRC, project(":base"), project(":graphics"),
1698                 project(":controls"), project(":swt"), project(":swing")
1699         testCompile project(":graphics").sourceSets.test.output
1700     }
1701     test {
1702         // StubToolkit is not *really* needed here, but because some code inadvertently invokes performance
1703         // tracker and this attempts to fire up the toolkit and this looks for native libraries and fails,
1704         // we have to use the stub toolkit for now.
1705         jvmArgs "-Djavafx.toolkit=com.sun.javafx.pgstub.StubToolkit"
1706         classpath += files("$JDK_HOME/jre/lib/ext/nashorn.jar")
1707     }
1708 }
1709 
1710 project(":builders") {
1711     sourceCompatibility = 1.7
1712 
1713     if (!COMPILE_SWING) sourceSets.main.java.exclude ("**/swing/**")
1714     if (!COMPILE_SWT)   sourceSets.main.java.exclude ("**/swt/**")
1715 
1716     dependencies {
1717         compile BUILD_SRC, project(":base"), project(":graphics"),
1718                 project(":controls"), project(":swt"), project(":swing"), project(":media"), project(":web")
1719         testCompile project(":graphics").sourceSets.test.output
1720     }
1721     test {
1722         // StubToolkit is not *really* needed here, but because some code inadvertently invokes performance
1723         // tracker and this attempts to fire up the toolkit and this looks for native libraries and fails,
1724         // we have to use the stub toolkit for now.
1725         jvmArgs "-Djavafx.toolkit=com.sun.javafx.pgstub.StubToolkit"
1726     }
1727 }
1728 
1729 project(":jmx") {
1730     dependencies {
1731         compile project(":base")
1732         compile project(":graphics")
1733         compile project(":swing")
1734         compile project(":media")
1735     }
1736 
1737     // Tests are disabled until RT-33926 can be fixed
1738     test.enabled = false
1739 
1740     if (!DO_BUILD_SDK_FOR_TEST) {
1741        def javafxMxJar = new File(TEST_SDK_DIR, "lib/javafx-mx.jar")
1742        [test, compileTestJava].each {
1743            it.classpath = files(javafxMxJar) + it.classpath
1744        }
1745     }
1746 }
1747 
1748 // This project is for system tests that need to run with a full SDK.
1749 // Most of them display a stage or do other things that preclude running
1750 // them in a shared JVM or as part of the "smoke test" run (which must
1751 // not pop up any windows or use audio). As such, they are only enabled
1752 // when FULL_TEST is specified, and each test runs in its own JVM
1753 project(":systemTests") {
1754     test {
1755         enabled = IS_FULL_TEST
1756         if (!IS_USE_ROBOT) {
1757             // Disable all robot-based visual tests
1758             exclude("test/robot/**");
1759             exclude("**/helloworld/*.*");
1760             exclude("**/javafx/embed/swing/*.*");
1761             exclude("**/javafx/scene/layout/*.*");
1762             exclude("**/test3d/*.*");
1763             exclude("**/painttest/*.*");
1764             exclude("**/renderlock/*.*");
1765         }
1766         if (!IS_AWT_TEST) {
1767             // Disable all AWT-based tests
1768             exclude("**/javafx/embed/swing/*.*");
1769             exclude("**/com/sun/javafx/application/Swing*.*");
1770         }
1771 
1772         dependencies {
1773             testCompile project(":graphics").sourceSets.test.output
1774             testCompile project(":base").sourceSets.test.output
1775             testCompile project(":controls").sourceSets.test.output
1776         }
1777 
1778         forkEvery = 1
1779     }
1780 }
1781 
1782 project(":fxpackager") {
1783     tasks.all {
1784         if (!COMPILE_FXPACKAGER) it.enabled = false
1785     }
1786     // fxpackager has a dependency on ant in order to build the ant jar,
1787     // and as such needs to point to the apache binary repository
1788     if (!BUILD_CLOSED) {
1789         repositories {
1790             maven {
1791                 url "https://repository.apache.org"
1792             }
1793         }
1794     }
1795 
1796     dependencies {
1797         compile group: "org.apache.ant", name: "ant", version: "1.8.2"
1798     }
1799 
1800     // When producing the jar, we need to relocate a few class files
1801     // from their normal location to a resources/classes or resources/web-files
1802     // location
1803     jar {
1804         includeEmptyDirs = false
1805         archiveName = "ant-javafx.jar"
1806         eachFile { FileCopyDetails details ->
1807             if (details.path.startsWith("com/javafx/main")) {
1808                 details.path = "resources/classes/$details.path"
1809             }
1810         }
1811     }
1812 
1813     // The "man" task will create a $buildDir/man containing the man
1814     // files for the system being built
1815     task man(type: Copy) {
1816         includeEmptyDirs = false
1817         enabled = (IS_LINUX || IS_MAC) && COMPILE_FXPACKAGER
1818         from "src/main/man"
1819         into "$buildDir/man"
1820         exclude "**/*.html"
1821         if (IS_MAC) exclude "**/ja_JP.UTF-8/**"
1822     }
1823     processResources.dependsOn man
1824 
1825     // Compile the native launchers. These are included in ant-javafx.jar.
1826     if (IS_WINDOWS && COMPILE_FXPACKAGER) {
1827         task buildWinLauncher(type: CCTask, group: "Build") {
1828             description = "Compiles native sources for the application co-bundle launcher";
1829             matches = "WinLauncher\\.cpp";
1830             params.addAll(WIN.launcher.ccFlags);
1831             output(file("$buildDir/native/WinLauncher"));
1832             source(file("src/main/native/launcher/win"));
1833             compiler = WIN.launcher.compiler
1834             exe = true;
1835             linkerOptions.addAll(WIN.launcher.linkFlags);
1836             doLast {
1837                 copy {
1838                     from "$buildDir/native/WinLauncher/WinLauncher.exe"
1839                     from "$MSVCR"
1840                     from "$MSVCP"
1841                     into "$buildDir/classes/main/com/oracle/tools/packager/windows"
1842                 }
1843             }
1844         }
1845         task compileWinLibrary(type: CCTask, group: "Build") {
1846             description = "Compiles native sources for the application co-bundle launcher library";
1847             matches = ".*\\.cpp"
1848             source(file("src/main/native/library/common"));
1849             params.addAll(WIN.launcherlibrary.ccFlags)
1850             output(file("$buildDir/native/WinLauncher/obj"));
1851             compiler = WIN.launcherlibrary.compiler
1852         }
1853         task linkWinLibrary(type: LinkTask, group: "Build", dependsOn: compileWinLibrary) {
1854             description = "Links native sources for the application co-bundle launcher library";
1855             objectDir = file("$buildDir/native/WinLauncher/obj")
1856             linkParams.addAll(WIN.launcherlibrary.linkFlags);
1857             lib = file("$buildDir/native/WinLauncher/packager.dll")
1858             linker = WIN.launcherlibrary.linker
1859             doLast {
1860                 copy {
1861                     from "$buildDir/native/WinLauncher/packager.dll"
1862                     into "$buildDir/classes/main/com/oracle/tools/packager/windows"
1863                 }
1864             }
1865         }
1866         task buildWinLauncherSvc(type: CCTask, group: "Build") {
1867             description = "Compiles native sources for the application co-bundle launcher";
1868             matches = "WinLauncherSvc\\.cpp";
1869             params.addAll(WIN.launcher.ccFlags);
1870             output(file("$buildDir/native/WinLauncherSvc"));
1871             source(file("src/main/native/service/win"));
1872             compiler = WIN.launcher.compiler
1873             exe = true;
1874             linkerOptions.addAll(WIN.launcher.linkFlags);
1875             doLast {
1876                 copy {
1877                     from "$buildDir/native/WinLauncherSvc/WinLauncherSvc.exe"
1878                     into "$buildDir/classes/main/com/oracle/tools/packager/windows"
1879                 }
1880             }
1881         }
1882         task buildIconSwap(type: CCTask, group: "Build") {
1883             description = "Compiles native sources for the application co-bundle launcher"
1884             matches = "IconSwap\\.cpp"
1885             params.addAll(WIN.iconLauncher.ccFlags)
1886             output(file("$buildDir/native/IconSwap"))
1887             source file("src/main/native/tools/win")
1888             compiler = WIN.launcher.compiler
1889             exe = true
1890             linkerOptions.addAll(WIN.iconLauncher.linkFlags)
1891             doLast {
1892                 copy {
1893                     from "$buildDir/native/IconSwap/IconSwap.exe"
1894                     into "$buildDir/classes/main/com/oracle/tools/packager/windows"
1895                 }
1896             }
1897         }
1898         task compileLauncher(dependsOn: [buildWinLauncher, linkWinLibrary, buildWinLauncherSvc, buildIconSwap])
1899         jar.dependsOn compileLauncher;
1900     } else if (IS_MAC && COMPILE_FXPACKAGER) {
1901         task buildMacLauncher(type: CCTask, group: "Build") {
1902             description = "Compiles native sources for the application co-bundle launcher"
1903             matches = ".*\\.m"
1904             source file("src/main/native/launcher/mac")
1905             params.addAll(MAC.launcher.ccFlags)
1906             compiler = MAC.launcher.compiler
1907             output(file("$buildDir/classes/main/com/oracle/tools/packager/mac"))
1908             eachOutputFile = { f ->
1909                 return new File(f.getParent(), "JavaAppLauncher")
1910             }
1911         }
1912         task compileMacLibrary(type: CCTask, group: "Build") {
1913             description = "Compiles native sources for the application co-bundle launcher library"
1914             matches = ".*\\.cpp|.*\\.mm"
1915             source file("src/main/native/library/common");
1916             params.addAll(MAC.launcherlibrary.ccFlags)
1917             compiler = MAC.launcherlibrary.compiler
1918             output(file("$buildDir/native/maclauncher/obj"))
1919         }
1920         task linkMacLibrary(type: LinkTask, group: "Build", dependsOn: compileMacLibrary) {
1921             description = "Links native sources for the application co-bundle launcher library"
1922             objectDir = file("$buildDir/native/maclauncher/obj")
1923             linkParams.addAll(MAC.launcherlibrary.linkFlags)
1924             linker = MAC.launcherlibrary.linker
1925             lib = file("$buildDir/classes/main/com/oracle/tools/packager/mac/libpackager.dylib")
1926         }
1927         task compileLauncher(dependsOn: [buildMacLauncher, linkMacLibrary])
1928         jar.dependsOn compileLauncher;
1929     } else if (IS_LINUX && COMPILE_FXPACKAGER) {
1930         task compileLinuxLauncher(type: CCTask, group: "Build") {
1931             description = "Compiles native sources for the application co-bundle launcher"
1932             matches = ".*\\.cpp"
1933             source file("src/main/native/launcher/linux")
1934             params.addAll(LINUX.launcher.ccFlags)
1935             compiler = LINUX.launcher.compiler
1936             output(file("$buildDir/native/linuxlauncher/launcherobj"))
1937         }
1938         task linkLinuxLauncher(type: LinkTask, dependsOn: compileLinuxLauncher, group: "Build") {
1939             description = "Links native dynamic library for the application co-bundle launcher"
1940             objectDir = file("$buildDir/native/linuxlauncher/launcherobj")
1941             linkParams.addAll(LINUX.launcher.linkFlags)
1942             linker = LINUX.launcher.linker
1943             lib = file("$buildDir/classes/main/com/oracle/tools/packager/linux/JavaAppLauncher")
1944         }
1945         task compileLinuxLibrary(type: CCTask, group: "Build") {
1946             description = "Compiles native sources for the application co-bundle launcher library"
1947             matches = ".*\\.cpp"
1948             source file("src/main/native/library/common")
1949             params.addAll(LINUX.launcherlibrary.ccFlags)
1950             compiler = LINUX.launcherlibrary.compiler
1951             output(file("$buildDir/native/linuxlauncher/obj"))
1952         }
1953         task linkLinuxLibrary(type: LinkTask, dependsOn: compileLinuxLibrary, group: "Build") {
1954             description = "Links native dynamic library for the application co-bundle launcher library"
1955             objectDir = file("$buildDir/native/linuxlauncher/obj")
1956             linkParams.addAll(LINUX.launcherlibrary.linkFlags)
1957             linker = LINUX.launcherlibrary.linker
1958             lib = file("$buildDir/classes/main/com/oracle/tools/packager/linux/libpackager.so")
1959         }
1960         task compileLauncher(dependsOn: [linkLinuxLauncher, linkLinuxLibrary])
1961         jar.dependsOn compileLauncher;
1962     }
1963 
1964     // Builds the javapackager executable. For everything other than windows,
1965     // this is simply moving the existing shell script and ensuring it has proper
1966     // permissions. For Windows, this includes compiling the native executable
1967     if (IS_WINDOWS && COMPILE_FXPACKAGER){
1968         task buildJavaPackager(type: CCTask, group: "Build") {
1969             description = "Compiles native sources for javapackager.exe"
1970             matches = "javapackager\\.cpp"
1971             params.addAll(WIN.fxpackager.ccFlags)
1972             compiler = WIN.fxpackager.compiler
1973             output(file("$buildDir/native/javapackager"))
1974             source WIN.fxpackager.nativeSource
1975             doFirst {
1976                 copy {
1977                     mkdir "$buildDir/native"
1978                     mkdir "$buildDir/native/javapackager"
1979                     from file("src/main/native/javapackager/win/javapackager.manifest")
1980                     into file("$buildDir/native/javapackager")
1981                     filter { line->
1982                         line = line.replace("FXVERSION", "${RAW_VERSION}.${HUDSON_BUILD_NUMBER}");
1983                     }
1984                 }
1985             }
1986             doLast {
1987                 mkdir "$buildDir/native"
1988                 exec {
1989                     environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
1990                     commandLine(WIN.fxpackager.rcCompiler)
1991                     args(WIN.fxpackager.rcFlags)
1992                     args("/fo$buildDir/native/javapackager/javapackager.res")
1993                     args(WIN.fxpackager.rcSource)
1994                 }
1995             }
1996             doLast {
1997                 mkdir "$buildDir/javapackager"
1998                 exec({
1999                     commandLine("$WIN.fxpackager.linker", "/nologo", "/opt:REF", "/incremental:no", "/manifest", "kernel32.lib", "advapi32.lib",
2000                             "/out:$buildDir/native/javapackager/javapackager.exe",
2001                             "$buildDir/native/javapackager/javapackager.obj",
2002                             "$buildDir/native/javapackager/javapackager.res")
2003                     environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2004                 })
2005             }
2006             doLast {
2007                 exec({
2008                     commandLine("$MC", "-manifest",
2009                                        "$buildDir/native/javapackager/javapackager.manifest",
2010                                        "-outputresource:$buildDir/native/javapackager/javapackager.exe")
2011                     environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2012                 })
2013                 copy {
2014                     from file("$buildDir/native/javapackager/javapackager.exe")
2015                     into file("$buildDir/javapackager")
2016                 }
2017                 copy {
2018                     from file("$buildDir/native/javapackager/javapackager.exe")
2019                     into file("$buildDir/javapackager")
2020                     rename ('javapackager', 'javafxpackager')
2021                 }
2022             }
2023         }
2024     } else {
2025         task buildJavaPackager(group: "Build") {
2026             enabled = COMPILE_FXPACKAGER
2027             doLast {
2028                 copy {
2029                     from "src/main/native/javapackager/shell"
2030                     into "$buildDir/javapackager"
2031                     fileMode = 0755
2032                 }
2033                 copy {
2034                     from "src/main/native/javapackager/shell"
2035                     into "$buildDir/javapackager"
2036                     rename ('javapackager', 'javafxpackager')
2037                     fileMode = 0755
2038                 }
2039             }
2040         }
2041     }
2042 
2043     task packagerJar(type: Jar) {
2044         group = "Basic"
2045         description = "Creates the packager.jar"
2046         archiveName = "packager.jar";
2047         includeEmptyDirs = false
2048         from("$buildDir/classes/main");
2049         from("$buildDir/resources/main");
2050         include('jdk/packager/**')
2051 
2052         dependsOn(buildJavaPackager);
2053     }
2054 
2055     jar.dependsOn buildJavaPackager
2056     jar.dependsOn packagerJar
2057 
2058     classes << {
2059         // Copy all of the download libraries to libs directory for the sake of the IDEs
2060         File libsDir = rootProject.file("build/libs");
2061         File antLib = new File(libsDir, "ant-1.8.2.jar")
2062         libsDir.mkdirs();
2063         for (File f : configurations.compile.files) {
2064             copy {
2065                 into libsDir
2066                 from f.getParentFile()
2067                 include "**/ant-1.8.2.jar"
2068                 includeEmptyDirs = false
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                     def rcOutputDir = "${nativeOutputDir}/${buildType}"
2387                     mkdir rcOutputDir
2388                     exec {
2389                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2390                         commandLine (WIN.media.rcCompiler)
2391                         args(WIN.media.glibRcFlags)
2392                         args("/Fo${rcOutputDir}/${WIN.media.glibRcFile}", WIN.media.rcSource)
2393                     }
2394 
2395                     exec {
2396                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2397                         commandLine (WIN.media.rcCompiler)
2398                         args(WIN.media.gstreamerRcFlags)
2399                         args("/Fo${rcOutputDir}/${WIN.media.gstreamerRcFile}", WIN.media.rcSource)
2400                     }
2401 
2402                     exec {
2403                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2404                         commandLine (WIN.media.rcCompiler)
2405                         args(WIN.media.fxpluginsRcFlags)
2406                         args("/Fo${rcOutputDir}/${WIN.media.fxpluginsRcFile}", WIN.media.rcSource)
2407                     }
2408 
2409                     exec {
2410                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2411                         commandLine (WIN.media.rcCompiler)
2412                         args(WIN.media.jfxmediaRcFlags)
2413                         args("/Fo${rcOutputDir}/${WIN.media.jfxmediaRcFile}", WIN.media.rcSource)
2414                     }
2415                 }
2416 
2417                 def buildGlib = task("build${t.capital}Glib", dependsOn: [buildResources]) {
2418                     enabled = IS_COMPILE_MEDIA
2419                     doLast {
2420                         exec {
2421                             environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2422                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/glib-lite")
2423                             args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=glib-lite",
2424                                  IS_64 ? "ARCH=x64" : "ARCH=x32", "RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.glibRcFile}")
2425                         }
2426                     }
2427                 }
2428                 buildGStreamer.dependsOn buildGlib
2429 
2430             } else if (t.name == "mac") {
2431                 def buildGlib = task("build${t.capital}Glib") {
2432                     enabled = IS_COMPILE_MEDIA
2433                     doLast {
2434                         exec {
2435                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/libffi")
2436                             args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=ffi")
2437                             args ("CC=${mediaProperties.compiler}", "LINK=${mediaProperties.linker}", "AR=${mediaProperties.ar}")
2438                         }
2439 
2440                         exec {
2441                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/glib-lite")
2442                             args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=glib-lite")
2443                             args ("CC=${mediaProperties.compiler}", "LINK=${mediaProperties.linker}", "LIB=${mediaProperties.lib}")
2444                         }
2445                     }
2446                 }
2447                 buildGStreamer.dependsOn buildGlib
2448             } else if (t.name == "linux") {
2449                 def buildGlib = task("build${t.capital}Glib") {
2450                     enabled = IS_COMPILE_MEDIA
2451                     doLast {
2452                         exec {
2453                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/libffi")
2454                             args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=ffi")
2455                             args("CC=${mediaProperties.compiler}", "LINK=${mediaProperties.linker}", "AR=${mediaProperties.ar}")
2456                             args(IS_64 ? "ARCH=x64" : "ARCH=x32")
2457                         }
2458 
2459                         exec {
2460                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/glib-lite")
2461                             args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=glib-lite")
2462                             args("CC=${mediaProperties.compiler}", "LINK=${mediaProperties.linker}", "LIB=${mediaProperties.lib}")
2463                             args(IS_64 ? "ARCH=x64" : "ARCH=x32")
2464                         }
2465                     }
2466                 }
2467                 buildGStreamer.dependsOn buildGlib
2468             }
2469         }
2470 
2471         buildNativeTargets.dependsOn buildNative
2472     }
2473 
2474     jar {
2475         exclude("headergen/**")
2476 
2477         dependsOn compileJava
2478         if (IS_COMPILE_MEDIA) {
2479             dependsOn buildNativeTargets
2480         }
2481     }
2482 }
2483 
2484 project(":web") {
2485     configurations {
2486         webkit
2487     }
2488     dependencies {
2489         compile project(":base"), project(":graphics"), project(":controls"), project(":media")
2490     }
2491 
2492     task webArchiveJar(type: Jar) {
2493         from (project.file("$projectDir/src/test/resources/test/html")) {
2494             include "**/archive-*.*"
2495         }
2496         archiveName = "webArchiveJar.jar"
2497         destinationDir = file("$buildDir/testing/resources")
2498     }
2499 
2500     test {
2501         // Run web tests in headless mode
2502         systemProperty 'glass.platform', 'Monocle'
2503         systemProperty 'monocle.platform', 'Headless'
2504         systemProperty 'prism.order', 'sw'
2505         dependsOn webArchiveJar
2506         def testResourceDir = file("$buildDir/testing/resources")
2507         jvmArgs "-DWEB_ARCHIVE_JAR_TEST_DIR=$testResourceDir"
2508     }
2509 
2510     sourceSets.main.java.srcDirs += "src/main/native/Source/WebCore/bindings/java/dom3/java"
2511 
2512     task generateHeaders(dependsOn: compileJava) {
2513         doLast {
2514             def classpath = files("$buildDir/classes/main",
2515                                   project(":graphics").sourceSets.main.output.classesDir)
2516             def dest = file("$buildDir/generated-src/headers");
2517             mkdir dest;
2518             exec {
2519                 commandLine("$JAVAH", "-J-Djava.ext.dirs=", "-d", "$dest",
2520                             "-classpath", "${classpath.asPath}");
2521                 args("com.sun.webkit.ContextMenu",
2522                      "com.sun.webkit.ContextMenuItem",
2523                      "com.sun.webkit.CursorManager",
2524                      "com.sun.webkit.PageCache",
2525                      "com.sun.webkit.PopupMenu",
2526                      "com.sun.webkit.SharedBuffer",
2527                      "com.sun.webkit.WebPage",
2528                      "com.sun.webkit.LoadListenerClient",
2529                      "com.sun.webkit.event.WCFocusEvent",
2530                      "com.sun.webkit.event.WCKeyEvent",
2531                      "com.sun.webkit.event.WCMouseEvent",
2532                      "com.sun.webkit.event.WCMouseWheelEvent",
2533                      "com.sun.webkit.graphics.GraphicsDecoder",
2534                      "com.sun.webkit.graphics.RenderMediaControls",
2535                      "com.sun.webkit.graphics.RenderTheme",
2536                      "com.sun.webkit.graphics.ScrollBarTheme",
2537                      "com.sun.webkit.graphics.WCMediaPlayer",
2538                      "com.sun.webkit.graphics.WCGraphicsManager",
2539                      "com.sun.webkit.graphics.WCRenderQueue",
2540                      "com.sun.webkit.graphics.WCPath",
2541                      "com.sun.webkit.graphics.WCPathIterator",
2542                      "com.sun.webkit.Timer",
2543                      "com.sun.webkit.WCFrameView",
2544                      "com.sun.webkit.WCPasteboard",
2545                      "com.sun.webkit.WCPluginWidget",
2546                      "com.sun.webkit.dom.CharacterDataImpl",
2547                      "com.sun.webkit.dom.JSObject",
2548                      "com.sun.webkit.network.SocketStreamHandle",
2549                      "com.sun.webkit.network.URLLoader",
2550                      "com.sun.webkit.text.TextBreakIterator",
2551                      "com.sun.webkit.text.TextNormalizer");
2552             }
2553         }
2554     }
2555 
2556     task compileNative()
2557 
2558     compileTargets { t ->
2559         def targetProperties = project.rootProject.ext[t.upper]
2560         def webkitProperties = targetProperties.webkit
2561         def classifier = (t.name != "linux" && t.name != "win") ? t.name :
2562                           IS_64 ? "${t.name}-amd64" : "${t.name}-i586"
2563 
2564         def webkitOutputDir = cygpath("$buildDir/${t.name}")
2565         def webkitConfig = IS_DEBUG_NATIVE ? "Debug" : "Release"
2566 
2567         File nativeBuildDir = new File("${webkitOutputDir}")
2568         nativeBuildDir.mkdirs()
2569 
2570         def compileNativeTask = task("compileNative${t.capital}", dependsOn: generateHeaders) << {
2571             println "Building Webkit configuration /$webkitConfig/ into $webkitOutputDir"
2572 
2573             exec {
2574                 workingDir("$webkitOutputDir")
2575                 commandLine("perl", "$projectDir/src/main/native/Tools/Scripts/set-webkit-configuration", "--$webkitConfig")
2576                 environment(["WEBKIT_OUTPUTDIR" : webkitOutputDir])
2577             }
2578 
2579             exec {
2580                 workingDir("$projectDir/src/main/native")
2581                 def cmakeArgs = "-DENABLE_TOOLS=1"
2582                 if (t.name == "win") {
2583                     String parfaitPath = IS_COMPILE_PARFAIT ? System.getenv().get("PARFAIT_PATH") + ";" : "";
2584                     Map environmentSettings = new HashMap(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2585                     environmentSettings["PATH"] = parfaitPath + "$WINDOWS_VS_PATH"
2586                     /* To build with ICU:
2587                     1. Download http://javaweb.us.oracle.com/jcg/fx-webrevs/RT-17164/WebKitLibrariesICU.zip
2588                     and unzip it to WebKitLibraries folder.
2589                     2. Copy DLLs from
2590                     WebKitLibrariesICU.zip\WebKitLibraries\import\runtime
2591                     to %windir%\system32
2592                     3. Uncomment the line below
2593                      */
2594                     // args("--icu-unicode")
2595                 } else if (t.name == "mac") {
2596                     cmakeArgs = "-DCMAKE_OSX_DEPLOYMENT_TARGET=$MACOSX_MIN_VERSION -DCMAKE_OSX_SYSROOT=$MACOSX_SDK_PATH"
2597                 } else if (t.name == "linux") {
2598                     cmakeArgs = "-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_C_COMPILER=${webkitProperties.compiler}"
2599                     if (IS_64) {
2600                         cmakeArgs = "$cmakeArgs -DCMAKE_SYSTEM_PROCESSOR=x86_64"
2601                     } else {
2602                         cmakeArgs = "$cmakeArgs -DCMAKE_SYSTEM_PROCESSOR=i586"
2603                     }
2604                     // TODO: Use cflags and ldflags from all platforms
2605                     def cFlags = webkitProperties.ccFlags?.join(' ') ?: ''
2606                     def lFlags = webkitProperties.linkFlags?.join(' ') ?: ''
2607                     // -shared flag should be omitted while creating executable.
2608                     def exeFlags = webkitProperties.linkFlags?.join(' ')?.replace('-shared', '') ?: ''
2609                     cmakeArgs = "$cmakeArgs -DCMAKE_C_FLAGS='${cFlags}' -DCMAKE_CXX_FLAGS='${cFlags}'"
2610                     cmakeArgs = "$cmakeArgs -DCMAKE_SHARED_LINKER_FLAGS='${lFlags}' -DCMAKE_EXE_LINKER_FLAGS='${exeFlags}'"
2611                 } else if (t.name.startsWith("arm")) {
2612                     fail("ARM target is not supported as of now.")
2613                 }
2614 
2615                 if (IS_COMPILE_PARFAIT) {
2616                     environment([
2617                         "COMPILE_PARFAIT" : "true"
2618                     ])
2619                     cmakeArgs = "-DCMAKE_C_COMPILER=parfait-gcc -DCMAKE_CXX_COMPILER=parfait-g++"
2620                 }
2621 
2622                 environment([
2623                     "JAVA_HOME"       : JDK_HOME,
2624                     "WEBKIT_OUTPUTDIR" : webkitOutputDir,
2625                     "PYTHONDONTWRITEBYTECODE" : "1",
2626                 ])
2627 
2628                 def targetCpuBitDepthSwitch = ""
2629                 if (IS_64) {
2630                     targetCpuBitDepthSwitch = "--64-bit"
2631                 } else {
2632                     targetCpuBitDepthSwitch = "--32-bit"
2633                 }
2634 
2635                 cmakeArgs += " -DJAVAFX_RELEASE_VERSION=8.0"
2636                 commandLine("perl", "$projectDir/src/main/native/Tools/Scripts/build-webkit",
2637                     "--java", "--icu-unicode", targetCpuBitDepthSwitch,
2638                     "--cmakeargs=${cmakeArgs}")
2639             }
2640 
2641             // Cmake places Windows DLL in bin directory
2642             def dllDir = IS_WINDOWS ? "bin" : "lib"
2643             def library = rootProject.ext[t.upper].library
2644             copy {
2645                 from "$webkitOutputDir/$webkitConfig/$dllDir/${library('jfxwebkit')}"
2646                 into "$buildDir/libs/${t.name}"
2647             }
2648             copy {
2649                 from "$webkitOutputDir/$webkitConfig/$dllDir/${library('DumpRenderTreeJava')}"
2650                 into "$buildDir/test/${t.name}"
2651             }
2652         }
2653 
2654         compileNative.dependsOn compileNativeTask
2655 
2656         if (IS_WINDOWS && t.name == "win") {
2657             def rcTask = project.task("rc${t.capital}", type: CompileResourceTask) {
2658                 compiler = webkitProperties.rcCompiler
2659                 source(webkitProperties.rcSource)
2660                 if (webkitProperties.rcFlags) {
2661                     rcParams.addAll(webkitProperties.rcFlags)
2662                 }
2663                 output(file("$webkitOutputDir/$webkitConfig/WebCore/obj"))
2664             }
2665             compileNativeTask.dependsOn rcTask
2666         }
2667 
2668         if (!targetProperties.compileWebnodeNative) {
2669             println("Not compiling native Webkit for ${t.name} per configuration request");
2670             compileNativeTask.enabled = false
2671         }
2672     }
2673 
2674     def drtClasses = "com/sun/javafx/webkit/drt/**"
2675     jar.exclude(drtClasses)
2676     task drtJar(type: Jar, dependsOn: compileJava) {
2677         archiveName = "drt.jar"
2678         destinationDir = file("$buildDir/test")
2679         from "$buildDir/classes/main"
2680         include drtClasses
2681     }
2682     if (IS_COMPILE_WEBKIT) {
2683         jar.dependsOn compileNative, drtJar
2684     }
2685 }
2686 
2687 allprojects {
2688     // The following block is a workaround for the fact that presently Gradle
2689     // can't set the -XDignore.symbol.file flag, because it appears that the
2690     // javac API is lacking support for it. So what we'll do is find any Compile
2691     // task and manually provide the options necessary to fire up the
2692     // compiler with the right settings.
2693     //
2694     // Also, we need to remove jfxrt.jar from the ext classpath (if it is there)
2695     tasks.withType(JavaCompile) { compile ->
2696         if (compile.options.hasProperty("useAnt")) {
2697             compile.options.useAnt = true
2698             compile.options.useDepend = IS_USE_DEPEND
2699         } else if (compile.options.hasProperty("incremental")) {
2700             compile.options.incremental = IS_INCREMENTAL
2701         }
2702         compile.options.debug = true // we always generate debugging info in the class files
2703         compile.options.debugOptions.debugLevel = IS_DEBUG_JAVA ? "source,lines,vars" : "source,lines"
2704         compile.options.fork = true
2705         compile.options.forkOptions.executable = JAVAC
2706         compile.options.warnings = IS_LINT
2707         compile.options.compilerArgs = ["-Djava.ext.dirs=", "-XDignore.symbol.file", "-encoding", "UTF-8"]
2708         if (!DO_BUILD_SDK_FOR_TEST) {
2709             compile.classpath = files(jfxrtJarFromSdk) + compile.classpath
2710         }
2711 
2712         // Add in the -Xlint options
2713         if (IS_LINT) {
2714             LINT.split("[, ]").each { s ->
2715                 compile.options.compilerArgs += "-Xlint:$s"
2716             }
2717         }
2718     }
2719 
2720     // Some tasks should be disabled not to compile SDK, when running only the tests
2721     disabledTasks.each {
2722         project.getTasksByName(it, false)*.enabled = false
2723     }
2724 }
2725 
2726 /******************************************************************************
2727  *                                                                            *
2728  *                             Top Level Tasks                                *
2729  *                                                                            *
2730  *  These are the tasks which are defined only for the top level project and  *
2731  *  not for any sub projects. These are generally the entry point that is     *
2732  *  used by Hudson and by the continuous build system.                        *
2733  *                                                                            *
2734  *****************************************************************************/
2735 
2736 task clean() {
2737     group = "Basic"
2738     description = "Deletes the build directory and the build directory of all sub projects"
2739     getSubprojects().each { subProject ->
2740         dependsOn(subProject.getTasksByName("clean", true));
2741     }
2742     doLast {
2743         delete(buildDir);
2744     }
2745 }
2746 
2747 task cleanAll() {
2748     group = "Basic"
2749     description = "Scrubs the repo of build artifacts"
2750     dependsOn(clean)
2751     doLast {
2752         //delete(".gradle"); This causes problems on windows.
2753         delete("buildSrc/build");
2754     }
2755 }
2756 
2757 task javadoc(type: Javadoc) {
2758     enabled = IS_BUILD_JAVADOC
2759     group = "Basic"
2760     description = "Generates the JavaDoc for all the public API"
2761     executable = JAVADOC
2762     def projectsToDocument = [
2763             project(":base"), project(":graphics"), project(":controls"), project(":media"),
2764             project(":swing"), project(":swt"), project(":fxml"), project(":web")]
2765     source(projectsToDocument.collect({
2766         [it.sourceSets.main.java, "$it.buildDir/generated-src/builders"]
2767     }));
2768     setDestinationDir(new File(buildDir, 'javadoc'));
2769     // Might need a classpath
2770     classpath = files(projectsToDocument.collect { project ->
2771         project.sourceSets.main.compileClasspath
2772     });
2773     classpath += files(projectsToDocument.collect { project ->
2774         project.sourceSets.main.output
2775     });
2776     exclude("com/**/*", "Compile*", "javafx/builder/**/*", "javafx/scene/accessibility/**/*");
2777     options.windowTitle("${javadocTitle}")
2778     options.header("${javadocHeader}")
2779     options.bottom("${javadocBottom}")
2780     if (BUILD_CLOSED) {
2781         options.linksOffline(JDK_DOCS, JDK_DOCS_CLOSED);
2782     } else {
2783         options.links(JDK_DOCS);
2784     }
2785     options.addBooleanOption("XDignore.symbol.file").setValue(true);
2786     options.addBooleanOption("Xdoclint:none").setValue(!IS_DOC_LINT);
2787     options.addBooleanOption("javafx").setValue(true);
2788     options.addBooleanOption("use").setValue(true);
2789     doLast {
2790         projectsToDocument.each { p ->
2791             copy {
2792                 from "$p.projectDir/src/main/docs"
2793                 into "$buildDir/javadoc"
2794             }
2795         }
2796     }
2797 
2798     dependsOn(projectsToDocument.collect { project -> project.getTasksByName("classes", true)});
2799 }
2800 
2801 task jfxrt() {
2802     if (DO_BUILD_SDK_FOR_TEST) {
2803         rootProject.getTasksByName("compileTestJava", true).each { t ->
2804             if (t.enabled) t.dependsOn(jfxrt)
2805         }
2806     }
2807 }
2808 
2809 task sdk() {
2810     dependsOn(checkJfxrtJar)
2811 
2812     if (DO_BUILD_SDK_FOR_TEST) {
2813         rootProject.getTasksByName("test", true).each { t ->
2814             if (t.enabled) t.dependsOn(sdk)
2815         }
2816     }
2817 }
2818 
2819 task appsjar() {
2820     dependsOn(sdk)
2821     // Note: the jar dependencies get added elsewhere see project(":apps")
2822 }
2823 
2824 // these are empty tasks, allowing us to depend on the task, which may have other
2825 // real work items added later.
2826 task copyAppsArtifacts() {
2827     dependsOn(appsjar)
2828 }
2829 
2830 task apps() {
2831     dependsOn(sdk)
2832     dependsOn(appsjar)
2833     dependsOn(copyAppsArtifacts)
2834 }
2835 
2836 task findbugs() {
2837     dependsOn(sdk)
2838 
2839     doLast {
2840         if (!BUILD_CLOSED) {
2841             println "findbugs task is only run for a closed build"
2842         }
2843     }
2844 }
2845 
2846 // The following tasks are for the closed build only. They are a no-op for the open build
2847 
2848 task checkCache() {
2849     dependsOn(updateCacheIfNeeded)
2850 }
2851 
2852 // TODO: consider moving the "public-sdk" portion of this task here
2853 task publicExports() {
2854     doFirst {
2855         if (BUILD_CLOSED && !IS_BUILD_JAVADOC) {
2856             fail("publicExports task requires: -PBUILD_JAVADOC=true")
2857         }
2858     }
2859     dependsOn(sdk)
2860 }
2861 
2862 task perf() {
2863     dependsOn(sdk,apps)
2864     doLast {
2865         if (!BUILD_CLOSED) {
2866             println "perf task is only run for a closed build"
2867         }
2868     }
2869 }
2870 
2871 task zips() {
2872     doFirst {
2873         if (BUILD_CLOSED && !IS_BUILD_JAVADOC) {
2874             fail("zips task requires: -PBUILD_JAVADOC=true")
2875         }
2876     }
2877     dependsOn(sdk,publicExports,apps,perf)
2878 }
2879 
2880 task copySources(type: Copy) {
2881     enabled = IS_BUILD_SRC_ZIP
2882     def projectsToCopy = [
2883             project(":base"), project(":graphics"), project(":controls"),
2884             project(":swing"), project(":swt"), project(":fxml"),
2885             project(":builders"), project(":media"), project(":web")]
2886     from(projectsToCopy.collect({ proj ->
2887         files(proj.sourceSets.main.java.srcDirs)
2888     }))
2889     include "**/*.java"
2890     into "${buildDir}/javafx-src"
2891 }
2892 
2893 task zipSources(type: Zip) {
2894     enabled = IS_BUILD_SRC_ZIP
2895     dependsOn(copySources)
2896     archiveName = "javafx-src.zip"
2897     destinationDir = file("$buildDir")
2898     includeEmptyDirs = false
2899     from "${buildDir}/javafx-src"
2900 }
2901 
2902 task src {
2903     enabled = IS_BUILD_SRC_ZIP
2904     description = "Created the javafx-src.zip bundle"
2905     dependsOn(zipSources)
2906 }
2907 
2908 task all() {
2909     dependsOn(sdk,publicExports,apps,perf,zips)
2910 }
2911 
2912 compileTargets { t ->
2913     def targetProperties = project.ext[t.upper]
2914     def sdkDirName = targetProperties.sdkDirName
2915     def library = targetProperties.library
2916     // The jfxrt task is responsible for creating the jfxrt.jar. A developer may
2917     // have multiple SDK's on their system at any one time, depending on which
2918     // cross compiles they have done. For example, I might have:
2919     //      build/ios-sdk/rt/lib/ext/jfxrt.jar
2920     //      build/armhf-sdk/rt/lib/ext/jfxrt.jar
2921     // and so forth. The default host build will always install into 'sdk'
2922     // allowing for uses where a known sdk path is needed (like IDEs)
2923     //      build/sdk/rt/lib/ext/jfxrt.jar
2924     // This arrangement allows for multiple independent SDKs to
2925     // exist on a developer's system.
2926     def jfxrtTask = task("jfxrt$t.capital", type: Jar) {
2927         group = "Basic"
2928         description = "Creates the jfxrt.jar for the $t.name target"
2929         archiveName = "build/${sdkDirName}/rt/lib/ext/jfxrt.jar";
2930         includeEmptyDirs = false
2931         from("modules/base/build/classes/main",
2932              "modules/base/build/resources/main",
2933              "modules/builders/build/classes/main",
2934              "modules/graphics/build/classes/main",
2935              "modules/graphics/build/resources/main",
2936              "modules/controls/build/classes/main",
2937              "modules/controls/build/resources/main",
2938              "modules/fxml/build/classes/main",
2939              "modules/fxml/build/resources/main",
2940              "modules/graphics/build/classes/jsl-decora",
2941              "modules/graphics/build/resources/jsl-decora",
2942              "modules/graphics/build/classes/jsl-prism",
2943              "modules/graphics/build/resources/jsl-prism",
2944              "modules/media/build/classes/main",
2945              "modules/media/build/resources/main")
2946         if (COMPILE_SWING) from ("modules/swing/build/classes/main", "modules/swing/build/resources/main")
2947 
2948         if (!IS_MAC) {
2949             exclude ("modules/media/build/classes/main/com/sun/media/jfxmediaimpl/platform/osx/**",
2950                      "com/sun/prism/es2/MacGL*",
2951                      "com/sun/glass/events/mac",
2952                      "com/sun/glass/ui/mac",
2953                      "com/sun/prism/es2/gl/mac"
2954                      )
2955         }
2956         if (!IS_WINDOWS) {
2957             exclude ("**/*.hlsl",
2958                      "com/sun/glass/ui/win",
2959                      "com/sun/prism/d3d",
2960                      "com/sun/prism/es2/gl/win",
2961                      "com/sun/prism/es2/WinGL*",
2962                      "com/sun/scenario/effect/impl/hw/d3d"
2963                      )
2964         }
2965         if (!targetProperties.includeGTK) { //usually IS_LINUX
2966             exclude (
2967                      "com/sun/glass/ui/gtk",
2968                      "com/sun/prism/es2/EGL*",
2969                      "com/sun/prism/es2/gl/eglfb",
2970                      "com/sun/prism/es2/gl/eglx11",
2971                      "com/sun/prism/es2/gl/x11",
2972                      "com/sun/prism/es2/X11GL*"
2973                      )
2974         }
2975         if (!targetProperties.includeEGL) {
2976             exclude ("com/sun/prism/es2/EGL*")
2977         }
2978         if (!targetProperties.includeLens) {
2979             exclude ("com/sun/glass/ui/lens")
2980         }
2981         /* Note: Monocle is used in the test harness, and so should
2982          * not be excluded until the deploy phase
2983         if (!targetProperties.includeMonocle) {
2984             exclude ("com/sun/glass/ui/monocle")
2985         }
2986         */
2987         if (!targetProperties.includeNull3d) {
2988             // "com/sun/prism/null3d", // TODO This is used in dev builds but not the final sdk
2989             exclude ("com/sun/prism/null3d")
2990         }
2991         if (t.name != 'ios') {
2992             exclude ("modules/media/build/classes/main/com/sun/media/jfxmediaimpl/platform/ios/**",
2993                      "com/sun/glass/ui/ios",
2994                      "com/sun/prism/es2/IOS*"
2995                      )
2996         }
2997         if (t.name != 'android' && t.name != 'dalvik') {
2998             exclude ("com/sun/glass/ui/android/*")
2999         }
3000 
3001         if (t.name == 'android') {
3002             from ("modules/web/build/classes/android",
3003                   "modules/web/build/resources/android",
3004                   "modules/controls/build/classes/android",
3005                   "modules/controls/build/resources/android")
3006         } else if (t.name == 'ios') {
3007             from ("modules/web/build/classes/ios",
3008                   "modules/web/build/resources/ios",
3009                   "modules/extensions/build/classes/ios")
3010         } else {
3011             from ("modules/web/build/classes/main", "modules/web/build/resources/main")
3012         }
3013 
3014         exclude("**/javafx/embed/swt/**")
3015 
3016         if (!targetProperties.includeSWT) {
3017             exclude("com/sun/glass/ui/swt")
3018         }
3019 
3020         if (!targetProperties.includeSwing) {
3021             exclude("javafx/embed/swing")
3022         }
3023         exclude("js/**/*", // er...
3024                 "PrismLoaderBackend*", // More decora stuff
3025                 "**/*.stg",    // any glue files for decora must be excluded
3026                 "**/*.java",   // Builder java files are in build/classes and should be excluded
3027                 "com/sun/javafx/webkit/drt"); // Drt class
3028 
3029         // Filter out platform specific Java sources (glass) when compiling for other targets
3030         if (targetProperties.containsKey('jfxrtJarExcludes')) {
3031             exclude(targetProperties.jfxrtJarExcludes)
3032         }
3033 
3034         dependsOn(subprojects.collect { project -> project.getTasksByName("assemble", true)});
3035     }
3036     def jfxrtIndexTask = task("jfxrtIndex$t.capital") {
3037         //the following is a workaround for the lack of indexing in gradle 1.4 through 1.7
3038         dependsOn(jfxrtTask)
3039 
3040         doLast() {
3041             ant.jar (update: true, index: true, destfile: jfxrtTask.archiveName)
3042         }
3043     }
3044     jfxrt.dependsOn(jfxrtIndexTask)
3045 
3046     def jfxswtTask = task("jfxswt$t.capital", type: Jar) {
3047         enabled = COMPILE_SWT
3048         group = "Basic"
3049         description = "Creates the jfxswt.jar for the $t.name target"
3050         archiveName = "build/${sdkDirName}/rt/lib/jfxswt.jar";
3051         includeEmptyDirs = false
3052         from("modules/swt/build/classes/main");
3053         from("modules/builders/build/classes/main");
3054         include("**/javafx/embed/swt/**")
3055         exclude("**/*.java");  // Builder java files are in build/classes and should be excluded
3056 
3057         dependsOn(subprojects.collect { project -> project.getTasksByName("assemble", true)});
3058     }
3059     def jfxswtIndexTask = task("jfxswtIndex$t.capital") {
3060         //the following is a workaround for the lack of indexing in gradle 1.4 through 1.7
3061         dependsOn(jfxswtTask)
3062 
3063         doLast() {
3064             ant.jar (update: true, index: true, destfile: jfxswtTask.archiveName)
3065         }
3066     }
3067     jfxrt.dependsOn(jfxswtIndexTask)
3068 
3069     def jmxTask = task ("jmx${t.capital}", type: Jar) {
3070         group = "Basic"
3071         description = "Creates the javafx-mx.jar"
3072         archiveName = "build/${sdkDirName}/lib/javafx-mx.jar";
3073         includeEmptyDirs = false
3074         from "modules/jmx/build/classes/main"
3075         from "modules/jmx/build/resources/main"
3076         dependsOn project(":jmx").assemble
3077     }
3078 
3079     // The 'sdk' task will build the rest of the SDK, and depends on the 'jfxrtTask' task. After
3080     // executing this task the sdk bundle for the current COMPILE_TARGETS will be fully created.
3081     def sdkTask = task("sdk$t.capital") {
3082         group = "Basic"
3083         description = "Creates the SDK for $t.name"
3084         doLast {
3085             // TODO instead of using copy everywhere, I probably want to use "sync" instead?
3086             // Copy all of the .dll / .so / .dylib native libraries into build/sdk/rt/lib/
3087             copy {
3088                 def useLipo = targetProperties.containsKey('useLipo') ? targetProperties.useLipo : false
3089                 from("modules/graphics/build/libs/jsl-decora/${t.name}/${library(targetProperties.decora.lib)}")
3090                 def libs = ['font', 'prism', 'prismSW', 'prismES2', 'glass', 'iio']
3091                 if (IS_COMPILE_PANGO) {
3092                     libs += ['fontFreetype', 'fontPango'];
3093                 }
3094                 libs.each { lib ->
3095                     def variants = targetProperties[lib].containsKey('variants') && !useLipo ? targetProperties[lib].variants : [null]
3096                     variants.each { variant ->
3097                         def variantProperties = variant ? targetProperties[lib][variant] : targetProperties[lib]
3098                         println "modules/graphics/build/libs/$lib/$t.name/${library(variantProperties.lib)}"
3099                         from ("modules/graphics/build/libs/$lib/$t.name/${library(variantProperties.lib)}")
3100                     }
3101                 }
3102                 if (IS_WINDOWS) {
3103                     from ("modules/graphics/build/libs/prismD3D/${t.name}/${library(targetProperties.prismD3D.lib)}");
3104 
3105                     targetProperties.VS2017DLLs.each { vslib ->
3106                         from ("$vslib");
3107                     }
3108                     targetProperties.WinSDKDLLs.each { winsdklib ->
3109                         from ("$winsdklib");
3110                     }
3111                 }
3112                 if (IS_COMPILE_WEBKIT) {
3113                     from ("modules/web/build/libs/${t.name}/${library('jfxwebkit')}")
3114                 } else {
3115                     if (t.name != "android" && t.name != "ios" && t.name != "dalvik") {
3116                         from ("$LIBRARY_STUB/${library('jfxwebkit')}")
3117                     }
3118                 }
3119 
3120                 def mediaBuildType = project(":media").ext.buildType
3121                 if (IS_COMPILE_MEDIA) {
3122                     [ "fxplugins", "glib-lite", "gstreamer-lite", "jfxmedia" ].each { name ->
3123                         from ("modules/media/build/native/${t.name}/${mediaBuildType}/${library(name)}") }
3124 
3125                     if (t.name == "mac") {
3126                         // OSX media natives
3127                         [ "jfxmedia_qtkit", "jfxmedia_avf" ].each { name ->
3128                             from ("modules/media/build/native/${t.name}/${mediaBuildType}/${library(name)}") }
3129                     } else if (t.name == "linux") {
3130                         from("modules/media/build/native/${t.name}/${mediaBuildType}") { include "libavplugin*.so" }
3131                     }
3132                 } else {
3133                     if (t.name != "android" && t.name != "dalvik" ) {
3134                         [ "fxplugins", "glib-lite", "gstreamer-lite", "jfxmedia" ].each { name ->
3135                             from ("$LIBRARY_STUB/${library(name)}") }
3136                     }
3137 
3138                     if (t.name == "mac") {
3139                         // copy libjfxmedia_{avf,qtkit}.dylib if they exist
3140                         [ "jfxmedia_qtkit", "jfxmedia_avf" ].each { name ->
3141                             from ("$LIBRARY_STUB/${library(name)}") }
3142                     } else if (t.name == "linux") {
3143                         from(LIBRARY_STUB) { include "libavplugin*.so" }
3144                     }
3145                 }
3146 
3147                 def libDest = targetProperties.libDest
3148                 into ("build/${sdkDirName}/rt/$libDest")
3149             }
3150 
3151             // Create the javafx.properties file
3152             final File javafxProperties = file("build/${sdkDirName}/rt/lib/javafx.properties")
3153             javafxProperties.delete()
3154             javafxProperties << "javafx.runtime.version=$RAW_VERSION";
3155             javafxProperties << "\n"
3156             javafxProperties << "javafx.runtime.build=b$PROMOTED_BUILD_NUMBER";
3157             javafxProperties << "\n"
3158             // Include any properties that have been defined (most likely in
3159             // one of the various platform gradle files)
3160             if (targetProperties.containsKey("javafxProperties")) {
3161                 javafxProperties << targetProperties.javafxProperties
3162                 javafxProperties << "\n"
3163             }
3164 
3165             // Embedded builds define this file as well
3166             if (targetProperties.containsKey("javafxPlatformProperties")) {
3167                 final File javafxPlatformProperties = file("build/${sdkDirName}/rt/lib/javafx.platform.properties")
3168                 javafxPlatformProperties.delete()
3169                 javafxPlatformProperties << targetProperties.javafxPlatformProperties
3170                 javafxPlatformProperties << "\n"
3171             }
3172 
3173             // Copy over the javadocs that were generated. This is done rather than just generating
3174             // the docs into the "right place" because for a cross-compile you only need one set of
3175             // docs but need to have a copy in each created sdk
3176             if (IS_BUILD_JAVADOC) {
3177                 copy {
3178                     from "build/javadoc"
3179                     into "build/${sdkDirName}/docs/api"
3180                 }
3181             }
3182 
3183             // Copy over the javafx-src bundle
3184             if (IS_BUILD_SRC_ZIP) {
3185                 copy {
3186                     from "build/javafx-src.zip"
3187                     into "build/${sdkDirName}"
3188                 }
3189             }
3190 
3191             // Copy over the fxpackager and rename as ant-javafx.jar
3192             copy {
3193                 from "modules/fxpackager/build/libs"
3194                 into "build/${sdkDirName}/lib"
3195             }
3196 
3197             // Copy over the FXPackager man files
3198             copy {
3199                 from "modules/fxpackager/build/man"
3200                 into "build/${sdkDirName}/man"
3201             }
3202 
3203             // Copy over the javapackager executable
3204             if (t.name == "win" || t.name == "linux" || t.name == "mac") {
3205                 copy {
3206                     from "modules/fxpackager/build/javapackager"
3207                     into "build/${sdkDirName}/bin"
3208                 }
3209             }
3210         }
3211         dependsOn(jmxTask);
3212         dependsOn(jfxrtIndexTask)
3213         dependsOn(jfxswtIndexTask)
3214         dependsOn(javadoc)
3215         dependsOn(src)
3216     }
3217 
3218     def generateSymbols = targetProperties.containsKey('generateSymbols') ? targetProperties.generateSymbols : false
3219     if (generateSymbols) {
3220         def exportedSymbolsTask = project.task("exportedSymbols${t.capital}", type: ExportedSymbolsTask, dependsOn: sdkTask, group: "Build") {
3221             description = "Generates exported symbols file for iOS build (from .a libraries)"
3222             def libDirName = "build/${sdkDirName}/rt/$targetProperties.libDest"
3223             libDir = file("$libDirName")
3224             outputFile = file("$libDirName/exported.symbols")
3225             excludes = targetProperties.generateSymbolsExcludes
3226         }
3227         sdk.dependsOn(exportedSymbolsTask)
3228     }
3229 
3230     sdk.dependsOn(sdkTask)
3231 }
3232 
3233     //task integrationCheck {
3234     //    group = "Basic"
3235     //    description = "Performs all the tasks necessary to ensure that the current build is ready for integration."
3236     //    dependsOn sdk
3237     //    dependsOn subprojects.collect { project -> project.getTasksByName("check", true)}
3238     //}
3239 
3240 /*
3241  * This clause changes the way we handle a build.gradle within ./apps
3242  * It does a few things:
3243  *   modifies the classpath used to include the built runttime classes
3244  *   provides for copying the build applications to the artifacts tree
3245  *
3246  * The applications to be built will be under ./apps, but also must
3247  * be listed in the applications listed in the setting variable: JFXApplications
3248  */
3249 ext.JFXRT_CP =
3250     files(
3251         project(":base").sourceSets.main.output.classesDir,
3252         project(":graphics").sourceSets.main.output.classesDir,
3253         project(":controls").sourceSets.main.output.classesDir,
3254         project(":fxml").sourceSets.main.output.classesDir,
3255         project(":swing").sourceSets.main.output.classesDir, //NOTE - used by 3Dviewer
3256         project(":builders").sourceSets.main.output.classesDir,
3257             "modules/media/build/classes/main",
3258             "modules/web/build/classes/main",
3259     )
3260 
3261 project(":apps") {
3262     // The apps build is Ant based, and gradle lets us "import" ant build.xml
3263     // into our configuration.
3264 
3265     ant.importBuild 'build.xml'
3266 
3267     // Download the Lucene libraries needed for the Ensemble8 app
3268     def luceneVersion = "7.4.0"
3269     getConfigurations().create("lucene");
3270     dependencies {
3271         lucene group: "org.apache.lucene", name: "lucene-core", version: luceneVersion
3272         lucene group: "org.apache.lucene", name: "lucene-grouping", version: luceneVersion
3273         lucene group: "org.apache.lucene", name: "lucene-queryparser", version: luceneVersion
3274     }
3275 
3276     // Copy Lucene libraries into the Ensemble8/lib directory
3277     File ensembleLibDir = rootProject.file("apps/samples/Ensemble8/lib");
3278     def libNames = [ "lucene-core-${luceneVersion}.jar",
3279                      "lucene-grouping-${luceneVersion}.jar",
3280                      "lucene-queryparser-${luceneVersion}.jar" ]
3281 
3282 
3283     task getLucene(type: Copy) {
3284         doFirst {
3285             ensembleLibDir.mkdirs();
3286         }
3287         into ensembleLibDir
3288         includeEmptyDirs = false
3289         configurations.lucene.files.each { f ->
3290             libNames.each { name ->
3291                 if (name == f.getName()) {
3292                     from f.getPath()
3293                 }
3294             }
3295         }
3296     }
3297 
3298     compileTargets { t ->
3299         // The apps build is Ant based, and gradle lets us "import" ant apps/build.xml
3300         // into our configuration.
3301 
3302         // override the apps build.xml with an explicit pointer to our jar.
3303         def sdkDirName = rootProject.ext[t.upper].sdkDirName
3304         def jfxrtJar = "${rootProject.buildDir}/${sdkDirName}/rt/lib/ext/jfxrt.jar"
3305 
3306         def appsJar = project.task("appsJar${t.capital}") {
3307             dependsOn(sdk, getLucene)
3308             doLast() {
3309               ant.properties['targetBld'] = "$t.name"
3310               if (!rootProject.ext[t.upper].compileSwing) {
3311                 ant.properties['JFX_CORE_ONLY'] = 'true'
3312               }
3313               ant.properties['jfxbuild.jfxrt.jar'] = jfxrtJar
3314               ant.properties['platforms.JDK_1.8.home'] = "${rootProject.ext.JDK_HOME}"
3315               ant.project.executeTarget("sampleAppsJar")
3316               ant.project.executeTarget("scenebuilderSampleAppsJar")
3317               if (!t.name.startsWith("arm")) {
3318                 ant.project.executeTarget("scenebuilderAppJar")
3319               }
3320             }
3321         }
3322         rootProject.appsjar.dependsOn(appsJar)
3323 
3324         def appsClean = project.task("appsClean${t.capital}") {
3325             doLast() {
3326               ant.properties['targetBld'] = "$t.name"
3327               ant.properties['platforms.JDK_1.8.home'] = "${rootProject.ext.JDK_HOME}"
3328               ant.project.executeTarget("sampleAppsClean")
3329               ant.project.executeTarget("scenebuilderSampleAppsClean")
3330               if (!t.name.startsWith("arm")) {
3331                 ant.project.executeTarget("scenebuilderAppClean")
3332               }
3333               delete(ensembleLibDir);
3334             }
3335         }
3336         rootProject.clean.dependsOn(appsClean)
3337     }
3338 }
3339 
3340 /******************************************************************************
3341  *                                                                            *
3342  *                              OpenExport                                    *
3343  *                                                                            *
3344  *****************************************************************************/
3345 
3346 task openExport() {
3347     if (!BUILD_CLOSED) {
3348         publicExports.dependsOn(openExport)
3349     }
3350 }
3351 
3352 task openZip() {
3353     if (!BUILD_CLOSED) {
3354         zips.dependsOn(openZip)
3355     }
3356 }
3357 
3358 compileTargets { t ->
3359     def targetProperties = project.ext[t.upper]
3360 
3361     def sdkDir = "${project.buildDir}/${targetProperties.sdkDirName}"
3362     def exportDir = "${project.buildDir}/${targetProperties.exportDirName}"
3363     def exportSDKDir = "${exportDir}/sdk"
3364     def bundleDir = "${project.buildDir}/${targetProperties.bundleDirName}"
3365     def jfxrtJar = "$sdkDir/rt/lib/ext/jfxrt.jar"
3366 
3367     def isWindows = false
3368     if (IS_WINDOWS && t.name == "win") {
3369         isWindows = true
3370     }
3371 
3372     def String compressJar = "false"
3373     if (targetProperties.containsKey('deploy') &&
3374         targetProperties.deploy.containsKey('compressBigJar')) {
3375         compressJar = targetProperties.deploy.compressBigJar
3376     }
3377 
3378     def exportTask = project.task("openExport$t.capital", group: "Build") {
3379         dependsOn("sdk$t.capital")
3380 
3381         doLast {
3382             def exportTmp = "${exportDir}/tmp/classes"
3383 
3384             // delete any old exports dir before rebuilding it
3385             file("${exportDir}").deleteDir()
3386 
3387             mkdir "${exportTmp}"
3388 
3389             copy {
3390                 from "${sdkDir}"
3391                 into "${exportSDKDir}"
3392                 exclude '**/jfxrt.jar'
3393 
3394                 if (isWindows) {
3395                     exclude '**/prism_es2.dll'
3396                 }
3397 
3398                 eachFile {details ->
3399                     if (details.path.startsWith('rt/')) {
3400                         details.path = 'jre/' + details.path.substring(3);
3401                     }
3402                 }
3403             }
3404 
3405             copy {
3406                 from zipTree("${jfxrtJar}")
3407                 into "${exportTmp}"
3408             }
3409 
3410             mkdir "${exportSDKDir}/jre/lib/ext"
3411 
3412             ant.jar(
3413                     destfile: "${exportSDKDir}/jre/lib/ext/jfxrt.jar",
3414                     index: true,
3415                     compress: compressJar
3416                 ) {
3417                     delegate.manifest {
3418                       attribute(name: 'Implementation-Title', value: 'OpenJavaFX')
3419                     }
3420 
3421                     fileset(dir: "${exportTmp}") {
3422                        exclude(name:'META-INF/*')
3423                        exclude(name:'com/sun/javafx/tools/ant/*')
3424 
3425                        //-- Obsolete or experimental code --
3426                        exclude(name:'com/sun/embeddedswing/**')
3427                        exclude(name:'com/sun/javafx/tk/glass/**')
3428                        exclude(name:'com/sun/javafx/tk/swing/**')
3429                        exclude(name:'com/sun/prism/null3d/**')
3430                        exclude(name:'com/sun/scenario/scenegraph/**')
3431                        exclude(name:'com/sun/scenario/utils/**')
3432                        exclude(name:'com/sun/webpane/sg/swing/**')
3433                        exclude(name:'com/sun/webpane/swing/**')
3434                        exclude(name:'com/sun/glass/ui/swt/**')
3435 
3436                        if (isWindows) {
3437                            //-- Strip ES2 pipeline on Windows platform only --
3438                            exclude(name:'com/sun/prism/es2/**')
3439                            exclude(name:'com/sun/scenario/effect/impl/es2/**')
3440                            exclude(name:'com/sun/scenario/effect/impl/hw/ogl/**')
3441                            exclude(name:'com/sun/scenario/effect/impl/j2d/jogl/**')
3442                            exclude(name:'com/sun/scenario/effect/impl/j2d/rsl/**')
3443                        }
3444 
3445                        if(!targetProperties.includeLens) {
3446                            exclude(name:'com/sun/glass/ui/lens/**')
3447                        }
3448 
3449                        if(!targetProperties.includeMonocle) {
3450                            exclude(name:'com/sun/glass/ui/monocle/**')
3451                            exclude(name:'com/sun/prism/es2/Monocle*')
3452                        }
3453                 }
3454             } // ant.jar
3455 
3456             // remove {exportTmp}
3457             file("${exportTmp}").deleteDir()
3458         }
3459     }
3460 
3461     def jfxBundle = 'javafx-sdk-overlay.zip'
3462 
3463     def zipTask = project.task("openZip$t.capital", type: Zip, group: "Build") {
3464 
3465         doFirst() {
3466             file("${bundleDir}/${jfxBundle}").delete()
3467         }
3468 
3469         archiveName = jfxBundle
3470         destinationDir = file("$bundleDir")
3471         includeEmptyDirs = false
3472         from "${exportSDKDir}"
3473 
3474         dependsOn(exportTask)
3475     }
3476 
3477     openExport.dependsOn(exportTask)
3478     openZip.dependsOn(zipTask)
3479 }
3480 
3481 task checkrepo() {
3482     doLast {
3483         logger.info("checking for whitespace (open)");
3484         exec {
3485             if (IS_WINDOWS) {
3486                 commandLine  'bash', 'tools/scripts/checkWhiteSpace'
3487             } else {
3488                 commandLine  'bash', 'tools/scripts/checkWhiteSpace', '-x'
3489             }
3490         }
3491     }
3492 }
3493 
3494 task checkrepoall() {
3495     doLast {
3496         logger.info("checking for all whitespace (open)");
3497         exec {
3498             if (IS_WINDOWS) {
3499                 commandLine  'bash', 'tools/scripts/checkWhiteSpace', '-a'
3500             } else {
3501                 commandLine  'bash', 'tools/scripts/checkWhiteSpace', '-x', '-a'
3502             }
3503         }
3504     }
3505 }
3506 
3507 /******************************************************************************
3508  *                                                                            *
3509  *                              BUILD_CLOSED                                  *
3510  *                                                                            *
3511  * This next section should remain at the end of the build script. It allows  *
3512  * for a "supplemental" gradle file to be used to extend the normal build     *
3513  * structure. For example, this is used for passing a supplemental gradle     *
3514  * file for producing official JavaFX builds.                                 *
3515  *                                                                            *
3516  *****************************************************************************/
3517 
3518 if (BUILD_CLOSED) {
3519     apply from: supplementalBuildFile
3520 }
3521 
3522 task showFlags {
3523 }
3524 
3525 compileTargets { t ->
3526     // Every platform must define these variables
3527     def props = project.ext[t.upper];
3528     showFlags.dependsOn(
3529         project.task("showFlags$t.upper") {
3530             doLast() {
3531                 println "Properties set for $t.upper"
3532                 props.each { println it }
3533             }
3534         }
3535     )
3536 }
3537