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