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