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