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