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