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