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