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