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