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