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