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 = 1.9
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         def copyDumpTreeNativeTask = task("copyDumpTreeNative${t.capital}", type: Copy,
3799                 dependsOn: [ compileNativeTask]) {
3800             def library = rootProject.ext[t.upper].library
3801             from "$webkitOutputDir/$webkitConfig/lib/${library('DumpRenderTreeJava')}"
3802             into "$buildDir/test/${t.name}"
3803         }
3804 
3805         def copyNativeTask = task("copyNative${t.capital}", type: Copy,
3806                 dependsOn: [compileNativeTask, , copyDumpTreeNativeTask]) {
3807             enabled =  (IS_COMPILE_WEBKIT)
3808             def library = rootProject.ext[t.upper].library
3809             from "$webkitOutputDir/$webkitConfig/lib/${library('jfxwebkit')}"
3810             into "$buildDir/libs/${t.name}"
3811         }
3812 
3813         if (IS_WINDOWS && t.name == "win") {
3814             def rcTask = project.task("rc${t.capital}", type: CompileResourceTask) {
3815                 compiler = webkitProperties.rcCompiler
3816                 source(webkitProperties.rcSource)
3817                 if (webkitProperties.rcFlags) {
3818                     rcParams.addAll(webkitProperties.rcFlags)
3819                 }
3820                 output(file("$webkitOutputDir/$webkitConfig/WebCore/obj"))
3821             }
3822             compileNativeTask.dependsOn rcTask
3823         }
3824 
3825         def compileJavaDOMBindingTask = task("compileJavaDOMBinding${t.capital}", type: JavaCompile,
3826                 dependsOn: [compileJava, compileNativeTask, copyNativeTask]) {
3827             destinationDir = file("$buildDir/classes/java/main")
3828             classpath = configurations.compile
3829             source = project.sourceSets.main.java.srcDirs
3830             options.compilerArgs.addAll([
3831                 '-implicit:none',
3832                 '--module-source-path', defaultModuleSourcePath
3833                 ])
3834         }
3835 
3836         compileJavaDOMBinding.dependsOn compileJavaDOMBindingTask
3837 
3838         if (!targetProperties.compileWebnodeNative) {
3839             println("Not compiling native Webkit for ${t.name} per configuration request");
3840             compileNativeTask.enabled = false
3841         }
3842     }
3843 
3844     def drtClasses = "**/com/sun/javafx/webkit/drt/**"
3845     task drtJar(type: Jar, dependsOn: compileJava) {
3846         archiveName = "drt.jar"
3847         destinationDir = file("$buildDir/test")
3848         from "$buildDir/classes/java/main/javafx.web/"
3849         include drtClasses
3850         includeEmptyDirs = false
3851     }
3852 
3853     if (IS_COMPILE_WEBKIT) {
3854         assemble.dependsOn compileJavaDOMBinding, drtJar
3855     }
3856 }
3857 
3858 // This project is for system tests that need to run with a full SDK.
3859 // Most of them display a stage or do other things that preclude running
3860 // them in a shared JVM or as part of the "smoke test" run (which must
3861 // not pop up any windows or use audio). As such, they are only enabled
3862 // when FULL_TEST is specified, and each test runs in its own JVM
3863 project(":systemTests") {
3864 
3865     sourceSets {
3866         test
3867 
3868         // Source sets for standalone test apps (used for launcher tests)
3869         testapp1
3870 
3871         // Modular applications
3872         testapp2
3873         testapp3
3874         testapp4
3875         testapp5
3876         testapp6
3877     }
3878 
3879     project.ext.buildModule = false
3880     project.ext.moduleRuntime = false
3881     project.ext.moduleName = "systemTests"
3882 
3883     dependencies {
3884         testCompile project(":graphics").sourceSets.test.output
3885         testCompile project(":base").sourceSets.test.output
3886         testCompile project(":controls").sourceSets.test.output
3887         testCompile project(":swing").sourceSets.test.output
3888     }
3889 
3890     def dependentProjects = [ 'base', 'graphics', 'controls', 'media', 'web', 'swing', 'fxml' ]
3891     commonModuleSetup(project, dependentProjects)
3892 
3893     File testJavaPolicyFile = new File(rootProject.buildDir, TESTJAVAPOLICYFILE);
3894     File testRunArgsFile = new File(rootProject.buildDir,TESTRUNARGSFILE);
3895 
3896     File stRunArgsFile = new File(project.buildDir,"st.run.args");
3897 
3898     def sts = task("systemTestSetup") {
3899         outputs.file(stRunArgsFile)
3900 
3901         doLast() {
3902             stRunArgsFile.delete()
3903 
3904             logger.info("Creating patchmodule.args file ${stRunArgsFile}")
3905 
3906             // Create an argfile with the information needed to launch
3907             // the stand alone system unit tests.
3908 
3909             //First add in all of the patch-module args we use for the
3910             //normal unit tests, copied from test.run.args
3911             testRunArgsFile.eachLine { str ->
3912                 stRunArgsFile <<  "${str}\n"
3913             }
3914 
3915             // Now add in the working classpath elements (junit, test classes...)
3916             stRunArgsFile <<  "-cp \"\\\n"
3917             test.classpath.each() { elem ->
3918                 def e = cygpath("${elem}")
3919                 stRunArgsFile <<  "  ${e}${File.pathSeparator}\\\n"
3920             }
3921             stRunArgsFile <<  "\"\n"
3922         }
3923     }
3924 
3925     test.dependsOn(sts)
3926     test.dependsOn(createTestArgfiles);
3927 
3928     // Tasks to create standalone test applications for the launcher tests
3929 
3930     if (project.hasProperty('testModulePathArgs')) {
3931         compileTestapp1Java.options.compilerArgs.addAll(testModulePathArgs)
3932     }
3933     dependentProjects.each { e ->
3934         compileTestapp1Java.dependsOn(rootProject.project(e).testClasses)
3935     }
3936 
3937     def testapp1JarName = "testapp1.jar"
3938     task createTestapp1Jar1(type: Jar) {
3939         dependsOn compileTestapp1Java
3940         enabled = IS_FULL_TEST
3941 
3942         destinationDir = file("$buildDir/testapp1")
3943         archiveName = testapp1JarName
3944         includeEmptyDirs = false
3945         from project.sourceSets.testapp1.java.outputDir
3946         include("testapp/**")
3947         include("com/javafx/main/**")
3948 
3949         manifest {
3950             attributes(
3951                 "Main-Class" : "com.javafx.main.Main",
3952                 "JavaFX-Version" : "2.2",
3953                 "JavaFX-Application-Class" : "testapp.HelloWorld",
3954                 "JavaFX-Class-Path" : "jar2.jar"
3955             )
3956         }
3957     }
3958 
3959     task createTestapp1Jar2(type: Jar) {
3960         dependsOn compileTestapp1Java
3961         enabled = IS_FULL_TEST
3962 
3963         destinationDir = file("$buildDir/testapp1")
3964         archiveName = "jar2.jar";
3965         includeEmptyDirs = false
3966         from project.sourceSets.testapp1.java.outputDir
3967         include("pkg2/**")
3968     }
3969 
3970     task createTestApps() {
3971         dependsOn(createTestapp1Jar1)
3972         dependsOn(createTestapp1Jar2)
3973     }
3974     test.dependsOn(createTestApps);
3975 
3976     def modtestapps = [ "testapp2", "testapp3", "testapp4", "testapp5", "testapp6"  ]
3977     modtestapps.each { testapp ->
3978         def testappCapital = testapp.capitalize()
3979         def copyTestAppTask = task("copy${testappCapital}", type: Copy) {
3980             from project.sourceSets."${testapp}".java.outputDir
3981             from project.sourceSets."${testapp}".output.resourcesDir
3982             into "${project.buildDir}/modules/${testapp}"
3983         }
3984 
3985         def List<String> testAppSourceDirs = []
3986         project.sourceSets."${testapp}".java.srcDirs.each { dir ->
3987             testAppSourceDirs += dir
3988         }
3989         def testappCompileTasks = project.getTasksByName("compile${testappCapital}Java", true);
3990         def testappResourceTasks = project.getTasksByName("process${testappCapital}Resources", true);
3991         testappCompileTasks.each { appCompileTask ->
3992             appCompileTask.options.compilerArgs.addAll([
3993                 '-implicit:none',
3994                 '--module-source-path', testAppSourceDirs.join(File.pathSeparator),
3995                 ] )
3996             if (project.hasProperty('testModulePathArgs')) {
3997                 appCompileTask.options.compilerArgs.addAll(testModulePathArgs)
3998             }
3999 
4000             dependentProjects.each { e ->
4001                 appCompileTask.dependsOn(rootProject.project(e).testClasses)
4002             }
4003 
4004             copyTestAppTask.dependsOn(appCompileTask)
4005         }
4006         testappResourceTasks.each { appResourceTask ->
4007             copyTestAppTask.dependsOn(appResourceTask)
4008         }
4009 
4010         createTestApps.dependsOn(copyTestAppTask)
4011     }
4012 
4013     test {
4014         enabled = IS_FULL_TEST
4015 
4016         // Parse testPatchModuleArgs looking for "--module-path".
4017         // Save path if found so we can pass it to the module launcher tests
4018         def pendingModulePath = false
4019         testPatchModuleArgs.each { str ->
4020             if (pendingModulePath) {
4021                 project.ext.launcherModulePath = str;
4022                 pendingModulePath = false
4023             } else if (str == "--module-path") {
4024                 pendingModulePath = true
4025             }
4026         }
4027 
4028         // Properties passed to launcher tests
4029         systemProperty "launchertest.testapp1.jar", "build/testapp1/$testapp1JarName"
4030         modtestapps.each { testapp ->
4031             systemProperty "launchertest.${testapp}.module.path",
4032                     "${project.buildDir}/modules/${testapp}"
4033         }
4034 
4035         // Properties passed to test.util.Util
4036         systemProperties 'worker.debug': IS_WORKER_DEBUG
4037         systemProperties 'worker.patchmodule.file': cygpath(stRunArgsFile.path)
4038         if (project.hasProperty("launcherModulePath")) {
4039             systemProperties 'worker.module.path': launcherModulePath
4040         }
4041         systemProperties 'worker.patch.policy': cygpath(testJavaPolicyFile.path)
4042         systemProperties 'worker.java.cmd': JAVA
4043 
4044         if (!IS_USE_ROBOT) {
4045             // Disable all robot-based visual tests
4046             exclude("test/robot/**");
4047         }
4048         if (!IS_UNSTABLE_TEST) {
4049             // JDK-8196607 Don't run monocle test cases 
4050             exclude("test/robot/com/sun/glass/ui/monocle/**");
4051         }
4052         if (!IS_AWT_TEST) {
4053             // Disable all AWT-based tests
4054             exclude("**/javafx/embed/swing/*.*");
4055             exclude("**/com/sun/javafx/application/Swing*.*");
4056         }
4057 
4058         if (!HAS_JAVAFX_MODULES) {
4059             jvmArgs += qualExportsSwing
4060         }
4061 
4062         forkEvery = 1
4063     }
4064 }
4065 
4066 allprojects {
4067     // The following block is a workaround for the fact that presently Gradle
4068     // can't set the -XDignore.symbol.file flag, because it appears that the
4069     // javac API is lacking support for it. So what we'll do is find any Compile
4070     // task and manually provide the options necessary to fire up the
4071     // compiler with the right settings.
4072     tasks.withType(JavaCompile) { compile ->
4073         if (compile.options.hasProperty("useAnt")) {
4074             compile.options.useAnt = true
4075             compile.options.useDepend = IS_USE_DEPEND
4076         } else if (compile.options.hasProperty("incremental")) {
4077             compile.options.incremental = IS_INCREMENTAL
4078         }
4079         compile.options.debug = true // we always generate debugging info in the class files
4080         compile.options.debugOptions.debugLevel = IS_DEBUG_JAVA ? "source,lines,vars" : "source,lines"
4081         compile.options.fork = true
4082 
4083         compile.options.forkOptions.executable = JAVAC
4084 
4085         compile.options.warnings = IS_LINT
4086 
4087         compile.options.compilerArgs += ["-XDignore.symbol.file", "-encoding", "UTF-8"]
4088 
4089         // we use a custom javadoc command
4090         project.javadoc.enabled = false
4091 
4092         // Add in the -Xlint options
4093         if (IS_LINT) {
4094             LINT.split("[, ]").each { s ->
4095                 compile.options.compilerArgs += "-Xlint:$s"
4096             }
4097         }
4098     } // tasks with javaCompile
4099 
4100     // If I am a module....
4101     if (project.hasProperty('moduleSourcePath') &&
4102             (project.hasProperty('buildModule') && project.buildModule)) {
4103         project.compileJava {
4104             options.compilerArgs.addAll([
4105                 '-implicit:none',
4106                 '--module-source-path', project.moduleSourcePath
4107                 ])
4108         }
4109         // no jars needed for modules
4110         project.jar.enabled = false
4111 
4112         // and redirect the resources into the module
4113         project.processResources.destinationDir = project.moduleDir
4114     }
4115 
4116     if (project.hasProperty('moduleSourcePathShim') &&
4117             project.sourceSets.hasProperty('shims')) {
4118 
4119         // sync up the obvious source directories with the shims
4120         // others (like the shaders in graphics) should be added in there
4121         project.sourceSets.shims.java.srcDirs += project.sourceSets.main.java.srcDirs
4122         project.sourceSets.shims.java.srcDirs += "$buildDir/gensrc/java"
4123 
4124         project.compileShimsJava {
4125             options.compilerArgs.addAll([
4126                 '-implicit:none',
4127                 '--module-source-path', project.moduleSourcePathShim
4128                 ])
4129         }
4130         project.compileShimsJava.dependsOn(project.compileJava)
4131 
4132         def copyGeneratedShimsTask = task("copyGeneratedShims", type: Copy, dependsOn: [compileShimsJava, processShimsResources]) {
4133             from project.sourceSets.shims.java.outputDir
4134             into "${rootProject.buildDir}/shims"
4135             if (HAS_JAVAFX_MODULES) {
4136                 exclude("*/module-info.class")
4137             }
4138         }
4139 
4140         project.processShimsResources.dependsOn(project.processResources)
4141 
4142         // shims resources should have the main resouces as a base
4143         project.sourceSets.shims.resources.srcDirs += project.sourceSets.main.resources.srcDirs
4144 
4145         // and redirect the resources into the module
4146         project.processShimsResources.destinationDir = project.moduleShimsDir
4147 
4148        compileTestJava.dependsOn(copyGeneratedShimsTask)
4149     }
4150 
4151     if (project.hasProperty('modulePathArgs')) {
4152         project.compileJava.options.compilerArgs.addAll(modulePathArgs)
4153     }
4154 
4155     if (project.hasProperty('testModulePathArgs')) {
4156         project.compileTestJava.options.compilerArgs.addAll(testModulePathArgs)
4157     }
4158 
4159     if (project.hasProperty('testPatchModuleArgs')) {
4160         project.test.jvmArgs += testPatchModuleArgs
4161     }
4162 
4163     /* Note: we should not have to add extraAddExports to the normal
4164      * modular compile, as it contains all of the module-info files.
4165      * In fact doing so might cover up a module-info issue.
4166      * so we don't do it, and I will leave this commented out
4167      * block as a reminder of this fact.
4168     if (project.hasProperty('extraAddExports')) {
4169         project.compileJava.options.compilerArgs.addAll(extraAddExports);
4170     }
4171     */
4172 
4173     if (project.hasProperty('testAddExports')) {
4174         project.compileTestJava.options.compilerArgs.addAll(testAddExports);
4175         project.test.jvmArgs += testAddExports
4176     }
4177 
4178     if (rootProject.hasProperty("EXTRA_TEST_ARGS") && project.hasProperty('test')) {
4179         EXTRA_TEST_ARGS.split(' ').each() { e ->
4180             project.test.jvmArgs += e
4181         }
4182     }
4183 
4184     if (rootProject.hasProperty("EXTRA_COMPILE_ARGS") && project.hasProperty('compileJava')) {
4185         project.compileJava.options.compilerArgs.addAll(EXTRA_COMPILE_ARGS.split(' '))
4186     }
4187 
4188     if (rootProject.hasProperty("EXTRA_COMPILE_ARGS") && project.hasProperty('compileTestJava')) {
4189         project.compileTestJava.options.compilerArgs.addAll(EXTRA_COMPILE_ARGS.split(' '))
4190     }
4191 
4192 }
4193 
4194 /******************************************************************************
4195  *                                                                            *
4196  *                             Top Level Tasks                                *
4197  *                                                                            *
4198  *  These are the tasks which are defined only for the top level project and  *
4199  *  not for any sub projects. These are generally the entry point that is     *
4200  *  used by Hudson and by the continuous build system.                        *
4201  *                                                                            *
4202  *****************************************************************************/
4203 
4204 task clean() {
4205     group = "Basic"
4206     description = "Deletes the build directory and the build directory of all sub projects"
4207     getSubprojects().each { subProject ->
4208         dependsOn(subProject.getTasksByName("clean", true));
4209     }
4210     doLast {
4211         delete(buildDir);
4212     }
4213 }
4214 
4215 task cleanAll() {
4216     group = "Basic"
4217     description = "Scrubs the repo of build artifacts"
4218     dependsOn(clean)
4219     doLast {
4220         //delete(".gradle"); This causes problems on windows.
4221         delete("buildSrc/build");
4222     }
4223 }
4224 
4225 task createMSPfile() {
4226     group = "Build"
4227     File mspFile = new File(rootProject.buildDir,MODULESOURCEPATH)
4228     outputs.file(mspFile)
4229 
4230     doLast {
4231         mspFile.delete()
4232         mspFile << "--module-source-path\n"
4233         mspFile << defaultModuleSourcePath
4234         mspFile << "\n"
4235 
4236         if (!HAS_JAVAFX_MODULES) {
4237             appendQualExports(mspFile, qualExportsSwing)
4238         }
4239     }
4240 }
4241 
4242 task javadoc(type: Javadoc, dependsOn: createMSPfile) {
4243     group = "Basic"
4244     description = "Generates the JavaDoc for all the public API"
4245     executable = JAVADOC
4246     def projectsToDocument = [
4247             project(":base"), project(":graphics"), project(":controls"), project(":media"),
4248             project(":swing"), /*project(":swt"),*/ project(":fxml"), project(":web")]
4249     source(projectsToDocument.collect({
4250         [it.sourceSets.main.java]
4251     }));
4252     setDestinationDir(new File(buildDir, 'javadoc'));
4253 
4254     exclude("com/**/*", "Compile*", "javafx/builder/**/*", "javafx/scene/accessibility/**/*");
4255 
4256     options.tags("apiNote:a:API Note:")
4257     options.tags("implSpec:a:Implementation Requirements:")
4258     options.tags("implNote:a:Implementation Note:")
4259     options.tags("param")
4260     options.tags("return")
4261     options.tags("throws")
4262     options.tags("moduleGraph:X")
4263     options.tags("since")
4264     options.tags("version")
4265     options.tags("serialData")
4266     options.tags("factory")
4267     options.tags("see")
4268 
4269     options.windowTitle("${javadocTitle}")
4270     options.header("${javadocHeader}")
4271     options.bottom("${javadocBottom}")
4272     options.locale("en");
4273     if (JDK_DOCS_LINK != "") {
4274         options.linksOffline(JDK_DOCS, JDK_DOCS_LINK);
4275     } else {
4276         options.links(JDK_DOCS);
4277     }
4278     options.addBooleanOption("XDignore.symbol.file").setValue(true);
4279     options.addBooleanOption("Xdoclint:${DOC_LINT}").setValue(IS_DOC_LINT);
4280     options.addBooleanOption("html5").setValue(true);
4281     options.addBooleanOption("javafx").setValue(true);
4282     options.addBooleanOption("use").setValue(true);
4283 
4284     options.setOptionFiles([
4285         new File(rootProject.buildDir,MODULESOURCEPATH)
4286         ]);
4287 
4288     doLast {
4289         projectsToDocument.each { p ->
4290             copy {
4291                 from("$p.projectDir/src/main/docs") {
4292                     include "**/*.html"
4293                     filter { line->
4294                         line = line.replace("@FXVERSION@", RELEASE_VERSION)
4295                     }
4296                 }
4297                 from("$p.projectDir/src/main/docs") {
4298                     exclude "**/*.html"
4299                 }
4300 
4301                 into "$buildDir/javadoc"
4302             }
4303         }
4304     }
4305 
4306     dependsOn(projectsToDocument.collect { project -> project.getTasksByName("classes", true)});
4307 }
4308 
4309 task sdk() {
4310     if (DO_BUILD_SDK_FOR_TEST) {
4311         rootProject.getTasksByName("test", true).each { t ->
4312             if (t.enabled) t.dependsOn(sdk)
4313         }
4314     }
4315 }
4316 
4317 task jmods() {
4318     dependsOn(sdk)
4319     // real work items added later.
4320 }
4321 
4322 task appsjar() {
4323     dependsOn(sdk)
4324     // Note: the jar dependencies get added elsewhere see project(":apps")
4325 }
4326 
4327 // these are empty tasks, allowing us to depend on the task, which may have other
4328 // real work items added later.
4329 task copyAppsArtifacts() {
4330     dependsOn(appsjar)
4331 }
4332 
4333 task apps() {
4334     dependsOn(sdk)
4335     dependsOn(appsjar)
4336     dependsOn(copyAppsArtifacts)
4337 }
4338 
4339 task findbugs() {
4340     dependsOn(sdk)
4341 
4342     doLast {
4343         if (!BUILD_CLOSED) {
4344             println "findbugs task is only run for a closed build"
4345         }
4346     }
4347 }
4348 
4349 // create the zip file of modules for a JDK build
4350 task jdkZip {
4351     dependsOn(sdk)
4352 }
4353 
4354 // The following tasks are for the closed build only. They are a no-op for the open build
4355 
4356 task checkCache() {
4357     dependsOn(updateCacheIfNeeded)
4358 }
4359 
4360 task publicExports() {
4361     dependsOn(sdk, jmods, apps, javadoc, jdkZip)
4362     // note the real work is below in the compileTargets
4363 }
4364 
4365 task perf() {
4366     dependsOn(sdk, apps)
4367     doLast {
4368         if (!BUILD_CLOSED) {
4369             println "perf task is only run for a closed build"
4370         }
4371     }
4372 }
4373 
4374 task zips() {
4375     dependsOn(sdk, jmods, javadoc, apps, jdkZip, publicExports, perf)
4376     // note the real work is below in the compileTargets
4377 }
4378 
4379 task all() {
4380     dependsOn(sdk,publicExports,apps,perf,zips)
4381 }
4382 
4383 
4384 // Construct list of subprojects that are modules
4385 ext.moduleProjList = []
4386 subprojects {
4387     if (project.hasProperty("buildModule") && project.ext.buildModule) {
4388         rootProject.ext.moduleProjList += project
4389         println "module: $project (buildModule=YES)"
4390     } else {
4391         println "module: $project (buildModule=NO)"
4392     }
4393 }
4394 
4395 
4396 // Define the sdk task, which also produces the javafx.swt modular jar
4397 
4398 compileTargets { t ->
4399 
4400     def javafxSwtTask = task("javafxSwt$t.capital", type: Jar) {
4401         enabled = COMPILE_SWT
4402         group = "Basic"
4403         description = "Creates the javafx-swt.jar for the $t.name target"
4404         archiveName = "${project(":swt").buildDir}/libs/javafx-swt.jar";
4405         includeEmptyDirs = false
4406         from("${project(":swt").buildDir}/classes/java/main");
4407         include("**/javafx/embed/swt/**")
4408 
4409         dependsOn(
4410             project(":swt").compileJava,
4411             project(":swt").processResources,
4412             // note: assemble and classes are not enough for DidWork
4413             project(":swt").classes,
4414             // classes is needed for a jar copy
4415             )
4416     }
4417 
4418     // FIXME: do we really need the index task for this modular jar?
4419     def javafxSwtIndexTask = task("javafxSwtIndex$t.capital") {
4420         //the following is a workaround for the lack of indexing in gradle 1.4 through 1.7
4421         dependsOn(javafxSwtTask)
4422 
4423         doLast() {
4424             ant.jar (update: true, index: true, destfile: javafxSwtTask.archiveName)
4425         }
4426     }
4427 
4428     def sdkTask = task("sdk$t.capital") {
4429         group = "Basic"
4430         dependsOn(javafxSwtIndexTask)
4431     }
4432 
4433     sdk.dependsOn(sdkTask)
4434 }
4435 
4436 project(":apps") {
4437     // The apps build is Ant based, we will exec ant from gradle.
4438 
4439     // Download the Lucene libraries needed for the Ensemble8 app
4440     getConfigurations().create("lucene");
4441     dependencies {
4442         lucene group: "org.apache.lucene", name: "lucene-core", version: "7.1.0"
4443         lucene group: "org.apache.lucene", name: "lucene-grouping", version: "7.1.0"
4444         lucene group: "org.apache.lucene", name: "lucene-queryparser", version: "7.1.0"
4445     }
4446 
4447     // Copy Lucene libraries into the Ensemble8/lib directory
4448     File ensembleLibDir = rootProject.file("apps/samples/Ensemble8/lib");
4449     def libNames = [ "lucene-core-7.1.0.jar",
4450                      "lucene-grouping-7.1.0.jar",
4451                      "lucene-queryparser-7.1.0.jar" ]
4452 
4453 
4454     task getLucene(type: Copy) {
4455         doFirst {
4456             ensembleLibDir.mkdirs();
4457         }
4458         into ensembleLibDir
4459         includeEmptyDirs = false
4460         configurations.lucene.files.each { f ->
4461             libNames.each { name ->
4462                 if (name == f.getName()) {
4463                     from f.getPath()
4464                 }
4465             }
4466         }
4467     }
4468 
4469     compileTargets { t ->
4470         List<String> params = []
4471 
4472         params << "-DtargetBld=$t.name"
4473 
4474         if (!rootProject.ext[t.upper].compileSwing) {
4475             params << "-DJFX_CORE_ONLY=true"
4476         }
4477         params << "-Dplatforms.JDK_1.9.home=${rootProject.ext.JDK_HOME}"
4478         params << "-Dcompile.patch=@${rootProject.buildDir}/${COMPILEARGSFILE}"
4479         params << "-Drun.patch=@${rootProject.buildDir}/${RUNARGSFILE}"
4480 
4481         def appsJar = project.task("appsJar${t.capital}") {
4482             dependsOn(sdk, getLucene)
4483             doLast() {
4484                 ant(t.name,
4485                       projectDir.path,
4486                       "appsJar",
4487                       params);
4488             }
4489         }
4490         rootProject.appsjar.dependsOn(appsJar)
4491 
4492         def appsClean = project.task("clean${t.capital}") {
4493             doLast() {
4494                 ant(t.name,
4495                       project.projectDir.path,
4496                       "clean",
4497                       params);
4498                 delete(ensembleLibDir);
4499             }
4500         }
4501         rootProject.clean.dependsOn(appsClean)
4502     }
4503 }
4504 
4505 // Tasks to create the disk layout for the sdk, jmods, and docs
4506 // in the artifacts directory (publicExports), and zip them up in
4507 // artifacts/bundles (zips)
4508 // These tasks are only used for the standalone SDK.
4509 compileTargets { t ->
4510     if (!HAS_JAVAFX_MODULES) {
4511         def targetProperties = rootProject.ext[t.upper]
4512         def platformPrefix = targetProperties.platformPrefix
4513 
4514         def artifactsDir = "${rootProject.buildDir}/artifacts"
4515         def bundlesDir = "${artifactsDir}/bundles"
4516 
4517         def sdkDirName = "${platformPrefix}sdk"
4518         def sdkDir = "${rootProject.buildDir}/${sdkDirName}"
4519         def sdkBundleName = "javafx-sdk-${RELEASE_VERSION}"
4520         def sdkArtifactsDir = "${artifactsDir}/${sdkBundleName}"
4521 
4522         def docsDirName = "javadoc"
4523         def docsDir = "${rootProject.buildDir}/${docsDirName}"
4524         def docsBundleName = "javafx-docs-${RELEASE_VERSION}"
4525         def docsArtifactsDir = "${artifactsDir}/${docsBundleName}"
4526 
4527         def jmodsDirName = "jmods"
4528         def jmodsDir = "${rootProject.buildDir}/${jmodsDirName}"
4529         def jmodsBundleName = "javafx-jmods-${RELEASE_VERSION}"
4530         def jmodsArtifactsDir = "${artifactsDir}/${jmodsBundleName}"
4531 
4532         def publicExportsTask = task ("publicExportsStandalone${t.capital}") {
4533             group = "Basic"
4534             description = "Creates the disk layout for sdk, jmods, and docs"
4535         }
4536         publicExports.dependsOn(publicExportsTask)
4537 
4538         def copyArtifactsSdkTask = task("copyArtifactsSdk$t.capital", type: Copy, dependsOn: [sdk,jmods,apps,javadoc]) {
4539             from sdkDir
4540             into sdkArtifactsDir
4541         }
4542         publicExportsTask.dependsOn(copyArtifactsSdkTask)
4543 
4544         // Need to modify file permissions Windows to make sure that the
4545         // execute bit is set, and that the files are world readable
4546         def chmodArtifactsSdkTask = task("chmodArtifactsSdk$t.capital", dependsOn: copyArtifactsSdkTask) {
4547             if (IS_WINDOWS) {
4548                 doLast {
4549                     exec {
4550                         workingDir(sdkArtifactsDir)
4551                         commandLine("chmod", "-R", "755", ".")
4552                     }
4553                 }
4554             }
4555         }
4556         publicExportsTask.dependsOn(chmodArtifactsSdkTask)
4557 
4558         def copyArtifactsDocsTask = task("copyArtifactsDocs$t.capital", type: Copy, dependsOn: chmodArtifactsSdkTask) {
4559             from docsDir
4560             into "${docsArtifactsDir}/api"
4561         }
4562         publicExportsTask.dependsOn(copyArtifactsDocsTask)
4563 
4564         def copyArtifactsJmodsTask = task("copyArtifactsJmods$t.capital", type: Copy, dependsOn: copyArtifactsDocsTask) {
4565             from jmodsDir
4566             into "${jmodsArtifactsDir}"
4567         }
4568         publicExportsTask.dependsOn(copyArtifactsJmodsTask)
4569 
4570         def zipsTask = task ("zipsStandalone${t.capital}") {
4571             group = "Basic"
4572             description = "Creates the public zip bundles"
4573         }
4574         zips.dependsOn(zipsTask)
4575 
4576         // Use native zip tool so that file permissions are preserved on Windows
4577         def zipSdkTask = task("zipSdk$t.capital", dependsOn: publicExportsTask) {
4578             doLast {
4579                 def outZipFile = "${bundlesDir}/${sdkBundleName}.zip"
4580                 mkdir bundlesDir
4581                 exec {
4582                     workingDir(artifactsDir)
4583                     commandLine("zip", "-q", "-r", outZipFile, sdkBundleName)
4584                 }
4585             }
4586         }
4587         zipsTask.dependsOn(zipSdkTask)
4588 
4589         def zipDocsTask = task("zipDocs$t.capital", type: Zip, dependsOn: zipSdkTask) {
4590             destinationDir = file("${bundlesDir}")
4591             archiveName = "${docsBundleName}.zip"
4592             includeEmptyDirs = false
4593             from docsArtifactsDir
4594             into "${docsBundleName}"
4595         }
4596         zipsTask.dependsOn(zipDocsTask)
4597 
4598         def zipJmodsTask = task("zipJmods$t.capital", type: Zip, dependsOn: zipDocsTask) {
4599             destinationDir = file("${bundlesDir}")
4600             archiveName = "${jmodsBundleName}.zip"
4601             includeEmptyDirs = false
4602             from jmodsArtifactsDir
4603             into "${jmodsBundleName}"
4604         }
4605         zipsTask.dependsOn(zipJmodsTask)
4606     }
4607 }
4608 
4609 
4610 /******************************************************************************
4611  *                                                                            *
4612  *                               Modules                                      *
4613  *                                                                            *
4614  *****************************************************************************/
4615 
4616 ext.moduleDependencies = [file("dependencies")]
4617 
4618 task buildModules {
4619 }
4620 
4621 // Combine the classes, lib, and bin for each module
4622 compileTargets { t ->
4623     def targetProperties = project.ext[t.upper]
4624 
4625     def platformPrefix = targetProperties.platformPrefix
4626     def bundledSdkDirName = "${platformPrefix}modular-sdk"
4627     def bundledSdkDir = "${rootProject.buildDir}/${bundledSdkDirName}"
4628     def modulesDir = "${bundledSdkDir}/modules"
4629     def modulesCmdsDir = "${bundledSdkDir}/modules_cmds"
4630     def modulesLibsDir = "${bundledSdkDir}/modules_libs"
4631     def modulesSrcDir = "${bundledSdkDir}/modules_src"
4632     def modulesConfDir = "${bundledSdkDir}/modules_conf"
4633     def modulesLegalDir = "${bundledSdkDir}/modules_legal"
4634     def modulesMakeDir = "${bundledSdkDir}/make"
4635 
4636     final File runArgsFile = file("${rootProject.buildDir}/${RUNARGSFILE}")
4637     final File compileArgsFile = file("${rootProject.buildDir}/${COMPILEARGSFILE}")
4638 
4639     project.files(runArgsFile);
4640 
4641     def buildModulesTask = task("buildModules$t.capital", group: "Build") {
4642         // BUNDLED SDK
4643 
4644         // Copy dependencies/*/module-info.java.extra
4645         // merging as needed, removing duplicates
4646         // only lines with 'exports' will be copied
4647         def dependencyRoots = moduleDependencies
4648         if (rootProject.hasProperty("closedModuleDepedencies")) {
4649             dependencyRoots = [dependencyRoots, closedModuleDepedencies].flatten()
4650         }
4651 
4652         // Create the inputs/outputs list first to support UP-TO-DATE
4653         ArrayList outputNames = new ArrayList()
4654         dependencyRoots.each { root ->
4655             FileTree ft = fileTree(root).include('**/*.extra')
4656             ft.each() { e->
4657                 inputs.file(e)
4658 
4659                 String usename = e.path
4660                 String filePath = e.getAbsolutePath()
4661                 String folderPath = root.getAbsolutePath()
4662                 if (filePath.startsWith(folderPath)) {
4663                     usename = filePath.substring(folderPath.length() + 1);
4664                 }
4665                 if (! outputNames.contains(usename) ) {
4666                     outputNames.add(usename)
4667                 }
4668             }
4669         }
4670 
4671         outputNames.each() { e->
4672                 File f = new File(modulesSrcDir, e)
4673                 outputs.file(f)
4674         }
4675 
4676         def outputPolicyDir = "${modulesConfDir}/java.base/security"
4677         def outputPolicyFile = file("${outputPolicyDir}/java.policy.extra")
4678 
4679         outputs.file(outputPolicyFile)
4680         moduleProjList.each { project ->
4681             def policyDir = "${project.projectDir}/src/main/conf/security"
4682             def policyFile = file("${policyDir}/java.policy")
4683             if (policyFile.exists()) {
4684                 inputs.file(policyFile)
4685             }
4686         }
4687 
4688         doLast {
4689             Map extras = [:]
4690 
4691             dependencyRoots.each { root ->
4692                 FileTree ft = fileTree(root).include('**/*.extra')
4693                 ft.each() { e->
4694                     String usename = e.path
4695                     String filePath = e.getAbsolutePath()
4696                     String folderPath = root.getAbsolutePath()
4697                     if (filePath.startsWith(folderPath)) {
4698                         usename = filePath.substring(folderPath.length() + 1);
4699                     }
4700                     if (extras.containsKey(usename)) {
4701                         List<String> lines = extras.get(usename)
4702                         e.eachLine { line ->
4703                             line = line.trim()
4704                             if (line.length() > 1 && Character.isLetter(line.charAt(0))) {
4705                                 lines << line
4706                             }
4707                         }
4708 
4709                     } else {
4710                         List<String> lines = []
4711                         e.eachLine { line ->
4712                             line = line.trim()
4713                             if (line.length() > 1 && Character.isLetter(line.charAt(0))) {
4714                                 lines << line
4715                             }
4716                         }
4717                         extras.put(usename,lines)
4718                     }
4719                 }
4720             }
4721             extras.keySet().each() { e->
4722                 File f = new File(modulesSrcDir, e)
4723                 f.getParentFile().mkdirs()
4724                 f.delete()
4725 
4726                 extras.get(e).unique().each() { l->
4727                     f << l
4728                     f << "\n"
4729                 }
4730             }
4731 
4732             // concatecate java.policy files into a single file
4733             //
4734             mkdir outputPolicyDir
4735             outputPolicyFile.delete()
4736             moduleProjList.each { project ->
4737                 def policyDir = "${project.projectDir}/src/main/conf/security"
4738                 def policyFile = file("${policyDir}/java.policy")
4739                 if (policyFile.exists()) outputPolicyFile << policyFile.text
4740             }
4741         }
4742     }
4743     buildModules.dependsOn(buildModulesTask)
4744 
4745     // BUNDLED SDK
4746     moduleProjList.each { project ->
4747         // Copy classes, bin, and lib directories
4748 
4749         def moduleName = project.ext.moduleName
4750         def buildDir = project.buildDir
4751 
4752         def srcClassesDir = "${buildDir}/${platformPrefix}module-classes"
4753         def dstClassesDir = "${modulesDir}/${moduleName}"
4754         def copyClassFilesTask = project.task("copyClassFiles$t.capital", type: Copy, dependsOn: project.assemble) {
4755             from srcClassesDir
4756             into dstClassesDir
4757             exclude("module-info.class")
4758         }
4759 
4760         def srcCmdsDir = "${buildDir}/${platformPrefix}module-bin"
4761         def dstCmdsDir = "${modulesCmdsDir}/${moduleName}"
4762         def copyBinFilesTask = project.task("copyBinFiles$t.capital", type: Copy, dependsOn: copyClassFilesTask) {
4763             from srcCmdsDir
4764             into dstCmdsDir
4765         }
4766 
4767         def srcLibsDir = "${buildDir}/${platformPrefix}module-lib"
4768         def dstLibsDir = "${modulesLibsDir}/${moduleName}"
4769         def copyLibFilesTask = project.task("copyLibFiles$t.capital", type: Copy, dependsOn: copyBinFilesTask) {
4770             from srcLibsDir
4771             into dstLibsDir
4772         }
4773 
4774         // Copy module sources
4775         // FIXME: javafx.swt sources?
4776         def copySources = project.hasProperty("includeSources") && project.includeSources
4777         def copySourceFilesTask = project.task("copySourceFiles$t.capital", type: Copy, dependsOn: copyLibFilesTask) {
4778             if (copySources) {
4779                 from "${project.projectDir}/src/main/java"
4780                 if (project.name.equals("base")) {
4781                     from "${project.projectDir}/build/gensrc/java"
4782                 }
4783                 if (project.name.equals("web")) {
4784                     from "${project.projectDir}/src/main/native/Source/WebCore/bindings/java/dom3/java"
4785                 }
4786             } else {
4787                 from "${project.projectDir}/src/main/java/module-info.java"
4788             }
4789             into "${modulesSrcDir}/${moduleName}"
4790             include "**/*.java"
4791             if (project.hasProperty("sourceFilter")) {
4792                 filter(project.sourceFilter)
4793             }
4794         }
4795 
4796         // Copy .html and other files needed for doc bundles
4797         def copyDocFiles = project.task("copyDocFiles$t.capital", type: Copy, dependsOn: copySourceFilesTask) {
4798             if (copySources) {
4799                 from("${project.projectDir}/src/main/docs") {
4800                     include "**/*.html"
4801                     filter { line->
4802                         line = line.replace("@FXVERSION@", RELEASE_VERSION)
4803                     }
4804                 }
4805                 from("${project.projectDir}/src/main/docs") {
4806                     exclude "**/*.html"
4807                 }
4808                 from("${project.projectDir}/src/main/java") {
4809                     exclude "**/*.java"
4810                 }
4811 
4812                 into "${modulesSrcDir}/${moduleName}"
4813             }
4814         }
4815 
4816         // Copy make/build.properties
4817         def srcMakeDir = "${project.projectDir}/make"
4818         def dstMakeDir = "${modulesMakeDir}/${moduleName}"
4819         def copyBuildPropertiesTask = project.task("copyBuildProperties$t.capital", type: Copy, dependsOn: copyDocFiles) {
4820             from srcMakeDir
4821             into dstMakeDir
4822         }
4823 
4824         // Copy legal files
4825         def srcLegalDir = "${project.projectDir}/src/main/legal"
4826         def dstLegalDir = "${modulesLegalDir}/${moduleName}"
4827         def copyLegalTask = project.task("copyLegal$t.capital", type: Copy, dependsOn: copyBuildPropertiesTask) {
4828             from srcLegalDir
4829             into dstLegalDir
4830 
4831             // Exclude ANGLE since we (currently) do not use it
4832             exclude("angle.md")
4833         }
4834 
4835         buildModulesTask.dependsOn(
4836             copyClassFilesTask,
4837             copyLibFilesTask,
4838             copySourceFilesTask,
4839             copyDocFiles,
4840             copyBuildPropertiesTask,
4841             copyLegalTask)
4842     }
4843 
4844     // ============================================================
4845 
4846     def standaloneSdkDirName = "${platformPrefix}sdk"
4847     def standaloneSdkDir = "${rootProject.buildDir}/${standaloneSdkDirName}"
4848     def standaloneLibDir = "${standaloneSdkDir}/lib"
4849     def libDest=targetProperties.libDest
4850     def standaloneNativeDir = "${standaloneSdkDir}/${libDest}"
4851     def standaloneLegalDir = "${standaloneSdkDir}/legal"
4852     def standaloneSrcZipName = "src.zip"
4853 
4854     // STANDALONE SDK
4855     moduleProjList.each { project ->
4856         // Copy classes, bin, and lib directories
4857 
4858         def moduleName = project.ext.moduleName
4859         def buildDir = project.buildDir
4860 
4861         // Create modular jars
4862         def srcClassesDir = "${buildDir}/${platformPrefix}module-classes"
4863         def dstModularJarDir = "${standaloneLibDir}"
4864         def modularJarName = "${moduleName}.jar"
4865         def modularJarTask = project.task("modularJarStandalone$t.capital", type: Jar, dependsOn: project.assemble) {
4866             destinationDir = file("${dstModularJarDir}")
4867             archiveName = modularJarName
4868             includeEmptyDirs = false
4869             from srcClassesDir
4870         }
4871 
4872         // Copy native libraries
4873         def srcNativeDir = "${buildDir}/${platformPrefix}module-lib"
4874         def dstNativeDir = "${standaloneNativeDir}"
4875         def copyNativeFilesTask = project.task("copyNativeFilesStandalone$t.capital", type: Copy, dependsOn: modularJarTask) {
4876             from srcNativeDir
4877             into dstNativeDir
4878             include("*.dll")
4879         }
4880 
4881         // Copy other lib files
4882         def srcLibsDir = "${buildDir}/${platformPrefix}module-lib"
4883         def dstLibsDir = "${standaloneLibDir}"
4884         def copyLibFilesTask = project.task("copyLibFilesStandalone$t.capital", type: Copy, dependsOn: copyNativeFilesTask) {
4885             from srcLibsDir
4886             into dstLibsDir
4887             exclude("*.dll")
4888         }
4889 
4890         // Copy legal files
4891         def licenseFiles = [ "ADDITIONAL_LICENSE_INFO", "ASSEMBLY_EXCEPTION", "LICENSE" ]
4892         def srcLegalDir = "${project.projectDir}/src/main/legal"
4893         def dstLegalDir = "${standaloneLegalDir}/${moduleName}"
4894         def copyLegalTask = project.task("copyLegalStandalone$t.capital", type: Copy, dependsOn: copyLibFilesTask) {
4895 
4896             def rtDir = rootProject.file('.')
4897             licenseFiles.each { lFile ->
4898                 from "${rtDir}/${lFile}"
4899             }
4900 
4901             from srcLegalDir
4902 
4903             into dstLegalDir
4904 
4905             // Exclude ANGLE since we (currently) do not use it
4906             exclude("angle.md")
4907         }
4908 
4909         buildModulesTask.dependsOn(
4910             modularJarTask,
4911             copyNativeFilesTask,
4912             copyLibFilesTask,
4913             copyLegalTask)
4914     }
4915 
4916     // Zip module sources for standalone SDK
4917     //
4918     // NOTE: the input is taken from the modular-sdk/modules_src dir
4919     // so that we don't have to duplicate the logic and create another
4920     // temporary directory. This is somewhat inelegant, since the bundled sdk
4921     // and the standalone sdk should be independent of one another, but seems
4922     // better than the alternatives.
4923     def zipSourceFilesTask = project.task("zipSourceFilesStandalone$t.capital", type: Zip, dependsOn: buildModulesTask) {
4924         destinationDir = file("${standaloneLibDir}")
4925         archiveName = standaloneSrcZipName
4926         includeEmptyDirs = false
4927         from modulesSrcDir
4928         include "**/*.java"
4929     }
4930     buildModules.dependsOn(zipSourceFilesTask)
4931 
4932     // ============================================================
4933 
4934     def buildRunArgsTask = task("buildRunArgs$t.capital",
4935             group: "Build", dependsOn: buildModulesTask) {
4936         outputs.file(runArgsFile);
4937         inputs.file(EXTRAADDEXPORTS);
4938         doLast() {
4939             List<String>modpath = []
4940             List<String>modnames = []
4941 
4942             moduleProjList.each { project ->
4943                 def moduleName = project.ext.moduleName
4944                 def dstModuleDir = cygpath("${modulesDir}/${moduleName}")
4945                 if (HAS_JAVAFX_MODULES) {
4946                     modpath <<  "${moduleName}=${dstModuleDir}"
4947                 } else {
4948                     modnames << moduleName
4949                 }
4950             }
4951 
4952             if (HAS_JAVAFX_MODULES) {
4953                 writeRunArgsFile(runArgsFile, computeLibraryPath(true), modpath, null)
4954                 writeRunArgsFile(compileArgsFile, null, modpath, null)
4955 
4956                 if (rootProject.hasProperty("EXTRA_ADDEXPORTS_STRING")) {
4957                     runArgsFile << EXTRA_ADDEXPORTS_STRING
4958                     compileArgsFile << EXTRA_ADDEXPORTS_STRING
4959                 }
4960             } else {
4961                 modpath = [ cygpath("${standaloneLibDir}") ]
4962                 writeRunArgsFile(runArgsFile, null, modpath, modnames)
4963                 writeRunArgsFile(compileArgsFile, null, modpath, modnames)
4964             }
4965         }
4966     }
4967     buildModules.dependsOn(buildRunArgsTask)
4968 
4969     def isWindows = IS_WINDOWS && t.name == "win";
4970     def isMac = IS_MAC && t.name == "mac";
4971 
4972     // Create layout for modular classes
4973     moduleProjList.each { project ->
4974         def buildModuleClassesTask = project.task("buildModule$t.capital", group: "Build", type: Copy) {
4975             dependsOn(project.assemble)
4976             def buildDir = project.buildDir
4977             def sourceBuildDirs = [
4978                 "${buildDir}/classes/java/main/${project.moduleName}",
4979             ]
4980 
4981             def moduleClassesDir = "$buildDir/${platformPrefix}module-classes"
4982                 includeEmptyDirs = false
4983                 sourceBuildDirs.each { d ->
4984                     from d
4985                 }
4986                 into moduleClassesDir
4987 
4988                 // Exclude obsolete, experimental, or non-shipping code
4989                 exclude("version.rc")
4990                 exclude("com/sun/glass/ui/swt")
4991                 exclude("com/sun/javafx/tools/ant")
4992                 exclude("com/javafx/main")
4993                 exclude("com/sun/javafx/webkit/drt")
4994                 if (!IS_INCLUDE_NULL3D) {
4995                     exclude ("com/sun/prism/null3d")
4996                 }
4997                 if (!IS_INCLUDE_ES2) {
4998                        exclude("com/sun/prism/es2",
4999                                "com/sun/scenario/effect/impl/es2")
5000                 }
5001 
5002                 // Exclude platform-specific classes for other platforms
5003 
5004                 if (!isMac) {
5005                     exclude ("com/sun/media/jfxmediaimpl/platform/osx",
5006                              "com/sun/prism/es2/MacGL*",
5007                              "com/sun/glass/events/mac",
5008                              "com/sun/glass/ui/mac",
5009                              )
5010                 }
5011 
5012                 if (!isWindows) {
5013                     exclude ("**/*.hlsl",
5014                              "com/sun/glass/ui/win",
5015                              "com/sun/prism/d3d",
5016                              "com/sun/prism/es2/WinGL*",
5017                              "com/sun/scenario/effect/impl/hw/d3d"
5018                              )
5019                 }
5020 
5021                 if (!targetProperties.includeGTK) { //usually IS_LINUX
5022                     exclude (
5023                              "com/sun/glass/ui/gtk",
5024                              "com/sun/prism/es2/EGL*",
5025                              "com/sun/prism/es2/X11GL*"
5026                              )
5027                 }
5028 
5029                 if (!targetProperties.includeEGL) {
5030                     exclude ("com/sun/prism/es2/EGL*")
5031                 }
5032 
5033                 if (!targetProperties.includeMonocle) {
5034                     exclude ("com/sun/glass/ui/monocle")
5035                     exclude("com/sun/prism/es2/Monocle*")
5036                 }
5037 
5038                 if (t.name != 'ios') {
5039                     exclude ("com/sun/media/jfxmediaimpl/platform/ios",
5040                              "com/sun/glass/ui/ios",
5041                              "com/sun/prism/es2/IOS*"
5042                              )
5043                 }
5044 
5045                 if (t.name != 'android' && t.name != 'dalvik') {
5046                     exclude ("com/sun/glass/ui/android")
5047                 }
5048 
5049                 // Filter out other platform-specific classes
5050                 if (targetProperties.containsKey('jfxrtJarExcludes')) {
5051                     exclude(targetProperties.jfxrtJarExcludes)
5052                 }
5053 
5054                 /* FIXME: JIGSAW -- handle this in the module itself
5055                 String webbld = project(":web").buildDir.path
5056                 String ctrlbld = project(":controls").buildDir.path
5057                 if (t.name == 'android') {
5058                     from ("${webbld}/classes/android",
5059                           "${webbld}/resources/android",
5060                           "${ctrlbld}/classes/android",
5061                           "${ctrlbld}/resources/android")
5062                 } else if (t.name == 'ios') {
5063                     from ("${webbld}/classes/ios",
5064                           "${webbld}/resources/ios")
5065                 } else {
5066                     from ("${webbld}/classes/java/main")
5067                 }
5068                 */
5069         }
5070         buildModulesTask.dependsOn(buildModuleClassesTask)
5071     }
5072 
5073     def buildModuleLibsTask = task("buildModuleLibs$t.capital") {
5074         group = "Basic"
5075 
5076         def baseProject = project(":base");
5077 
5078         def graphicsProject = project(":graphics");
5079 
5080         def mediaProject = project(":media");
5081 
5082         def webProject = project(":web");
5083         dependsOn(webProject.assemble)
5084 
5085         def swtProject = project(":swt");
5086 
5087         def packagerProject = project(":fxpackager");
5088         dependsOn(packagerProject.assemble)
5089         dependsOn(packagerProject.jar)
5090         dependsOn(project(":fxpackagerservices").jar)
5091 
5092         def library = targetProperties.library
5093 
5094         def useLipo = targetProperties.containsKey('useLipo') ? targetProperties.useLipo : false
5095         def modLibDest = targetProperties.modLibDest
5096         def moduleNativeDirName = "${platformPrefix}module-$modLibDest"
5097 
5098         def buildModuleBaseTask = task("buildModuleBase$t.capital", dependsOn: baseProject.assemble) {
5099             group = "Basic"
5100             description = "creates javafx.base property files"
5101 
5102             def moduleLibDir = "${baseProject.buildDir}/${platformPrefix}module-lib"
5103             final File javafxProperties = file("${moduleLibDir}/javafx.properties")
5104             outputs.file(javafxProperties)
5105 
5106             if (targetProperties.containsKey("javafxPlatformProperties")) {
5107                 final File javafxPlatformProperties = file("${moduleLibDir}/javafx.platform.properties")
5108                 outputs.file(javafxPlatformProperties)
5109             }
5110 
5111             doLast {
5112                 mkdir moduleLibDir
5113 
5114                 javafxProperties.delete()
5115                 javafxProperties << "javafx.version=$RELEASE_VERSION_SHORT";
5116                 javafxProperties << "\n"
5117                 javafxProperties << "javafx.runtime.version=$RELEASE_VERSION_LONG";
5118                 javafxProperties << "\n"
5119                 javafxProperties << "javafx.runtime.build=$PROMOTED_BUILD_NUMBER";
5120                 javafxProperties << "\n"
5121                 // Include any properties that have been defined (most likely in
5122                 // one of the various platform gradle files)
5123                 if (targetProperties.containsKey("javafxProperties")) {
5124                     javafxProperties << targetProperties.javafxProperties
5125                     javafxProperties << "\n"
5126                 }
5127 
5128                 // Embedded builds define this file as well
5129                 if (targetProperties.containsKey("javafxPlatformProperties")) {
5130                     final File javafxPlatformProperties = file("${moduleLibDir}/javafx.platform.properties")
5131                     javafxPlatformProperties.delete()
5132                     javafxPlatformProperties << targetProperties.javafxPlatformProperties
5133                     javafxPlatformProperties << "\n"
5134                 }
5135             }
5136         }
5137 
5138         def buildModuleGraphicsTask = task("buildModuleGraphics$t.capital", type: Copy, dependsOn: graphicsProject.assemble) {
5139             group = "Basic"
5140             description = "copies javafx.graphics native libraries"
5141 
5142             into "${graphicsProject.buildDir}/${moduleNativeDirName}"
5143 
5144             from("${graphicsProject.buildDir}/libs/jsl-decora/${t.name}/${library(targetProperties.decora.lib)}")
5145             def libs = ['font', 'prism', 'prismSW', 'glass', 'iio']
5146             if (IS_INCLUDE_ES2) {
5147                 libs += ['prismES2'];
5148             }
5149             if (IS_COMPILE_PANGO) {
5150                 libs += ['fontFreetype', 'fontPango'];
5151             }
5152             libs.each { lib ->
5153                 def variants = targetProperties[lib].containsKey('variants') && !useLipo ? targetProperties[lib].variants : [null]
5154                 variants.each { variant ->
5155                     def variantProperties = variant ? targetProperties[lib][variant] : targetProperties[lib]
5156                     from ("${graphicsProject.buildDir}/libs/$lib/$t.name/${library(variantProperties.lib)}")
5157                 }
5158             }
5159             if (IS_WINDOWS) {
5160                 from ("${graphicsProject.buildDir}/libs/prismD3D/${t.name}/${library(targetProperties.prismD3D.lib)}");
5161                 targetProperties.VS2017DLLs.each { vslib ->
5162                     from ("$vslib");
5163                 }
5164                 targetProperties.WinSDKDLLs.each { winsdklib ->
5165                     from ("$winsdklib");
5166                 }
5167             }
5168         }
5169 
5170         def buildModuleMediaTask = task("buildModuleMedia$t.capital", type: Copy, dependsOn: mediaProject.assemble) {
5171             group = "Basic"
5172             description = "copies javafx.media native libraries"
5173 
5174             into "${mediaProject.buildDir}/${moduleNativeDirName}"
5175 
5176             def mediaBuildType = project(":media").ext.buildType
5177             if (IS_COMPILE_MEDIA) {
5178                 [ "fxplugins", "gstreamer-lite", "jfxmedia" ].each { name ->
5179                     from ("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}/${library(name)}") }
5180 
5181                 if (t.name == "mac") {
5182                     // OSX media natives
5183                     [ "jfxmedia_qtkit", "jfxmedia_avf", "glib-lite" ].each { name ->
5184                         from ("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}/${library(name)}") }
5185                 } else if (t.name == "linux") {
5186                     from("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}") { include "libavplugin*.so" }
5187                 } else from ("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}/${library("glib-lite")}")
5188             } else {
5189                 if (t.name != "android"  && t.name != "dalvik" ) {
5190                     [ "fxplugins", "gstreamer-lite", "jfxmedia" ].each { name ->
5191                         from ("$MEDIA_STUB/${library(name)}") }
5192                 }
5193 
5194                 if (t.name == "mac") {
5195                     // copy libjfxmedia_{avf,qtkit}.dylib if they exist
5196                     [ "jfxmedia_qtkit", "jfxmedia_avf", "glib-lite" ].each { name ->
5197                         from ("$MEDIA_STUB/${library(name)}") }
5198                 } else if (t.name == "linux") {
5199                     from(MEDIA_STUB) { include "libavplugin*.so" }
5200                 }
5201                 else if (t.name != "android"  && t.name != "dalvik" ) {
5202                     from ("$MEDIA_STUB/${library("glib-lite")}")
5203                 }
5204             }
5205         }
5206 
5207         def buildModuleWeb = task("buildModuleWeb$t.capital", type: Copy, dependsOn: webProject.assemble) {
5208             group = "Basic"
5209             description = "copies javafx.web native libraries"
5210 
5211             into "${webProject.buildDir}/${moduleNativeDirName}"
5212 
5213             if (IS_COMPILE_WEBKIT) {
5214                 from ("${webProject.buildDir}/libs/${t.name}/${library('jfxwebkit')}")
5215             } else {
5216                 if (t.name != "android" && t.name != "ios" && t.name != "dalvik") {
5217                     from ("$WEB_STUB/${library('jfxwebkit')}")
5218                 }
5219             }
5220         }
5221 
5222         def buildModuleSWT = task("buildModuleSWT$t.capital", type: Copy) {
5223             group = "Basic"
5224             description = "copies SWT JAR"
5225 
5226             // FIXME: the following is a hack to workaround the fact that there
5227             // is no way to deliver javafx-swt.jar other than in one of the
5228             // existing runtime modules.
5229 
5230             dependsOn(buildModuleGraphicsTask) // we copy to the graphics module
5231 
5232             if (COMPILE_SWT) {
5233                 def javafxSwtIndexTask = tasks.getByName("javafxSwtIndex${t.capital}");
5234                 dependsOn(javafxSwtIndexTask)
5235                 //enabled = COMPILE_SWT
5236             }
5237 
5238             // Copy javafx-swt.jar to the javafx-graphics module lib dir
5239             from "${swtProject.buildDir}/libs/javafx-swt.jar"
5240             into "${graphicsProject.buildDir}/${platformPrefix}module-lib"
5241         }
5242 
5243         def buildModulePackagerLibs = task("buildModulePackagerLibs$t.capital",
5244                 type: Copy,
5245                 dependsOn: [ packagerProject.assemble, project(":fxpackagerservices").assemble ]) {
5246             group = "Basic"
5247             description = "copies jdk.packager libraries"
5248 
5249             from "${packagerProject.buildDir}/libs"
5250             into "${packagerProject.buildDir}/${platformPrefix}module-lib"
5251         }
5252 
5253         def buildModulePackagerExes = task("buildModulePackagerExe$t.capital",
5254                 type: Copy,
5255                 dependsOn: [ packagerProject.assemble, project(":fxpackagerservices").assemble ]) {
5256             group = "Basic"
5257             description = "copies jdk.packager executable"
5258 
5259             // Copy over the javapackager executable
5260             enabled = (t.name == "win" || t.name == "linux" || t.name == "mac")
5261 
5262             from "${packagerProject.buildDir}/javapackager"
5263             into "${packagerProject.buildDir}/${platformPrefix}module-bin"
5264         }
5265 
5266         dependsOn(
5267             buildModuleBaseTask,
5268             buildModuleGraphicsTask,
5269             buildModuleMediaTask,
5270             buildModuleWeb,
5271             buildModuleSWT,
5272             buildModulePackagerLibs,
5273             buildModulePackagerExes
5274             )
5275     }
5276     buildModulesTask.dependsOn(buildModuleLibsTask)
5277 
5278     def zipTask = project.task("buildModuleZip$t.capital", type: Zip, group: "Build",
5279             dependsOn: buildModulesTask ) {
5280 
5281         // FIXME: JIGSAW -- this should be moved to a sub-directory so we can keep the same name
5282         def jfxBundle = "${platformPrefix}javafx-exports.zip"
5283 
5284         doFirst() {
5285             file("${rootProject.buildDir}/${jfxBundle}").delete()
5286         }
5287 
5288         archiveName = jfxBundle
5289         destinationDir = file("${rootProject.buildDir}")
5290         includeEmptyDirs = false
5291         from "${bundledSdkDir}"
5292     }
5293     jdkZip.dependsOn(zipTask)
5294 
5295     Task testArgFiles = task("createTestArgfiles${t.capital}") {
5296 
5297         File testRunArgsFile = new File(rootProject.buildDir, TESTRUNARGSFILE)
5298         //test (shimed) version
5299         File testCompileArgsFile = new File(rootProject.buildDir, TESTCOMPILEARGSFILE)
5300         // And a test java.policy file
5301         File testJavaPolicyFile = new File(rootProject.buildDir, TESTJAVAPOLICYFILE)
5302         // and the non-test version to go with run.args
5303         File runJavaPolicyFile = new File(rootProject.buildDir, RUNJAVAPOLICYFILE);
5304 
5305         outputs.file(testRunArgsFile)
5306         outputs.file(testCompileArgsFile)
5307         outputs.file(testJavaPolicyFile)
5308         outputs.file(runJavaPolicyFile)
5309         inputs.file(EXTRAADDEXPORTS);
5310 
5311         doLast() {
5312             rootProject.buildDir.mkdir()
5313 
5314             List<String> projNames = []
5315             moduleProjList.each { project ->
5316                 projNames << project.name
5317             }
5318 
5319             // And the test (shimed) variation...
5320 
5321             testRunArgsFile.delete()
5322             testCompileArgsFile.delete()
5323 
5324             testJavaPolicyFile.delete()
5325             runJavaPolicyFile.delete()
5326 
5327             List<String> modpath = []
5328 
5329             if (HAS_JAVAFX_MODULES) {
5330                 moduleProjList.each { project ->
5331                     if (project.hasProperty("moduleName") && project.buildModule) {
5332                         File dir;
5333                         if (project.sourceSets.hasProperty('shims')) {
5334                            dir = new File(rootProject.buildDir, "shims/${project.ext.moduleName}")
5335                         } else {
5336                            dir = new File(rootProject.buildDir, "modular-sdk/modules/${project.ext.moduleName}")
5337                         }
5338 
5339                         def dstModuleDir = cygpath(dir.path)
5340                         modpath << "${project.ext.moduleName}=${dstModuleDir}"
5341 
5342                         String themod = dir.toURI()
5343                         testJavaPolicyFile <<  "grant codeBase \"${themod}\" {\n" +
5344                         "    permission java.security.AllPermission;\n" +
5345                         "};\n"
5346 
5347                         dir = new File(rootProject.buildDir, "modular-sdk/modules/${project.ext.moduleName}")
5348                         themod = dir.toURI()
5349                         runJavaPolicyFile <<  "grant codeBase \"${themod}\" {\n" +
5350                         "    permission java.security.AllPermission;\n" +
5351                         "};\n"
5352                     }
5353                 }
5354 
5355                 writeRunArgsFile(testCompileArgsFile, null, modpath, null)
5356                 writeRunArgsFile(testRunArgsFile, computeLibraryPath(true), modpath, null)
5357 
5358                 if (rootProject.hasProperty("EXTRA_ADDEXPORTS_STRING")) {
5359                     testCompileArgsFile << EXTRA_ADDEXPORTS_STRING
5360                     testRunArgsFile << EXTRA_ADDEXPORTS_STRING
5361                 }
5362             } else  {
5363                 def modnames = []
5364                 moduleProjList.each { project ->
5365                     if (project.hasProperty("moduleName") && project.buildModule) {
5366                         modnames << project.ext.moduleName
5367                         File dir;
5368                         if (project.sourceSets.hasProperty('shims')) {
5369                            dir = new File(rootProject.buildDir, "shims/${project.ext.moduleName}")
5370                         } else {
5371                            dir = new File(rootProject.buildDir, "sdk/lib/${project.ext.moduleName}.jar")
5372                         }
5373 
5374                         def dstModuleDir = cygpath(dir.path)
5375                         modpath << "${dstModuleDir}"
5376 
5377                         String themod = dir.toURI()
5378                         testJavaPolicyFile <<  "grant codeBase \"${themod}\" {\n" +
5379                         "    permission java.security.AllPermission;\n" +
5380                         "};\n"
5381 
5382                         dir = new File(rootProject.buildDir, "sdk/lib/${project.ext.moduleName}.jar")
5383                         themod = dir.toURI()
5384                         runJavaPolicyFile <<  "grant codeBase \"${themod}\" {\n" +
5385                         "    permission java.security.AllPermission;\n" +
5386                         "};\n"
5387                     }
5388                 }
5389 
5390                 writeRunArgsFile(testCompileArgsFile, null, modpath, modnames)
5391                 writeRunArgsFile(testRunArgsFile, computeLibraryPath(true), modpath, modnames)
5392 
5393                 appendQualExports(testCompileArgsFile, qualExportsSwing)
5394                 appendQualExports(testRunArgsFile, qualExportsSwing)
5395             }
5396         }
5397     }
5398     sdk.dependsOn(testArgFiles)
5399     createTestArgfiles.dependsOn(testArgFiles)
5400 
5401     def sdkTask = tasks.getByName("sdk${t.capital}");
5402     sdkTask.dependsOn(buildModulesTask)
5403 }
5404 sdk.dependsOn(buildModules)
5405 
5406 // Build the jmod for each module for the standalone SDK only.
5407 compileTargets { t ->
5408     if (!HAS_JAVAFX_MODULES) {
5409         def targetProperties = project.ext[t.upper]
5410 
5411         def platformPrefix = targetProperties.platformPrefix
5412         def jmodsDirName = "${platformPrefix}jmods"
5413         def jmodsDir = "${rootProject.buildDir}/${jmodsDirName}"
5414         def standaloneSdkDirName = "${platformPrefix}sdk"
5415         def standaloneSdkDir = "${rootProject.buildDir}/${standaloneSdkDirName}"
5416         def standaloneLegalDir = "${standaloneSdkDir}/legal"
5417 
5418         moduleProjList.each { project ->
5419             def moduleName = project.ext.moduleName
5420             def buildDir = project.buildDir
5421 
5422             def srcClassesDir = "${buildDir}/${platformPrefix}module-classes"
5423             def srcLibDir = "${buildDir}/${platformPrefix}module-lib"
5424             def srcLegalDir = "${standaloneLegalDir}/${moduleName}"
5425 
5426             def jmodName = "${moduleName}.jmod"
5427             def jmodFile = "${jmodsDir}/${jmodName}"
5428             def jmodTask = project.task("jmod$t.capital", group: "Build", dependsOn: sdk) {
5429                 doLast {
5430                     mkdir jmodsDir
5431                     delete(jmodFile);
5432                     exec {
5433                         commandLine(JMOD)
5434                         args("create")
5435                         args("--class-path")
5436                         args(srcClassesDir)
5437                         // Not all modules have a "lib" dir
5438                         if (file(srcLibDir).isDirectory()) {
5439                             args("--libs")
5440                             args(srcLibDir)
5441                         }
5442                         args("--legal-notices")
5443                         args(srcLegalDir)
5444                         args(jmodFile)
5445                     }
5446                 }
5447             }
5448 
5449             jmods.dependsOn(jmodTask)
5450         }
5451     }
5452 }
5453 
5454 task checkrepo() {
5455     doLast {
5456         logger.info("checking for whitespace (open)");
5457         exec {
5458             if (IS_WINDOWS) {
5459                 commandLine  'bash', 'tools/scripts/checkWhiteSpace'
5460             } else {
5461                 commandLine  'bash', 'tools/scripts/checkWhiteSpace', '-x'
5462             }
5463         }
5464     }
5465 }
5466 
5467 task checkrepoall() {
5468     doLast {
5469         logger.info("checking for all whitespace (open)");
5470         exec {
5471             if (IS_WINDOWS) {
5472                 commandLine  'bash', 'tools/scripts/checkWhiteSpace', '-a'
5473             } else {
5474                 commandLine  'bash', 'tools/scripts/checkWhiteSpace', '-x', '-a'
5475             }
5476         }
5477     }
5478 }
5479 
5480 /******************************************************************************
5481  *                                                                            *
5482  *                              BUILD_CLOSED                                  *
5483  *                                                                            *
5484  * This next section should remain at the end of the build script. It allows  *
5485  * for a "supplemental" gradle file to be used to extend the normal build     *
5486  * structure. For example, this is used for passing a supplemental gradle     *
5487  * file for producing official JavaFX builds.                                 *
5488  *                                                                            *
5489  *****************************************************************************/
5490 
5491 if (BUILD_CLOSED) {
5492     apply from: supplementalBuildFile
5493 }
5494 
5495 task showFlags {
5496 }
5497 
5498 compileTargets { t ->
5499     // Every platform must define these variables
5500     def props = project.ext[t.upper];
5501     showFlags.dependsOn(
5502         project.task("showFlags$t.upper") {
5503             doLast() {
5504                 println "Properties set for $t.upper"
5505                 props.each { println it }
5506             }
5507         }
5508     )
5509 
5510 }