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