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