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