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