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