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