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