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