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