1 /*
   2  * Copyright (c) 2013, 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  *          - is jfxrt.jar there?
  35  *          - does jfxrt.jar contain stuff it shouldn't (doc-files, iml, etc)
  36  *          - does jfxrt.jar contain stuff it should (bss files, etc)
  37  *  - Perform sanity checking to make sure a JDK exists with javac, javah, etc
  38  *  - Support building with no known JDK location, as long as javac, javah, etc are on the path
  39  *  - Check all of the native flags. We're adding weight to some libs that don't need it, and so forth.
  40  *
  41  * Additional projects to work on as we go:
  42  *  - Add "developer debug". This is where the natives do not have debug symbols, but the Java code does
  43  *  - The genVSproperties.bat doesn't find the directory where RC.exe lives. So it is hard coded. Might be a problem.
  44  *  - special tasks for common needs, such as:
  45  *      - updating copyright headers
  46  *      - stripping trailing whitespace (?)
  47  *  - checkstyle
  48  *  - findbugs
  49  *  - re needs?
  50  *  - sqe testing
  51  *  - API change check
  52  *  - Pushing results to a repo?
  53  *  - ServiceWithSecurityManagerTest fails to complete when run from gradle.
  54  *  - Integrate Parfait reports for C code
  55  *  - FXML Project tests are not running
  56  */
  57 defaultTasks = ["sdk"]
  58 
  59 import java.util.concurrent.CountDownLatch
  60 import java.util.concurrent.ExecutorService
  61 import java.util.concurrent.Executors
  62 import java.util.concurrent.Future
  63 
  64 /******************************************************************************
  65  *                              Utility methods                               *
  66  *****************************************************************************/
  67 
  68 /**
  69  * If the given named property is not defined, then this method will define
  70  * it with the given defaultValue. Any properties defined by this method can
  71  * be substituted on the command line by using -P, or by specifying a
  72  * gradle.properties file in the user home dir
  73  *
  74  * @param name The name of the property to define
  75  * @param defaultValue The default value to assign the property
  76  */
  77 void defineProperty(String name, String defaultValue) {
  78     if (!project.hasProperty(name)) {
  79         project.ext.set(name, defaultValue);
  80     }
  81 }
  82 
  83 /**
  84  * If the given named property is not defined, then this method will attempt to
  85  * look up the property in the props map, and use the defaultValue if it cannot be found.
  86  *
  87  * @param name The name of the property to look up and/or define
  88  * @param props The properties to look for the named property in, if it has not already been defined
  89  * @param defaultValue The default value if the property has not been defined and the
  90  *                     props map does not contain the named property
  91  */
  92 void defineProperty(String name, Properties props, String defaultValue) {
  93     if (!project.hasProperty(name)) {
  94         project.ext.set(name, props.getProperty(name, defaultValue));
  95     }
  96 }
  97 
  98 /**
  99  * Converts cygwin style paths to windows style paths, but with a forward slash.
 100  * This method is safe to call from any platform, and will only do work if
 101  * called on Windows (in all other cases it simply returns the supplied path.
 102  * In the future I would like to modify this so that it only does work if
 103  * cygwin is installed, as I hope one day to remove the requirement to build
 104  * with cygwin, but at present (due to GStreamer / Webkit) cygwin is needed
 105  * anyway.
 106  * 
 107  * @param path the path to convert
 108  * @return the path converted to windows style, if on windows, otherwise it
 109  *         is the supplied path.
 110  */
 111 String cygpath(String path) {
 112     if (!IS_WINDOWS) return path;
 113     if (path == null || "".equals(path)) return path;
 114     ByteArrayOutputStream out = new ByteArrayOutputStream();
 115     logger.info("Converting path '$path' via cygpath")
 116     exec {
 117         standardOutput = out
 118         commandLine "cmd", "/c", "cygpath", "-m", path
 119     }
 120     return out.toString().trim();
 121 }
 122 
 123 void loadProperties(String sourceFileName) {
 124     def config = new Properties()
 125     def propFile = new File(sourceFileName)
 126     if (propFile.canRead()) {
 127         config.load(new FileInputStream(propFile))
 128         for (Map.Entry property in config) {
 129             def keySplit = property.key.split("\\.");
 130             def key = keySplit[0];
 131             for (int i = 1; i < keySplit.length; i++) {
 132                 key = key + keySplit[i].capitalize();
 133             }
 134             ext[key] = property.value;
 135         }
 136     }
 137 }
 138 
 139 /**
 140  * Struct used to contain some information passed to the closure
 141  * passed to compileTargets.
 142  */
 143 class CompileTarget {
 144     String name;
 145     String upper;
 146     String capital;
 147 }
 148 
 149 /**
 150  * Iterates over each of the compile targets, passing the given closure
 151  * a CompileTarget instance.
 152  * 
 153  * @param c The closure to call
 154  */
 155 void compileTargets(Closure c) {
 156     if (COMPILE_TARGETS == "") {
 157         return
 158     }
 159     COMPILE_TARGETS.split(",").each { target ->
 160         CompileTarget ct = new CompileTarget();
 161         ct.name = target;
 162         ct.upper = target.trim().toUpperCase(Locale.ROOT)
 163         ct.capital = target.trim().capitalize()
 164         c(ct)
 165     }
 166 }
 167 
 168 /**
 169  * Manages the execution of some closure which is responsible for producing
 170  * content for a properties file built at build time and stored in the
 171  * root project's $buildDir, and then loading that properties file and
 172  * passing it to the processor closure.
 173  * 
 174  * This is used on windows to produce a properties file containing all the
 175  * windows visual studio paths and environment variables, and on Linux
 176  * for storing the results of pkg-config calls.
 177  * 
 178  * @param name the name of the file to produce
 179  * @param loader a closure which is invoked, given the properties file. This
 180  *        closure is invoked only if the properties file needs to be created
 181  *        and is responsible for populating the properties file.
 182  * @param processor a closure which is invoked every time this method is
 183  *        called and which will be given a Properties object, fully populated.
 184  *        The processor is then responsible for doing whatever it is that it
 185  *        must do with those properties (such as setting up environment
 186  *        variables used in subsequent native builds, or whatnot).
 187  */
 188 void setupTools(String name, Closure loader, Closure processor) {
 189     // Check to see whether $buildDir/$name.properties file exists. If not,
 190     // then generate it. Once generated, we need to read the properties file to
 191     // help us define the defaults for this block of properties
 192     File propFile = file("$buildDir/${name}.properties");
 193     if (!propFile.exists()) {
 194         // Create the properties file
 195         propFile.getParentFile().mkdirs();
 196         propFile.createNewFile();
 197         loader(propFile);
 198     }
 199 
 200     // Try reading the properties in order to define the properties. If the property file cannot
 201     // be located, then we will throw an exception because we cannot guess these values
 202     InputStream propStream = null;
 203     try {
 204         Properties properties = new Properties();
 205         propStream = new FileInputStream(propFile);
 206         properties.load(propStream);
 207         processor(properties);
 208     } finally {
 209         try { propStream.close() } catch (Exception e) { }
 210     }
 211 }
 212 
 213 /**
 214  * Fails the build with the specified error message
 215  *
 216  * @param msg the reason for the failure
 217  */
 218 void fail(String msg) {
 219     throw new GradleException("FAIL: " + msg);
 220 }
 221 
 222 /******************************************************************************
 223  *                                                                            *
 224  *                   Definition of project properties                         *
 225  *                                                                            *
 226  *  All properties defined using ext. are immediately available throughout    *
 227  *  the script as variables that can be used. These variables are attached    *
 228  *  to the root project (whereas if they were defined as def variables then   *
 229  *  they would only be available within the root project scope).              *
 230  *                                                                            *
 231  *  All properties defined using the "defineProperty" method can be replaced  *
 232  *  on the command line by using the -P flag. For example, to override the    *
 233  *  location of the binary plug, you would specify -PBINARY_PLUG=some/where   *
 234  *                                                                            *
 235  *****************************************************************************/
 236 
 237 // If the ../rt-closed directory exists, then we are doing a closed build.
 238 // In this case, build and property files will be read from
 239 // ../rt-closed/closed-build.gradle and ../rt-closed/closed-properties.gradle
 240 // respectively
 241 
 242 def closedDir = file("../rt-closed")
 243 def buildClosed = closedDir.isDirectory()
 244 ext.BUILD_CLOSED = buildClosed
 245 
 246 // These variables indicate what platform is running the build. Is
 247 // this build running on a Mac, Windows, or Linux machine? 32 or 64 bit?
 248 ext.OS_NAME = System.getProperty("os.name").toLowerCase()
 249 ext.OS_ARCH = System.getProperty("os.arch")
 250 ext.IS_64 = OS_ARCH.toLowerCase().contains("64")
 251 ext.IS_MAC = OS_NAME.contains("mac") || OS_NAME.contains("darwin")
 252 ext.IS_WINDOWS = OS_NAME.contains("windows")
 253 ext.IS_LINUX = OS_NAME.contains("linux")
 254 
 255 // Get the JDK_HOME automatically based on the version of Java used to execute gradle. Or, if specified,
 256 // use a user supplied JDK_HOME, STUB_RUNTIME, JAVAC, and/or JAVAH, all of which may be specified
 257 // independently (or we'll try to get the right one based on other supplied info). Sometimes the
 258 // JRE might be the thing that is being used instead of the JRE embedded in the JDK, such as:
 259 //    c:\Program Files (x86)\Java\jdk1.8.0\jre
 260 //    c:\Program Files (x86)\Java\jre8\
 261 // Because of this, you may sometimes get the jdk's JRE (in which case the logic we used to have here
 262 // was correct and consistent with all other platforms), or it might be the standalone JRE (for the love!).
 263 def envJavaHome = cygpath(System.getenv("JDK_HOME"))
 264 if (envJavaHome == null || envJavaHome.equals("")) envJavaHome = cygpath(System.getenv("JAVA_HOME"))
 265 def javaHome = envJavaHome == null || envJavaHome.equals("") ? System.getProperty("java.home") : envJavaHome
 266 def javaHomeFile = file(javaHome)
 267 defineProperty("JDK_HOME",
 268         javaHomeFile.name == "jre" ?
 269         javaHomeFile.getParent().toString() :
 270         javaHomeFile.name.startsWith("jre") ?
 271         new File(javaHomeFile.getParent(), "jdk1.${javaHomeFile.name.substring(3)}.0").toString() :
 272         javaHome) // we have to bail and set it to something and this is as good as any!
 273 ext.JAVA_HOME = JDK_HOME
 274 defineProperty("JAVA", cygpath("$JDK_HOME/bin/java${IS_WINDOWS ? '.exe' : ''}"))
 275 defineProperty("JAVAC", cygpath("$JDK_HOME/bin/javac${IS_WINDOWS ? '.exe' : ''}"))
 276 defineProperty("JAVAH", cygpath("$JDK_HOME/bin/javah${IS_WINDOWS ? '.exe' : ''}"))
 277 defineProperty("JAVADOC", cygpath("$JDK_HOME/bin/javadoc${IS_WINDOWS ? '.exe' : ''}"))
 278 defineProperty("JDK_DOCS", "http://download.oracle.com/javase/7/docs/api")
 279 
 280 defineProperty("javaRuntimeVersion", System.getProperty("java.runtime.version"))
 281 defineProperty("javaVersion", javaRuntimeVersion.split("[_\\-]")[0])
 282 defineProperty("javaBuildNumber", javaRuntimeVersion.substring(javaRuntimeVersion.lastIndexOf("-b") + 2))
 283 
 284 loadProperties("$projectDir/build.properties")
 285 
 286 def String closedCacheStubRuntime = cygpath("$projectDir") + "/../caches/sdk/rt"
 287 defineProperty("STUB_RUNTIME", BUILD_CLOSED ? closedCacheStubRuntime : cygpath("$JDK_HOME/jre"))
 288 defineProperty("LIBRARY_STUB", IS_MAC ? "$STUB_RUNTIME/lib" :
 289                                IS_WINDOWS ? "$STUB_RUNTIME/bin" :
 290                                "$STUB_RUNTIME/lib/$OS_ARCH")
 291 defineProperty("UPDATE_STUB_CACHE", (STUB_RUNTIME.equals(closedCacheStubRuntime) ? 'true' : 'false'))
 292 
 293 def supplementalPreBuildFile = file("$closedDir/closed-pre-build.gradle");
 294 def supplementalBuildFile = file("$closedDir/closed-build.gradle");
 295 
 296 if (BUILD_CLOSED) {
 297     apply from: supplementalPreBuildFile
 298 }
 299 
 300 // COMPILE_WEBKIT specifies whether to build all of webkit.
 301 defineProperty("COMPILE_WEBKIT", "false")
 302 ext.IS_COMPILE_WEBKIT = Boolean.parseBoolean(COMPILE_WEBKIT)
 303 
 304 // COMPILE_MEDIA specifies whether to build all of media.
 305 defineProperty("COMPILE_MEDIA", "false")
 306 ext.IS_COMPILE_MEDIA = Boolean.parseBoolean(COMPILE_MEDIA)
 307 
 308 // COMPILE_PANGO specifies whether to build javafx_font_pango.
 309 defineProperty("COMPILE_PANGO", "${IS_LINUX}")
 310 ext.IS_COMPILE_PANGO = Boolean.parseBoolean(COMPILE_PANGO)
 311 
 312 // COMPILE_PARFAIT specifies whether to build parfait
 313 defineProperty("COMPILE_PARFAIT", "false")
 314 ext.IS_COMPILE_PARFAIT = Boolean.parseBoolean(COMPILE_PARFAIT)
 315 
 316 
 317 // Define the SWT.jar that we are going to have to download during the build process based
 318 // on what platform we are compiling from (not based on our target).
 319 ext.SWT_FILE_NAME = IS_MAC ? "org.eclipse.swt.cocoa.macosx.x86_64_3.7.2.v3740f" :
 320     IS_WINDOWS && IS_64 ? "org.eclipse.swt.win32.win32.x86_64_3.7.2.v3740f" :
 321     IS_WINDOWS && !IS_64 ? "org.eclipse.swt.win32.win32.x86_3.7.2.v3740f" :
 322     IS_LINUX && IS_64 ? "org.eclipse.swt.gtk.linux.x86_64_3.7.2.v3740f" :
 323     IS_LINUX && !IS_64 ? "org.eclipse.swt.gtk.linux.x86_3.7.2.v3740f" : ""
 324 
 325 // Build javadocs only if BUILD_JAVADOC=true
 326 defineProperty("BUILD_JAVADOC", "false")
 327 ext.IS_BUILD_JAVADOC = Boolean.parseBoolean(BUILD_JAVADOC)
 328 
 329 // Specifies whether to build the javafx-src bundle
 330 defineProperty("BUILD_SRC_ZIP", "false")
 331 ext.IS_BUILD_SRC_ZIP = Boolean.parseBoolean(BUILD_SRC_ZIP)
 332 
 333 // Specifies whether to run full tests (true) or smoke tests (false)
 334 defineProperty("FULL_TEST", "false")
 335 ext.IS_FULL_TEST = Boolean.parseBoolean(FULL_TEST);
 336 
 337 // Specifies whether to run robot-based visual tests (only used when FULL_TEST is also enabled)
 338 defineProperty("USE_ROBOT", "true")
 339 ext.IS_USE_ROBOT = Boolean.parseBoolean(USE_ROBOT);
 340 
 341 // Specified whether to run tests in headless mode
 342 defineProperty("HEADLESS_TEST", "false")
 343 ext.IS_HEADLESS_TEST = Boolean.parseBoolean(HEADLESS_TEST);
 344 
 345 // Specifies whether to run system tests that depend on AWT (only used when FULL_TEST is also enabled)
 346 defineProperty("AWT_TEST", "true")
 347 ext.IS_AWT_TEST = Boolean.parseBoolean(AWT_TEST);
 348 
 349 // Specify the build configuration (Release, Debug, or DebugNative)
 350 defineProperty("CONF", "Debug")
 351 ext.IS_DEBUG_JAVA = CONF == "Debug" || CONF == "DebugNative"
 352 ext.IS_DEBUG_NATIVE = CONF == "DebugNative"
 353 
 354 // Defines the compiler warning levels to use. If empty, then no warnings are generated. If
 355 // not empty, then the expected syntax is as a space or comma separated list of names, such
 356 // as defined in the javac documentation.
 357 defineProperty("LINT", "none")
 358 ext.IS_LINT = LINT != "none"
 359 
 360 defineProperty("DOC_LINT", "none")
 361 ext.IS_DOC_LINT = DOC_LINT != "none"
 362 
 363 // Specifies whether to use the "useDepend" option when compiling Java sources
 364 defineProperty("USE_DEPEND", "true")
 365 ext.IS_USE_DEPEND = Boolean.parseBoolean(USE_DEPEND)
 366 
 367 // Specifies whether to generate code coverage statistics when running tests
 368 defineProperty("JCOV", "false")
 369 ext.DO_JCOV = Boolean.parseBoolean(JCOV)
 370 
 371 // Define the number of threads to use when compiling (specifically for native compilation)
 372 defineProperty("NUM_COMPILE_THREADS", "${Runtime.runtime.availableProcessors()}")
 373 
 374 //
 375 // The next three sections of properties are used to generate the
 376 // VersionInfo class, and the Windows DLL manifest.
 377 //
 378 
 379 // The following properties should be left alone by developers and set only from Hudson.
 380 defineProperty("HUDSON_JOB_NAME", "not_hudson")
 381 defineProperty("HUDSON_BUILD_NUMBER","0000")
 382 defineProperty("PROMOTED_BUILD_NUMBER", "00")
 383 
 384 // The following properties define the product name for Oracle JDK and OpenJDK
 385 // for VersionInfo and the DLL manifest.
 386 if (BUILD_CLOSED) {
 387     defineProperty("PRODUCT_NAME", "Java(TM)")
 388     defineProperty("COMPANY_NAME", "Oracle Corporation")
 389     defineProperty("PLATFORM_NAME", "Platform SE")
 390 } else {
 391     defineProperty("PRODUCT_NAME", "OpenJFX")
 392     defineProperty("COMPANY_NAME", "N/A")
 393     defineProperty("PLATFORM_NAME", "Platform")
 394 }
 395 
 396 // The following properties are set based on properties defined in
 397 // build.properties. The release number or milestone number should be updated
 398 // in that file.
 399 def jfxReleaseVersion = "${jfxReleaseMajorVersion}.${jfxReleaseMinorVersion}.${jfxReleaseMicroVersion}"
 400 defineProperty("RAW_VERSION", jfxReleaseVersion)
 401 defineProperty("RELEASE_NAME", jfxReleaseName)
 402 defineProperty("RELEASE_MILESTONE", jfxReleaseMilestone)
 403 
 404 // Check whether the COMPILE_TARGETS property has been specified (if so, it was done by
 405 // the user and not by this script). If it has not been defined then default
 406 // to building the normal desktop build for this machine
 407 project.ext.set("defaultHostTarget", IS_MAC ? "mac" : IS_WINDOWS ? "win" : IS_LINUX ? "linux" : "");
 408 defineProperty("COMPILE_TARGETS", "$defaultHostTarget")
 409 
 410 // Flag indicating whether to import cross compile tools
 411 def importCrossTools = BUILD_CLOSED ? true : false;
 412 if (!importCrossTools && hasProperty("IMPORT_CROSS_TOOLS")) {
 413     importCrossTools = Boolean.parseBoolean(IMPORT_CROSS_TOOLS);
 414 }
 415 ext.IS_IMPORT_CROSS_TOOLS = importCrossTools
 416 
 417 // Location of the cross compile tools
 418 def crossToolsDir = "../crosslibs" 
 419 if (hasProperty("CROSS_TOOLS_DIR")) {
 420     crossToolsDir = CROSS_TOOLS_DIR
 421 }
 422 ext.CROSS_TOOLS_DIR = file(crossToolsDir)
 423 
 424 /**
 425  * Fetch/Check that external tools are present for the build. This method
 426  * will conditionally download the packages from project defined ivy repositories
 427  * and unpack them into the specified destdir
 428  *
 429  * @param configName A unique name to distinguish the configuration (ie "ARMSFV6")
 430  * @param packages A list of required packages (with extensions .tgz, .zip)
 431  * @param destdir where the packages should be unpacked
 432  * @param doFetch if true, the named packages will be download
 433  */
 434 void fetchExternalTools(String configName, List packages, File destdir, boolean doFetch) {
 435     if (doFetch) {
 436         // create a unique configuration for this fetch
 437         def String fetchToolsConfig = "fetchTools$configName"
 438         rootProject.configurations.create(fetchToolsConfig)
 439 
 440         def List<String> fetchedPackages = []
 441         def int fetchCount = 0
 442 
 443         packages.each { pkgname->
 444             def int dotdex = pkgname.lastIndexOf('.')
 445             def int dashdex = pkgname.lastIndexOf('-')
 446             def String basename = pkgname.substring(0,dashdex)
 447             def String ver = pkgname.substring(dashdex+1,dotdex)
 448             def String ext = pkgname.substring(dotdex+1)
 449             def File pkgdir = file("$destdir/$basename-$ver")
 450 
 451             if (!pkgdir.isDirectory()) {
 452                 rootProject.dependencies.add(fetchToolsConfig, "javafx:$basename:$ver", {
 453                     artifact {
 454                         name = basename
 455                         version = ver
 456                         type = ext
 457                     }
 458                 })
 459                 println "adding $pkgname as a downloadable item did not find $pkgdir"
 460                 fetchedPackages.add(pkgname)
 461                 fetchCount++
 462             }
 463         }
 464 
 465         //fetch all the missing packages
 466         if (fetchedPackages.size > 0) {
 467             destdir.mkdirs()
 468 
 469             logger.quiet "fetching missing packages $fetchedPackages"
 470             copy {
 471                 from rootProject.configurations[fetchToolsConfig]
 472                 into destdir
 473             }
 474 
 475             // unpack the fetched packages
 476             fetchedPackages.each { pkgname->
 477                 logger.quiet "expanding the package $pkgname"
 478                 def srcball = file("${destdir}/${pkgname}")
 479 
 480                 if (!srcball.exists()) {
 481                     throw new GradleException("Failed to fetch $pkgname");
 482                 }
 483 
 484                 def String basename = pkgname.substring(0,pkgname.lastIndexOf("."))
 485                 def File pkgdir = file("$destdir/$basename")
 486 
 487                 if (pkgname.endsWith(".tgz")) {
 488                     if (IS_LINUX || IS_MAC) {
 489                         // use native tar to support symlinks
 490                         pkgdir.mkdirs()
 491                         exec {
 492                             workingDir pkgdir
 493                             commandLine "tar", "zxf", "${srcball}"
 494                          }
 495                     } else {
 496                         copy {
 497                             from tarTree(resources.gzip("${srcball}"))
 498                             into pkgdir
 499                         }
 500                     }
 501                 } else if (pkgname.endsWith(".zip")) {
 502                      copy {
 503                          from zipTree("${srcball}")
 504                          into pkgdir
 505                      }
 506                 } else {
 507                     throw new GradleException("Unhandled pacakge type for compile package ${pkgname}")
 508                 }
 509                 srcball.deleteOnExit();
 510             }
 511         } else {
 512             logger.quiet "all tool packages are present $packages"
 513         }
 514     } else { // !doFetch - so just check they are present
 515         // check that all the dirs are really there
 516         def List<String> errors = []
 517         packages.each { pkgname->
 518             def String basename = pkgname.substring(0,pkgname.lastIndexOf("."))
 519             def File pkgdir = file("$destdir/$basename")
 520 
 521             if (!pkgdir.isDirectory()) {
 522                 errors.add(pkgname)
 523             }
 524         }
 525         if (errors.size > 0) {
 526             throw new GradleException("Error: missing tool packages: $errors")
 527         } else {
 528             logger.quiet "all tool packages are present $packages"
 529         }
 530     }
 531 }
 532 
 533 // Now we need to define the native compilation tasks. The set of parameters to
 534 // native compilation depends on the target platform (and also to some extent what platform
 535 // you are compiling on). These settings are contained in various gradle files
 536 // such as mac.gradle and linux.gradle and armhf.gradle. Additionally, the developer
 537 // can specify COMPILE_FLAGS_FILE to be a URL or path to a different gradle file
 538 // that will contain the appropriate flags.
 539 defineProperty("COMPILE_FLAGS_FILES", COMPILE_TARGETS.split(",").collect {"buildSrc/${it.trim()}.gradle"}.join(","))
 540 if (COMPILE_TARGETS == "all") {
 541     def tmp = []
 542     File buildSrcDir = file("buildSrc")
 543     buildSrcDir.listFiles().each { File f ->
 544         if (f.isFile() && f.name.endsWith(".gradle") && !f.name.equals("build.gradle")) {
 545             def target = f.name.substring(0, f.name.lastIndexOf('.gradle')).toUpperCase(Locale.ROOT)
 546             apply from: f
 547             if (project.ext["${target}"].canBuild) {
 548                 tmp.add(target)
 549             }
 550         }
 551     }
 552     COMPILE_FLAGS_FILES = tmp.collect { "buildSrc/${it}.gradle"}.join(",")
 553     COMPILE_TARGETS = tmp.collect { "${it.toLowerCase()}"}.join(",")
 554 } else {
 555     COMPILE_FLAGS_FILES.split(",").each {
 556         logger.info("Applying COMPILE_FLAGS_FILE '$it'")
 557         apply from: it
 558     }
 559 }
 560 
 561 if (COMPILE_TARGETS != "") {
 562     def tmp = []
 563     COMPILE_TARGETS.split(",").each {target ->
 564         if (project.ext["${target.toUpperCase(Locale.ROOT)}"].canBuild) {
 565             tmp.add(target)
 566         }
 567     }
 568     COMPILE_TARGETS = tmp.collect { "${it.toLowerCase()}"}.join(",")
 569 }
 570 
 571 // Sanity check the expected properties all exist
 572 compileTargets { t ->
 573     // Every platform must define these variables
 574     if (!project.hasProperty(t.upper)) throw new Exception("ERROR: Incorrectly configured compile flags file, missing ${t.name} property")
 575     def props = project.ext[t.upper];
 576     ["jfxrtJarExcludes", "compileSwing", "compileSWT", "compileFXPackager", "compileDesignTime", "libDest"].each { prop ->
 577         if (!props.containsKey(prop)) throw new Exception("ERROR: Incorrectly configured compile flags file, missing ${prop} property on ${t.name}")
 578     }
 579 }
 580 
 581 // Various build flags may be set by the different target files, such as
 582 // whether to build Swing, SWT, FXPackager, etc. We iterate over all
 583 // compile targets and look for these settings in our properties. Note that
 584 // these properties cannot be set from the command line, but are set by
 585 // the target build files such as armv6hf.gradle or mac.gradle.
 586 ext.COMPILE_SWING = false;
 587 ext.COMPILE_SWT = false;
 588 ext.COMPILE_FXPACKAGER = false;
 589 ext.COMPILE_DESIGN_TIME = false;
 590 compileTargets { t ->
 591     if (project.ext[t.upper].compileSwing) COMPILE_SWING = true
 592     if (project.ext[t.upper].compileSWT) COMPILE_SWT = true
 593     if (project.ext[t.upper].compileFXPackager) COMPILE_FXPACKAGER = true
 594     if (project.ext[t.upper].compileDesignTime) COMPILE_DESIGN_TIME = true
 595 }
 596 
 597 /******************************************************************************
 598  *                                                                            *
 599  *                         Build Setup Sanity Checks                          *
 600  *                                                                            *
 601  *  Here we do a variety of checks so that if the version of Java you are     *
 602  *  building with is misconfigured, or you are using the wrong version of     *
 603  *  gradle, etc you will get some kind of helpful error / warning message     *
 604  *                                                                            *
 605  *****************************************************************************/
 606 
 607 // Verify that the architecture & OS are supported configurations. Note that
 608 // at present building on PI is not supported, but we would only need to make
 609 // some changes on assumptions on what should be built (like SWT / Swing) and
 610 // such and we could probably make it work.
 611 if (!IS_MAC && !IS_WINDOWS && !IS_LINUX) logger.error("Unsupported build OS ${OS_NAME}")
 612 if (IS_WINDOWS && OS_ARCH != "x86" && OS_ARCH != "amd64") {
 613     throw new Exception("Unknown and unsupported build architecture: $OS_ARCH")
 614 } else if (IS_MAC && OS_ARCH != "x86_64") {
 615     throw new Exception("Unknown and unsupported build architecture: $OS_ARCH")
 616 } else if (IS_LINUX && OS_ARCH != "i386" && OS_ARCH != "amd64") {
 617     throw new Exception("Unknown and unsupported build architecture: $OS_ARCH")
 618 }
 619 
 620 // Sanity check that we actually have a list of compile targets to execute
 621 if (COMPILE_TARGETS == null || COMPILE_TARGETS == "") {
 622     throw new Exception("Unable to determine compilation platform, must specify valid COMPILE_TARGETS!")
 623 }
 624 
 625 // Make sure JDK_HOME/bin/java exists
 626 if (!file(JAVA).exists()) throw new Exception("Missing or incorrect path to 'java': '$JAVA'. Perhaps bad JDK_HOME? $JDK_HOME")
 627 if (!file(JAVAC).exists()) throw new Exception("Missing or incorrect path to 'javac': '$JAVAC'. Perhaps bad JDK_HOME? $JDK_HOME")
 628 if (!file(JAVAH).exists()) throw new Exception("Missing or incorrect path to 'javah': '$JAVAH'. Perhaps bad JDK_HOME? $JDK_HOME")
 629 if (!file(JAVADOC).exists()) throw new Exception("Missing or incorrect path to 'javadoc': '$JAVADOC'. Perhaps bad JDK_HOME? $JDK_HOME")
 630 
 631 
 632 // Determine the verion of Java in JDK_HOME. It looks like this:
 633 //
 634 // $ java -version
 635 // java version "1.7.0_45"
 636 // Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
 637 // Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
 638 //
 639 // We need to parse the second line
 640 def inStream = new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.ProcessBuilder(JAVA, "-version").start().getErrorStream()));
 641 try {
 642     if (inStream.readLine() != null) {
 643         String v = inStream.readLine();
 644         if (v != null) {
 645             int ib = v.indexOf(" (build ");
 646             if (ib != -1) {
 647                 String ver = v.substring(ib + 8, v.size() - 1);
 648 
 649                 defineProperty("jdkRuntimeVersion", ver)
 650                 defineProperty("jdkVersion", jdkRuntimeVersion.split("[_\\-]")[0])
 651                 defineProperty("jdkBuildNumber", jdkRuntimeVersion.substring(jdkRuntimeVersion.lastIndexOf("-b") + 2))
 652             }
 653         }
 654     }
 655 } finally {
 656     inStream.close();
 657 }
 658 if (!project.hasProperty("jdkRuntimeVersion")) throw new Exception("Unable to determine the version of Java in JDK_HOME at $JDK_HOME");
 659 
 660 
 661 
 662 // Verify that CONF is something useful
 663 if (CONF != "Release" && CONF != "Debug") logger.warn("Unknown configuration CONF='$CONF'. Treating as 'Release'")
 664 
 665 // If the number of compile threads is less than 1 then we have a problem!
 666 if (Integer.parseInt(NUM_COMPILE_THREADS.toString()) < 1) {
 667     logger.warn("NUM_COMPILE_THREADS was specified as '$NUM_COMPILE_THREADS' which is less than the minimum value of 1. " +
 668             "Building with a value of 1 instead.")
 669     NUM_COMPILE_THREADS = 1
 670 }
 671 
 672 // Check that Gradle 1.8 is in use.
 673 if (gradle.gradleVersion != "1.8") {
 674     logger.warn("Unsupported gradle version $gradle.gradleVersion in use. Only 1.8 is supported")
 675 }
 676 
 677 /******************************************************************************
 678  *                                                                            *
 679  *                      Logging of Properties and Settings                    *
 680  *                                                                            *
 681  *  Log some of the settings we've determined. We could log more here, it     *
 682  *  doesn't really hurt.                                                      *
 683  *                                                                            *
 684  *****************************************************************************/
 685 
 686 logger.quiet("OS_NAME: $OS_NAME")
 687 logger.quiet("OS_ARCH: $OS_ARCH")
 688 logger.quiet("JAVA_HOME: $JAVA_HOME")
 689 logger.quiet("JDK_HOME: $JDK_HOME")
 690 logger.quiet("java.runtime.version: ${javaRuntimeVersion}")
 691 logger.quiet("java version: ${javaVersion}")
 692 logger.quiet("java build number: ${javaBuildNumber}")
 693 logger.quiet("jdk.runtime.version: ${jdkRuntimeVersion}")
 694 logger.quiet("jdk version: ${jdkVersion}")
 695 logger.quiet("jdk build number: ${jdkBuildNumber}")
 696 logger.quiet("minimum java build number: ${jfxBuildJdkBuildnumMin}")
 697 logger.quiet("COMPILE_TARGETS: $COMPILE_TARGETS")
 698 logger.quiet("COMPILE_FLAGS_FILES: $COMPILE_FLAGS_FILES")
 699 logger.quiet("HUDSON_JOB_NAME: $HUDSON_JOB_NAME")
 700 logger.quiet("HUDSON_BUILD_NUMBER: $HUDSON_BUILD_NUMBER")
 701 logger.quiet("PROMOTED_BUILD_NUMBER: $PROMOTED_BUILD_NUMBER")
 702 logger.quiet("PRODUCT_NAME: $PRODUCT_NAME")
 703 logger.quiet("RAW_VERSION: $RAW_VERSION")
 704 logger.quiet("RELEASE_NAME: $RELEASE_NAME")
 705 logger.quiet("RELEASE_MILESTONE: $RELEASE_MILESTONE")
 706 
 707 if (UPDATE_STUB_CACHE) {
 708     logger.quiet("UPDATE_STUB_CACHE: $UPDATE_STUB_CACHE")
 709 }
 710 
 711 /******************************************************************************
 712  *                                                                            *
 713  *                Definition of Native Code Compilation Tasks                 *
 714  *                                                                            *
 715  *    - JavaHeaderTask is used to run javah. The JAVAH property will point at *
 716  *      the version of javah to be used (i.e.: a path to javah)               *
 717  *    - CCTask compiles native code. Specifically it will compile .m, .c,     *
 718  *      .cpp, or .cc files. It uses the headers provided by the               *
 719  *      JavaHeaderTask plus additional platform specific headers. It will     *
 720  *      compile into .obj files.                                              *
 721  *    - LinkTask will perform native linking and create the .dll / .so /      *
 722  *      .dylib as necessary.                                                  *
 723  *                                                                            *
 724  *****************************************************************************/
 725 
 726 // Save a reference to the buildSrc.jar file because we need it for actually
 727 // compiling things, not just for the sake of this build script
 728 // (such as generating the builders, JSL files, etc)
 729 ext.BUILD_SRC = rootProject.files("buildSrc/build/libs/buildSrc.jar")
 730 
 731 /**
 732  * Convenience method for creating javah, cc, link, and "native" tasks in the given project. These
 733  * tasks are parameterized by name, so that we can produce, for example, javahGlass, ccGlass, etc
 734  * named tasks.
 735  * 
 736  * @param project The project to add tasks to
 737  * @param name The name of the project, such as "prism-common". This name is used
 738  *        in the name of the generated task, such as ccPrismCommon, and also
 739  *        in the name of the final library, such as libprism-common.dylib.
 740  */
 741 void addNative(Project project, String name) {
 742     addNative(project, name, null)
 743 }
 744 
 745 /**
 746  * Convenience method for creating javah, cc, link, and "native" tasks in the given project. These
 747  * tasks are parameterized by name, so that we can produce, for example, javahGlass, ccGlass, etc
 748  * named tasks.
 749  * 
 750  * @param project The project to add tasks to
 751  * @param name The name of the project, such as "prism-common". This name is used
 752  *        in the name of the generated task, such as ccPrismCommon, and also
 753  *        in the name of the final library, such as libprism-common.dylib.
 754  * @param list of compile targets. Library is applicable only for these targets.
 755  */
 756 void addNative(Project project, String name, List<String> includeTargets) {
 757     // TODO if we want to handle 32/64 bit windows in the same build,
 758     // Then we will need to modify the win compile target to be win32 or win64
 759     def capitalName = name.split("-").collect{it.capitalize()}.join()
 760     def nativeTask = project.task("native$capitalName", group: "Build") {
 761         description = "Generates JNI headers, compiles, and builds native dynamic library for $name for all compile targets"
 762     }
 763     def cleanTask = project.task("cleanNative$capitalName", type: Delete, group: "Build") {
 764         description = "Clean native objects for $name"
 765     }
 766     if (project.hasProperty("nativeAllTask")) project.nativeAllTask.dependsOn nativeTask
 767     project.assemble.dependsOn(nativeTask)
 768     if (project.hasProperty("cleanNativeAllTask")) project.cleanNativeAllTask.dependsOn cleanTask
 769     
 770     // Each of the different compile targets will be placed in a sub directory
 771     // of these root dirs, with the name of the dir being the name of the target
 772     def headerRootDir = project.file("$project.buildDir/generated-src/headers/$name")
 773     def nativeRootDir = project.file("$project.buildDir/native/$name")
 774     def libRootDir = project.file("$project.buildDir/libs/$name")
 775     // For each compile target, create a javah / cc / link triplet
 776     compileTargets { t ->
 777         if (includeTargets != null && !includeTargets.contains(t.name)) {
 778             return
 779         }
 780         def targetProperties = project.rootProject.ext[t.upper]
 781         def library = targetProperties.library
 782         def properties = targetProperties.get(name)
 783         def nativeDir = file("$nativeRootDir/${t.name}")
 784         def headerDir = file("$headerRootDir/${t.name}")
 785         
 786         def javahTask = project.task("javah${t.capital}${capitalName}", type: JavaHeaderTask, dependsOn: project.classes, group: "Build") {
 787             description = "Generates JNI Headers for ${name} for ${t.name}"
 788             if (properties.javahSource == null) {
 789                 source(project.sourceSets.main.output.classesDir)
 790             } else {
 791                 source(properties.javahSource)
 792             }
 793             if (properties.javahClasspath == null) {
 794                 classpath = project.files(project.sourceSets.main.output.classesDir)
 795             } else {
 796                 classpath = project.files(properties.javahClasspath)
 797             }
 798             output = headerDir
 799             include(properties.javahInclude)
 800             cleanTask.delete headerDir
 801         }
 802 
 803         def variants = properties.containsKey("variants") ? properties.variants : [""];
 804         variants.each { variant ->
 805             def variantProperties = variant == "" ? properties : properties.get(variant)
 806             def capitalVariant = variant.capitalize()
 807             def ccOutput = variant == "" ? nativeDir : file("$nativeDir/$variant")
 808             def ccTask = project.task("cc${t.capital}$capitalName$capitalVariant", type: CCTask, dependsOn: javahTask, group: "Build") {
 809                 description = "Compiles native sources for ${name} for ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}"
 810                 matches = ".*\\.c|.*\\.cpp|.*\\.m|.*\\.cc"
 811                 headers = headerDir
 812                 output(ccOutput)
 813                 params.addAll(variantProperties.ccFlags)
 814                 compiler = variantProperties.compiler
 815                 source(variantProperties.nativeSource)
 816                 cleanTask.delete ccOutput
 817             }
 818             def linkTask = project.task("link${t.capital}$capitalName$capitalVariant", type: LinkTask, dependsOn: ccTask, group: "Build") {
 819                 description = "Creates native dynamic library for $name for ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}"
 820                 objectDir = ccOutput
 821                 linkParams.addAll(variantProperties.linkFlags)
 822                 lib = file("$libRootDir/${t.name}/${variant == '' ? library(properties.lib) : library(variantProperties.lib)}")
 823                 linker = variantProperties.linker
 824                 cleanTask.delete "$libRootDir/${t.name}"
 825             }
 826             nativeTask.dependsOn(linkTask)
 827             if (IS_WINDOWS && t.name == "win") {
 828                 def rcTask = project.task("rc$capitalName$capitalVariant", type: CompileResourceTask, dependsOn: javahTask, group: "Build") {
 829                     description = "Compiles native sources for $name"
 830                     matches = ".*\\.rc"
 831                     compiler = variantProperties.rcCompiler
 832                     source(variantProperties.rcSource)
 833                     if (variantProperties.rcFlags) {
 834                         rcParams.addAll(variantProperties.rcFlags)
 835                     }
 836                     output(ccOutput)
 837                 }
 838                 linkTask.dependsOn rcTask;
 839             }
 840         }
 841 
 842         def useLipo = targetProperties.containsKey('useLipo') ? targetProperties.useLipo : false
 843         if (useLipo) {
 844             def lipoTask = project.task("lipo${t.capital}$capitalName", type: LipoTask, dependsOn: javahTask, group: "Build") {
 845                 description = "Creates native fat library for $name for ${t.name}"
 846                 libDir = file("$libRootDir/${t.name}")
 847                 lib = file("$libRootDir/${t.name}/${library(properties.lib)}")
 848             }
 849             nativeTask.dependsOn(lipoTask)
 850         }
 851     }
 852 }
 853 
 854 void addJSL(Project project, String name, String pkg, Closure compile) {
 855     def lowerName = name.toLowerCase()
 856 
 857     def compileCompilers = project.task("compile${name}Compilers", type: JavaCompile, dependsOn: project.compileJava) {
 858         description = "Compile the $name JSL Compilers"
 859         classpath = project.files(project.sourceSets.main.output.classesDir) +
 860                 rootProject.BUILD_SRC +
 861                 project.configurations.antlr3
 862         source = [project.file("src/main/jsl-$lowerName")]
 863         destinationDir = project.file("$project.buildDir/classes/jsl-compilers/$lowerName")
 864     }
 865 
 866     def generateShaders = project.task("generate${name}Shaders", dependsOn: compileCompilers) {
 867         description = "Generate $name shaders from JSL"
 868         def sourceDir = project.file("src/main/jsl-$lowerName")
 869         def destinationDir = project.file("$project.buildDir/generated-src/jsl-$lowerName")
 870         inputs.dir sourceDir
 871         outputs.dir destinationDir
 872         doLast {
 873             compile(sourceDir, destinationDir)
 874         }
 875     }
 876 
 877     project.task("compile${name}JavaShaders", type: JavaCompile, dependsOn: generateShaders) {
 878         description = "Compile the Java $name JSL shaders"
 879         classpath = project.files(project.sourceSets.main.output.classesDir) + rootProject.BUILD_SRC
 880         source = [project.file("$project.buildDir/generated-src/jsl-$lowerName")]
 881         destinationDir = project.file("$project.buildDir/classes/jsl-$lowerName")
 882     }
 883 
 884     def compileHLSLShaders = project.task("compile${name}HLSLShaders", dependsOn: generateShaders, type: CompileHLSLTask) {
 885         enabled = IS_WINDOWS
 886         description = "Compile $name HLSL files into .obj files"
 887         matches = ".*\\.hlsl"
 888         output project.file("$project.buildDir/hlsl/$name/$pkg")
 889         source project.file("$project.buildDir/generated-src/jsl-$lowerName/$pkg")
 890     }
 891 
 892     project.task("process${name}Shaders", dependsOn: [generateShaders, compileHLSLShaders], type: Copy, description: "Copy hlsl / frag shaders to build/resources/jsl-$lowerName") {
 893         from("$project.buildDir/hlsl/$name") {
 894             include "**/*.obj"
 895         }
 896         from("$project.buildDir/generated-src/jsl-$lowerName") {
 897             include("**/*.frag")
 898         }
 899         into "$project.buildDir/resources/jsl-$lowerName"
 900     }
 901 }
 902 
 903 // Task to verify the minimum level of Java needed to build JavaFX
 904 task verifyJava() {
 905     doLast {
 906         if (jdkVersion != jfxBuildJdkVersion) {
 907             fail("java version mismatch: ${jdkVersion} must be ${jfxBuildJdkVersion}")
 908         }
 909         def buildNum = Integer.parseInt(jdkBuildNumber)
 910         def minBuildNum = Integer.parseInt(jfxBuildJdkBuildnumMin)
 911         if (buildNum < minBuildNum) {
 912             fail("java build number ($buildNum) < minimum build number ($minBuildNum)")
 913         }
 914     }
 915 }
 916 
 917 // Task to check whether jfxrt.jar is present in the JDK
 918 task checkJfxrtJar {
 919     doLast {
 920         def jfxrtFile = new File("$JDK_HOME/jre/lib/ext/jfxrt.jar");
 921         if (jfxrtFile.exists()) {
 922             if (BUILD_CLOSED) {
 923                 fail("$jfxrtFile must be removed before building closed sdk")
 924             } else {
 925                 logger.warn("****************************************************************")
 926                 logger.warn("$jfxrtFile may interfere with testing or running applications against locally build jfxrt.jar")
 927                 logger.warn("****************************************************************")
 928             }
 929         }
 930     }
 931 }
 932 
 933 task updateCacheIfNeeded() {
 934     // an empty task we can add to as needed for UPDATE_STUB_CACHE
 935 }
 936 
 937 /*****************************************************************************
 938 *        Project definitions (dependencies, etc)                             *
 939 *****************************************************************************/
 940 
 941 void addJCov(p, test) {
 942     test.doFirst {
 943         def jcovJVMArgument =
 944                 "include=javafx," +
 945                 "include=com.sun.javafx," +
 946                 "include=com.sun.glass," +
 947                 "include=com.sun.openpisces," +
 948                 "include=com.sun.pisces," +
 949                 "include=com.sun.prism," +
 950                 "include=com.sun.scenario," +
 951                 "include=com.sun.webkit," +
 952                 "exclude=com," +
 953                 "exclude=java," +
 954                 "exclude=javax," +
 955                 "exclude=\"**.test\"," +
 956                 "exclude=\"**.*Test\"," +
 957                 "file=build/reports/jcov/report.xml," +
 958                 "merge=merge";
 959         test.jvmArgs("-javaagent:${p.configurations.testCompile.files.find { it.name.startsWith('jcov') }}=$jcovJVMArgument");
 960         p.mkdir p.file("build/reports/jcov")
 961     }
 962     test.doLast {
 963         def reportFile = p.file("build/reports/jcov/report.xml")
 964         if (reportFile.exists()) {
 965             p.javaexec {
 966                 workingDir = p.file("build/reports/jcov")
 967                 classpath = p.files(p.configurations.testCompile.files.find { it.name.startsWith('jcov') })
 968                 main = "com.sun.tdk.jcov.Helper"
 969                 args = [
 970                         "RepGen",
 971                         "-exclude", "\"**.test\"",
 972                         "-exclude", "\"**.*Test\"",
 973                         "-output", ".",
 974                         "-source", p.sourceSets.main.java.srcDirs.collect{p.file(it)}.join(":"),
 975                         "report.xml"
 976                 ]
 977             }
 978         }
 979     }
 980 }
 981 
 982 allprojects {
 983     // We want to configure all projects as java projects and use the same compile settings
 984     // etc, except for the root project which we just want to ignore (and for now media)
 985     if (project == rootProject) {
 986        return
 987     }
 988     if (project.path.startsWith(":apps")) {
 989         // Lets handle the apps tree differently, as it is a collection of ant builds,
 990         // and the ant importer collides with the 'apply plugin:java'
 991         return
 992     }
 993     // All of our projects are java projects
 994     apply plugin: "java"
 995     sourceCompatibility = 1.8
 996 
 997     // Setup the repositories that we'll download libraries from. Maven Central is
 998     // just easy for most things. The custom "ivy" repo is for downloading SWT. The way it
 999     // works is to setup the download URL such that it will resolve to the actual jar file
1000     // to download. See SWT_FILE_NAME for the name of the jar that will be used as the
1001     // "artifact" in the pattern below. Note that the closed builds use different repositories
1002     // so if you are debugging a closed-build artifact related build issue, check out the
1003     // closed gradle file instead.
1004     if (!BUILD_CLOSED) {
1005         repositories {
1006             mavenCentral()
1007             ivy {
1008                 url "http://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/plugins/"
1009                 layout "pattern", {
1010                     artifact "[artifact].[ext]"
1011                 }
1012             }
1013         }
1014     }
1015 
1016     // By default all of our projects require junit for testing so we can just
1017     // setup this dependency here.
1018     dependencies {
1019         testCompile group: "junit", name: "junit", version: "4.8.2"
1020         if (BUILD_CLOSED && DO_JCOV)  {
1021             testCompile name: "jcov"
1022         }
1023     }
1024 
1025     // Compile and run tests against the jfxrt.jar in the built sdk of the host machine
1026     def sdkDir = "${rootProject.buildDir}/${defaultHostTarget}-sdk"
1027     def jfxrtJar = "$sdkDir/rt/lib/ext/jfxrt.jar"
1028 
1029     // At the moment the ASM library shipped with Gradle that is used to
1030     // discover the different test classes fails on Java 8, so in order
1031     // to have sourceCompatibility set to 1.8 I have to also turn scanForClasses off
1032     // and manually specify the includes / excludes. At the moment we use
1033     // Java 7 but when we switch to 8 this will be needed, and probably again when
1034     // we start building with Java 9.
1035     test {
1036         jvmArgs("-Djava.ext.dirs=");
1037         executable = JAVA;
1038         enableAssertions = true;
1039         testLogging.exceptionFormat = "full";
1040         scanForTestClasses = false;
1041         include("**/*Test.*");
1042         if (BUILD_CLOSED && DO_JCOV) {
1043             addJCov(project, test)
1044         }
1045         classpath = files("$jfxrtJar") + classpath
1046         if (IS_HEADLESS_TEST) {
1047             systemProperty 'glass.platform', 'Monocle'
1048             systemProperty 'monocle.platform', 'Headless'
1049             systemProperty 'prism.order', 'sw'
1050         }
1051     }
1052 
1053     compileTestJava {
1054         classpath = files("$jfxrtJar") + classpath
1055     }
1056 
1057     // Exclude any non-public-API classes from having javadoc generated. This block is used
1058     // when generating JavaDocs for a specific project. When generating the JavaDocs for the
1059     // entire SDK, a different javadoc command is used (see the javadoc task on the top level)
1060     javadoc {
1061         enabled = IS_BUILD_JAVADOC
1062         exclude("com/**/*", "javafx/scene/ParentDesignInfo*", "Compile*", "javafx/builder/**/*");
1063         executable = JAVADOC;
1064         options.windowTitle("JavaFX Project ${project.name} ${RELEASE_NAME}")
1065         options.links(JDK_DOCS);
1066         options.addBooleanOption("XDignore.symbol.file").setValue(true);
1067         options.addBooleanOption("Xdoclint:none").setValue(!IS_DOC_LINT);
1068         options.addBooleanOption("javafx").setValue(true);
1069         // All doc-files are located in src/main/docs because Gradle's javadoc doesn't copy
1070         // over the doc-files if they are embedded with the sources. I find this arrangement
1071         // somewhat cleaner anyway (never was a fan of mixing javadoc files with the sources)
1072         doLast {
1073             copy {
1074                 from "src/main/docs"
1075                 into "$buildDir/docs/javadoc"
1076             }
1077         }
1078     }
1079 }
1080 
1081 // The "base" project is our first module and the most basic one required for
1082 // all other modules. It is useful even for non-GUI applications.
1083 project(":base") {
1084     dependencies {
1085         compile BUILD_SRC
1086     }
1087 
1088     // We need to take the VersionInfo.java file and replace the various
1089     // properties within it
1090     def replacements = [
1091         "BUILD_TIMESTAMP": new java.util.Date(),
1092         "HUDSON_JOB_NAME": HUDSON_JOB_NAME,
1093         "HUDSON_BUILD_NUMBER": HUDSON_BUILD_NUMBER,
1094         "PROMOTED_BUILD_NUMBER": PROMOTED_BUILD_NUMBER,
1095         "PRODUCT_NAME": PRODUCT_NAME,
1096         "RAW_VERSION": RAW_VERSION,
1097         "RELEASE_NAME": RELEASE_NAME,
1098         "RELEASE_MILESTONE": RELEASE_MILESTONE];
1099     task processVersionInfo(type: Copy, description: "Replace params in VersionInfo and copy file to destination") {
1100         doFirst { mkdir "$buildDir/generated-src/version-info" }
1101         from "src/main/version-info"
1102         into "$buildDir/generated-src/version-info/com/sun/javafx/runtime"
1103         filter {line->
1104             replacements.each() {k, v ->
1105                 line = line.replace("@$k@", v.toString());
1106             }
1107             line
1108         }
1109     }
1110 
1111     compileJava.dependsOn updateCacheIfNeeded
1112     compileJava.dependsOn verifyJava
1113 
1114     // Make sure to include $buildDir/generated-src/version-info that we previously created.
1115     // We DO NOT want to include src/main/version-info
1116     sourceSets.main.java.srcDirs = ["src/main/java", "$buildDir/generated-src/version-info"]
1117     compileJava.dependsOn processVersionInfo
1118 }
1119 
1120 // The graphics module is needed for any graphical JavaFX application. It requires
1121 // the base module and includes the scene graph, layout, css, prism, windowing, etc.
1122 // This is a fairly complicated module. There are many different types of native components
1123 // that all need to be compiled.
1124 project(":graphics") {
1125     // Workaround for lack of Antlr 3 support in Gradle. By defining a configuration,
1126     // we can then give it a class path and use that classpath to execute a java command
1127     getConfigurations().add("antlr3");
1128 
1129     sourceSets {
1130         main
1131         test
1132         stub
1133     }
1134 
1135     dependencies {
1136         compile project(":base"), BUILD_SRC
1137         compile name: SWT_FILE_NAME
1138         stubCompile group: "junit", name: "junit", version: "4.8.2",
1139         project(":base").sourceSets.test.output, sourceSets.main.output
1140         antlr3 group: "org.antlr", name: "antlr", version: "3.1.3"
1141         antlr3 group: "org.antlr", name: "antlr-runtime",  version: "3.1.3"
1142         antlr3 group: "org.antlr", name: "stringtemplate", version: "3.2"
1143     }
1144 
1145     // Create a single "native" task which will depend on all the individual native tasks for graphics
1146     project.ext.nativeAllTask = task("native", group: "Build", description: "Compiles and Builds all native libraries for Graphics");
1147     project.ext.cleanNativeAllTask = task("cleanNative", group: "Build", description: "Clean all native libraries and objects for Graphics");
1148 
1149     // Add tasks for native compilation
1150     addNative(project, "glass");
1151     addNative(project, "prism")
1152     addNative(project, "prismSW")
1153     addNative(project, "font")
1154     addNative(project, "iio")
1155     addNative(project, "prismES2")
1156 
1157     if (IS_COMPILE_PANGO) {
1158         // TODO: embedded support
1159         addNative(project, "fontFreetype", ["linux"])
1160         addNative(project, "fontPango", ["linux"])
1161     }
1162 
1163     if (IS_WINDOWS) {
1164         addNative(project, "prismD3D")
1165         // TODO need to hook this up to be executed only if PassThroughVS.h is missing or PassThroughVS.hlsl is changed
1166         task generateD3DHeaders(group: "Build") {
1167             enabled = IS_WINDOWS
1168             dependsOn javahWinPrismD3D
1169             inputs.file "src/main/native-prism-d3d/hlsl/Mtl1PS.hlsl"
1170             inputs.file "src/main/native-prism-d3d/hlsl/Mtl1VS.hlsl"
1171             inputs.file "src/main/native-prism-d3d/PassThroughVS.hlsl"
1172             outputs.dir "$buildDir/headers/PrismD3D/"
1173             outputs.dir "$buildDir/headers/PrismD3D/hlsl/"
1174             description = "Generate headers by compiling hlsl files"
1175             doLast {
1176                 mkdir file("$buildDir/headers/PrismD3D/hlsl")
1177                 def PS_3D_SRC = file("src/main/native-prism-d3d/hlsl/Mtl1PS.hlsl")
1178                 def VS_3D_SRC = file("src/main/native-prism-d3d/hlsl/Mtl1VS.hlsl")
1179                 def PASSTHROUGH_VS_SRC = file("src/main/native-prism-d3d/PassThroughVS.hlsl")
1180                 def jobs = [
1181                         ["$FXC", "/nologo", "/T", "vs_3_0", "/Fh", "$buildDir/headers/PrismD3D/PassThroughVS.h", "/E", "passThrough", "$PASSTHROUGH_VS_SRC"],
1182                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS.h", "/DSpec=0", "/DSType=0", "$PS_3D_SRC"],
1183                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_i.h", "/DSpec=0", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"],
1184                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1n.h", "/DSpec=1", "/DSType=0", "$PS_3D_SRC"],
1185                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2n.h", "/DSpec=2", "/DSType=0", "$PS_3D_SRC"],
1186                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3n.h", "/DSpec=3", "/DSType=0", "$PS_3D_SRC"],
1187                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1t.h", "/DSpec=1", "/DSType=1", "$PS_3D_SRC"],
1188                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2t.h", "/DSpec=2", "/DSType=1", "$PS_3D_SRC"],
1189                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3t.h", "/DSpec=3", "/DSType=1", "$PS_3D_SRC"],
1190                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1c.h", "/DSpec=1", "/DSType=2", "$PS_3D_SRC"],
1191                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2c.h", "/DSpec=2", "/DSType=2", "$PS_3D_SRC"],
1192                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3c.h", "/DSpec=3", "/DSType=2", "$PS_3D_SRC"],
1193                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1m.h", "/DSpec=1", "/DSType=3", "$PS_3D_SRC"],
1194                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2m.h", "/DSpec=2", "/DSType=3", "$PS_3D_SRC"],
1195                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3m.h", "/DSpec=3", "/DSType=3", "$PS_3D_SRC"],
1196                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1n.h", "/DSpec=1", "/DSType=0", "/DBump=1", "$PS_3D_SRC"],
1197                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2n.h", "/DSpec=2", "/DSType=0", "/DBump=1", "$PS_3D_SRC"],
1198                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3n.h", "/DSpec=3", "/DSType=0", "/DBump=1", "$PS_3D_SRC"],
1199                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1t.h", "/DSpec=1", "/DSType=1", "/DBump=1", "$PS_3D_SRC"],
1200                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2t.h", "/DSpec=2", "/DSType=1", "/DBump=1", "$PS_3D_SRC"],
1201                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3t.h", "/DSpec=3", "/DSType=1", "/DBump=1", "$PS_3D_SRC"],
1202                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1c.h", "/DSpec=1", "/DSType=2", "/DBump=1", "$PS_3D_SRC"],
1203                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2c.h", "/DSpec=2", "/DSType=2", "/DBump=1", "$PS_3D_SRC"],
1204                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3c.h", "/DSpec=3", "/DSType=2", "/DBump=1", "$PS_3D_SRC"],
1205                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1m.h", "/DSpec=1", "/DSType=3", "/DBump=1", "$PS_3D_SRC"],
1206                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2m.h", "/DSpec=2", "/DSType=3", "/DBump=1", "$PS_3D_SRC"],
1207                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3m.h", "/DSpec=3", "/DSType=3", "/DBump=1", "$PS_3D_SRC"],
1208                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1ni.h", "/DSpec=1", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"],
1209                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2ni.h", "/DSpec=2", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"],
1210                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3ni.h", "/DSpec=3", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"],
1211                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1ti.h", "/DSpec=1", "/DSType=1", "/DIllumMap=1", "$PS_3D_SRC"],
1212                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2ti.h", "/DSpec=2", "/DSType=1", "/DIllumMap=1", "$PS_3D_SRC"],
1213                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3ti.h", "/DSpec=3", "/DSType=1", "/DIllumMap=1", "$PS_3D_SRC"],
1214                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1ci.h", "/DSpec=1", "/DSType=2", "/DIllumMap=1", "$PS_3D_SRC"],
1215                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2ci.h", "/DSpec=2", "/DSType=2", "/DIllumMap=1", "$PS_3D_SRC"],
1216                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3ci.h", "/DSpec=3", "/DSType=2", "/DIllumMap=1", "$PS_3D_SRC"],
1217                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1mi.h", "/DSpec=1", "/DSType=3", "/DIllumMap=1", "$PS_3D_SRC"],
1218                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2mi.h", "/DSpec=2", "/DSType=3", "/DIllumMap=1", "$PS_3D_SRC"],
1219                         ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3mi.h", "/DSpec=3", "/DSType=3", "/DIllumMap=1", "$PS_3D_SRC"],
1220                         ["$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"],
1221                         ["$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"],
1222                         ["$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"],
1223                         ["$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"],
1224                         ["$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"],
1225                         ["$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"],
1226                         ["$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"],
1227                         ["$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"],
1228                         ["$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"],
1229                         ["$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"],
1230                         ["$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"],
1231                         ["$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"],
1232                         ["$FXC", "/nologo", "/T", "vs_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1VS_Obj.h", "/DVertexType=ObjVertex", "$VS_3D_SRC"]
1233                 ]
1234                 final ExecutorService executor = Executors.newFixedThreadPool(Integer.parseInt(project.NUM_COMPILE_THREADS.toString()));
1235                 final CountDownLatch latch = new CountDownLatch(jobs.size());
1236                 List futures = new ArrayList<Future>();
1237                 jobs.each { cmd ->
1238                     futures.add(executor.submit(new Runnable() {
1239                         @Override public void run() {
1240                             try {
1241                                 exec {
1242                                     commandLine cmd
1243                                 }
1244                             } finally {
1245                                 latch.countDown();
1246                             }
1247                         }
1248                     }));
1249                 }
1250                 latch.await();
1251                 // Looking for whether an exception occurred while executing any of the futures.
1252                 // By calling "get()" on each future an exception will be thrown if one had occurred
1253                 // on the background thread.
1254                 futures.each {it.get();}
1255             }
1256         }
1257 
1258         ccWinPrismD3D.dependsOn generateD3DHeaders
1259     }
1260 
1261     // The Decora and Prism JSL files have to be generated in a very specific set of steps.
1262     //      1) Compile the *Compile.java classes. These live in src/main/jsl-* and will be
1263     //         output to $buildDir/classes/jsl-compilers/* (where * == decora or prism).
1264     //      2) Generate source files from the JSL files contained in src/main/jsl-*. These
1265     //         will be output to $buildDir/generated-src/jsl-*
1266     //      3) Compile the JSL Java sources in $buildDir/generated-src/jsl-* and put the output
1267     //         into classes/jsl-*
1268     //      4) Compile the native JSL sources in $buildDir/generated-src/jsl-* and put the obj
1269     //         files into native/jsl-* and the resulting library into libs/jsl-*.dll|so|dylib
1270     //      5) Modify the jar step to include classes/jsl-*
1271     // The native library must be copied over during SDK creation time in the "sdk" task. In
1272     // addition to these steps, the clean task is created. Note that I didn't bother to create
1273     // a new task for each of the decora files, preferring instead just to create a rule?? Also
1274     // need "clean" tasks for each compile task.
1275 
1276     addJSL(project, "Decora", "com/sun/scenario/effect/impl/hw/d3d/hlsl") { sourceDir, destinationDir ->
1277         [[fileName: "ColorAdjust", generator: "CompileJSL", outputs: "-all"],
1278          [fileName: "Brightpass", generator: "CompileJSL", outputs: "-all"],
1279          [fileName: "SepiaTone", generator: "CompileJSL", outputs: "-all"],
1280          [fileName: "PerspectiveTransform", generator: "CompileJSL", outputs: "-all"],
1281          [fileName: "DisplacementMap", generator: "CompileJSL", outputs: "-all"],
1282          [fileName: "InvertMask", generator: "CompileJSL", outputs: "-all"],
1283          [fileName: "Blend", generator: "CompileBlend", outputs: "-all"],
1284          [fileName: "PhongLighting", generator: "CompilePhong", outputs: "-all"],
1285          [fileName: "LinearConvolve", generator: "CompileLinearConvolve", outputs: "-hw"],
1286          [fileName: "LinearConvolveShadow", generator: "CompileLinearConvolve", outputs: "-hw"]].each { settings ->
1287             javaexec {
1288                 executable = JAVA
1289                 workingDir = "modules/graphics"
1290                 main = settings.generator
1291                 classpath = configurations.compile + configurations.antlr3
1292                 classpath += files("$buildDir/classes/main")
1293                 classpath += files("$buildDir/classes/jsl-compilers/decora")
1294                 args = ["-i", sourceDir, "-o", destinationDir, "-t", "-pkg", "com/sun/scenario/effect", "$settings.outputs", "$settings.fileName"]
1295                 jvmArgs "-Djava.ext.dirs="
1296             }
1297         }
1298     }
1299 
1300     task generateDecoraNativeHeaders(type: JavaHeaderTask, dependsOn: compileDecoraJavaShaders) {
1301         description = "Generates JNI Headers for Decora SSE Natives"
1302         source file("$buildDir/classes/jsl-decora")
1303         source file("$buildDir/classes/main")
1304         include("com/sun/scenario/effect/impl/sw/sse/*");
1305         classpath = files("$buildDir/classes/main", "$buildDir/classes/jsl-decora")
1306         output = file("$buildDir/generated-src/headers/jsl-decora")
1307     }
1308 
1309     task nativeDecora(dependsOn: compileDecoraHLSLShaders, group: "Build") {
1310         description = "Generates JNI headers, compiles, and builds native dynamic library for Decora"
1311     }
1312     task cleanNativeDecora(type: Delete, group: "Build") {
1313         description = "Clean native objects for Decora"
1314     }
1315 
1316     def headerDir = file("$buildDir/generated-src/headers/jsl-decora")
1317     def nativeRootDir = project.file("$project.buildDir/native/jsl-decora")
1318     def libRootDir = project.file("$project.buildDir/libs/jsl-decora")
1319     // For each compile target, create cc and link tasks
1320     compileTargets { t ->
1321         def target = t.name
1322         def upperTarget = t.upper
1323         def capitalTarget = t.capital
1324         def properties = rootProject.ext[upperTarget];
1325         def library = properties.library
1326         def ccOutput = file("$nativeRootDir/$target");
1327 
1328         def ccTask = task("compileDecoraNativeShaders$capitalTarget", type: CCTask, dependsOn: generateDecoraNativeHeaders) {
1329             description = "Compiles Decora SSE natives"
1330             matches = ".*\\.cc"
1331             source file("$buildDir/generated-src/jsl-decora")
1332             source file("modules/graphics/src/main/native-decora")
1333             headers = headerDir
1334             params.addAll(properties.decora.ccFlags)
1335             output(ccOutput)
1336             compiler = properties.decora.compiler
1337             cleanNativeDecora.delete ccOutput
1338         }
1339 
1340         def linkTask = task("linkDecoraNativeShaders$capitalTarget", type: LinkTask, dependsOn: ccTask) {
1341             description = "Creates native dynamic library for Decora SSE"
1342             objectDir = file("$nativeRootDir/$target")
1343             linkParams.addAll(properties.decora.linkFlags)
1344             lib = file("$libRootDir/$t.name/${library(properties.decora.lib)}")
1345             linker = properties.decora.linker
1346             cleanNativeDecora.delete "$libRootDir/$t.name/"
1347         }
1348 
1349         if (IS_WINDOWS && target == "win") {
1350             def rcTask = project.task("rcDecoraNativeShaders$capitalTarget", type: CompileResourceTask, dependsOn: generateDecoraNativeHeaders) {
1351                 description = "Compiles native sources for Decora SSE"
1352                 matches = ".*\\.rc"
1353                 compiler = properties.decora.rcCompiler
1354                 source(properties.decora.rcSource)
1355                 if (properties.decora.rcFlags) {
1356                     rcParams.addAll(properties.decora.rcFlags)
1357                 }
1358                 output(ccOutput)
1359             }
1360             linkTask.dependsOn rcTask;
1361         }
1362 
1363         nativeDecora.dependsOn(linkTask)
1364     }
1365 
1366     // Prism JSL
1367     addJSL(project, "Prism", "com/sun/prism/d3d/hlsl") { sourceDir, destinationDir ->
1368         def inputFiles = fileTree(dir: sourceDir)
1369         inputFiles.include "**/*.jsl"
1370         inputFiles.each { file ->
1371             javaexec {
1372                 executable = JAVA
1373                 workingDir = "modules/graphics"
1374                 main = "CompileJSL"
1375                 classpath = configurations.compile + configurations.antlr3
1376                 classpath += files("$buildDir/classes/jsl-compilers/prism", "modules/graphics/src/main/jsl-prism") // for the .stg
1377                 args = ["-i", sourceDir, "-o", destinationDir, "-t", "-pkg", "com/sun/prism", "-d3d", "-es2", "-name", "$file"]
1378                 jvmArgs "-Djava.ext.dirs="
1379             }
1380         }
1381     }
1382 
1383     classes.dependsOn compilePrismJavaShaders;
1384     nativePrism.dependsOn compilePrismHLSLShaders;
1385 
1386     project.nativeAllTask.dependsOn nativeDecora
1387     project.cleanNativeAllTask.dependsOn cleanNativeDecora
1388     assemble.dependsOn nativeDecora
1389     processResources.dependsOn processDecoraShaders, processPrismShaders
1390 
1391     test {
1392         jvmArgs "-Djava.ext.dirs=", "-Djavafx.toolkit=com.sun.javafx.pgstub.StubToolkit", "-DCSS_META_DATA_TEST_DIR=${file('$buildDir/classes/main/javafx')}"
1393         enableAssertions = true
1394         testLogging.exceptionFormat = "full"
1395         scanForTestClasses = false
1396         include "**/*Test.*"
1397         if (BUILD_CLOSED && DO_JCOV) {
1398             addJCov(project, test)
1399         }
1400     }
1401 
1402     // To enable the IDEs to all be happy (no red squiggles) we need to have the libraries
1403     // available in some known location. Maybe in the future the Gradle plugins to each
1404     // of the IDEs will be good enough that we won't need this hack anymore.
1405     classes << {
1406         // Copy all of the download libraries to the libs directory for the sake of the IDEs
1407         File libsDir = rootProject.file("build/libs");
1408         libsDir.mkdirs();
1409         for (File f : [configurations.compile.files, configurations.antlr3.files].flatten()) {
1410             copy {
1411                 into libsDir
1412                 from f.getParentFile()
1413                 include "**/antlr-3.1.3.jar"
1414                 include "**/stringtemplate-3.2.jar"
1415                 include "**/antlr-runtime-3.1.3.jar"
1416                 includeEmptyDirs = false
1417             }
1418             // Have to rename the swt jar because it is some platform specific name but
1419             // for the sake of the IDEs we need to have a single stable name that works
1420             // on every platform
1421             copy {
1422                 into libsDir
1423                 from f.getParentFile()
1424                 include "**/*swt*.jar"
1425                 includeEmptyDirs = false
1426                 rename ".*swt.*jar", "swt-debug\\.jar"
1427             }
1428         }
1429     }
1430 }
1431 
1432 project(":controls") {
1433     dependencies {
1434         compile BUILD_SRC, project(":base"), project(":graphics"), project(":designTime")
1435         // TODO not sure how to specify this? processResources project(":base"), project(":graphics")
1436         testCompile project(":graphics").sourceSets.test.output
1437         testCompile project(":base").sourceSets.test.output
1438     }
1439 
1440     test {
1441         jvmArgs "-Djavafx.toolkit=com.sun.javafx.pgstub.StubToolkit"
1442     }
1443 
1444     // TODO Css2Bin really should be moved out and put into buildSrc if it can be
1445     // TODO could change script to dynamically locate all .css files and create bss for them, probably better
1446     // TODO also not sure there is any benefit to having css files in the jfxrt.jar at all
1447     processResources << {
1448         ["$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/caspian.css",
1449         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/caspian-no-transparency.css",
1450         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/embedded-qvga.css",
1451         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/embedded.css",
1452         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/fxvk.css",
1453         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/caspian/highcontrast.css",
1454         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/modena/modena.css",
1455         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/modena/modena-no-transparency.css",
1456         "$buildDir/resources/main/com/sun/javafx/scene/control/skin/modena/touch.css"].each { css ->
1457             javaexec {
1458                 executable = JAVA
1459                 workingDir = "modules/controls"
1460                 classpath files("$buildDir/classes/main",
1461                         project(":graphics").sourceSets.main.output,
1462                         project(":base").sourceSets.main.output)
1463                 main = "com.sun.javafx.css.parser.Css2Bin"
1464                 args css
1465                 jvmArgs "-Djava.ext.dirs="
1466             }
1467         }
1468     }
1469 }
1470 
1471 project(":extensions") {
1472     dependencies {
1473         compile BUILD_SRC, project(":base"), project(":graphics")
1474     }
1475 }
1476 
1477 project(":swing") {
1478     /* should not be built, but needed in builders and JMX
1479     tasks.all {
1480         if (!COMPILE_SWING) it.enabled = false
1481     }
1482     */
1483     dependencies {
1484         compile BUILD_SRC, project(":base"), project(":graphics")
1485     }
1486 }
1487 
1488 project(":swt") {
1489     tasks.all {
1490         if (!COMPILE_SWT) it.enabled = false
1491     }
1492     dependencies {
1493         compile BUILD_SRC, project(":base"), project(":graphics")
1494         compile name: SWT_FILE_NAME
1495     }
1496 }
1497 
1498 project(":fxml") {
1499     dependencies {
1500         compile BUILD_SRC, project(":base"), project(":graphics"),
1501                 project(":controls"), project(":swt"), project(":swing")
1502         testCompile project(":graphics").sourceSets.test.output
1503     }
1504     test {
1505         // StubToolkit is not *really* needed here, but because some code inadvertently invokes performance
1506         // tracker and this attempts to fire up the toolkit and this looks for native libraries and fails,
1507         // we have to use the stub toolkit for now.
1508         jvmArgs "-Djavafx.toolkit=com.sun.javafx.pgstub.StubToolkit"
1509         classpath += files("$JDK_HOME/jre/lib/ext/nashorn.jar")
1510     }
1511 }
1512 
1513 project(":builders") {
1514     sourceCompatibility = 1.7
1515 
1516     if (!COMPILE_SWING) sourceSets.main.java.exclude ("**/swing/**")
1517     if (!COMPILE_SWT)   sourceSets.main.java.exclude ("**/swt/**")
1518     if (!IS_COMPILE_WEBKIT) sourceSets.main.java.exclude ("**/web/**")
1519 
1520     dependencies {
1521         compile BUILD_SRC, project(":base"), project(":graphics"),
1522                 project(":controls"), project(":swt"), project(":swing"), project(":media"), project(":web")
1523         testCompile project(":graphics").sourceSets.test.output
1524     }
1525     test {
1526         // StubToolkit is not *really* needed here, but because some code inadvertently invokes performance
1527         // tracker and this attempts to fire up the toolkit and this looks for native libraries and fails,
1528         // we have to use the stub toolkit for now.
1529         jvmArgs "-Djavafx.toolkit=com.sun.javafx.pgstub.StubToolkit"
1530     }
1531 }
1532 
1533 project(":designTime") {
1534     tasks.all {
1535         if (!COMPILE_DESIGN_TIME) it.enabled = false
1536     }
1537     dependencies {
1538         compile project(":graphics")
1539     }
1540 }
1541 
1542 project(":jmx") {
1543     dependencies {
1544         compile project(":base")
1545         compile project(":graphics")
1546         compile project(":swing")
1547         compile project(":media")
1548     }
1549 
1550     // Tests are disabled until RT-33926 can be fixed
1551     test.enabled = false
1552 }
1553 
1554 // This project is for system tests that need to run with a full SDK.
1555 // Most of them display a stage or do other things that preclude running
1556 // them in a shared JVM or as part of the "smoke test" run (which must
1557 // not pop up any windows or use audio). As such, they are only enabled
1558 // when FULL_TEST is specified, and each test runs in its own JVM
1559 project(":systemTests") {
1560     test {
1561         enabled = IS_FULL_TEST
1562         if (!IS_USE_ROBOT) {
1563             // Disable all robot-based visual tests
1564             exclude("**/helloworld/*.*");
1565             exclude("**/javafx/embed/swing/*.*");
1566             exclude("**/javafx/scene/layout/*.*");
1567             exclude("**/test3d/*.*");
1568             exclude("**/painttest/*.*");
1569         }
1570         if (!IS_AWT_TEST) {
1571             // Disable all AWT-based tests
1572             exclude("**/javafx/embed/swing/*.*");
1573             exclude("**/com/sun/javafx/application/Swing*.*");
1574         }
1575         forkEvery = 1
1576     }
1577 }
1578 
1579 project(":fxpackager") {
1580     tasks.all {
1581         if (!COMPILE_FXPACKAGER) it.enabled = false
1582     }
1583     // fxpackager has a dependency on ant in order to build the ant jar,
1584     // and as such needs to point to the apache binary repository
1585     if (!BUILD_CLOSED) {
1586         repositories {
1587             maven {
1588                 url "https://repository.apache.org"
1589             }
1590         }
1591     }
1592 
1593     dependencies {
1594         compile group: "org.apache.ant", name: "ant", version: "1.8.2"
1595     }
1596 
1597     // When producing the jar, we need to relocate a few class files
1598     // from their normal location to a resources/classes or resources/web-files
1599     // location
1600     jar {
1601         includeEmptyDirs = false
1602         archiveName = "ant-javafx.jar"
1603         eachFile { FileCopyDetails details ->
1604             if (details.path.startsWith("com/javafx/main")) {
1605                 details.path = "resources/classes/$details.path"
1606             } else if (details.path.startsWith("web-files")) {
1607                 details.path = "resources/$details.path"
1608             }
1609         }
1610     }
1611 
1612     // The "man" task will create a $buildDir/man containing the man
1613     // files for the system being built
1614     task man(type: Copy) {
1615         includeEmptyDirs = false
1616         enabled = (IS_LINUX || IS_MAC) && COMPILE_FXPACKAGER
1617         from "src/main/man"
1618         into "$buildDir/man"
1619         exclude "**/*.html"
1620         if (IS_MAC) exclude "**/ja_JP.UTF-8/**"
1621     }
1622     processResources.dependsOn man
1623 
1624     // Compile the native launchers. These are included in ant-javafx.jar
1625     // TODO should teach this to know 32 / 64 bit
1626     if (IS_WINDOWS && COMPILE_FXPACKAGER) {
1627         task compileWinLauncher(type: CCTask, group: "Build") {
1628             description = "Compiles native sources for the application co-bundle launcher";
1629             matches = "WinLauncher\\.cpp";
1630             params.addAll(WIN.launcher.ccFlags);
1631             output(file("$buildDir/native/WinLauncher"));
1632             source(file("src/main/native/launcher/win"));
1633             compiler = WIN.launcher.compiler
1634             exe = true;
1635             linkerOptions.addAll(WIN.launcher.linkFlags);
1636             doLast {
1637                 copy {
1638                     from "$buildDir/native/WinLauncher/WinLauncher.exe"
1639                     into "$buildDir/classes/main/com/sun/javafx/tools/resource/windows"
1640                 }
1641             }
1642         }
1643         task compileIconSwap(type: CCTask, group: "Build") {
1644             description = "Compiles native sources for the application co-bundle launcher"
1645             matches = "IconSwap\\.cpp"
1646             params.addAll(WIN.iconLauncher.ccFlags)
1647             output(file("$buildDir/native/IconSwap"))
1648             source file("src/main/native/launcher/win")
1649             compiler = WIN.launcher.compiler
1650             exe = true
1651             linkerOptions.addAll(WIN.iconLauncher.linkFlags)
1652             doLast {
1653                 copy {
1654                     from "$buildDir/native/IconSwap/IconSwap.exe"
1655                     into "$buildDir/classes/main/com/sun/javafx/tools/resource/windows"
1656                 }
1657             }
1658         }
1659         task compileLauncher(dependsOn: [compileWinLauncher, compileIconSwap])
1660         jar.dependsOn compileLauncher;
1661     } else if (COMPILE_FXPACKAGER) {
1662         if (IS_MAC) {
1663             task compileLauncher(type: CCTask, group: "Build") {
1664                 description = "Compiles native sources for the application co-bundle launcher"
1665                 matches = ".*\\.m"
1666                 output(file("$buildDir/classes/main/com/sun/javafx/tools/resource/mac"))
1667                 params.addAll(MAC.launcher.ccFlags)
1668                 source file("src/main/native/launcher/mac")
1669                 compiler = MAC.launcher.compiler
1670                 eachOutputFile = { f ->
1671                     return new File(f.getParent(), "JavaAppLauncher")
1672                 }
1673             }
1674             jar.dependsOn compileLauncher;
1675         } else {
1676             def ccTask = project.task("compileLauncher", type: CCTask, group: "Build") {
1677                 description = "Compiles native sources for the application co-bundle launcher"
1678                 matches = ".*\\.c"
1679                 output(file("$buildDir/native/launcher"))
1680                 params.addAll(LINUX.launcher.ccFlags)
1681                 compiler = LINUX.launcher.compiler
1682                 source file("src/main/native/launcher/linux")
1683             }
1684             def linkTask = project.task("linkLauncher", type: LinkTask, dependsOn: ccTask, group: "Build") {
1685                 description = "Creates native dynamic library for the application co-bundle launcher"
1686                 linker = LINUX.launcher.linker
1687                 linkParams.addAll(LINUX.launcher.linkFlags)
1688                 objectDir = file("$buildDir/native/launcher")
1689                 lib = file("$buildDir/classes/main/com/sun/javafx/tools/resource/linux/JavaAppLauncher")
1690             }
1691             jar.dependsOn linkTask;
1692         }
1693     }
1694 
1695     // Builds the javafxpackager executable. For everything other than windows,
1696     // this is simply moving the existing shell script and ensuring it has proper
1697     // permissions. For Windows, this includes compiling the native executable
1698     if (IS_WINDOWS && COMPILE_FXPACKAGER){
1699         task buildJavaFXPackager(type: CCTask, group: "Build") {
1700             description = "Compiles native sources for javafxpackager.exe"
1701             matches = "javafxpackager\\.cpp"
1702             params.addAll(WIN.fxpackager.ccFlags)
1703             compiler = WIN.fxpackager.compiler
1704             output(file("$buildDir/native/javafxpackager"))
1705             source WIN.fxpackager.nativeSource
1706             doFirst {
1707                 copy {
1708                     mkdir "$buildDir/native"
1709                     mkdir "$buildDir/native/javafxpackager"
1710                     from file("src/main/native/javafxpackager/win/javafxpackager.manifest")
1711                     into file("$buildDir/native/javafxpackager")
1712                     filter { line->
1713                         line = line.replace("FXVERSION", "${RAW_VERSION}.${HUDSON_BUILD_NUMBER}");
1714                     }
1715                 }
1716             }
1717             doLast {
1718                 mkdir "$buildDir/native"
1719                 exec({
1720                     commandLine("$RC", "/nologo", "/l", "0x409", "/r", "/dJFX_DVERSION=8", "/dJFX_VERSION=8",
1721                             "/fo$buildDir/native/javafxpackager/javafxpackager.res",
1722                             "src/main/native/javafxpackager/win/javafxpackager.rc");
1723                     environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT);
1724                 });
1725             }
1726             doLast {
1727                 mkdir "$buildDir/javafxpackager"
1728                 exec({
1729                     commandLine("$WIN.fxpackager.linker", "/nologo", "/opt:REF", "/incremental:no", "/manifest", "kernel32.lib", "advapi32.lib",
1730                             "/out:$buildDir/native/javafxpackager/javafxpackager.exe",
1731                             "$buildDir/native/javafxpackager/javafxpackager.obj",
1732                             "$buildDir/native/javafxpackager/javafxpackager.res")
1733                     environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
1734                 })
1735             }
1736             doLast {
1737                 exec({
1738                     commandLine("$MC", "-manifest",
1739                                        "$buildDir/native/javafxpackager/javafxpackager.manifest",
1740                                        "-outputresource:$buildDir/native/javafxpackager/javafxpackager.exe")
1741                     environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
1742                 })
1743                 copy {
1744                     from file("$buildDir/native/javafxpackager/javafxpackager.exe")
1745                     into file("$buildDir/javafxpackager")
1746                 }
1747             }
1748         }
1749     } else {
1750         task buildJavaFXPackager(group: "Build") {
1751             enabled = COMPILE_FXPACKAGER
1752             doLast {
1753                     copy {
1754                     from "src/main/native/javafxpackager/shell"
1755                             into "$buildDir/javafxpackager"
1756                         fileMode = 0755
1757                 }
1758             }
1759         }
1760     }
1761 
1762     jar.dependsOn buildJavaFXPackager
1763 
1764     classes << {
1765         // Copy all of the download libraries to libs directory for the sake of the IDEs
1766         File libsDir = rootProject.file("build/libs");
1767         File antLib = new File(libsDir, "ant-1.8.2.jar")
1768         libsDir.mkdirs();
1769         for (File f : configurations.compile.files) {
1770             copy {
1771                 into libsDir
1772                 from f.getParentFile()
1773                 include "**/ant-1.8.2.jar"
1774                 includeEmptyDirs = false
1775             }
1776         }
1777     }
1778 }
1779 
1780 project(":media") {
1781     configurations {
1782         media
1783     }
1784 
1785     dependencies {
1786         compile BUILD_SRC, project(":base"), project(":graphics")
1787     }
1788 
1789     sourceSets {
1790         tools {
1791             java.srcDir "src/tools/java"
1792         }
1793     }
1794 
1795     compileToolsJava {
1796         enabled = IS_COMPILE_MEDIA
1797         classpath = sourceSets.main.output;
1798     }
1799 
1800     project.ext.makeJobsFlag = IS_WINDOWS && IS_DEBUG_NATIVE ? "-j1" : "-j5";
1801     project.ext.buildType = IS_DEBUG_NATIVE ? "Debug" : "Release";
1802 
1803     def nativeSrcDir = file("${projectDir}/src/main/native")
1804     def generatedHeadersDir = file("${buildDir}/generated-src/headers")
1805     
1806     task generateHeaders(dependsOn: compileJava) {
1807         enabled = IS_COMPILE_MEDIA
1808         doLast {
1809             def classpath = sourceSets.main.output;
1810             mkdir generatedHeadersDir;
1811 
1812             def classesList = ["com.sun.media.jfxmedia.logging.Logger",
1813                              "com.sun.media.jfxmedia.track.AudioTrack",
1814                              "com.sun.media.jfxmedia.control.VideoDataBuffer",
1815                              "com.sun.media.jfxmedia.control.VideoFormat\$FormatTypes",
1816                              "com.sun.media.jfxmediaimpl.NativeAudioClip",
1817                              "com.sun.media.jfxmediaimpl.NativeMediaPlayer",
1818                              "com.sun.media.jfxmediaimpl.NativeVideoBuffer",
1819                              "com.sun.media.jfxmediaimpl.platform.gstreamer.GSTPlatform",
1820                              "com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMedia",
1821                              "com.sun.media.jfxmediaimpl.platform.gstreamer.GSTMediaPlayer",
1822                              "com.sun.media.jfxmediaimpl.platform.gstreamer.GSTAudioEqualizer",
1823                              "com.sun.media.jfxmediaimpl.platform.gstreamer.GSTEqualizerBand",
1824                              "com.sun.media.jfxmediaimpl.platform.gstreamer.GSTAudioSpectrum"]
1825             if (IS_MAC) {
1826                 classesList.addAll( ["com.sun.media.jfxmediaimpl.platform.osx.OSXPlatform",
1827                                      "com.sun.media.jfxmediaimpl.platform.osx.OSXMedia",
1828                                      "com.sun.media.jfxmediaimpl.platform.osx.OSXMediaPlayer"] );
1829             }
1830             exec {
1831                 commandLine ("${JAVAH}", "-J-Djava.ext.dirs=", "-d", "${generatedHeadersDir}", "-classpath", "${classpath.asPath}");
1832                 args classesList;
1833             }
1834         }
1835     }
1836     
1837     task generateMediaErrorHeader(dependsOn: [compileToolsJava, compileJava]) {
1838         enabled = IS_COMPILE_MEDIA
1839         doLast {
1840             def classpath = files(sourceSets.main.output, sourceSets.tools.output);
1841             def sourcepath = sourceSets.main.java.srcDirs;
1842             def headerpath = file("$generatedHeadersDir/jfxmedia_errors.h");
1843             def srcRoot = (sourcepath.toArray())[0];
1844 
1845             mkdir generatedHeadersDir;
1846 
1847             exec {
1848                 commandLine("$JAVA", "-Djava.ext.dirs=", "-classpath", "${classpath.asPath}");
1849                 args("headergen.HeaderGen", "$headerpath", "$srcRoot");
1850             }
1851         }
1852     }
1853 
1854     task buildNativeTargets {
1855         enabled = IS_COMPILE_MEDIA
1856     }
1857     
1858     compileTargets { t->        
1859         def nativeOutputDir = file("${buildDir}/native/${t.name}")
1860         def projectDir = t.name.startsWith("arm") ? "linux" : t.name
1861         def mediaProperties = project.rootProject.ext[t.upper].media
1862         
1863         def buildNative = task("build${t.capital}Native", dependsOn: [generateHeaders, generateMediaErrorHeader]) {
1864             enabled = IS_COMPILE_MEDIA
1865             doLast {
1866                 exec {
1867                     commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/jfxmedia/projects/${projectDir}")
1868                     args("JAVA_HOME=${JDK_HOME}", "GENERATED_HEADERS_DIR=${generatedHeadersDir}",
1869                          "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=jfxmedia")
1870 
1871                     if (t.name == "win") {
1872                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
1873                         args(IS_64 ? "ARCH=x64" : "ARCH=x32", "RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.jfxmediaRcFile}")
1874                     } else {
1875                         args ("CC=${mediaProperties.compiler}", "LINK=${mediaProperties.linker}", "LIB=${mediaProperties.lib}")
1876 
1877                         if (t.name.startsWith("arm"))
1878                             args("EXTRA_CFLAGS=${mediaProperties.extra_cflags}", "EXTRA_LDFLAGS=${mediaProperties.extra_ldflags}")
1879                         else
1880                             args("HOST_COMPILE=1")
1881                     }
1882                 }
1883             }
1884         }        
1885         
1886         if (!t.name.startsWith("arm")) {
1887             // Building GStreamer
1888             def buildGStreamer = task("build${t.capital}GStreamer") {
1889                 enabled = IS_COMPILE_MEDIA
1890                 doLast {
1891                     exec {
1892                         commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/gstreamer-lite")
1893                         args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=gstreamer-lite")
1894 
1895                         if (t.name == "win") {
1896                             environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
1897                             args(IS_64 ? "ARCH=x64" : "ARCH=x32", "RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.gstreamerRcFile}")
1898                         } else
1899                             args ("CC=${mediaProperties.compiler}", "LINK=${mediaProperties.linker}", "LIB=${mediaProperties.lib}")
1900                     }
1901                 }
1902             }
1903 
1904             def buildPlugins = task("build${t.capital}Plugins", dependsOn: buildGStreamer) {
1905                 enabled = IS_COMPILE_MEDIA
1906 
1907                 if (!project.ext.properties.containsKey("ON2_SRCDIR"))
1908                     project.ext.ON2_SRCDIR = "";
1909 
1910                 if (!project.ext.properties.containsKey("ON2_LIB"))
1911                     project.ext.ON2_LIB = "";
1912 
1913                 doLast {
1914                     exec {
1915                         commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/fxplugins")
1916                         args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=fxplugins", 
1917                              "ON2_SRCDIR=${project.ext.ON2_SRCDIR}", "ON2_LIB=${project.ext.ON2_LIB}")
1918 
1919                         if (t.name == "win") {
1920                             Map winEnv = new HashMap(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
1921 
1922                             String sdkDir = System.getenv("BASECLASSES_SDK_DIR");
1923                             if (sdkDir == null)
1924                             {
1925                                 sdkDir = "C:/Program Files/Microsoft SDKs/Windows/v7.1" // Default value
1926                                 winEnv["BASECLASSES_SDK_DIR"] = sdkDir
1927                             }
1928                             environment(winEnv)
1929 
1930                             args(IS_64 ? "ARCH=x64" : "ARCH=x32", "RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.fxpluginsRcFile}")
1931                         } else
1932                             args ("CC=${mediaProperties.compiler}", "LINK=${mediaProperties.linker}", "LIB=${mediaProperties.lib}")
1933                     }
1934                 }
1935             }
1936             
1937             buildNative.dependsOn buildPlugins
1938 
1939             if (t.name == "linux") {
1940                 def buildAVPlugin = task( "buildAVPlugin", dependsOn: [buildPlugins]) {
1941                     enabled = IS_COMPILE_MEDIA
1942 
1943                     if (!project.ext.properties.containsKey("LIBAV"))
1944                         project.ext.LIBAV = "";
1945 
1946                     doLast {
1947                         // Building fxavcodec plugin (libav plugin)
1948                         exec {
1949                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/linux/avplugin")
1950                             args("CC=${mediaProperties.compiler}", "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", 
1951                                      "BASE_NAME=avplugin", "LIBAV_DIR=${project.ext.LIBAV}")
1952                         }
1953                     }
1954                 }
1955                 buildNative.dependsOn buildAVPlugin
1956             }
1957 
1958             if (t.name == "win") {
1959                 def buildResources = task("buildResources") << {
1960                     def rcOutputDir = "${nativeOutputDir}/${buildType}"
1961                     mkdir rcOutputDir
1962                     exec {
1963                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
1964                         commandLine (WIN.media.rcCompiler)
1965                         args(WIN.media.glibRcFlags)
1966                         args("/Fo${rcOutputDir}/${WIN.media.glibRcFile}", WIN.media.rcSource)
1967                     }
1968 
1969                     exec {
1970                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
1971                         commandLine (WIN.media.rcCompiler)
1972                         args(WIN.media.gstreamerRcFlags)
1973                         args("/Fo${rcOutputDir}/${WIN.media.gstreamerRcFile}", WIN.media.rcSource)
1974                     }
1975 
1976                     exec {
1977                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
1978                         commandLine (WIN.media.rcCompiler)
1979                         args(WIN.media.fxpluginsRcFlags)
1980                         args("/Fo${rcOutputDir}/${WIN.media.fxpluginsRcFile}", WIN.media.rcSource)
1981                     }
1982 
1983                     exec {
1984                         environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
1985                         commandLine (WIN.media.rcCompiler)
1986                         args(WIN.media.jfxmediaRcFlags)
1987                         args("/Fo${rcOutputDir}/${WIN.media.jfxmediaRcFile}", WIN.media.rcSource)
1988                     }
1989                 }
1990                 
1991                 def buildGlib = task("build${t.capital}Glib", dependsOn: [buildResources]) {
1992                     enabled = IS_COMPILE_MEDIA
1993                     doLast {
1994                         exec {
1995                             environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
1996                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/glib-lite")
1997                             args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=glib-lite",
1998                                  IS_64 ? "ARCH=x64" : "ARCH=x32", "RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.glibRcFile}")
1999                         }
2000                     }
2001                 }
2002                 buildGStreamer.dependsOn buildGlib
2003                 
2004             } else if (t.name == "mac") {
2005                 def buildGlib = task("build${t.capital}Glib") {
2006                     enabled = IS_COMPILE_MEDIA
2007                     doLast {
2008                         exec {
2009                             commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/glib-lite")
2010                             args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=glib-lite")
2011                             args ("CC=${mediaProperties.compiler}", "LINK=${mediaProperties.linker}", "LIB=${mediaProperties.lib}")
2012                         }
2013                     }
2014                 }
2015                 buildGStreamer.dependsOn buildGlib
2016             }
2017         }
2018         
2019         buildNativeTargets.dependsOn buildNative
2020     }
2021  
2022     jar {
2023         exclude("headergen/**")
2024 
2025         dependsOn compileJava
2026         if (IS_COMPILE_MEDIA)
2027             dependsOn buildNativeTargets
2028     }
2029 }
2030 
2031 project(":web") {
2032     configurations {
2033         webkit
2034     }
2035     dependencies {
2036         compile project(":base"), project(":graphics"), project(":controls"), project(":media")
2037     }
2038     
2039     compileJava {
2040         if (IS_COMPILE_WEBKIT) {
2041             // These classes will be generated by native build
2042             sourceSets.main.java.exclude("com/sun/webkit/dom/**")
2043         }
2044     }
2045     
2046     task generateHeaders(dependsOn: compileJava) {
2047         doLast {
2048             def classpath = files("$buildDir/classes/main",
2049                                   project(":graphics").sourceSets.main.output.classesDir)
2050             def dest = file("$buildDir/generated-src/headers");
2051             mkdir dest;
2052             exec {
2053                 commandLine("$JAVAH", "-J-Djava.ext.dirs=", "-d", "$dest",
2054                             "-classpath", "${classpath.asPath}");
2055                 args("java.lang.Character",
2056                      "java.net.IDN",
2057                      "com.sun.webkit.ContextMenu",
2058                      "com.sun.webkit.ContextMenuItem",
2059                      "com.sun.webkit.CursorManager",
2060                      "com.sun.webkit.PageCache",
2061                      "com.sun.webkit.PopupMenu",
2062                      "com.sun.webkit.SharedBuffer",
2063                      "com.sun.webkit.WatchdogTimer",
2064                      "com.sun.webkit.WebPage",
2065                      "com.sun.webkit.LoadListenerClient",
2066                      "com.sun.webkit.event.WCFocusEvent",
2067                      "com.sun.webkit.event.WCKeyEvent",
2068                      "com.sun.webkit.event.WCMouseEvent",
2069                      "com.sun.webkit.event.WCMouseWheelEvent",
2070                      "com.sun.webkit.graphics.GraphicsDecoder",
2071                      "com.sun.webkit.graphics.RenderMediaControls",
2072                      "com.sun.webkit.graphics.RenderTheme",
2073                      "com.sun.webkit.graphics.ScrollBarTheme",
2074                      "com.sun.webkit.graphics.WCMediaPlayer",
2075                      "com.sun.webkit.graphics.WCGraphicsManager",
2076                      "com.sun.webkit.graphics.WCRenderQueue",
2077                      "com.sun.webkit.graphics.WCPath",
2078                      "com.sun.webkit.graphics.WCPathIterator",
2079                      "com.sun.webkit.Timer",
2080                      "com.sun.webkit.WCFrameView",
2081                      "com.sun.webkit.WCPasteboard",
2082                      "com.sun.webkit.WCPluginWidget",
2083                      "com.sun.webkit.dom.JSObject",
2084                      "com.sun.webkit.network.SocketStreamHandle",
2085                      "com.sun.webkit.network.URLLoader",
2086                      "com.sun.webkit.text.TextBreakIterator",
2087                      "com.sun.webkit.text.TextNormalizer");
2088             }
2089         }
2090     }
2091 
2092     task compileGenerated()
2093 
2094     compileTargets { t ->
2095         def classifier = (t.name != "linux" && t.name != "win") ? t.name :
2096                           IS_64 ? "${t.name}-amd64" : "${t.name}-i586"
2097         dependencies {
2098             webkit group: "com.sun.webkit", name: "webview-deps",
2099                    version: "1.2", classifier: "$classifier", ext: "zip"
2100         }
2101 
2102         def webkitOutputDir = "$buildDir/${t.name}"
2103         def webkitConfig = IS_DEBUG_NATIVE ? "Debug" : "Release"
2104 
2105         def compileNativeTask = task("compileNative${t.capital}", dependsOn: generateHeaders) << {
2106             println "Building Webkit configuration /$webkitConfig/ into $webkitOutputDir"
2107             
2108             def dependencyFile = configurations.webkit.filter(
2109                     { File f -> f.getName().contains(classifier) }
2110                 ).getSingleFile()
2111             ant.unzip(src:  dependencyFile,
2112                       dest: webkitOutputDir)
2113 
2114             exec {
2115                 workingDir("$projectDir/src/main/native")
2116                 commandLine("perl", "Tools/Scripts/set-webkit-configuration", "--$webkitConfig")
2117                 environment(["WEBKITOUTPUTDIR" : webkitOutputDir])
2118             }
2119 
2120             exec {
2121                 workingDir("$projectDir/src/main/native")
2122                 if (t.name == "win") {
2123                     String qtDir = cygpath(System.getenv().get("QTSDK_DIR"))
2124                     String parfaitPath = IS_COMPILE_PARFAIT ? System.getenv().get("PARFAIT_PATH") + ";" : "";
2125                     Map environmentSettings = new HashMap(WINDOWS_NATIVE_COMPILE_ENVIRONMENT)
2126                     environmentSettings["PATH"] = parfaitPath + "$WINDOWS_VS_PATH;$qtDir/bin;$qtDir/qt/bin"
2127                     environmentSettings["QMAKESPEC"] = "win32-msvc2008"
2128                     environment(environmentSettings)
2129                     /* To build with ICU:
2130                     1. Download http://javaweb.us.oracle.com/jcg/fx-webrevs/RT-17164/WebKitLibrariesICU.zip
2131                     and unzip it to WebKitLibraries folder.
2132                     2. Copy DLLs from
2133                     WebKitLibrariesICU.zip\WebKitLibraries\import\runtime
2134                     to %windir%\system32
2135                     3. Uncomment the line below
2136                      */
2137                     // args("--icu-unicode")
2138                 } else if (t.name == "mac") {
2139                     environment([
2140                         "QMAKESPEC"      : "macx-g++",
2141                         "QMAKE_CFLAGS"   : "-m64",
2142                         "QMAKE_LFLAGS"   : "-m64",
2143                     ])
2144                 } else if (t.name.startsWith("arm")) {
2145                     // ARM cross build
2146                     def webkitProperties = project.rootProject.ext[t.upper].webkit
2147                     def qmakeSpecDir = "$webkitOutputDir/qws/linux-cross-${t.name}-g++"
2148                     mkdir qmakeSpecDir
2149                     File qmakeSpec = new File("$qmakeSpecDir/qmake.conf")
2150                     qmakeSpec.append(
2151 """TARGET_PLATFORM         = unix
2152 include(/usr/share/qt4/mkspecs/common/linux.conf)
2153 include(/usr/share/qt4/mkspecs/common/g++.conf)
2154 include(/usr/share/qt4/mkspecs/common/qws.conf)
2155 QMAKE_CC                = $webkitProperties.compiler
2156 QMAKE_CXX               = $webkitProperties.linker
2157 QMAKE_LINK              = $webkitProperties.linker
2158 QMAKE_LINK_SHLIB        = $webkitProperties.linker
2159 QMAKE_AR                = $webkitProperties.ar cqs
2160 QMAKE_OBJCOPY           = $webkitProperties.objcopy
2161 QMAKE_STRIP             = $webkitProperties.strip
2162 QMAKE_CXXFLAGS          = $webkitProperties.ccFlags
2163 QMAKE_LFLAGS            = $webkitProperties.linkFlags
2164 load(qt_config)""")
2165                     environment([
2166                         "QMAKESPEC" : file(qmakeSpecDir).getAbsolutePath(),
2167                         "PATH"      : "$System.env.PATH:$webkitProperties.binDir",
2168                     ])
2169                     args("--nocache")
2170                 }
2171                 environment([
2172                     "JAVA_HOME"       : JDK_HOME,
2173                     "WEBKITOUTPUTDIR" : webkitOutputDir,
2174                 ])
2175 
2176                 if (IS_COMPILE_PARFAIT) {
2177                     environment([
2178                         "CC"        : "parfait-gcc",
2179                         "QMAKE_CC"  : "parfait-gcc",
2180                         "CXX"       : "parfait-g++",
2181                         "QMAKE_CXX" : "parfait-g++",
2182                         "CPP"       : "parfait-g++",
2183                         "cc"        : "parfait-gcc",
2184                         "LINK"      : "parfait-g++",
2185                         "QMAKE_LINK": "parfait-g++",
2186                     ])
2187                 }
2188                 commandLine("perl", "Tools/Scripts/build-webkit", "--java", "--imageio")
2189             }
2190 
2191             def library = rootProject.ext[t.upper].library
2192             copy {
2193                 from "$webkitOutputDir/$webkitConfig/lib/${library('jfxwebkit')}"
2194                 into "$buildDir/libs/${t.name}"
2195             }
2196             copy {
2197                 from "$webkitOutputDir/$webkitConfig/lib/${library('DumpRenderTreeJava')}"
2198                 into "$buildDir/test/${t.name}"
2199             }
2200         }
2201     
2202         if (IS_WINDOWS && t.name == "win") {
2203             def webkitProperties = project.rootProject.ext[t.upper].webkit
2204             def rcTask = project.task("rc${t.capital}", type: CompileResourceTask) {
2205                 compiler = webkitProperties.rcCompiler
2206                 source(webkitProperties.rcSource)
2207                 if (webkitProperties.rcFlags) {
2208                     rcParams.addAll(webkitProperties.rcFlags)
2209                 }
2210                 output(file("$webkitOutputDir/$webkitConfig/WebCore/obj"))
2211             }
2212             compileNativeTask.dependsOn rcTask
2213         }
2214         
2215         def compileGeneratedTask = task("compileGenerated${t.capital}", type: JavaCompile, dependsOn: compileNativeTask) {
2216             def gensrcDir = "$webkitOutputDir/$webkitConfig/WebCore/generated/java"
2217             doFirst {
2218                 copy {
2219                     from "$projectDir/src/main/java/com/sun/webkit/dom/EventListenerImpl.java"
2220                     into "$gensrcDir/com/sun/webkit/dom"
2221                 }
2222             }
2223             classpath = files(project(":graphics").sourceSets.main.output) // for JSObject
2224             source gensrcDir
2225             destinationDir = file("$buildDir/classes/main")
2226         }
2227 
2228         compileGenerated.dependsOn compileGeneratedTask
2229     }
2230     
2231     def drtClasses = "com/sun/javafx/webkit/drt/**"
2232     jar.exclude(drtClasses)
2233     task drtJar(type: Jar, dependsOn: compileJava) {
2234         archiveName = "drt.jar"
2235         destinationDir = file("$buildDir/test")
2236         from "$buildDir/classes/main"
2237         include drtClasses
2238     }
2239 
2240     if (IS_COMPILE_WEBKIT) {
2241         jar.dependsOn compileGenerated, drtJar
2242     }
2243 }
2244 
2245 allprojects {
2246     // The following block is a workaround for the fact that presently Gradle
2247     // can't set the -XDignore.symbol.file flag, because it appears that the
2248     // javac API is lacking support for it. So what we'll do is find any Compile
2249     // task and manually provide the options necessary to fire up the
2250     // compiler with the right settings.
2251     //
2252     // Also, we need to remove jfxrt.jar from the ext classpath (if it is there)
2253     tasks.withType(Compile) { compile ->
2254         // It looks like we have to use ant to compile instead of the built-in gradle
2255         // compiler stuff because otherwise it won't compile on CYGWIN
2256         // TODO need to file issue with Gradle
2257         compile.options.useAnt = true
2258         compile.options.debug = true // we always generate debugging info in the class files
2259         compile.options.debugOptions.debugLevel = IS_DEBUG_JAVA ? "source,lines,vars" : "source,lines"
2260         compile.options.fork = true
2261         compile.options.forkOptions.executable = JAVAC
2262         compile.options.warnings = IS_LINT
2263         compile.options.useDepend = IS_USE_DEPEND
2264         compile.options.compilerArgs = ["-Djava.ext.dirs=", "-XDignore.symbol.file", "-encoding", "UTF-8"]
2265 
2266         // Add in the -Xlint options
2267         if (IS_LINT) {
2268             LINT.split("[, ]").each { s ->
2269                 compile.options.compilerArgs += "-Xlint:$s"
2270             }
2271         }
2272     }
2273 }
2274 
2275 /******************************************************************************
2276  *                                                                            *
2277  *                             Top Level Tasks                                *
2278  *                                                                            *
2279  *  These are the tasks which are defined only for the top level project and  *
2280  *  not for any sub projects. These are generally the entry point that is     *
2281  *  used by Hudson and by the continuous build system.                        *
2282  *                                                                            *
2283  *****************************************************************************/
2284 
2285 task clean() {
2286     group = "Basic"
2287     description = "Deletes the build directory and the build directory of all sub projects"
2288     getSubprojects().each { subProject ->
2289         dependsOn(subProject.getTasksByName("clean", true));
2290     }
2291     doLast {
2292         delete(buildDir);
2293     }
2294 }
2295 
2296 
2297 task javadoc(type: Javadoc) {
2298     enabled = IS_BUILD_JAVADOC
2299     group = "Basic"
2300     description = "Generates the JavaDoc for all the public API"
2301     executable = JAVADOC
2302     def projectsToDocument = [
2303             project(":base"), project(":graphics"), project(":controls"), project(":media"),
2304             project(":swing"), project(":swt"), project(":fxml"), project(":web")]
2305     source(projectsToDocument.collect({
2306         [it.sourceSets.main.java, "$it.buildDir/generated-src/builders"]
2307     }));
2308     setDestinationDir(new File(buildDir, 'javadoc'));
2309     // Might need a classpath
2310     classpath = files(projectsToDocument.collect { project ->
2311         project.sourceSets.main.compileClasspath
2312     });
2313     classpath += files(projectsToDocument.collect { project ->
2314         project.sourceSets.main.output
2315     });
2316     exclude("com/**/*", "javafx/scene/ParentDesignInfo*", "Compile*", "javafx/builder/**/*");
2317     options.windowTitle("${javadocTitle}")
2318     options.header("${javadocHeader}")
2319     options.bottom("${javadocBottom}")
2320     options.links(JDK_DOCS);
2321     options.addBooleanOption("XDignore.symbol.file").setValue(true);
2322     options.addBooleanOption("Xdoclint:none").setValue(!IS_DOC_LINT);
2323     options.addBooleanOption("javafx").setValue(true);
2324     doLast {
2325         projectsToDocument.each { p ->
2326             copy {
2327                 from "$p.projectDir/src/main/docs"
2328                 into "$buildDir/javadoc"
2329             }
2330         }
2331     }
2332 
2333     dependsOn(projectsToDocument.collect { project -> project.getTasksByName("classes", true)});
2334 }
2335 
2336 task jfxrt() {
2337     rootProject.getTasksByName("compileTestJava", true).each { t ->
2338         if (t.enabled) t.dependsOn(jfxrt)
2339     }
2340 }
2341 
2342 task sdk() {
2343     dependsOn(checkJfxrtJar)
2344 
2345     rootProject.getTasksByName("test", true).each { t ->
2346         if (t.enabled) t.dependsOn(sdk)
2347     }
2348 }
2349 
2350 task appsjar() {
2351     dependsOn(sdk)
2352     // Note: the jar dependencies get added elsewhere see project(":apps")
2353 }
2354 
2355 // these are empty tasks, allowing us to depend on the task, which may have other
2356 // real work items added later.
2357 task copyAppsArtifacts() {
2358     dependsOn(appsjar)
2359 }
2360 
2361 task apps() {
2362     dependsOn(sdk)
2363     dependsOn(appsjar)
2364     dependsOn(copyAppsArtifacts)
2365 }
2366 
2367 task findbugs() {
2368     dependsOn(sdk)
2369 
2370     // TODO: implement this
2371     doLast {
2372         if (!BUILD_CLOSED) {
2373             println "findbugs task is not implemented"
2374         }
2375     }
2376 }
2377 
2378 // The following tasks are for the closed build only. They are a no-op for the open build
2379 
2380 task checkCache() {
2381     dependsOn(updateCacheIfNeeded)
2382 }
2383 
2384 // TODO: consider moving the "public-sdk" portion of this task here
2385 task publicExports() {
2386     doFirst {
2387         if (!IS_BUILD_JAVADOC) {
2388             fail("publicExports task requires: -PBUILD_JAVADOC=true")
2389         }
2390     }
2391     dependsOn(sdk)
2392     doLast {
2393         if (!BUILD_CLOSED) {
2394             println "publicExports task is only run for a closed build"
2395         }
2396     }
2397 }
2398 
2399 task perf() {
2400     dependsOn(sdk,apps)
2401     doLast {
2402         if (!BUILD_CLOSED) {
2403             println "perf task is only run for a closed build"
2404         }
2405     }
2406 }
2407 
2408 task zips() {
2409     doFirst {
2410         if (!IS_BUILD_JAVADOC) {
2411             fail("zips task requires: -PBUILD_JAVADOC=true")
2412         }
2413     }
2414     dependsOn(sdk,publicExports,apps,perf)
2415     doLast {
2416         if (!BUILD_CLOSED) {
2417             println "zips task is only run for a closed build"
2418         }
2419     }
2420 }
2421 
2422 task copySources(type: Copy) {
2423     enabled = IS_BUILD_SRC_ZIP
2424     def projectsToCopy = [
2425             project(":base"), project(":graphics"), project(":controls"),
2426             project(":swing"), project(":swt"), project(":fxml"),
2427             project(":builders"), project(":web")]
2428     from(projectsToCopy.collect({
2429         ["${it.projectDir}/src/main/java"]
2430     }))
2431     include "**/*.java"
2432     into "${buildDir}/javafx-src"
2433 }
2434 
2435 task zipSources(type: Zip) {
2436     enabled = IS_BUILD_SRC_ZIP
2437     dependsOn(copySources)
2438     archiveName = "javafx-src.zip"
2439     destinationDir = file("$buildDir")
2440     includeEmptyDirs = false
2441     from "${buildDir}/javafx-src"
2442 }
2443 
2444 task src {
2445     enabled = IS_BUILD_SRC_ZIP
2446     description = "Created the javafx-src.zip bundle"
2447     dependsOn(zipSources)
2448 }
2449 
2450 task all() {
2451     dependsOn(sdk,publicExports,apps,perf,zips)
2452 }
2453 
2454 compileTargets { t ->
2455     def targetProperties = project.ext[t.upper]
2456     def library = targetProperties.library
2457     // The jfxrt task is responsible for creating the jfxrt.jar. A developer may
2458     // have multiple SDK's on their system at any one time, depending on which
2459     // cross compiles they have done. For example, I might have:
2460     //      build/mac-sdk/rt/lib/ext/jfxrt.jar
2461     //      build/ios-sdk/rt/lib/ext/jfxrt.jar
2462     //      build/win-sdk/rt/lib/ext/jfxrt.jar
2463     //      build/armhf-sdk/rt/lib/ext/jfxrt.jar
2464     //
2465     // and so forth. This arrangement allows for multiple independent SDKs to
2466     // exist on a developer's system.
2467     def jfxrtTask = task("jfxrt$t.capital", type: Jar) {
2468         group = "Basic"
2469         description = "Creates the jfxrt.jar for the $t.name target"
2470         archiveName = "build/${t.name}-sdk/rt/lib/ext/jfxrt.jar";
2471         includeEmptyDirs = false
2472         from("modules/base/build/classes/main",
2473              "modules/base/build/resources/main",
2474              "modules/builders/build/classes/main",
2475              "modules/graphics/build/classes/main",
2476              "modules/graphics/build/resources/main",
2477              "modules/controls/build/classes/main",
2478              "modules/controls/build/resources/main",
2479              "modules/fxml/build/classes/main",
2480              "modules/fxml/build/resources/main",
2481              "modules/graphics/build/classes/jsl-decora",
2482              "modules/graphics/build/resources/jsl-decora",
2483              "modules/graphics/build/classes/jsl-prism",
2484              "modules/graphics/build/resources/jsl-prism",
2485              "modules/media/build/classes/main",
2486              "modules/media/build/resources/main")
2487         if (COMPILE_SWING) from ("modules/swing/build/classes/main", "modules/swing/build/resources/main")
2488 
2489         if (t.name != 'mac') 
2490             exclude ("modules/media/build/classes/main/com/sun/media/jfxmediaimpl/platform/osx/**")
2491         if (t.name != 'ios') 
2492             exclude ("modules/media/build/classes/main/com/sun/media/jfxmediaimpl/platform/ios/**")
2493 
2494         if (t.name == 'android') {
2495             from ("modules/web/build/classes/android",
2496                   "modules/web/build/resources/android",
2497                   "modules/controls/build/classes/android",
2498                   "modules/controls/build/resources/android")
2499         } else if (t.name == 'ios') {
2500             from ("modules/web/build/classes/ios",
2501                   "modules/web/build/resources/ios",
2502                   "modules/extensions/build/classes/ios")
2503         } else {
2504             from ("modules/web/build/classes/main", "modules/web/build/resources/main")
2505         }
2506         exclude("**/javafx/embed/swt/**")
2507         exclude("js/**/*", // er...
2508                 "PrismLoaderBackend*", // More decora stuff
2509                 "**/*.stg",    // any glue files for decora must be excluded
2510                 "**/*.java");  // Builder java files are in build/classes and should be excluded
2511 
2512         // Filter out platform specific Java sources (glass) when compiling for other targets
2513         exclude(targetProperties.jfxrtJarExcludes)
2514 
2515         dependsOn(subprojects.collect { project -> project.getTasksByName("assemble", true)});
2516     }
2517     def jfxrtIndexTask = task("jfxrtIndex$t.capital") {
2518         //the following is a workaround for the lack of indexing in gradle 1.4 through 1.7
2519         dependsOn(jfxrtTask)
2520 
2521         doLast() {
2522             ant.jar (update: true, index: true, destfile: jfxrtTask.archiveName)
2523         }
2524     }
2525     jfxrt.dependsOn(jfxrtIndexTask)
2526 
2527     def jfxswtTask = task("jfxswt$t.capital", type: Jar) {
2528         enabled = COMPILE_SWT
2529         group = "Basic"
2530         description = "Creates the jfxswt.jar for the $t.name target"
2531         archiveName = "build/${t.name}-sdk/rt/lib/jfxswt.jar";
2532         includeEmptyDirs = false
2533         from("modules/swt/build/classes/main");
2534         from("modules/builders/build/classes/main");
2535         include("**/javafx/embed/swt/**")
2536         exclude("**/*.java");  // Builder java files are in build/classes and should be excluded
2537 
2538         dependsOn(subprojects.collect { project -> project.getTasksByName("assemble", true)});
2539     }
2540     def jfxswtIndexTask = task("jfxswtIndex$t.capital") {
2541         //the following is a workaround for the lack of indexing in gradle 1.4 through 1.7
2542         dependsOn(jfxswtTask)
2543 
2544         doLast() {
2545             ant.jar (update: true, index: true, destfile: jfxswtTask.archiveName)
2546         }
2547     }
2548     jfxrt.dependsOn(jfxswtIndexTask)
2549 
2550     def jmxTask = task ("jmx${t.capital}", type: Jar) {
2551         group = "Basic"
2552         description = "Creates the javafx-mx.jar"
2553         archiveName = "build/${t.name}-sdk/lib/javafx-mx.jar";
2554         includeEmptyDirs = false
2555         from "modules/jmx/build/classes/main"
2556         from "modules/jmx/build/resources/main"
2557         dependsOn project(":jmx").assemble
2558     }
2559 
2560     // The 'sdk' task will build the rest of the SDK, and depends on the 'jfxrtTask' task. After
2561     // executing this task the sdk bundle for the current COMPILE_TARGETS will be fully created.
2562     def sdkTask = task("sdk$t.capital") {
2563         group = "Basic"
2564         description = "Creates the SDK for $t.name"
2565         doLast {
2566             // TODO instead of using copy everywhere, I probably want to use "sync" instead?
2567             // Copy all of the .dll / .so / .dylib native libraries into build/sdk/rt/lib/
2568             copy {
2569                 def useLipo = targetProperties.containsKey('useLipo') ? targetProperties.useLipo : false
2570                 from("modules/graphics/build/libs/jsl-decora/${t.name}/${library(targetProperties.decora.lib)}")
2571                 def libs = ['font', 'prism', 'prismSW', 'prismES2', 'glass', 'iio']
2572                 if (IS_COMPILE_PANGO) {
2573                     // TODO: embedded support
2574                     if ("${defaultHostTarget}" == "${t.name}") {
2575                         libs += ['fontFreetype', 'fontPango'];
2576                     }
2577                 }
2578                 libs.each { lib ->
2579                     def variants = targetProperties[lib].containsKey('variants') && !useLipo ? targetProperties[lib].variants : [null]
2580                     variants.each { variant ->
2581                         def variantProperties = variant ? targetProperties[lib][variant] : targetProperties[lib]
2582                         println "modules/graphics/build/libs/$lib/$t.name/${library(variantProperties.lib)}"
2583                         from ("modules/graphics/build/libs/$lib/$t.name/${library(variantProperties.lib)}")
2584                     }
2585                 }
2586                 if (IS_WINDOWS) {
2587                     from ("modules/graphics/build/libs/prismD3D/${t.name}/${library(targetProperties.prismD3D.lib)}");
2588                 }
2589                 if (IS_COMPILE_WEBKIT) {
2590                     from ("modules/web/build/libs/${t.name}/${library('jfxwebkit')}")
2591                 } else {
2592                     if (t.name != "android" && t.name != "ios") {
2593                         from ("$LIBRARY_STUB/${library('jfxwebkit')}")
2594                     }
2595                 }
2596 
2597                 def mediaBuildType = project(":media").ext.buildType
2598                 if (IS_COMPILE_MEDIA) {
2599                     [ "fxplugins", "gstreamer-lite", "jfxmedia" ].each { name ->
2600                         from ("modules/media/build/native/${t.name}/${mediaBuildType}/${library(name)}") }
2601                     
2602                     if (t.name == "linux") from ("modules/media/build/native/${t.name}/${mediaBuildType}/${library("avplugin")}")
2603                     else from ("modules/media/build/native/${t.name}/${mediaBuildType}/${library("glib-lite")}")                        
2604                 } else {
2605                     [ "fxplugins", "gstreamer-lite", "jfxmedia" ].each { name ->
2606                         from ("$LIBRARY_STUB/${library(name)}") }
2607 
2608                     if (t.name == "linux") from ("$LIBRARY_STUB/${library("avplugin")}")
2609                     else from ("$LIBRARY_STUB/${library("glib-lite")}")
2610                 }
2611                 
2612                 def libDest = targetProperties.libDest
2613                 into ("build/${t.name}-sdk/rt/$libDest")
2614             }
2615 
2616             // Create the javafx.properties file
2617             final File javafxProperties = file("build/${t.name}-sdk/rt/lib/javafx.properties")
2618             javafxProperties.delete()
2619             javafxProperties << "javafx.runtime.version=$RAW_VERSION";
2620             // Include any properties that have been defined (most likely in
2621             // one of the various platform gradle files)
2622             if (targetProperties.containsKey("javafxProperties")) {
2623                 javafxProperties << "\n"
2624                 javafxProperties << targetProperties.javafxProperties
2625             }
2626 
2627             // Embedded builds define this file as well
2628             if (targetProperties.containsKey("javafxPlatformProperties")) {
2629                 final File javafxPlatformProperties = file("build/${t.name}-sdk/rt/lib/javafx.platform.properties")
2630                 javafxPlatformProperties.delete()
2631                 javafxPlatformProperties << targetProperties.javafxPlatformProperties
2632             }
2633 
2634             // Copy over the javadocs that were generated. This is done rather than just generating
2635             // the docs into the "right place" because for a cross-compile you only need one set of
2636             // docs but need to have a copy in each created sdk
2637             if (IS_BUILD_JAVADOC) {
2638                 copy {
2639                     from "build/javadoc"
2640                     into "build/${t.name}-sdk/docs/api"
2641                 }
2642             }
2643 
2644             // Copy over the javafx-src bundle
2645             if (IS_BUILD_SRC_ZIP) {
2646                 copy {
2647                     from "build/javafx-src.zip"
2648                     into "build/${t.name}-sdk"
2649                 }
2650             }
2651 
2652             // Copy over the fxpackager and rename as ant-javafx.jar
2653             copy {
2654                 from "modules/fxpackager/build/libs"
2655                 into "build/${t.name}-sdk/lib"
2656             }
2657 
2658             // Copy over the FXPackager man files
2659             copy {
2660                 from "modules/fxpackager/build/man"
2661                 into "build/${t.name}-sdk/man"
2662             }
2663 
2664             // Copy over the javafxpackager executable
2665             if (t.name == "win" || t.name == "linux" || t.name == "mac") {
2666                 copy {
2667                     from "modules/fxpackager/build/javafxpackager"
2668                     into "build/${t.name}-sdk/bin"
2669                 }
2670             }
2671         }
2672         dependsOn(jmxTask);
2673         dependsOn(jfxrtIndexTask)
2674         dependsOn(jfxswtIndexTask)
2675         dependsOn(javadoc)
2676         dependsOn(src)
2677     }
2678 
2679     def generateSymbols = targetProperties.containsKey('generateSymbols') ? targetProperties.generateSymbols : false
2680     if (generateSymbols) {
2681         def exportedSymbolsTask = project.task("exportedSymbols${t.capital}", type: ExportedSymbolsTask, dependsOn: sdkTask, group: "Build") {
2682             description = "Generates exported symbols file for iOS build (from .a libraries)"
2683             def libDirName = "build/${t.name}-sdk/rt/$targetProperties.libDest"
2684             libDir = file("$libDirName")
2685             outputFile = file("$libDirName/exported.symbols")
2686             excludes = targetProperties.generateSymbolsExcludes
2687         }
2688         sdk.dependsOn(exportedSymbolsTask)
2689     }
2690 
2691     sdk.dependsOn(sdkTask)
2692 }
2693 
2694     //task integrationCheck {
2695     //    group = "Basic"
2696     //    description = "Performs all the tasks necessary to ensure that the current build is ready for integration."
2697     //    dependsOn sdk
2698     //    dependsOn subprojects.collect { project -> project.getTasksByName("check", true)}
2699     //}
2700 
2701 /*
2702  * This clause changes the way we handle a build.gradle within ./apps
2703  * It does a few things:
2704  *   modifies the classpath used to include the built runttime classes
2705  *   provides for copying the build applications to the artifacts tree
2706  *
2707  * The applications to be built will be under ./apps, but also must
2708  * be listed in the applications listed in the setting variable: JFXApplications
2709  */
2710 ext.JFXRT_CP =
2711     files(
2712         project(":base").sourceSets.main.output.classesDir,
2713         project(":graphics").sourceSets.main.output.classesDir,
2714         project(":controls").sourceSets.main.output.classesDir,
2715         project(":fxml").sourceSets.main.output.classesDir,
2716         project(":swing").sourceSets.main.output.classesDir, //NOTE - used by 3Dviewer
2717         project(":builders").sourceSets.main.output.classesDir,
2718             "modules/media/build/classes/main",
2719             "modules/web/build/classes/main",
2720     )
2721 
2722 project(":apps") {
2723     // The apps build is Ant based, and gradle lets us "import" ant build.xml
2724     // into our configuration.
2725 
2726     ant.importBuild 'build.xml'
2727 
2728     compileTargets { t ->
2729         // The apps build is Ant based, and gradle lets us "import" ant apps/build.xml
2730         // into our configuration.
2731 
2732         // override the apps build.xml with an explicit pointer to our jar.
2733         def jfxrtJar = "${rootProject.buildDir}/${t.name}-sdk/rt/lib/ext/jfxrt.jar"
2734 
2735         def appsJar = project.task("appsJar${t.capital}") {
2736             doLast() {
2737               ant.properties['targetBld'] = "$t.name"
2738               if (!rootProject.ext[t.upper].compileSwing) {
2739                 ant.properties['JFX_CORE_ONLY'] = 'true'
2740               }
2741               ant.properties['jfxbuild.jfxrt.jar'] = jfxrtJar
2742               ant.properties['platforms.JDK_1.8.home'] = "${rootProject.ext.JDK_HOME}"
2743               ant.project.executeTarget("sampleAppsJar")
2744             }
2745         }
2746         rootProject.appsjar.dependsOn(appsJar)
2747 
2748         def appsClean = project.task("appsClean${t.capital}") {
2749             doLast() {
2750               ant.properties['targetBld'] = "$t.name"
2751               ant.properties['platforms.JDK_1.8.home'] = "${rootProject.ext.JDK_HOME}"
2752               ant.project.executeTarget("sampleAppsClean")
2753             }
2754         }
2755         rootProject.clean.dependsOn(appsClean)
2756     }
2757 }
2758 
2759 /******************************************************************************
2760  *                                                                            *
2761  *                              BUILD_CLOSED                                  *
2762  *                                                                            *
2763  * This next section should remain at the end of the build script. It allows  *
2764  * for a "supplemental" gradle file to be used to extend the normal build     *
2765  * structure. For example, this is used for passing a supplemental gradle     *
2766  * file for producing official JavaFX builds.                                 *
2767  *                                                                            *
2768  *****************************************************************************/
2769 
2770 if (BUILD_CLOSED) {
2771     apply from: supplementalBuildFile
2772 }
2773 
2774 task showFlags {
2775 }
2776 
2777 compileTargets { t ->
2778     // Every platform must define these variables
2779     def props = project.ext[t.upper];
2780     showFlags.dependsOn(
2781         project.task("showFlags$t.upper") {
2782             doLast() {
2783                 println "Properties set for $t.upper"
2784                 props.each { println it }
2785             }
2786         }
2787     )
2788 }