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