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