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