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 
2616 project(":media") {
2617     configurations {
2618         media
2619     }
2620 
2621     project.ext.buildModule = true
2622     project.ext.includeSources = true
2623     project.ext.moduleRuntime = true
2624     project.ext.moduleName = "javafx.media"
2625 
2626     sourceSets {
2627         main
2628         //shims // no test shims needed
2629         test
2630         tools {
2631             java.srcDir "src/tools/java"
2632         }
2633     }
2634 
2635     project.ext.moduleSourcePath = defaultModuleSourcePath
2636     project.ext.moduleSourcePathShim = defaultModuleSourcePathShim
2637 
2638     commonModuleSetup(project, [ 'base', 'graphics', 'media' ])
2639 
2640     dependencies {
2641     }
2642 
2643     compileJava.dependsOn updateCacheIfNeeded
2644 
2645     compileJava {
2646         // generate the native headers during compile
2647         options.compilerArgs.addAll([
2648             '-h', "${project.buildDir}/gensrc/headers"
2649             ])
2650     }
2651 
2652     compileToolsJava {
2653         enabled = IS_COMPILE_MEDIA
2654         options.compilerArgs.addAll(project.modulePathArgs)
2655         options.compilerArgs.addAll([
2656             '--add-exports', 'javafx.media/com.sun.media.jfxmedia=ALL-UNNAMED',
2657             ])
2658     }
2659 
2660     project.ext.makeJobsFlag = IS_WINDOWS && IS_DEBUG_NATIVE ? "-j1" : "-j5";
2661     project.ext.buildType = IS_DEBUG_NATIVE ? "Debug" : "Release";
2662 
2663     def nativeSrcDir = file("${projectDir}/src/main/native")
2664     def generatedHeadersDir = file("${buildDir}/gensrc/headers/${project.moduleName}")
2665 
2666     task generateMediaErrorHeader(dependsOn: [compileToolsJava, compileJava]) {
2667         enabled = IS_COMPILE_MEDIA
2668         def headerpath = file("$generatedHeadersDir/jfxmedia_errors.h");
2669         doLast {
2670             def classpath = files(sourceSets.tools.output);
2671             def sourcepath = sourceSets.main.java.srcDirs;
2672             def srcRoot = (sourcepath.toArray())[0];
2673 
2674             mkdir generatedHeadersDir;
2675 
2676             exec {
2677                 commandLine("$JAVA");
2678                 args += patchModuleArgs
2679                 args +=  [ '--add-exports=javafx.media/com.sun.media.jfxmedia=ALL-UNNAMED' ]
2680                 args +=  [ '-classpath', "${classpath.asPath}" ]
2681                 args += [ "headergen.HeaderGen", "$headerpath", "$srcRoot" ]
2682             }
2683         }
2684         outputs.file(project.file("$headerpath"))
2685     }
2686 
2687     task buildNativeTargets {
2688         enabled = IS_COMPILE_MEDIA
2689     }
2690 
2691     compileTargets { t->
2692         def targetProperties = project.rootProject.ext[t.upper]
2693         def nativeOutputDir = file("${buildDir}/native/${t.name}")
2694         def projectDir = t.name.startsWith("arm") ? "linux" : t.name
2695         def mediaProperties = targetProperties.media
2696         // Makefile for OSX needs to know if we're building for parfait
2697         def compileParfait = IS_COMPILE_PARFAIT ? "true" : "false"
2698 
2699         def buildNative = task("build${t.capital}Native", dependsOn: [generateMediaErrorHeader]) {
2700             enabled = targetProperties.compileMediaNative
2701             if (!targetProperties.compileMediaNative) {
2702                 println("Not compiling native Media for ${t.name} per configuration request");
2703             }
2704 
2705             doLast {
2706                 exec {
2707                     commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/jfxmedia/projects/${projectDir}")
2708                     args("JAVA_HOME=${JDK_HOME}", "GENERATED_HEADERS_DIR=${generatedHeadersDir}",
2709                          "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=jfxmedia",
2710                          "COMPILE_PARFAIT=${compileParfait}",
2711                          IS_64 ? "ARCH=x64" : "ARCH=x32",
2712                         "CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}")
2713 
2714                     if (t.name == "win") {
2715                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2716                         args( "RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.jfxmediaRcFile}")
2717                     } else {
2718                         if (t.name.startsWith("arm")) {
2719                             args("EXTRA_CFLAGS=${mediaProperties.extra_cflags}", "EXTRA_LDFLAGS=${mediaProperties.extra_ldflags}")
2720                         } else {
2721                             args("HOST_COMPILE=1")
2722                         }
2723                     }
2724                 }
2725             }
2726         }
2727 
2728         // check for the property disable${name} = true
2729         def boolean disabled = targetProperties.containsKey('disableMedia') ? targetProperties.get('disableMedia') : false
2730         if (!disabled) {
2731             // Building GStreamer
2732             def buildGStreamer = task("build${t.capital}GStreamer") {
2733                 enabled = IS_COMPILE_MEDIA
2734                 doLast {
2735                     exec {
2736                         commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/gstreamer-lite")
2737                         args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=gstreamer-lite",
2738                              IS_64 ? "ARCH=x64" : "ARCH=x32", "CC=${mediaProperties.compiler}",
2739                              "AR=${mediaProperties.ar}", "LINKER=${mediaProperties.linker}")
2740 
2741                         if (t.name == "win") {
2742                             environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2743                             args("RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.gstreamerRcFile}")
2744                         }
2745                     }
2746                 }
2747             }
2748 
2749             def buildPlugins = task("build${t.capital}Plugins", dependsOn: buildGStreamer) {
2750                 enabled = IS_COMPILE_MEDIA
2751 
2752                 if (!project.ext.properties.containsKey("ON2_SRCDIR")) {
2753                     project.ext.ON2_SRCDIR = "";
2754                 }
2755 
2756                 if (!project.ext.properties.containsKey("ON2_LIB")) {
2757                     project.ext.ON2_LIB = "";
2758                 }
2759 
2760                 doLast {
2761                     exec {
2762                         commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/fxplugins")
2763                         args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=fxplugins",
2764                              "ON2_SRCDIR=${project.ext.ON2_SRCDIR}", "ON2_LIB=${project.ext.ON2_LIB}",
2765                              IS_64 ? "ARCH=x64" : "ARCH=x32",
2766                              "CC=${mediaProperties.compiler}", "AR=${mediaProperties.ar}", "LINKER=${mediaProperties.linker}")
2767 
2768                         if (t.name == "win") {
2769                             Map winEnv = new HashMap(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2770 
2771                             String sdkDir = System.getenv("BASECLASSES_SDK_DIR");
2772                             if (sdkDir == null) {
2773                                 sdkDir = "C:/Program Files/Microsoft SDKs/Windows/v7.1" // Default value
2774                                 winEnv["BASECLASSES_SDK_DIR"] = sdkDir
2775                             }
2776                             environment(winEnv)
2777 
2778                             args("RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.fxpluginsRcFile}")
2779                         }
2780                     }
2781                 }
2782             }
2783 
2784             buildNative.dependsOn buildPlugins
2785 
2786             if (t.name == "linux") {
2787                 def buildAVPlugin = task( "buildAVPlugin", dependsOn: [buildPlugins]) {
2788                     enabled = IS_COMPILE_MEDIA
2789 
2790                     doLast {
2791                         if (project.ext.properties.containsKey("libav")) {
2792                             project.ext.libav.versions.each { version ->
2793                                 def libavDir = "${project.ext.libav.basedir}-${version}"
2794                                 File dir = file(libavDir)
2795                                 if (dir.exists()) {
2796                                     exec {
2797                                         commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/linux/avplugin")
2798                                         args("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}",
2799                                              "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}",
2800                                              "BASE_NAME=avplugin", "VERSION=${version}", "LIBAV_DIR=${libavDir}",
2801                                              "SUFFIX=", IS_64 ? "ARCH=x64" : "ARCH=x32")
2802                                     }
2803                                 }
2804                             }
2805 
2806                             project.ext.libav.ffmpeg.versions.each { version ->
2807                                 def libavDir = "${project.ext.libav.ffmpeg.basedir}-${version}"
2808                                 File dir = file(libavDir)
2809                                 if (dir.exists()) {
2810                                     exec {
2811                                         commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/linux/avplugin")
2812                                         args("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}",
2813                                              "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}",
2814                                              "BASE_NAME=avplugin", "VERSION=${version}", "LIBAV_DIR=${libavDir}",
2815                                              "SUFFIX=-ffmpeg", IS_64 ? "ARCH=x64" : "ARCH=x32")
2816                                     }
2817                                 }
2818                             }
2819                         } else {
2820                             // Building fxavcodec plugin (libav plugin)
2821                             exec {
2822                                 commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/linux/avplugin")
2823                                 args("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}",
2824                                      "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}",
2825                                      "BASE_NAME=avplugin", IS_64 ? "ARCH=x64" : "ARCH=x32")
2826                             }
2827                         }
2828                     }
2829                 }
2830                 buildNative.dependsOn buildAVPlugin
2831             }
2832 
2833             if (t.name == "win") {
2834                 def buildResources = task("buildResources") << {
2835                     def rcOutputDir = "${nativeOutputDir}/${buildType}"
2836                     mkdir rcOutputDir
2837                     exec {
2838                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2839                         commandLine (WIN.media.rcCompiler)
2840                         args(WIN.media.glibRcFlags)
2841                         args("/Fo${rcOutputDir}/${WIN.media.glibRcFile}", WIN.media.rcSource)
2842                     }
2843 
2844                     exec {
2845                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2846                         commandLine (WIN.media.rcCompiler)
2847                         args(WIN.media.gstreamerRcFlags)
2848                         args("/Fo${rcOutputDir}/${WIN.media.gstreamerRcFile}", WIN.media.rcSource)
2849                     }
2850 
2851                     exec {
2852                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2853                         commandLine (WIN.media.rcCompiler)
2854                         args(WIN.media.fxpluginsRcFlags)
2855                         args("/Fo${rcOutputDir}/${WIN.media.fxpluginsRcFile}", WIN.media.rcSource)
2856                     }
2857 
2858                     exec {
2859                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2860                         commandLine (WIN.media.rcCompiler)
2861                         args(WIN.media.jfxmediaRcFlags)
2862                         args("/Fo${rcOutputDir}/${WIN.media.jfxmediaRcFile}", WIN.media.rcSource)
2863                     }
2864                 }
2865 
2866                 def buildGlib = task("build${t.capital}Glib", dependsOn: [buildResources]) {
2867                     enabled = IS_COMPILE_MEDIA
2868                     doLast {
2869                         exec {
2870                             environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2871                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/glib-lite")
2872                             args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=glib-lite",
2873                                  IS_64 ? "ARCH=x64" : "ARCH=x32", "RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.glibRcFile}",
2874                                  "CC=${mediaProperties.compiler}", "AR=${mediaProperties.ar}", "LINKER=${mediaProperties.linker}")
2875                         }
2876                     }
2877                 }
2878                 buildGStreamer.dependsOn buildGlib
2879 
2880             } else if (t.name == "mac") {
2881                 def buildGlib = task("build${t.capital}Glib") {
2882                     enabled = IS_COMPILE_MEDIA
2883                     doLast {
2884                         exec {
2885                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/libffi")
2886                             args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=ffi")
2887                             args ("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}", "AR=${mediaProperties.ar}")
2888                         }
2889 
2890                         exec {
2891                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/glib-lite")
2892                             args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=glib-lite")
2893                             args ("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}")
2894                         }
2895                     }
2896                 }
2897                 buildGStreamer.dependsOn buildGlib
2898             }
2899         }
2900 
2901         buildNativeTargets.dependsOn buildNative
2902     }
2903 
2904     jar {
2905         exclude("headergen/**")
2906 
2907         dependsOn compileJava
2908         if (IS_COMPILE_MEDIA) {
2909             dependsOn buildNativeTargets
2910         }
2911     }
2912 }
2913 
2914 project(":web") {
2915     configurations {
2916         webkit
2917     }
2918     project.ext.buildModule = true
2919     project.ext.includeSources = true
2920     project.ext.moduleRuntime = true
2921     project.ext.moduleName = "javafx.web"
2922 
2923     sourceSets {
2924         main
2925         shims
2926         test
2927     }
2928 
2929     project.ext.moduleSourcePath = defaultModuleSourcePath
2930     project.ext.moduleSourcePathShim = defaultModuleSourcePathShim
2931 
2932     commonModuleSetup(project, [ 'base', 'graphics', 'controls', 'media', 'web' ])
2933 
2934     dependencies {
2935     }
2936 
2937     compileJava.dependsOn updateCacheIfNeeded
2938 
2939     task webArchiveJar(type: Jar) {
2940         from (project.file("$projectDir/src/test/resources/test/html")) {
2941             include "**/archive-*.*"
2942         }
2943         archiveName = "webArchiveJar.jar"
2944         destinationDir = file("$buildDir/testing/resources")
2945     }
2946 
2947     def gensrcDir = "${buildDir}/gensrc/java"
2948 
2949     // add in the wrappers to the compile
2950     sourceSets.main.java.srcDirs += "${gensrcDir}"
2951 
2952     if (IS_COMPILE_WEBKIT) {
2953         compileJava {
2954             // generate the native headers during compile
2955             // only needed if we are doing the native compile
2956             options.compilerArgs.addAll([
2957                 '-h', "${project.buildDir}/gensrc/headers"
2958                 ])
2959         }
2960     } else {
2961         // Instead of compiling native wrappers, use a pre-generated version
2962 
2963         // Copy these to a common location in the moduleSourcePath
2964         def copyWrappers = project.task("copyPreGeneratedWrappers", type: Copy) {
2965             enabled =  (!IS_COMPILE_WEBKIT)
2966 
2967             from "src/main/java-wrappers"
2968             into "${gensrcDir}"
2969         }
2970 
2971         compileJava.dependsOn(copyWrappers);
2972     }
2973 
2974     test {
2975         // Run web tests in headless mode
2976         systemProperty 'glass.platform', 'Monocle'
2977         systemProperty 'monocle.platform', 'Headless'
2978         systemProperty 'prism.order', 'sw'
2979         dependsOn webArchiveJar
2980         def testResourceDir = file("$buildDir/testing/resources")
2981         jvmArgs "-DWEB_ARCHIVE_JAR_TEST_DIR=$testResourceDir"
2982     }
2983 
2984     // generate some headers that are not part of our build
2985     task generateHeaders(dependsOn: compileJava) {
2986         doLast {
2987             def dest = file("$buildDir/gensrc/headers/${project.moduleName}");
2988             mkdir dest;
2989             exec {
2990                 commandLine("$JAVAH", "-d", "$dest",);
2991                 args("java.lang.Character",
2992                      "java.net.IDN",
2993                      );
2994             }
2995         }
2996     }
2997 
2998     task compileGenerated()
2999 
3000     compileTargets { t ->
3001         def targetProperties = project.rootProject.ext[t.upper]
3002         def classifier = (t.name != "linux" && t.name != "win") ? t.name :
3003                           IS_64 ? "${t.name}-amd64" : "${t.name}-i586"
3004         dependencies {
3005             webkit group: "com.sun.webkit", name: "webview-deps",
3006                    version: "1.3.2", classifier: "$classifier", ext: "zip"
3007         }
3008 
3009         def webkitOutputDir = cygpath("$buildDir/${t.name}")
3010         def webkitConfig = IS_DEBUG_NATIVE ? "Debug" : "Release"
3011 
3012         def compileNativeTask = task("compileNative${t.capital}", dependsOn: [generateHeaders, compileJava]) {
3013             println "Building Webkit configuration /$webkitConfig/ into $webkitOutputDir"
3014             enabled =  (IS_COMPILE_WEBKIT)
3015 
3016             outputs.upToDateWhen { false }
3017             outputs.dir("$webkitOutputDir/$webkitConfig/DerivedSources/WebCore/nativeJava/java")
3018 
3019             doLast {
3020                 def dependencyFile = configurations.webkit.filter(
3021                         { File f -> f.getName().contains(classifier) }
3022                     ).getSingleFile()
3023                 ant.unzip(src:  dependencyFile,
3024                           dest: webkitOutputDir)
3025 
3026                 exec {
3027                     workingDir("$projectDir/src/main/native")
3028                     commandLine("perl", "Tools/Scripts/set-webkit-configuration", "--$webkitConfig")
3029                     environment(["WEBKIT_OUTPUTDIR" : webkitOutputDir])
3030                 }
3031 
3032                 exec {
3033                     workingDir("$projectDir/src/main/native")
3034                     def cmakeArgs = "-DENABLE_TOOLS=1"
3035                     if (t.name == "win") {
3036                         String parfaitPath = IS_COMPILE_PARFAIT ? System.getenv().get("PARFAIT_PATH") + ";" : "";
3037                         Map environmentSettings = new HashMap(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
3038                         environmentSettings["PATH"] = parfaitPath + "$WINDOWS_VS_PATH"
3039                         /* To build with ICU:
3040                         1. Download http://javaweb.us.oracle.com/jcg/fx-webrevs/RT-17164/WebKitLibrariesICU.zip
3041                         and unzip it to WebKitLibraries folder.
3042                         2. Copy DLLs from
3043                         WebKitLibrariesICU.zip\WebKitLibraries\import\runtime
3044                         to %windir%\system32
3045                         3. Uncomment the line below
3046                          */
3047                         // args("--icu-unicode")
3048                     } else if (t.name == "mac") {
3049                         // Add any osx specific flags.
3050                     } else if (t.name == "linux") {
3051                         if (!IS_64) {
3052                             cmakeArgs = "-DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32"
3053                         }
3054                     } else if (t.name.startsWith("arm")) {
3055                         fail("ARM target is not supported as of now.")
3056                     }
3057 
3058                     if (IS_COMPILE_PARFAIT) {
3059                         environment([
3060                             "COMPILE_PARFAIT" : "true"
3061                         ])
3062                         cmakeArgs = "-DCMAKE_C_COMPILER=parfait-gcc -DCMAKE_CXX_COMPILER=parfait-g++"
3063                     }
3064 
3065                     environment([
3066                         "JAVA_HOME"       : JDK_HOME,
3067                         "WEBKIT_OUTPUTDIR" : webkitOutputDir,
3068                     ])
3069 
3070                     def targetCpuBitDepthSwitch = ""
3071                     if (IS_64) {
3072                         targetCpuBitDepthSwitch = "--64-bit"
3073                     } else {
3074                         targetCpuBitDepthSwitch = "--32-bit"
3075                     }
3076 
3077                     commandLine("perl", "Tools/Scripts/build-webkit",
3078                         "--java", "--icu-unicode", targetCpuBitDepthSwitch,
3079                         "--cmakeargs=${cmakeArgs}")
3080                 }
3081 
3082                 def library = rootProject.ext[t.upper].library
3083                 copy {
3084                     from "$webkitOutputDir/$webkitConfig/lib/${library('jfxwebkit')}"
3085                     into "$buildDir/libs/${t.name}"
3086                 }
3087                 copy {
3088                     from "$webkitOutputDir/$webkitConfig/lib/${library('DumpRenderTreeJava')}"
3089                     into "$buildDir/test/${t.name}"
3090                 }
3091 
3092             }
3093         }
3094 
3095         if (IS_WINDOWS && t.name == "win") {
3096             def webkitProperties = project.rootProject.ext[t.upper].webkit
3097             def rcTask = project.task("rc${t.capital}", type: CompileResourceTask) {
3098                 compiler = webkitProperties.rcCompiler
3099                 source(webkitProperties.rcSource)
3100                 if (webkitProperties.rcFlags) {
3101                     rcParams.addAll(webkitProperties.rcFlags)
3102                 }
3103                 output(file("$webkitOutputDir/$webkitConfig/WebCore/obj"))
3104             }
3105             compileNativeTask.dependsOn rcTask
3106         }
3107 
3108         def copyGeneratedTask = task("copyGenerated${t.capital}", dependsOn: [compileJava, compileNativeTask]) {
3109             enabled =  (IS_COMPILE_WEBKIT)
3110 
3111             outputs.dir "${gensrcDir}"
3112 
3113             doLast{
3114                 copy {
3115                     from "$projectDir/src/main/java-wrappers/com/sun/webkit/dom/EventListenerImpl.java"
3116                     into "${gensrcDir}/com/sun/webkit/dom"
3117                 }
3118                 copy {
3119                     from "$webkitOutputDir/$webkitConfig/DerivedSources/WebCore/nativeJava/java"
3120                     into "${gensrcDir}"
3121                 }
3122             }
3123         }
3124 
3125         def compileGeneratedTask = task("compileGenerated${t.capital}", type: JavaCompile, dependsOn: copyGeneratedTask) {
3126             destinationDir = file("$buildDir/classes/main")
3127             classpath = configurations.compile
3128             source = project.sourceSets.main.java.srcDirs
3129             options.compilerArgs.addAll([
3130                 '-implicit:none',
3131                 '--module-source-path', defaultModuleSourcePath
3132                 ])
3133         }
3134 
3135         compileGenerated.dependsOn compileGeneratedTask
3136 
3137         if (!targetProperties.compileWebnodeNative) {
3138             println("Not compiling native Webkit for ${t.name} per configuration request");
3139             compileNativeTask.enabled = false
3140         }
3141     }
3142 
3143     def drtClasses = "com/sun/javafx/webkit/drt/**"
3144     jar.exclude(drtClasses)
3145     task drtJar(type: Jar, dependsOn: compileJava) {
3146         archiveName = "drt.jar"
3147         destinationDir = file("$buildDir/test")
3148         from "$buildDir/classes/main"
3149         include drtClasses
3150     }
3151 
3152     if (IS_COMPILE_WEBKIT) {
3153         assemble.dependsOn compileGenerated, drtJar
3154     }
3155 }
3156 
3157 // This project is for system tests that need to run with a full SDK.
3158 // Most of them display a stage or do other things that preclude running
3159 // them in a shared JVM or as part of the "smoke test" run (which must
3160 // not pop up any windows or use audio). As such, they are only enabled
3161 // when FULL_TEST is specified, and each test runs in its own JVM
3162 project(":systemTests") {
3163 
3164     project.ext.buildModule = false
3165     project.ext.moduleRuntime = false
3166     project.ext.moduleName = "systemTests"
3167 
3168     dependencies {
3169         testCompile project(":graphics").sourceSets.test.output
3170         testCompile project(":base").sourceSets.test.output
3171         testCompile project(":controls").sourceSets.test.output
3172         testCompile project(":swing").sourceSets.test.output
3173     }
3174 
3175     commonModuleSetup(project, [ 'base', 'graphics', 'controls', 'media', 'web', 'swing', 'fxml' ])
3176 
3177     File testJavaPolicyFile = new File(rootProject.buildDir, TESTJAVAPOLICYFILE);
3178     File testRunArgsFile = new File(rootProject.buildDir,TESTRUNARGSFILE);
3179 
3180     File stRunArgsFile = new File(project.buildDir,"st.run.args");
3181 
3182     def sts = task("systemTestSetup") {
3183         outputs.file(stRunArgsFile)
3184 
3185         doLast() {
3186             stRunArgsFile.delete()
3187 
3188             logger.info("Creating patchmodule.args file ${stRunArgsFile}")
3189 
3190             // Create an argfile with the information needed to launch
3191             // the stand alone system unit tests.
3192 
3193             //First add in all of the patch-module args we use for the
3194             //normal unit tests, copied from test.run.args
3195             testRunArgsFile.eachLine { str ->
3196                 stRunArgsFile <<  "${str}\n"
3197             }
3198 
3199             // Now add in the working classpath elements (junit, test classes...)
3200             stRunArgsFile <<  "-cp \"\\\n"
3201             test.classpath.each() { elem ->
3202                 def e = cygpath("${elem}")
3203                 stRunArgsFile <<  "  ${e}${File.pathSeparator}\\\n"
3204             }
3205             stRunArgsFile <<  "\"\n"
3206         }
3207     }
3208 
3209     test.dependsOn(sts)
3210     test.dependsOn(createTestArgfiles);
3211 
3212     test {
3213         enabled = IS_FULL_TEST
3214 
3215         // Properties passed to test.util.Util
3216         systemProperties 'worker.debug': IS_WORKER_DEBUG
3217         systemProperties 'worker.patchmodule.file': cygpath(stRunArgsFile.path)
3218         systemProperties 'worker.patch.policy': cygpath(testJavaPolicyFile.path)
3219         systemProperties 'worker.java.cmd': JAVA
3220 
3221         if (!IS_USE_ROBOT) {
3222             // Disable all robot-based visual tests
3223             exclude("test/robot/**");
3224         }
3225         if (!IS_AWT_TEST) {
3226             // Disable all AWT-based tests
3227             exclude("**/javafx/embed/swing/*.*");
3228             exclude("**/com/sun/javafx/application/Swing*.*");
3229         }
3230 
3231         forkEvery = 1
3232     }
3233 }
3234 
3235 allprojects {
3236     // The following block is a workaround for the fact that presently Gradle
3237     // can't set the -XDignore.symbol.file flag, because it appears that the
3238     // javac API is lacking support for it. So what we'll do is find any Compile
3239     // task and manually provide the options necessary to fire up the
3240     // compiler with the right settings.
3241     tasks.withType(JavaCompile) { compile ->
3242         if (compile.options.hasProperty("useAnt")) {
3243             compile.options.useAnt = true
3244             compile.options.useDepend = IS_USE_DEPEND
3245         } else if (compile.options.hasProperty("incremental")) {
3246             compile.options.incremental = IS_INCREMENTAL
3247         }
3248         compile.options.debug = true // we always generate debugging info in the class files
3249         compile.options.debugOptions.debugLevel = IS_DEBUG_JAVA ? "source,lines,vars" : "source,lines"
3250         compile.options.fork = true
3251 
3252         compile.options.forkOptions.executable = JAVAC
3253 
3254         compile.options.warnings = IS_LINT
3255 
3256         compile.options.compilerArgs += ["-XDignore.symbol.file", "-encoding", "UTF-8"]
3257 
3258         // If I am a module....
3259         if (project.hasProperty('moduleSourcePath') &&
3260                 (project.hasProperty('buildModule') && project.buildModule)) {
3261             project.compileJava {
3262                 options.compilerArgs.addAll([
3263                     '-implicit:none',
3264                     '--module-source-path', project.moduleSourcePath
3265                     ])
3266             }
3267             // no jars needed for modules
3268             project.jar.enabled = false
3269 
3270             // and redirect the resources into the module
3271             project.processResources.destinationDir = project.moduleDir
3272         }
3273 
3274         // Add in the -Xlint options
3275         if (IS_LINT) {
3276             LINT.split("[, ]").each { s ->
3277                 compile.options.compilerArgs += "-Xlint:$s"
3278             }
3279         }
3280     } // tasks with javaCompile
3281 
3282     if (project.hasProperty('moduleSourcePathShim') &&
3283             project.sourceSets.hasProperty('shims')) {
3284 
3285         // sync up the obvious source directories with the shims
3286         // others (like the shaders in graphics) should be added in there
3287         project.sourceSets.shims.java.srcDirs += project.sourceSets.main.java.srcDirs
3288         project.sourceSets.shims.java.srcDirs += "$buildDir/gensrc/java"
3289 
3290         project.compileShimsJava {
3291             options.compilerArgs.addAll([
3292                 '-implicit:none',
3293                 '--module-source-path', project.moduleSourcePathShim
3294                 ])
3295         }
3296 
3297         compileTestJava.dependsOn(compileShimsJava)
3298 
3299         def copyGeneratedShimsTask = task("copyGeneratedShims", type: Copy, dependsOn: [compileShimsJava]) {
3300             from project.sourceSets.shims.output.classesDir
3301             into "${rootProject.buildDir}/shims"
3302             exclude("*/module-info.class")
3303         }
3304 
3305         compileTestJava.dependsOn(copyGeneratedShimsTask)
3306     }
3307 
3308     if (project.hasProperty('modulePathArgs')) {
3309         project.compileJava.options.compilerArgs.addAll(modulePathArgs)
3310     }
3311 
3312     if (project.hasProperty('testModulePathArgs')) {
3313         project.compileTestJava.options.compilerArgs.addAll(testModulePathArgs)
3314     }
3315 
3316     if (project.hasProperty('testPatchModuleArgs')) {
3317         project.test.jvmArgs += testPatchModuleArgs
3318     }
3319 
3320     if (project.hasProperty('addExports')) {
3321         project.compileTestJava.options.compilerArgs.addAll(addExports);
3322         project.test.jvmArgs += addExports
3323     }
3324 
3325     if (rootProject.hasProperty("EXTRA_TEST_ARGS") && project.hasProperty('test')) {
3326         EXTRA_TEST_ARGS.split(' ').each() { e ->
3327             project.test.jvmArgs += e
3328         }
3329     }
3330 
3331     if (rootProject.hasProperty("EXTRA_COMPILE_ARGS") && project.hasProperty('compileJava')) {
3332         project.compileJava.options.compilerArgs.addAll(EXTRA_COMPILE_ARGS.split(' '))
3333     }
3334 
3335     if (rootProject.hasProperty("EXTRA_COMPILE_ARGS") && project.hasProperty('compileTestJava')) {
3336         project.compileTestJava.options.compilerArgs.addAll(EXTRA_COMPILE_ARGS.split(' '))
3337     }
3338 
3339 }
3340 
3341 /******************************************************************************
3342  *                                                                            *
3343  *                             Top Level Tasks                                *
3344  *                                                                            *
3345  *  These are the tasks which are defined only for the top level project and  *
3346  *  not for any sub projects. These are generally the entry point that is     *
3347  *  used by Hudson and by the continuous build system.                        *
3348  *                                                                            *
3349  *****************************************************************************/
3350 
3351 task clean() {
3352     group = "Basic"
3353     description = "Deletes the build directory and the build directory of all sub projects"
3354     getSubprojects().each { subProject ->
3355         dependsOn(subProject.getTasksByName("clean", true));
3356     }
3357     doLast {
3358         delete(buildDir);
3359     }
3360 }
3361 
3362 task cleanAll() {
3363     group = "Basic"
3364     description = "Scrubs the repo of build artifacts"
3365     dependsOn(clean)
3366     doLast {
3367         //delete(".gradle"); This causes problems on windows.
3368         delete("buildSrc/build");
3369     }
3370 }
3371 
3372 task createMSPfile() {
3373     group = "Build"
3374     File mspFile = new File(rootProject.buildDir,MODULESOURCEPATH)
3375     outputs.file(mspFile)
3376 
3377     doLast {
3378         mspFile.delete()
3379         mspFile << "--module-source-path\n"
3380         mspFile << defaultModuleSourcePath
3381         mspFile << "\n"
3382     }
3383 }
3384 
3385 task javadoc(type: Javadoc, dependsOn: createMSPfile) {
3386     enabled = IS_BUILD_JAVADOC
3387     group = "Basic"
3388     description = "Generates the JavaDoc for all the public API"
3389     executable = JAVADOC
3390     def projectsToDocument = [
3391             project(":base"), project(":graphics"), project(":controls"), project(":media"),
3392             project(":swing"), /*project(":swt"),*/ project(":fxml"), project(":web")]
3393     source(projectsToDocument.collect({
3394         [it.sourceSets.main.java]
3395     }));
3396     setDestinationDir(new File(buildDir, 'javadoc'));
3397 
3398     exclude("com/**/*", "Compile*", "javafx/builder/**/*", "javafx/scene/accessibility/**/*");
3399     options.windowTitle("${javadocTitle}")
3400     options.header("${javadocHeader}")
3401     options.bottom("${javadocBottom}")
3402     if (BUILD_CLOSED) {
3403         options.linksOffline(JDK_DOCS, JDK_DOCS_CLOSED);
3404     } else {
3405         options.links(JDK_DOCS);
3406     }
3407     options.addBooleanOption("XDignore.symbol.file").setValue(true);
3408     options.addBooleanOption("Xdoclint:none").setValue(!IS_DOC_LINT);
3409     options.addBooleanOption("javafx").setValue(true);
3410     options.addBooleanOption("use").setValue(true);
3411 
3412     options.setOptionFiles([
3413         new File(rootProject.buildDir,MODULESOURCEPATH)
3414         ]);
3415 
3416     doLast {
3417         projectsToDocument.each { p ->
3418             copy {
3419                 from "$p.projectDir/src/main/docs"
3420                 into "$buildDir/javadoc"
3421             }
3422         }
3423     }
3424 
3425     dependsOn(projectsToDocument.collect { project -> project.getTasksByName("classes", true)});
3426 }
3427 
3428 task sdk() {
3429     if (DO_BUILD_SDK_FOR_TEST) {
3430         rootProject.getTasksByName("test", true).each { t ->
3431             if (t.enabled) t.dependsOn(sdk)
3432         }
3433     }
3434 }
3435 
3436 task appsjar() {
3437     dependsOn(sdk)
3438     // Note: the jar dependencies get added elsewhere see project(":apps")
3439 }
3440 
3441 // these are empty tasks, allowing us to depend on the task, which may have other
3442 // real work items added later.
3443 task copyAppsArtifacts() {
3444     dependsOn(appsjar)
3445 }
3446 
3447 task apps() {
3448     dependsOn(sdk)
3449     dependsOn(appsjar)
3450     dependsOn(copyAppsArtifacts)
3451 }
3452 
3453 task findbugs() {
3454     dependsOn(sdk)
3455 
3456     doLast {
3457         if (!BUILD_CLOSED) {
3458             println "findbugs task is only run for a closed build"
3459         }
3460     }
3461 }
3462 
3463 // The following tasks are for the closed build only. They are a no-op for the open build
3464 
3465 task checkCache() {
3466     dependsOn(updateCacheIfNeeded)
3467 }
3468 
3469 // TODO: consider moving the "public-sdk" portion of this task here
3470 task publicExports() {
3471     doFirst {
3472         if (BUILD_CLOSED && !IS_BUILD_JAVADOC) {
3473             fail("publicExports task requires: -PBUILD_JAVADOC=true")
3474         }
3475     }
3476     dependsOn(sdk)
3477 }
3478 
3479 task perf() {
3480     dependsOn(sdk,apps)
3481     doLast {
3482         if (!BUILD_CLOSED) {
3483             println "perf task is only run for a closed build"
3484         }
3485     }
3486 }
3487 
3488 task zips() {
3489     doFirst {
3490         if (BUILD_CLOSED && !IS_BUILD_JAVADOC) {
3491             fail("zips task requires: -PBUILD_JAVADOC=true")
3492         }
3493     }
3494     dependsOn(sdk,publicExports,apps,perf)
3495 }
3496 
3497 task all() {
3498     dependsOn(sdk,publicExports,apps,perf,zips)
3499 }
3500 
3501 
3502 // Construct list of subprojects that are modules
3503 ext.moduleProjList = []
3504 subprojects {
3505     if (project.hasProperty("buildModule") && project.ext.buildModule) {
3506         rootProject.ext.moduleProjList += project
3507         println "module: $project (buildModule=YES)"
3508     } else {
3509         println "module: $project (buildModule=NO)"
3510     }
3511 }
3512 
3513 
3514 // Define the sdk task, which also produces the javafx.swt modular jar
3515 
3516 compileTargets { t ->
3517 
3518     def javafxSwtTask = task("javafxSwt$t.capital", type: Jar) {
3519         enabled = COMPILE_SWT
3520         group = "Basic"
3521         description = "Creates the javafx-swt.jar for the $t.name target"
3522         archiveName = "${project(":swt").buildDir}/libs/javafx-swt.jar";
3523         includeEmptyDirs = false
3524         from("${project(":swt").buildDir}/classes/main");
3525         include("**/javafx/embed/swt/**")
3526 
3527         // FIXME: should only need to depend on the :swt:assemble task
3528         dependsOn(subprojects.collect { project -> project.getTasksByName("assemble", true)});
3529     }
3530 
3531     // FIXME: do we really need the index task for this modular jar?
3532     def javafxSwtIndexTask = task("javafxSwtIndex$t.capital") {
3533         //the following is a workaround for the lack of indexing in gradle 1.4 through 1.7
3534         dependsOn(javafxSwtTask)
3535 
3536         doLast() {
3537             ant.jar (update: true, index: true, destfile: javafxSwtTask.archiveName)
3538         }
3539     }
3540 
3541     def sdkTask = task("sdk$t.capital") {
3542         group = "Basic"
3543         dependsOn(javafxSwtIndexTask)
3544         dependsOn(javadoc)
3545     }
3546 
3547     sdk.dependsOn(sdkTask)
3548 }
3549 
3550 project(":apps") {
3551     // The apps build is Ant based, we will exec ant from gradle.
3552 
3553     compileTargets { t ->
3554         List<String> params = []
3555 
3556         params << "-DtargetBld=$t.name"
3557 
3558         if (!rootProject.ext[t.upper].compileSwing) {
3559             params << "-DJFX_CORE_ONLY=true"
3560         }
3561         params << "-Dplatforms.JDK_1.9.home=${rootProject.ext.JDK_HOME}"
3562         params << "-Dcompile.patch=@${rootProject.buildDir}/${COMPILEARGSFILE}"
3563         params << "-Drun.patch=@${rootProject.buildDir}/${RUNARGSFILE}"
3564 
3565         def appsJar = project.task("appsJar${t.capital}") {
3566             dependsOn(sdk)
3567             doLast() {
3568                 ant(t.name,
3569                       projectDir.path,
3570                       "appsJar",
3571                       params);
3572             }
3573         }
3574         rootProject.appsjar.dependsOn(appsJar)
3575 
3576         def appsClean = project.task("clean${t.capital}") {
3577             doLast() {
3578                 ant(t.name,
3579                       project.projectDir.path,
3580                       "clean",
3581                       params);
3582             }
3583         }
3584         rootProject.clean.dependsOn(appsClean)
3585     }
3586 }
3587 
3588 
3589 /******************************************************************************
3590  *                                                                            *
3591  *                               Modules                                      *
3592  *                                                                            *
3593  *****************************************************************************/
3594 
3595 ext.moduleDependencies = [file("dependencies")]
3596 
3597 task buildModules {
3598 }
3599 
3600 // Combine the classes, lib, and bin for each module
3601 compileTargets { t ->
3602     def targetProperties = project.ext[t.upper]
3603 
3604     def platformPrefix = targetProperties.platformPrefix
3605     def modularSdkDirName = "${platformPrefix}modular-sdk"
3606     def modularSdkDir = "${rootProject.buildDir}/${modularSdkDirName}"
3607     def modulesDir = "${modularSdkDir}/modules"
3608     def modulesCmdsDir = "${modularSdkDir}/modules_cmds"
3609     def modulesLibsDir = "${modularSdkDir}/modules_libs"
3610     def modulesSrcDir = "${modularSdkDir}/modules_src"
3611     def modulesConfDir = "${modularSdkDir}/modules_conf"
3612     def modulesMakeDir = "${modularSdkDir}/make"
3613     final File runArgsFile = file("${rootProject.buildDir}/${RUNARGSFILE}")
3614     final File compileArgsFile = file("${rootProject.buildDir}/${COMPILEARGSFILE}")
3615 
3616     project.files(runArgsFile);
3617 
3618     def zipTask = project.task("buildModuleZip$t.capital", type: Zip, group: "Build") {
3619         enabled = IS_BUILD_MODULE_ZIP
3620 
3621         // FIXME: JIGSAW -- this should be moved to a sub-directory so we can keep the same name
3622         def jfxBundle = "${platformPrefix}javafx-exports.zip"
3623 
3624         doFirst() {
3625             file("${rootProject.buildDir}/${jfxBundle}").delete()
3626         }
3627 
3628         archiveName = jfxBundle
3629         destinationDir = file("${rootProject.buildDir}")
3630         includeEmptyDirs = false
3631         from "${modularSdkDir}"
3632     }
3633     buildModules.dependsOn(zipTask)
3634 
3635     def buildModulesTask = task("buildModules$t.capital", group: "Build") {
3636         doLast {
3637             moduleProjList.each { project ->
3638 
3639                 // Copy classes, bin, and lib directories
3640 
3641                 def moduleName = project.ext.moduleName
3642                 def buildDir = project.buildDir
3643 
3644                 def srcClassesDir = "${buildDir}/${platformPrefix}module-classes"
3645                 def dstClassesDir = "${modulesDir}/${moduleName}"
3646                 copy {
3647                     from srcClassesDir
3648                     into dstClassesDir
3649                     exclude("module-info.class")
3650                 }
3651 
3652                 def srcCmdsDir = "${buildDir}/${platformPrefix}module-bin"
3653                 def dstCmdsDir = "${modulesCmdsDir}/${moduleName}"
3654                 copy {
3655                     from srcCmdsDir
3656                     into dstCmdsDir
3657                 }
3658 
3659                 def srcLibsDir = "${buildDir}/${platformPrefix}module-lib"
3660                 def dstLibsDir = "${modulesLibsDir}/${moduleName}"
3661                 copy {
3662                     from srcLibsDir
3663                     into dstLibsDir
3664                 }
3665 
3666                 // Copy module sources
3667                 // FIXME: javafx.swt sources?
3668                 def copySources = project.hasProperty("includeSources") && project.includeSources
3669                 copy {
3670                     if (copySources) {
3671                         from "${project.projectDir}/src/main/java"
3672                         if (project.name.equals("base")) {
3673                             from "${project.projectDir}/build/gensrc/java"
3674                         }
3675                         if (project.name.equals("web")) {
3676                             from "${project.projectDir}/src/main/java-wrappers"
3677                         }
3678                     } else {
3679                         from "${project.projectDir}/src/main/java/module-info.java"
3680                     }
3681                     into "${modulesSrcDir}/${moduleName}"
3682                     include "**/*.java"
3683                     if (project.hasProperty("sourceFilter")) {
3684                         filter(project.sourceFilter)
3685                     }
3686                 }
3687                 // Copy .html and other files needed for doc bundles
3688                 if (copySources) {
3689                     copy {
3690                         from "${project.projectDir}/src/main/java"
3691                         from "${project.projectDir}/src/main/docs"
3692                         into "${modulesSrcDir}/${moduleName}"
3693                         exclude "**/*.java"
3694                     }
3695                 }
3696 
3697                 // Copy make/build.properties
3698                 def srcMakeDir = "${project.projectDir}/make"
3699                 def dstMakeDir = "${modulesMakeDir}/${moduleName}"
3700                 copy {
3701                     from srcMakeDir
3702                     into dstMakeDir
3703                 }
3704             }
3705 
3706             // Copy dependencies/*/module-info.java.extra
3707             // merging as needed, removing duplicates
3708             // only lines with 'exports' will be copied
3709             def dependencyRoots = moduleDependencies
3710             if (rootProject.hasProperty("closedModuleDepedencies")) {
3711                 dependencyRoots = [dependencyRoots, closedModuleDepedencies].flatten()
3712             }
3713 
3714             Map extras = [:]
3715 
3716             dependencyRoots.each { root ->
3717                 FileTree ft = fileTree(root).include('**/*.extra')
3718                 ft.each() { e->
3719                     String usename = e.path
3720                     String filePath = e.getAbsolutePath()
3721                     String folderPath = root.getAbsolutePath()
3722                     if (filePath.startsWith(folderPath)) {
3723                         usename = filePath.substring(folderPath.length() + 1);
3724                     }
3725                     if (extras.containsKey(usename)) {
3726                         List<String> lines = extras.get(usename)
3727                         e.eachLine { line ->
3728                             line = line.trim()
3729                             if (line.length() > 1 && Character.isLetter(line.charAt(0))) {
3730                                 lines << line
3731                             }
3732                         }
3733 
3734                     } else {
3735                         List<String> lines = []
3736                         e.eachLine { line ->
3737                             line = line.trim()
3738                             if (line.length() > 1 && Character.isLetter(line.charAt(0))) {
3739                                 lines << line
3740                             }
3741                         }
3742                         extras.put(usename,lines)
3743                     }
3744                 }
3745             }
3746             extras.keySet().each() { e->
3747                 File f = new File(modulesSrcDir, e)
3748                 f.getParentFile().mkdirs()
3749                 f.delete()
3750 
3751                 extras.get(e).unique().each() { l->
3752                     f << l
3753                     f << "\n"
3754                 }
3755             }
3756 
3757             // concatecate java.policy files into a single file
3758             //
3759             def outputPolicyDir = "${modulesConfDir}/java.base/security"
3760             def outputPolicyFile = file("${outputPolicyDir}/java.policy.extra")
3761             mkdir outputPolicyDir
3762             outputPolicyFile.delete()
3763             moduleProjList.each { project ->
3764                 def policyDir = "${project.projectDir}/src/main/conf/security"
3765                 def policyFile = file("${policyDir}/java.policy")
3766                 if (policyFile.exists()) outputPolicyFile << policyFile.text
3767             }
3768         }
3769     }
3770     zipTask.dependsOn(buildModulesTask);
3771     buildModules.dependsOn(buildModulesTask)
3772 
3773     def buildRunArgsTask = task("buildRunArgs$t.capital",
3774             group: "Build", dependsOn: buildModulesTask) {
3775         outputs.file(runArgsFile);
3776         doLast() {
3777             List<String>libpath = []
3778             List<String>modpath = []
3779 
3780             moduleProjList.each { project ->
3781                 def moduleName = project.ext.moduleName
3782                 def dstModuleDir = cygpath("${modulesDir}/${moduleName}")
3783                 modpath <<  "${moduleName}=${dstModuleDir}"
3784             }
3785 
3786             writeRunArgsFile(runArgsFile, computeLibraryPath(true), modpath)
3787             writeRunArgsFile(compileArgsFile, null, modpath)
3788         }
3789     }
3790     buildModules.dependsOn(buildRunArgsTask)
3791 
3792     def isWindows = IS_WINDOWS && t.name == "win";
3793     def isMac = IS_MAC && t.name == "mac";
3794 
3795     // Create layout for modular classes
3796     moduleProjList.each { project ->
3797         def buildModuleClassesTask = project.task("buildModule$t.capital", group: "Build") {
3798             dependsOn(project.assemble)
3799             def buildDir = project.buildDir
3800             def sourceBuildDirs = [
3801                 "${buildDir}/classes/main/${project.moduleName}",
3802             ]
3803             doLast {
3804                 def moduleClassesDir = "$buildDir/${platformPrefix}module-classes"
3805                 copy {
3806                     includeEmptyDirs = false
3807                     sourceBuildDirs.each { d ->
3808                         from d
3809                     }
3810                     into moduleClassesDir
3811 
3812                     // Exclude obsolete, experimental, or non-shipping code
3813                     exclude("version.rc")
3814                     exclude("com/sun/glass/ui/swt")
3815                     exclude("com/sun/javafx/tools/ant")
3816                     exclude("com/javafx/main")
3817                     if (!IS_INCLUDE_NULL3D) {
3818                         exclude ("com/sun/prism/null3d")
3819                     }
3820                     if (!IS_INCLUDE_ES2) {
3821                            exclude("com/sun/prism/es2",
3822                                    "com/sun/scenario/effect/impl/es2")
3823                     }
3824 
3825                     // Exclude platform-specific classes for other platforms
3826 
3827                     if (!isMac) {
3828                         exclude ("com/sun/media/jfxmediaimpl/platform/osx",
3829                                  "com/sun/prism/es2/MacGL*",
3830                                  "com/sun/glass/events/mac",
3831                                  "com/sun/glass/ui/mac",
3832                                  )
3833                     }
3834 
3835                     if (!isWindows) {
3836                         exclude ("**/*.hlsl",
3837                                  "com/sun/glass/ui/win",
3838                                  "com/sun/prism/d3d",
3839                                  "com/sun/prism/es2/WinGL*",
3840                                  "com/sun/scenario/effect/impl/hw/d3d"
3841                                  )
3842                     }
3843 
3844                     if (!targetProperties.includeGTK) { //usually IS_LINUX
3845                         exclude (
3846                                  "com/sun/glass/ui/gtk",
3847                                  "com/sun/prism/es2/EGL*",
3848                                  "com/sun/prism/es2/X11GL*"
3849                                  )
3850                     }
3851 
3852                     if (!targetProperties.includeEGL) {
3853                         exclude ("com/sun/prism/es2/EGL*")
3854                     }
3855 
3856                     if (!targetProperties.includeLens) {
3857                         exclude ("com/sun/glass/ui/lens")
3858                     }
3859 
3860                     // FIXME: JIGSAW -- Figure out what to do with Monocle
3861                     /*
3862                     if (!targetProperties.includeMonocle) {
3863                         exclude ("com/sun/glass/ui/monocle")
3864                         exclude("com/sun/prism/es2/Monocle*")
3865                     }
3866                     */
3867 
3868                     if (t.name != 'ios') {
3869                         exclude ("com/sun/media/jfxmediaimpl/platform/ios",
3870                                  "com/sun/glass/ui/ios",
3871                                  "com/sun/prism/es2/IOS*"
3872                                  )
3873                     }
3874 
3875                     if (t.name != 'android' && t.name != 'dalvik') {
3876                         exclude ("com/sun/glass/ui/android")
3877                     }
3878 
3879                     // Filter out other platform-specific classes
3880                     if (targetProperties.containsKey('jfxrtJarExcludes')) {
3881                         exclude(targetProperties.jfxrtJarExcludes)
3882                     }
3883 
3884                     /* FIXME: JIGSAW -- handle this in the module itself
3885                     String webbld = project(":web").buildDir.path
3886                     String ctrlbld = project(":controls").buildDir.path
3887                     if (t.name == 'android') {
3888                         from ("${webbld}/classes/android",
3889                               "${webbld}/resources/android",
3890                               "${ctrlbld}/classes/android",
3891                               "${ctrlbld}/resources/android")
3892                     } else if (t.name == 'ios') {
3893                         from ("${webbld}/classes/ios",
3894                               "${webbld}/resources/ios")
3895                     } else {
3896                         from ("${webbld}/classes/main",
3897                               "${webbld}resources/main")
3898                     }
3899                     */
3900                 }
3901             }
3902         }
3903         buildModulesTask.dependsOn(buildModuleClassesTask)
3904     }
3905 
3906 
3907     def buildModuleLibsTask = task("buildModuleLibs$t.capital") {
3908         group = "Basic"
3909 
3910         def graphicsProject = project(":graphics");
3911         dependsOn(graphicsProject.assemble)
3912 
3913         def mediaProject = project(":media");
3914         dependsOn(mediaProject.assemble)
3915 
3916         def webProject = project(":web");
3917         dependsOn(webProject.assemble)
3918 
3919         def swtProject = project(":swt");
3920         if (COMPILE_SWT) {
3921             def javafxSwtIndexTask = tasks.getByName("javafxSwtIndex${t.capital}");
3922             dependsOn(javafxSwtIndexTask)
3923         }
3924 
3925         def packagerProject = project(":fxpackager");
3926         //dependsOn(packagerProject.assemble)
3927         dependsOn(packagerProject.jar)
3928         dependsOn(project(":fxpackagerservices").jar)
3929 
3930         doLast {
3931 
3932             def library = targetProperties.library
3933 
3934             // javafx.base (lib/javafx.properties)
3935 
3936             def baseProject = project(":base");
3937             def moduleLibDir = "${baseProject.buildDir}/${platformPrefix}module-lib"
3938             mkdir moduleLibDir
3939             final File javafxProperties = file("${moduleLibDir}/javafx.properties")
3940             javafxProperties.delete()
3941             javafxProperties << "javafx.version=$RELEASE_VERSION_SHORT";
3942             javafxProperties << "\n"
3943             javafxProperties << "javafx.runtime.version=$RELEASE_VERSION_LONG";
3944             javafxProperties << "\n"
3945             javafxProperties << "javafx.runtime.build=$PROMOTED_BUILD_NUMBER";
3946             javafxProperties << "\n"
3947             // Include any properties that have been defined (most likely in
3948             // one of the various platform gradle files)
3949             if (targetProperties.containsKey("javafxProperties")) {
3950                 javafxProperties << targetProperties.javafxProperties
3951                 javafxProperties << "\n"
3952             }
3953 
3954             // Embedded builds define this file as well
3955             if (targetProperties.containsKey("javafxPlatformProperties")) {
3956                 final File javafxPlatformProperties = file("${moduleLibDir}/javafx.platform.properties")
3957                 javafxPlatformProperties.delete()
3958                 javafxPlatformProperties << targetProperties.javafxPlatformProperties
3959                 javafxPlatformProperties << "\n"
3960             }
3961 
3962 
3963             def useLipo = targetProperties.containsKey('useLipo') ? targetProperties.useLipo : false
3964             def modLibDest = targetProperties.modLibDest
3965             def moduleNativeDirName = "${platformPrefix}module-$modLibDest"
3966 
3967             // javafx.graphics native libraries
3968 
3969             copy {
3970                 into "${graphicsProject.buildDir}/${moduleNativeDirName}"
3971 
3972                 from("${graphicsProject.buildDir}/libs/jsl-decora/${t.name}/${library(targetProperties.decora.lib)}")
3973                 def libs = ['font', 'prism', 'prismSW', 'glass', 'iio']
3974                 if (IS_INCLUDE_ES2) {
3975                     libs += ['prismES2'];
3976                 }
3977                 if (IS_COMPILE_PANGO) {
3978                     libs += ['fontFreetype', 'fontPango'];
3979                 }
3980                 libs.each { lib ->
3981                     def variants = targetProperties[lib].containsKey('variants') && !useLipo ? targetProperties[lib].variants : [null]
3982                     variants.each { variant ->
3983                         def variantProperties = variant ? targetProperties[lib][variant] : targetProperties[lib]
3984                         from ("${graphicsProject.buildDir}/libs/$lib/$t.name/${library(variantProperties.lib)}")
3985                     }
3986                 }
3987                 if (IS_WINDOWS) {
3988                     from ("${graphicsProject.buildDir}/libs/prismD3D/${t.name}/${library(targetProperties.prismD3D.lib)}");
3989                 }
3990             }
3991 
3992 
3993             // javafx.media native libraries
3994 
3995             copy {
3996                 into "${mediaProject.buildDir}/${moduleNativeDirName}"
3997 
3998                 def mediaBuildType = project(":media").ext.buildType
3999                 if (IS_COMPILE_MEDIA) {
4000                     [ "fxplugins", "gstreamer-lite", "jfxmedia" ].each { name ->
4001                         from ("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}/${library(name)}") }
4002 
4003                     if (t.name == "mac") {
4004                         // OSX media natives
4005                         [ "jfxmedia_qtkit", "jfxmedia_avf", "glib-lite" ].each { name ->
4006                             from ("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}/${library(name)}") }
4007                     } else if (t.name == "linux") {
4008                         from("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}") { include "libavplugin*.so" }
4009                     } else from ("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}/${library("glib-lite")}")
4010                 } else {
4011                     if (t.name != "android"  && t.name != "dalvik" ) {
4012                         [ "fxplugins", "gstreamer-lite", "jfxmedia" ].each { name ->
4013                             from ("$MEDIA_STUB/${library(name)}") }
4014                     }
4015 
4016                     if (t.name == "mac") {
4017                         // copy libjfxmedia_{avf,qtkit}.dylib if they exist
4018                         [ "jfxmedia_qtkit", "jfxmedia_avf", "glib-lite" ].each { name ->
4019                             from ("$MEDIA_STUB/${library(name)}") }
4020                     } else if (t.name == "linux") {
4021                         from(MEDIA_STUB) { include "libavplugin*.so" }
4022                     }
4023                     else if (t.name != "android"  && t.name != "dalvik" ) {
4024                         from ("$MEDIA_STUB/${library("glib-lite")}")
4025                     }
4026                 }
4027             }
4028 
4029 
4030             // javafx.web native libraries
4031 
4032             copy {
4033                 into "${webProject.buildDir}/${moduleNativeDirName}"
4034 
4035                 if (IS_COMPILE_WEBKIT) {
4036                     from ("${webProject.buildDir}/libs/${t.name}/${library('jfxwebkit')}")
4037                 } else {
4038                     if (t.name != "android" && t.name != "ios" && t.name != "dalvik") {
4039                         from ("$WEB_STUB/${library('jfxwebkit')}")
4040                     }
4041                 }
4042             }
4043 
4044             // FIXME: the following is a hack to workaround the fact that there
4045             // is no way to deliver javafx-swt.jar other than in one of the
4046             // existing runtime modules.
4047             if (COMPILE_SWT) {
4048                 // Copy javafx-swt.jar to the javafx-graphics module lib dir
4049                 copy {
4050                     from "${swtProject.buildDir}/libs/javafx-swt.jar"
4051                     into "${graphicsProject.buildDir}/${platformPrefix}module-lib"
4052                 }
4053             }
4054 
4055             // javafx.packager libraries and executable
4056 
4057             // Copy over the javapackager libs
4058             copy {
4059                 from "${packagerProject.buildDir}/libs"
4060                 into "${packagerProject.buildDir}/${platformPrefix}module-lib"
4061             }
4062 
4063             // Copy over the javapackager executable
4064             if (t.name == "win" || t.name == "linux" || t.name == "mac") {
4065                 copy {
4066                     from "${packagerProject.buildDir}/javapackager"
4067                     into "${packagerProject.buildDir}/${platformPrefix}module-bin"
4068                 }
4069             }
4070 
4071         }
4072     }
4073     buildModulesTask.dependsOn(buildModuleLibsTask)
4074 
4075     Task testArgFiles = task("createTestArgfiles${t.capital}") {
4076 
4077         File testRunArgsFile = new File(rootProject.buildDir, TESTRUNARGSFILE)
4078         //test (shimed) version
4079         File testCompileArgsFile = new File(rootProject.buildDir, TESTCOMPILEARGSFILE)
4080         // And a test java.policy file
4081         File testJavaPolicyFile = new File(rootProject.buildDir, TESTJAVAPOLICYFILE)
4082         // and the non-test version to go with run.args
4083         File runJavaPolicyFile = new File(rootProject.buildDir, RUNJAVAPOLICYFILE);
4084 
4085         outputs.file(testRunArgsFile)
4086         outputs.file(testCompileArgsFile)
4087         outputs.file(testJavaPolicyFile)
4088         outputs.file(runJavaPolicyFile)
4089 
4090         doLast() {
4091             rootProject.buildDir.mkdir()
4092 
4093             List<String> projNames = []
4094             moduleProjList.each { project ->
4095                 projNames << project.name
4096             }
4097 
4098             // And the test (shimed) variation...
4099 
4100             testRunArgsFile.delete()
4101             testCompileArgsFile.delete()
4102 
4103             testJavaPolicyFile.delete()
4104 
4105             List<String> modpath = []
4106 
4107             moduleProjList.each { project ->
4108                 if (project.hasProperty("moduleName") && project.buildModule) {
4109                     File dir;
4110                     if (project.sourceSets.hasProperty('shims')) {
4111                        dir = new File(rootProject.buildDir, "shims/${project.ext.moduleName}")
4112                     } else {
4113                        dir = new File(rootProject.buildDir, "modular-sdk/modules/${project.ext.moduleName}")
4114                     }
4115 
4116                     def dstModuleDir = cygpath(dir.path)
4117                     modpath << "${project.ext.moduleName}=${dstModuleDir}"
4118 
4119                     String themod = dir.toURI()
4120                     testJavaPolicyFile <<  "grant codeBase \"${themod}\" {\n" +
4121                     "    permission java.security.AllPermission;\n" +
4122                     "};\n"
4123 
4124                     dir = new File(rootProject.buildDir, "modular-sdk/modules/${project.ext.moduleName}")
4125                     themod = dir.toURI()
4126                     runJavaPolicyFile <<  "grant codeBase \"${themod}\" {\n" +
4127                     "    permission java.security.AllPermission;\n" +
4128                     "};\n"
4129                 }
4130             }
4131 
4132             writeRunArgsFile(testCompileArgsFile, null, modpath)
4133             writeRunArgsFile(testRunArgsFile, computeLibraryPath(true), modpath)
4134         }
4135     }
4136     sdk.dependsOn(testArgFiles)
4137     createTestArgfiles.dependsOn(testArgFiles)
4138 
4139     def sdkTask = tasks.getByName("sdk${t.capital}");
4140     sdkTask.dependsOn(buildModulesTask)
4141 }
4142 sdk.dependsOn(buildModules)
4143 
4144 task checkrepo() {
4145     doLast {
4146         logger.info("checking for whitespace (open)");
4147         exec {
4148             if (IS_WINDOWS) {
4149                 commandLine  'bash', 'tools/scripts/checkWhiteSpace'
4150             } else {
4151                 commandLine  'bash', 'tools/scripts/checkWhiteSpace', '-x'
4152             }
4153         }
4154     }
4155 }
4156 
4157 task checkrepoall() {
4158     doLast {
4159         logger.info("checking for all whitespace (open)");
4160         exec {
4161             if (IS_WINDOWS) {
4162                 commandLine  'bash', 'tools/scripts/checkWhiteSpace', '-a'
4163             } else {
4164                 commandLine  'bash', 'tools/scripts/checkWhiteSpace', '-x', '-a'
4165             }
4166         }
4167     }
4168 }
4169 
4170 /******************************************************************************
4171  *                                                                            *
4172  *                              BUILD_CLOSED                                  *
4173  *                                                                            *
4174  * This next section should remain at the end of the build script. It allows  *
4175  * for a "supplemental" gradle file to be used to extend the normal build     *
4176  * structure. For example, this is used for passing a supplemental gradle     *
4177  * file for producing official JavaFX builds.                                 *
4178  *                                                                            *
4179  *****************************************************************************/
4180 
4181 if (BUILD_CLOSED) {
4182     apply from: supplementalBuildFile
4183 }
4184 
4185 task showFlags {
4186 }
4187 
4188 compileTargets { t ->
4189     // Every platform must define these variables
4190     def props = project.ext[t.upper];
4191     showFlags.dependsOn(
4192         project.task("showFlags$t.upper") {
4193             doLast() {
4194                 println "Properties set for $t.upper"
4195                 props.each { println it }
4196             }
4197         }
4198     )
4199 
4200 }