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