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