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