/* * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /** * The main build script for JavaFX. * * MUST FIX tasks to complete: * - build check -- making sure the final artifact has the right bits * - some things worth automatically sanity checking: * - are there images in the javadocs? * - are all of the expected dylibs etc there? * - Perform sanity checking to make sure a JDK exists with javac, javah, etc * - Support building with no known JDK location, as long as javac, javah, etc are on the path * - Check all of the native flags. We're adding weight to some libs that don't need it, and so forth. * * Additional projects to work on as we go: * - Add "developer debug". This is where the natives do not have debug symbols, but the Java code does * - The genVSproperties.bat doesn't find the directory where RC.exe lives. So it is hard coded. Might be a problem. * - special tasks for common needs, such as: * - updating copyright headers * - stripping trailing whitespace (?) * - checkstyle * - findbugs * - re needs? * - sqe testing * - API change check * - Pushing results to a repo? * - ServiceWithSecurityManagerTest fails to complete when run from gradle. * - Integrate Parfait reports for C code * - FXML Project tests are not running */ defaultTasks = ["sdk"] import java.util.concurrent.CountDownLatch import java.util.concurrent.ExecutorService import java.util.concurrent.Executors import java.util.concurrent.Future /****************************************************************************** * Utility methods * *****************************************************************************/ /** * If the given named property is not defined, then this method will define * it with the given defaultValue. Any properties defined by this method can * be substituted on the command line by using -P, or by specifying a * gradle.properties file in the user home dir * * @param name The name of the property to define * @param defaultValue The default value to assign the property */ void defineProperty(String name, String defaultValue) { if (!project.hasProperty(name)) { project.ext.set(name, defaultValue); } } /** * If the given named property is not defined, then this method will attempt to * look up the property in the props map, and use the defaultValue if it cannot be found. * * @param name The name of the property to look up and/or define * @param props The properties to look for the named property in, if it has not already been defined * @param defaultValue The default value if the property has not been defined and the * props map does not contain the named property */ void defineProperty(String name, Properties props, String defaultValue) { if (!project.hasProperty(name)) { project.ext.set(name, props.getProperty(name, defaultValue)); } } /** * Converts cygwin style paths to windows style paths, but with a forward slash. * This method is safe to call from any platform, and will only do work if * called on Windows (in all other cases it simply returns the supplied path. * * @param path the path to convert * @return the path converted to windows style, if on windows, otherwise it * is the supplied path. */ String cygpath(String path) { if (!IS_WINDOWS) return path; if (path == null || "".equals(path)) return path; String ret = path.replaceAll('\\\\', '/') logger.info("Converting path '$path' via cygpath to "+ret) return ret } void loadProperties(String sourceFileName) { def config = new Properties() def propFile = new File(sourceFileName) if (propFile.canRead()) { config.load(new FileInputStream(propFile)) for (java.util.Map.Entry property in config) { def keySplit = property.key.split("\\."); def key = keySplit[0]; for (int i = 1; i < keySplit.length; i++) { key = key + keySplit[i].capitalize(); } ext[key] = property.value; } } } /** * Struct used to contain some information passed to the closure * passed to compileTargets. */ class CompileTarget { String name; String upper; String capital; } /** * Iterates over each of the compile targets, passing the given closure * a CompileTarget instance. * * @param c The closure to call */ void compileTargets(Closure c) { if (COMPILE_TARGETS == "") { return } COMPILE_TARGETS.split(",").each { target -> CompileTarget ct = new CompileTarget(); ct.name = target; ct.upper = target.trim().toUpperCase(Locale.ROOT) ct.capital = target.trim().capitalize() c(ct) } } /** * Manages the execution of some closure which is responsible for producing * content for a properties file built at build time and stored in the * root project's $buildDir, and then loading that properties file and * passing it to the processor closure. * * This is used on windows to produce a properties file containing all the * windows visual studio paths and environment variables, and on Linux * for storing the results of pkg-config calls. * * @param name the name of the file to produce * @param loader a closure which is invoked, given the properties file. This * closure is invoked only if the properties file needs to be created * and is responsible for populating the properties file. * @param processor a closure which is invoked every time this method is * called and which will be given a Properties object, fully populated. * The processor is then responsible for doing whatever it is that it * must do with those properties (such as setting up environment * variables used in subsequent native builds, or whatnot). */ void setupTools(String name, Closure loader, Closure processor) { // Check to see whether $buildDir/$name.properties file exists. If not, // then generate it. Once generated, we need to read the properties file to // help us define the defaults for this block of properties File propFile = file("$buildDir/${name}.properties"); if (!propFile.exists()) { // Create the properties file propFile.getParentFile().mkdirs(); propFile.createNewFile(); loader(propFile); } // Try reading the properties in order to define the properties. If the property file cannot // be located, then we will throw an exception because we cannot guess these values InputStream propStream = null; try { Properties properties = new Properties(); propStream = new FileInputStream(propFile); properties.load(propStream); processor(properties); } finally { try { propStream.close() } catch (Exception e) { } } } String[] parseJavaVersion(String jRuntimeVersion) { def jVersion = jRuntimeVersion.split("[-\\+]")[0] def tmpBuildNumber = "0" if (jVersion.startsWith("1.")) { // This is a pre-JEP-223 version string def dashbIdx = jRuntimeVersion.lastIndexOf("-b") if (dashbIdx != -1) { tmpBuildNumber = jRuntimeVersion.substring(dashbIdx + 2) } } else { // This is a post-JEP-223 version string def plusIdx = jRuntimeVersion.indexOf("+") if (plusIdx != -1) { tmpBuildNumber = jRuntimeVersion.substring(plusIdx + 1) } } def jBuildNumber = tmpBuildNumber.split("[-\\+]")[0] def versionInfo = new String[2]; versionInfo[0] = jVersion versionInfo[1] = jBuildNumber return versionInfo } /** * Fails the build with the specified error message * * @param msg the reason for the failure */ void fail(String msg) { throw new GradleException("FAIL: " + msg); } /****************************************************************************** * * * Definition of project properties * * * * All properties defined using ext. are immediately available throughout * * the script as variables that can be used. These variables are attached * * to the root project (whereas if they were defined as def variables then * * they would only be available within the root project scope). * * * * All properties defined using the "defineProperty" method can be replaced * * on the command line by using the -P flag. For example, to override the * * location of the binary plug, you would specify -PBINARY_PLUG=some/where * * * *****************************************************************************/ // If the ../rt-closed directory exists, then we are doing a closed build. // In this case, build and property files will be read from // ../rt-closed/closed-build.gradle and ../rt-closed/closed-properties.gradle // respectively def closedDir = file("../rt-closed") def buildClosed = closedDir.isDirectory() ext.BUILD_CLOSED = buildClosed ext.RUNARGSFILE = "run.args" ext.COMPILEARGSFILE = "compile.args" ext.RUNJAVAPOLICYFILE = 'run.java.policy' ext.TESTCOMPILEARGSFILE = "testcompile.args" ext.TESTRUNARGSFILE = "testrun.args" ext.TESTJAVAPOLICYFILE = 'test.java.policy' ext.MODULESOURCEPATH = "modulesourcepath.args" // These variables indicate what platform is running the build. Is // this build running on a Mac, Windows, or Linux machine? 32 or 64 bit? ext.OS_NAME = System.getProperty("os.name").toLowerCase() ext.OS_ARCH = System.getProperty("os.arch") ext.IS_64 = OS_ARCH.toLowerCase().contains("64") ext.IS_MAC = OS_NAME.contains("mac") || OS_NAME.contains("darwin") ext.IS_WINDOWS = OS_NAME.contains("windows") ext.IS_LINUX = OS_NAME.contains("linux") // Verify that the architecture & OS are supported configurations. Note that // at present building on PI is not supported, but we would only need to make // some changes on assumptions on what should be built (like SWT / Swing) and // such and we could probably make it work. if (!IS_MAC && !IS_WINDOWS && !IS_LINUX) fail("Unsupported build OS ${OS_NAME}") if (IS_WINDOWS && OS_ARCH != "x86" && OS_ARCH != "amd64") { fail("Unknown and unsupported build architecture: $OS_ARCH") } else if (IS_MAC && OS_ARCH != "x86_64") { fail("Unknown and unsupported build architecture: $OS_ARCH") } else if (IS_LINUX && OS_ARCH != "i386" && OS_ARCH != "amd64") { fail("Unknown and unsupported build architecture: $OS_ARCH") } // Get the JDK_HOME automatically based on the version of Java used to execute gradle. Or, if specified, // use a user supplied JDK_HOME, STUB_RUNTIME, JAVAC, all of which may be specified // independently (or we'll try to get the right one based on other supplied info). Sometimes the // JRE might be the thing that is being used instead of the JRE embedded in the JDK, such as: // c:\Program Files (x86)\Java\jdk1.8.0\jre // c:\Program Files (x86)\Java\jre8\ // Because of this, you may sometimes get the jdk's JRE (in which case the logic we used to have here // was correct and consistent with all other platforms), or it might be the standalone JRE (for the love!). def envJavaHome = cygpath(System.getenv("JDK_HOME")) if (envJavaHome == null || envJavaHome.equals("")) envJavaHome = cygpath(System.getenv("JAVA_HOME")) def javaHome = envJavaHome == null || envJavaHome.equals("") ? System.getProperty("java.home") : envJavaHome def javaHomeFile = file(javaHome) defineProperty("JDK_HOME", javaHomeFile.name == "jre" ? javaHomeFile.getParent().toString() : javaHomeFile.name.startsWith("jre") ? new File(javaHomeFile.getParent(), "jdk1.${javaHomeFile.name.substring(3)}.0").toString() : javaHome) // we have to bail and set it to something and this is as good as any! ext.JAVA_HOME = JDK_HOME defineProperty("JAVA", cygpath("$JDK_HOME/bin/java${IS_WINDOWS ? '.exe' : ''}")) defineProperty("JAVAC", cygpath("$JDK_HOME/bin/javac${IS_WINDOWS ? '.exe' : ''}")) defineProperty("JAVAH", cygpath("$JDK_HOME/bin/javah${IS_WINDOWS ? '.exe' : ''}")) defineProperty("JAVADOC", cygpath("$JDK_HOME/bin/javadoc${IS_WINDOWS ? '.exe' : ''}")) defineProperty("JDK_DOCS", "http://download.java.net/java/jdk9/docs/api/") defineProperty("JDK_JMODS", cygpath(System.getenv("JDK_JMODS")) ?: cygpath(System.getenv("JDK_HOME") + "/jmods")) defineProperty("javaRuntimeVersion", System.getProperty("java.runtime.version")) def javaVersionInfo = parseJavaVersion(javaRuntimeVersion) defineProperty("javaVersion", javaVersionInfo[0]) defineProperty("javaBuildNumber", javaVersionInfo[1]) loadProperties("$projectDir/build.properties") // Look for stub runtime in either JDK or modular-sdk dir layout def String closedCacheStubRuntime = cygpath("$projectDir") + "/../caches/modular-sdk" def String jdkStubRuntime = cygpath("$JDK_HOME") defineProperty("STUB_RUNTIME", BUILD_CLOSED ? closedCacheStubRuntime : jdkStubRuntime) def cachedStub = STUB_RUNTIME.equals(closedCacheStubRuntime) if (cachedStub) { def stubModulesLib = "$STUB_RUNTIME/modules_libs" defineProperty("MEDIA_STUB", "$stubModulesLib/javafx.media") defineProperty("WEB_STUB", "$stubModulesLib/javafx.web") } else { def libraryStub = IS_WINDOWS ? "$STUB_RUNTIME/bin" : "$STUB_RUNTIME/lib" defineProperty("MEDIA_STUB", libraryStub) defineProperty("WEB_STUB", libraryStub) } defineProperty("UPDATE_STUB_CACHE", (cachedStub ? 'true' : 'false')) def supplementalPreBuildFile = file("$closedDir/closed-pre-build.gradle"); def supplementalBuildFile = file("$closedDir/closed-build.gradle"); if (BUILD_CLOSED) { apply from: supplementalPreBuildFile } // GRADLE_VERSION_CHECK specifies whether to fail the build if the // gradle version check fails defineProperty("GRADLE_VERSION_CHECK", "true") ext.IS_GRADLE_VERSION_CHECK = Boolean.parseBoolean(GRADLE_VERSION_CHECK) // COMPILE_WEBKIT specifies whether to build all of webkit. defineProperty("COMPILE_WEBKIT", "false") ext.IS_COMPILE_WEBKIT = Boolean.parseBoolean(COMPILE_WEBKIT) // COMPILE_MEDIA specifies whether to build all of media. defineProperty("COMPILE_MEDIA", "false") ext.IS_COMPILE_MEDIA = Boolean.parseBoolean(COMPILE_MEDIA) // COMPILE_PANGO specifies whether to build javafx_font_pango. defineProperty("COMPILE_PANGO", "${IS_LINUX}") ext.IS_COMPILE_PANGO = Boolean.parseBoolean(COMPILE_PANGO) // COMPILE_HARFBUZZ specifies whether to use Harfbuzz. defineProperty("COMPILE_HARFBUZZ", "false") ext.IS_COMPILE_HARFBUZZ = Boolean.parseBoolean(COMPILE_HARFBUZZ) // COMPILE_PARFAIT specifies whether to build parfait defineProperty("COMPILE_PARFAIT", "false") ext.IS_COMPILE_PARFAIT = Boolean.parseBoolean(COMPILE_PARFAIT) // BUILD_FXPACKAGER enables building the packager modules and native code defineProperty("BUILD_FXPACKAGER", "true") ext.IS_BUILD_FXPACKAGER = Boolean.parseBoolean(BUILD_FXPACKAGER) // RETAIN_PACKAGER_TESTS specifies whether the tests in fxpackager should // keep generated files instead of attempting to automatically delete them defineProperty("RETAIN_PACKAGER_TESTS", "false") ext.IS_RETAIN_PACKAGER_TESTS = Boolean.parseBoolean(RETAIN_PACKAGER_TESTS) // TEST_PACKAGER_DMG whether tests that create DMG files via hdiutil // should be run. On OSX 10.7 this tends to hang automated builds defineProperty("TEST_PACKAGER_DMG", "false") ext.IS_TEST_PACKAGER_DMG = Boolean.parseBoolean(TEST_PACKAGER_DMG) // Define the SWT.jar that we are going to have to download during the build process based // on what platform we are compiling from (not based on our target). ext.SWT_FILE_NAME = IS_MAC ? "org.eclipse.swt.cocoa.macosx.x86_64_3.7.2.v3740f" : IS_WINDOWS && IS_64 ? "org.eclipse.swt.win32.win32.x86_64_3.7.2.v3740f" : IS_WINDOWS && !IS_64 ? "org.eclipse.swt.win32.win32.x86_3.7.2.v3740f" : IS_LINUX && IS_64 ? "org.eclipse.swt.gtk.linux.x86_64_3.7.2.v3740f" : IS_LINUX && !IS_64 ? "org.eclipse.swt.gtk.linux.x86_3.7.2.v3740f" : "" // Specifies whether to run full tests (true) or smoke tests (false) defineProperty("FULL_TEST", "false") ext.IS_FULL_TEST = Boolean.parseBoolean(FULL_TEST); defineProperty("FORCE_TESTS", "false") ext.IS_FORCE_TESTS = Boolean.parseBoolean(FORCE_TESTS); // Specifies whether to run robot-based visual tests (only used when FULL_TEST is also enabled) defineProperty("USE_ROBOT", "false") ext.IS_USE_ROBOT = Boolean.parseBoolean(USE_ROBOT); // Specified whether to run tests in headless mode defineProperty("HEADLESS_TEST", "false") ext.IS_HEADLESS_TEST = Boolean.parseBoolean(HEADLESS_TEST); // Specifies whether to run system tests that depend on AWT (only used when FULL_TEST is also enabled) defineProperty("AWT_TEST", "true") ext.IS_AWT_TEST = Boolean.parseBoolean(AWT_TEST); // Specifies whether to run system tests that depend on SWT (only used when FULL_TEST is also enabled) defineProperty("SWT_TEST", "true") ext.IS_SWT_TEST = Boolean.parseBoolean(SWT_TEST); // Specifies whether to run unstable tests (true) - tests that don't run well with Hudson builds // These tests should be protected with : // assumeTrue(Boolean.getBoolean("unstable.test")); defineProperty("UNSTABLE_TEST", "false") ext.IS_UNSTABLE_TEST = Boolean.parseBoolean(UNSTABLE_TEST); // Toggle diagnostic output from the Gradle workaround and the Sandbox test apps. defineProperty("WORKER_DEBUG", "false") ext.IS_WORKER_DEBUG = Boolean.parseBoolean(WORKER_DEBUG); // Specify the build configuration (Release, Debug, or DebugNative) defineProperty("CONF", "Debug") ext.IS_DEBUG_JAVA = CONF == "Debug" || CONF == "DebugNative" ext.IS_DEBUG_NATIVE = CONF == "DebugNative" // Defines the compiler warning levels to use. If empty, then no warnings are generated. If // not empty, then the expected syntax is as a space or comma separated list of names, such // as defined in the javac documentation. defineProperty("LINT", "none") ext.IS_LINT = LINT != "none" defineProperty("DOC_LINT", "all") ext.IS_DOC_LINT = DOC_LINT != "" // Specifies whether to use the "useDepend" option when compiling Java sources defineProperty("USE_DEPEND", "true") ext.IS_USE_DEPEND = Boolean.parseBoolean(USE_DEPEND) // Specifies whether to use the "incremental" option when compiling Java sources defineProperty("INCREMENTAL", "false") ext.IS_INCREMENTAL = Boolean.parseBoolean(INCREMENTAL) // Specifies whether to include the Null3D pipeline (for perf debugging) defineProperty("INCLUDE_NULL3D", "false") ext.IS_INCLUDE_NULL3D = Boolean.parseBoolean(INCLUDE_NULL3D) // Specifies whether to include the ES2 pipeline if available defineProperty("INCLUDE_ES2", IS_WINDOWS ? "false" : "true") ext.IS_INCLUDE_ES2 = Boolean.parseBoolean(INCLUDE_ES2) // Specifies whether to generate code coverage statistics when running tests defineProperty("JCOV", "false") ext.DO_JCOV = Boolean.parseBoolean(JCOV) // Define the number of threads to use when compiling (specifically for native compilation) // On Mac we limit it to 1 by default due to problems running gcc in parallel if (IS_MAC) { defineProperty("NUM_COMPILE_THREADS", "1") } else { defineProperty("NUM_COMPILE_THREADS", "${Runtime.runtime.availableProcessors()}") } // // The next three sections of properties are used to generate the // VersionInfo class, and the Windows DLL manifest. // // The following properties should be left alone by developers and set only from Hudson. defineProperty("HUDSON_JOB_NAME", "not_hudson") defineProperty("HUDSON_BUILD_NUMBER","0000") defineProperty("PROMOTED_BUILD_NUMBER", "0") // The following properties define the product name for Oracle JDK and OpenJDK // for VersionInfo and the DLL manifest. if (BUILD_CLOSED) { defineProperty("PRODUCT_NAME", "Java(TM)") defineProperty("COMPANY_NAME", "Oracle Corporation") defineProperty("PLATFORM_NAME", "Platform SE") } else { defineProperty("PRODUCT_NAME", "OpenJFX") defineProperty("COMPANY_NAME", "N/A") defineProperty("PLATFORM_NAME", "Platform") } // The following properties are set based on properties defined in // build.properties. The release version and suffix should be updated // in that file. def relVer = 0 if (jfxReleasePatchVersion == "0") { if (jfxReleaseSecurityVersion == "0") { if (jfxReleaseMinorVersion == "0") { relVer = "${jfxReleaseMajorVersion}" } else { relVer = "${jfxReleaseMajorVersion}.${jfxReleaseMinorVersion}" } } else { relVer = "${jfxReleaseMajorVersion}.${jfxReleaseMinorVersion}.${jfxReleaseSecurityVersion}" } } else { relVer = "${jfxReleaseMajorVersion}.${jfxReleaseMinorVersion}.${jfxReleaseSecurityVersion}.${jfxReleasePatchVersion}" } defineProperty("RELEASE_VERSION", relVer) defineProperty("RELEASE_VERSION_PADDED", "${jfxReleaseMajorVersion}.${jfxReleaseMinorVersion}.${jfxReleaseSecurityVersion}.${jfxReleasePatchVersion}") def buildDate = new java.util.Date() def buildTimestamp = new java.text.SimpleDateFormat("yyyy-MM-dd-HHmmss").format(buildDate) defineProperty("BUILD_TIMESTAMP", buildTimestamp) def relSuffix = "" def relOpt = "" if (HUDSON_JOB_NAME == "not_hudson") { relSuffix = "-internal" relOpt = "-${buildTimestamp}" } else { relSuffix = jfxReleaseSuffix } defineProperty("RELEASE_SUFFIX", relSuffix) defineProperty("RELEASE_VERSION_SHORT", "${RELEASE_VERSION}${RELEASE_SUFFIX}") defineProperty("RELEASE_VERSION_LONG", "${RELEASE_VERSION_SHORT}+${PROMOTED_BUILD_NUMBER}${relOpt}") // Check whether the COMPILE_TARGETS property has been specified (if so, it was done by // the user and not by this script). If it has not been defined then default // to building the normal desktop build for this machine project.ext.set("defaultHostTarget", IS_MAC ? "mac" : IS_WINDOWS ? "win" : IS_LINUX ? "linux" : ""); defineProperty("COMPILE_TARGETS", "$defaultHostTarget") // Flag indicating whether to import cross compile tools def importCrossTools = BUILD_CLOSED ? true : false; if (!importCrossTools && hasProperty("IMPORT_CROSS_TOOLS")) { importCrossTools = Boolean.parseBoolean(IMPORT_CROSS_TOOLS); } ext.IS_IMPORT_CROSS_TOOLS = importCrossTools // Location of the cross compile tools def crossToolsDir = "../crosslibs" if (hasProperty("CROSS_TOOLS_DIR")) { crossToolsDir = CROSS_TOOLS_DIR } ext.CROSS_TOOLS_DIR = file(crossToolsDir) // Specifies whether to run tests with the existing javafx.* modules instead of compiling a new one defineProperty("BUILD_SDK_FOR_TEST", "true") ext.DO_BUILD_SDK_FOR_TEST = Boolean.parseBoolean(BUILD_SDK_FOR_TEST) // All "classes" and "jar" tasks and their dependencies would be disabled // when running with DO_BUILD_SDK_FOR_TEST=false as they're unneeded for running tests if (!DO_BUILD_SDK_FOR_TEST) { gradle.taskGraph.useFilter({ task -> !task.name.equals("classes") && !task.name.equals("jar") }) } /** * Fetch/Check that external tools are present for the build. This method * will conditionally download the packages from project defined ivy repositories * and unpack them into the specified destdir * * @param configName A unique name to distinguish the configuration (ie "ARMSFV6") * @param packages A list of required packages (with extensions .tgz, .zip) * @param destdir where the packages should be unpacked * @param doFetch if true, the named packages will be download */ void fetchExternalTools(String configName, List packages, File destdir, boolean doFetch) { if (doFetch) { // create a unique configuration for this fetch def String fetchToolsConfig = "fetchTools$configName" rootProject.configurations.create(fetchToolsConfig) def List fetchedPackages = [] def int fetchCount = 0 packages.each { pkgname-> def int dotdex = pkgname.lastIndexOf('.') def int dashdex = pkgname.lastIndexOf('-') def String basename = pkgname.substring(0,dashdex) def String ver = pkgname.substring(dashdex+1,dotdex) def String ext = pkgname.substring(dotdex+1) def File pkgdir = file("$destdir/$basename-$ver") if (!pkgdir.isDirectory()) { rootProject.dependencies.add(fetchToolsConfig, "javafx:$basename:$ver", { artifact { name = basename version = ver type = ext } }) println "adding $pkgname as a downloadable item did not find $pkgdir" fetchedPackages.add(pkgname) fetchCount++ } } //fetch all the missing packages if (fetchedPackages.size > 0) { destdir.mkdirs() logger.quiet "fetching missing packages $fetchedPackages" copy { from rootProject.configurations[fetchToolsConfig] into destdir } // unpack the fetched packages fetchedPackages.each { pkgname-> logger.quiet "expanding the package $pkgname" def srcball = file("${destdir}/${pkgname}") if (!srcball.exists()) { throw new GradleException("Failed to fetch $pkgname"); } def String basename = pkgname.substring(0,pkgname.lastIndexOf(".")) def File pkgdir = file("$destdir/$basename") if (pkgname.endsWith(".tgz")) { if (IS_LINUX || IS_MAC) { // use native tar to support symlinks pkgdir.mkdirs() exec { workingDir pkgdir commandLine "tar", "zxf", "${srcball}" } } else { copy { from tarTree(resources.gzip("${srcball}")) into pkgdir } } } else if (pkgname.endsWith(".zip")) { copy { from zipTree("${srcball}") into pkgdir } } else { throw new GradleException("Unhandled package type for compile package ${pkgname}") } srcball.deleteOnExit(); } } else { logger.quiet "all tool packages are present $packages" } } else { // !doFetch - so just check they are present // check that all the dirs are really there def List errors = [] packages.each { pkgname-> def String basename = pkgname.substring(0,pkgname.lastIndexOf(".")) def File pkgdir = file("$destdir/$basename") if (!pkgdir.isDirectory()) { errors.add(pkgname) } } if (errors.size > 0) { throw new GradleException("Error: missing tool packages: $errors") } else { logger.quiet "all tool packages are present $packages" } } } // Make a forked ANT call. // This needs to be forked so that ant can be used with the right JDK and updated modules // for testing obscure things like packaging of apps void ant(String conf, // platform configuration String dir, // directory to run from String target, // ant target List params // parameters (usually -Dxxx=yyy) ) { // Try to use ANT_HOME String antHomeEnv = System.getenv("ANT_HOME") String antHome = antHomeEnv != null ? cygpath(antHomeEnv) : null; String ant = (antHome != null && !antHome.equals("")) ? "$antHome/bin/ant" : "ant"; exec { workingDir = dir environment("JDK_HOME", JDK_HOME) environment("JAVA_HOME", JDK_HOME) if (IS_WINDOWS) { environment([ "VCINSTALLDIR" : WINDOWS_VS_VCINSTALLDIR, "VSINSTALLDIR" : WINDOWS_VS_VSINSTALLDIR, "DEVENVDIR" : WINDOWS_VS_DEVENVDIR, "MSVCDIR" : WINDOWS_VS_MSVCDIR, "INCLUDE" : WINDOWS_VS_INCLUDE, "LIB" : WINDOWS_VS_LIB, "LIBPATH" : WINDOWS_VS_LIBPATH, "DXSDK_DIR" : WINDOWS_DXSDK_DIR ]); commandLine "cmd", "/c", ant, "-Dbuild.compiler=javac1.7" } else { commandLine ant, "-Dbuild.compiler=javac1.7" } if ((conf != null) && !rootProject.defaultHostTarget.equals(conf)) { def targetProperties = rootProject.ext[t.trim().toUpperCase()] args("-Dcross.platform=$conf") if (targetProperties.containsKey('arch')) { args("-Dcross.platform.arch=${targetProperties.arch}") } } if (params != null) { params.each() { s-> args(s) } } args(target); } } List computeLibraryPath(boolean working) { List lp = [] List modsWithNative = [ 'graphics', 'media', 'web' ] // the build/modular-sdk area def platformPrefix = "" def modularSdkDirName = "${platformPrefix}modular-sdk" def modularSdkDir = "${rootProject.buildDir}/${modularSdkDirName}" def modulesLibsDir = "${modularSdkDir}/modules_libs" modsWithNative.each() { m -> lp << cygpath("${modulesLibsDir}/javafx.${m}") } return lp } // Return list with the arguments needed for --patch-module for the provided projects // used with Java executables ie. tests List computePatchModuleArgs(List deps, boolean test, boolean includeJLP) { List pma = [] deps.each {String projname -> def proj = project(projname) if (proj.hasProperty("moduleName")) { File dir; if (test && proj.sourceSets.hasProperty('shims')) { dir = file("${rootProject.buildDir}/shims") } else { dir = file("${rootProject.buildDir}/modular-sdk/modules") } String moduleName = proj.ext.moduleName String dirpath = cygpath("${dir}/${moduleName}") pma += "--patch-module=${moduleName}=${dirpath}" } } if (includeJLP) { pma += "-Djava.library.path=" + computeLibraryPath(true).join(File.pathSeparator) } return pma } // Return a list containing the --upgrade-module-path // used with Javac List computeModulePathArgs(String pname, List deps, boolean test) { List mpa = [ '--upgrade-module-path' ] String mp = null deps.each {String projname -> def proj = project(projname) // for a non test set of args, we don't want the current module in the list // for a test test, we do need it to update what we built if (proj.hasProperty("moduleName") && proj.buildModule && !(!test && proj.name.equals(pname))) { File dir; if (test && proj.sourceSets.hasProperty('shims')) { dir = new File(proj.sourceSets.shims.output.classesDir, proj.ext.moduleName); } else { dir = new File(proj.sourceSets.main.output.classesDir, proj.ext.moduleName); } if (mp == null) { mp = dir.path } else { mp = mp + File.pathSeparator + dir.path } } } // in some cases like base we could end up with an empty // path... make sure we don't pass one back if (mp == null) { return null } mpa += mp return mpa } void writeRunArgsFile(File dest, List libpath, List modpath) { dest.delete() logger.info("Creating file ${dest.path}") if (libpath != null) { dest << "-Djava.library.path=\"\\\n" libpath.each() { e-> dest << " " dest << e dest << File.pathSeparator dest << "\\\n" } dest << " \"\n" } modpath.each { e -> dest << "--patch-module=\"" dest << e dest << "\"\n" } } // perform common project manipulation for modules void commonModuleSetup(Project p, List moduleChain) { p.ext.moduleChain = moduleChain if (p.hasProperty("moduleName")) { p.ext.moduleDir = new File (p.sourceSets.main.output.classesDir, "${p.moduleName}") if (p.sourceSets.hasProperty('shims')) { p.ext.moduleShimsDir = new File (p.sourceSets.shims.output.classesDir, "${p.moduleName}") } } def mpa = computeModulePathArgs(p.name, moduleChain, false) if (mpa != null) { p.ext.modulePathArgs = mpa } p.ext.testModulePathArgs = computePatchModuleArgs(moduleChain, true, false) p.ext.patchModuleArgs = computePatchModuleArgs(moduleChain ,false, true) p.ext.testPatchModuleArgs = computePatchModuleArgs(moduleChain, true, true) moduleChain.each() {e -> if (!e.equals(p.name)) { p.compileJava.dependsOn(project(e).classes) p.compileTestJava.dependsOn(project(e).testClasses) } } // read in any addExports file File addExportsFile = new File(p.projectDir,"src/test/addExports") if (addExportsFile.exists()) { List ae = [] addExportsFile.eachLine { line -> line = line.trim() if (!(line.startsWith("#") || line.equals(""))) { // one line arguments are a bit easier to debug //if (line.startsWith('--add-exports ')) { // line = line.replaceFirst('--add-exports ', '--add-exports=') //} line = line.replace('--add-exports *', '--add-exports=') ae += line.split(' ') } } p.ext.addExports = ae.flatten() } } // Now we need to define the native compilation tasks. The set of parameters to // native compilation depends on the target platform (and also to some extent what platform // you are compiling on). These settings are contained in various gradle files // such as mac.gradle and linux.gradle and armhf.gradle. Additionally, the developer // can specify COMPILE_FLAGS_FILE to be a URL or path to a different gradle file // that will contain the appropriate flags. defineProperty("COMPILE_FLAGS_FILES", COMPILE_TARGETS.split(",").collect {"buildSrc/${it.trim()}.gradle"}.join(",")) if (COMPILE_TARGETS == "all") { def tmp = [] File buildSrcDir = file("buildSrc") buildSrcDir.listFiles().each { File f -> if (f.isFile() && f.name.endsWith(".gradle") && !f.name.equals("build.gradle")) { def target = f.name.substring(0, f.name.lastIndexOf('.gradle')).toUpperCase(Locale.ROOT) apply from: f if (project.ext["${target}"].canBuild) { tmp.add(target) } } } COMPILE_FLAGS_FILES = tmp.collect { "buildSrc/${it}.gradle"}.join(",") COMPILE_TARGETS = tmp.collect { "${it.toLowerCase()}"}.join(",") } else { COMPILE_FLAGS_FILES.split(",").each { logger.info("Applying COMPILE_FLAGS_FILE '$it'") apply from: it } } if (COMPILE_TARGETS != "") { def tmp = [] COMPILE_TARGETS.split(",").each {target -> if (project.ext["${target.toUpperCase(Locale.ROOT)}"].canBuild) { tmp.add(target) } } COMPILE_TARGETS = tmp.collect { "${it.toLowerCase()}"}.join(",") } // Sanity check the expected properties all exist compileTargets { t -> // Every platform must define these variables if (!project.hasProperty(t.upper)) throw new Exception("ERROR: Incorrectly configured compile flags file, missing ${t.name} property") def props = project.ext[t.upper]; // TODO: we could remove libDest in favor of modLibDest ["compileSwing", "compileSWT", "compileFXPackager", "libDest"].each { prop -> if (!props.containsKey(prop)) throw new Exception("ERROR: Incorrectly configured compile flags file, missing ${prop} property on ${t.name}") } } // Various build flags may be set by the different target files, such as // whether to build Swing, SWT, FXPackager, etc. We iterate over all // compile targets and look for these settings in our properties. Note that // these properties cannot be set from the command line, but are set by // the target build files such as armv6hf.gradle or mac.gradle. ext.COMPILE_SWING = false; ext.COMPILE_SWT = false; ext.COMPILE_FXPACKAGER = false; compileTargets { t -> def targetProperties = project.rootProject.ext[t.upper] if (targetProperties.compileSwing) COMPILE_SWING = true if (targetProperties.compileSWT) COMPILE_SWT = true if (IS_BUILD_FXPACKAGER && targetProperties.compileFXPackager) COMPILE_FXPACKAGER = true if (!targetProperties.containsKey('compileWebnodeNative')) { // unless specified otherwise, we will compile native Webnode if IS_COMPILE_WEBKIT targetProperties.compileWebnodeNative = true } if (!targetProperties.containsKey('compileMediaNative')) { // unless specified otherwise, we will compile native Media if IS_COMPILE_MEDIA targetProperties.compileMediaNative = true } if (!targetProperties.containsKey('includeSWT')) targetProperties.includeSWT = true if (!targetProperties.containsKey('includeSwing')) targetProperties.includeSwing = true if (!targetProperties.containsKey('includeNull3d')) targetProperties.includeNull3d = true if (!targetProperties.containsKey('includeLens')) targetProperties.includeLens = false if (!targetProperties.containsKey('includeMonocle')) targetProperties.includeMonocle = false if (!targetProperties.containsKey('includeEGL')) targetProperties.includeEGL = false if (!targetProperties.containsKey('includeGTK')) targetProperties.includeGTK = IS_LINUX if (!targetProperties.containsKey('modLibDest')) targetProperties.modLibDest = targetProperties.libDest // This value is used as a prefix for various directories under ./build, // such as sdk, to allow for a common name for the hosted build // (for use when building apps) and a unique name for cross builds. if (rootProject.defaultHostTarget.equals(t.name)) { // use a simple common default for the "host" build targetProperties.platformPrefix="" } else { // and a more complex one for cross builds targetProperties.platformPrefix="${t.name}-" } } /****************************************************************************** * * * Build Setup Sanity Checks * * * * Here we do a variety of checks so that if the version of Java you are * * building with is misconfigured, or you are using the wrong version of * * gradle, etc you will get some kind of helpful error / warning message * * * *****************************************************************************/ // Sanity check that we actually have a list of compile targets to execute if (COMPILE_TARGETS == null || COMPILE_TARGETS == "") { throw new Exception("Unable to determine compilation platform, must specify valid COMPILE_TARGETS!") } // Make sure JDK_HOME/bin/java exists if (!file(JAVA).exists()) throw new Exception("Missing or incorrect path to 'java': '$JAVA'. Perhaps bad JDK_HOME? $JDK_HOME") if (!file(JAVAC).exists()) throw new Exception("Missing or incorrect path to 'javac': '$JAVAC'. Perhaps bad JDK_HOME? $JDK_HOME") if (!file(JAVAH).exists()) throw new Exception("Missing or incorrect path to 'javah': '$JAVAH'. Perhaps bad JDK_HOME? $JDK_HOME") if (!file(JAVADOC).exists()) throw new Exception("Missing or incorrect path to 'javadoc': '$JAVADOC'. Perhaps bad JDK_HOME? $JDK_HOME") // Determine the verion of Java in JDK_HOME. It looks like this: // // $ java -version // java version "1.7.0_45" // Java(TM) SE Runtime Environment (build 1.7.0_45-b18) // Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode) // // We need to parse the second line def inStream = new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.ProcessBuilder(JAVA, "-fullversion").start().getErrorStream())); try { String v = inStream.readLine().trim(); if (v != null) { int ib = v.indexOf("full version \""); if (ib != -1) { String str = v.substring(ib); String ver = str.substring(str.indexOf("\"") + 1, str.size() - 1); defineProperty("jdkRuntimeVersion", ver) def jdkVersionInfo = parseJavaVersion(ver) defineProperty("jdkVersion", jdkVersionInfo[0]) defineProperty("jdkBuildNumber", jdkVersionInfo[1]) } } } finally { inStream.close(); } if (!project.hasProperty("jdkRuntimeVersion")) throw new Exception("Unable to determine the version of Java in JDK_HOME at $JDK_HOME"); // Verify that CONF is something useful if (CONF != "Release" && CONF != "Debug" && CONF != "DebugNative") { logger.warn("Unknown configuration CONF='$CONF'. Treating as 'Release'") } // If the number of compile threads is less than 1 then we have a problem! if (Integer.parseInt(NUM_COMPILE_THREADS.toString()) < 1) { logger.warn("NUM_COMPILE_THREADS was specified as '$NUM_COMPILE_THREADS' which is less than the minimum value of 1. " + "Building with a value of 1 instead.") NUM_COMPILE_THREADS = 1 } // Check for Gradle 3.1, error if < 3.0. if (gradle.gradleVersion != "3.1") { def ver = gradle.gradleVersion.split("[\\.]"); def gradleMajor = Integer.parseInt(ver[0]); def gradleMinor = Integer.parseInt(ver[1]); def err = ""; if (gradleMajor < 3) { err = "Gradle version too old: ${gradle.gradleVersion}; must be at least 3.0" } if (IS_GRADLE_VERSION_CHECK && err != "") { fail(err); } logger.warn("*****************************************************************"); logger.warn("Unsupported gradle version $gradle.gradleVersion in use."); logger.warn("Only version 3.1 is supported. Use this version at your own risk"); if ( err != "") logger.warn(err); logger.warn("*****************************************************************"); } /****************************************************************************** * * * Logging of Properties and Settings * * * * Log some of the settings we've determined. We could log more here, it * * doesn't really hurt. * * * *****************************************************************************/ logger.quiet("gradle.gradleVersion: $gradle.gradleVersion") logger.quiet("OS_NAME: $OS_NAME") logger.quiet("OS_ARCH: $OS_ARCH") logger.quiet("JAVA_HOME: $JAVA_HOME") logger.quiet("JDK_HOME: $JDK_HOME") logger.quiet("java.runtime.version: ${javaRuntimeVersion}") logger.quiet("java version: ${javaVersion}") logger.quiet("java build number: ${javaBuildNumber}") logger.quiet("jdk.runtime.version: ${jdkRuntimeVersion}") logger.quiet("jdk version: ${jdkVersion}") logger.quiet("jdk build number: ${jdkBuildNumber}") logger.quiet("minimum jdk version: ${jfxBuildJdkVersionMin}") logger.quiet("minimum jdk build number: ${jfxBuildJdkBuildnumMin}") logger.quiet("STUB_RUNTIME: $STUB_RUNTIME") logger.quiet("CONF: $CONF") logger.quiet("NUM_COMPILE_THREADS: $NUM_COMPILE_THREADS") logger.quiet("COMPILE_TARGETS: $COMPILE_TARGETS") logger.quiet("COMPILE_FLAGS_FILES: $COMPILE_FLAGS_FILES") logger.quiet("HUDSON_JOB_NAME: $HUDSON_JOB_NAME") logger.quiet("HUDSON_BUILD_NUMBER: $HUDSON_BUILD_NUMBER") logger.quiet("PROMOTED_BUILD_NUMBER: $PROMOTED_BUILD_NUMBER") logger.quiet("PRODUCT_NAME: $PRODUCT_NAME") logger.quiet("RELEASE_VERSION: $RELEASE_VERSION") logger.quiet("RELEASE_SUFFIX: $RELEASE_SUFFIX") logger.quiet("RELEASE_VERSION_SHORT: $RELEASE_VERSION_SHORT") logger.quiet("RELEASE_VERSION_LONG: $RELEASE_VERSION_LONG") logger.quiet("RELEASE_VERSION_PADDED: $RELEASE_VERSION_PADDED") if (UPDATE_STUB_CACHE) { logger.quiet("UPDATE_STUB_CACHE: $UPDATE_STUB_CACHE") } /****************************************************************************** * * * Definition of Native Code Compilation Tasks * * * * - JavaHeaderTask is used to run javah. The JAVAH property will point at * * the version of javah to be used (i.e.: a path to javah) * * - CCTask compiles native code. Specifically it will compile .m, .c, * * .cpp, or .cc files. It uses the headers provided by the * * JavaHeaderTask plus additional platform specific headers. It will * * compile into .obj files. * * - LinkTask will perform native linking and create the .dll / .so / * * .dylib as necessary. * * * *****************************************************************************/ // Save a reference to the buildSrc.jar file because we need it for actually // compiling things, not just for the sake of this build script // (such as generating the JSL files, etc) ext.BUILD_SRC = rootProject.files("buildSrc/build/libs/buildSrc.jar") /** * Convenience method for creating javah, cc, link, and "native" tasks in the given project. These * tasks are parameterized by name, so that we can produce, for example, javahGlass, ccGlass, etc * named tasks. * * @param project The project to add tasks to * @param name The name of the project, such as "prism-common". This name is used * in the name of the generated task, such as ccPrismCommon, and also * in the name of the final library, such as libprism-common.dylib. */ void addNative(Project project, String name) { // TODO if we want to handle 32/64 bit windows in the same build, // Then we will need to modify the win compile target to be win32 or win64 def capitalName = name.split("-").collect{it.capitalize()}.join() def nativeTask = project.task("native$capitalName", group: "Build") { description = "Generates JNI headers, compiles, and builds native dynamic library for $name for all compile targets" } def cleanTask = project.task("cleanNative$capitalName", type: Delete, group: "Build") { description = "Clean native objects for $name" } if (project.hasProperty("nativeAllTask")) project.nativeAllTask.dependsOn nativeTask project.assemble.dependsOn(nativeTask) if (project.hasProperty("cleanNativeAllTask")) project.cleanNativeAllTask.dependsOn cleanTask // Each of the different compile targets will be placed in a sub directory // of these root dirs, with the name of the dir being the name of the target def nativeRootDir = project.file("$project.buildDir/native/$name") def libRootDir = project.file("$project.buildDir/libs/$name") // For each compile target, create a javah / cc / link triplet compileTargets { t -> def targetProperties = project.rootProject.ext[t.upper] def library = targetProperties.library def properties = targetProperties.get(name) def nativeDir = file("$nativeRootDir/${t.name}") def headerDir = file("${project.buildDir}/gensrc/headers/${project.moduleName}") // If there is not a library clause in the properties, assume it is not wanted if (!targetProperties.containsKey(name)) { println("Ignoring native library ${name}. Not defined in ${t.name} project properties"); return } // check for the property disable${name} = true def String disableKey = "disable${name}" def boolean disabled = targetProperties.containsKey(disableKey) ? targetProperties.get(disableKey) : false if (disabled) { println("Native library ${name} disabled in ${t.name} project properties"); return } def variants = properties.containsKey("variants") ? properties.variants : [""]; variants.each { variant -> def variantProperties = variant == "" ? properties : properties.get(variant) def capitalVariant = variant.capitalize() def ccOutput = variant == "" ? nativeDir : file("$nativeDir/$variant") def ccTask = project.task("cc${t.capital}$capitalName$capitalVariant", type: CCTask, group: "Build") { description = "Compiles native sources for ${name} for ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}" matches = ".*\\.c|.*\\.cpp|.*\\.m|.*\\.cc" headers = headerDir output(ccOutput) params.addAll(variantProperties.ccFlags) compiler = variantProperties.compiler source(variantProperties.nativeSource) cleanTask.delete ccOutput } def linkTask = project.task("link${t.capital}$capitalName$capitalVariant", type: LinkTask, dependsOn: ccTask, group: "Build") { description = "Creates native dynamic library for $name for ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}" objectDir = ccOutput linkParams.addAll(variantProperties.linkFlags) lib = file("$libRootDir/${t.name}/${variant == '' ? library(properties.lib) : library(variantProperties.lib)}") linker = variantProperties.linker cleanTask.delete "$libRootDir/${t.name}" } nativeTask.dependsOn(linkTask) if (IS_WINDOWS && t.name == "win") { def rcTask = project.task("rc$capitalName$capitalVariant", type: CompileResourceTask, group: "Build") { description = "Compiles native sources for $name" matches = ".*\\.rc" compiler = variantProperties.rcCompiler source(variantProperties.rcSource) if (variantProperties.rcFlags) { rcParams.addAll(variantProperties.rcFlags) } output(ccOutput) } linkTask.dependsOn rcTask; } } def useLipo = targetProperties.containsKey('useLipo') ? targetProperties.useLipo : false if (useLipo) { def lipoTask = project.task("lipo${t.capital}$capitalName", type: LipoTask, group: "Build") { description = "Creates native fat library for $name for ${t.name}" libDir = file("$libRootDir/${t.name}") lib = file("$libRootDir/${t.name}/${library(properties.lib)}") } nativeTask.dependsOn(lipoTask) } } } void addJSL(Project project, String name, String pkg, List addExports, Closure compile) { def lowerName = name.toLowerCase() def compileCompilers = project.task("compile${name}Compilers", type: JavaCompile, dependsOn: project.compileJava) { description = "Compile the $name JSL Compilers" classpath = project.files(project.sourceSets.main.output.classesDir) + project.files(project.sourceSets.jslc.output.classesDir) + project.configurations.antlr source = [project.file("src/main/jsl-$lowerName")] destinationDir = project.file("$project.buildDir/classes/jsl-compilers/$lowerName") if (addExports != null) { options.compilerArgs.addAll(addExports) } } def generateShaders = project.task("generate${name}Shaders", dependsOn: compileCompilers) { description = "Generate $name shaders from JSL" def sourceDir = project.file("src/main/jsl-$lowerName") def destinationDir = project.file("$project.buildDir/gensrc/jsl-$lowerName") inputs.dir sourceDir outputs.dir destinationDir doLast { compile(sourceDir, destinationDir) } } def compileHLSLShaders = project.task("compile${name}HLSLShaders", dependsOn: generateShaders, type: CompileHLSLTask) { enabled = IS_WINDOWS description = "Compile $name HLSL files into .obj files" matches = ".*\\.hlsl" output project.file("$project.buildDir/hlsl/$name/$pkg") source project.file("$project.buildDir/gensrc/jsl-$lowerName/$pkg") } def processShaders = project.task("process${name}Shaders", dependsOn: [generateShaders, compileHLSLShaders], type: Copy, description: "Copy hlsl / frag shaders to build/resources/jsl-$lowerName") { from("$project.buildDir/hlsl/$name") { include "**/*.obj" } from("$project.buildDir/gensrc/jsl-$lowerName") { include("**/*.frag") } into project.moduleDir } project.processShaders.dependsOn(processShaders) project.sourceSets.shaders.output.dir("$project.buildDir/gensrc/jsl-$lowerName", builtBy: processShaders ) def processShimsShaders = project.task("process${name}ShimsShaders", dependsOn: [generateShaders, compileHLSLShaders], type: Copy, description: "Copy hlsl / frag shaders to shims") { from("$project.buildDir/hlsl/$name") { include "**/*.obj" } from("$project.buildDir/gensrc/jsl-$lowerName") { include("**/*.frag") } into project.moduleShimsDir } project.processShimsShaders.dependsOn(processShimsShaders) } /** * Parses a JDK version string. The string must be in one of the following * two formats: * * major.minor.subminor * or * major.minor.subminor_update * * In both cases a list of 4 integers is returned, with element 3 set to * 0 in the former case. */ List parseJdkVersion(String version) { def arr = version.split("[_\\.]"); def intArr = []; arr.each { s -> intArr += Integer.parseInt(s); } while (intArr.size() < 4) intArr += 0; return intArr; } /** * Returns -1, 0, or 1 depending on whether JDK version "a" is less than, * equal to, or grater than version "b". */ int compareJdkVersion(String a, String b) { def aIntArr = parseJdkVersion(a); def bIntArr = parseJdkVersion(b); for (int i = 0; i < 4; i++) { if (aIntArr[i] < bIntArr[i]) return -1; if (aIntArr[i] > bIntArr[i]) return 1; } return 0; } // Task to verify the minimum level of Java needed to build JavaFX task verifyJava() { doLast { def status = compareJdkVersion(jdkVersion, jfxBuildJdkVersionMin); if (status < 0) { fail("java version mismatch: JDK version (${jdkVersion}) < minimum version (${jfxBuildJdkVersionMin})") } else if (status == 0) { def buildNum = Integer.parseInt(jdkBuildNumber) def minBuildNum = Integer.parseInt(jfxBuildJdkBuildnumMin) if (buildNum != 0 && buildNum < minBuildNum) { fail("JDK build number ($buildNum) < minimum build number ($minBuildNum)") } } } } task updateCacheIfNeeded() { // an empty task we can add to as needed for UPDATE_STUB_CACHE } task createTestArgfiles { // an empty task we can add to as needed } /***************************************************************************** * Project definitions (dependencies, etc) * *****************************************************************************/ void addJCov(p, test) { test.doFirst { def jcovJVMArgument = "include=javafx," + "include=com.sun.javafx," + "include=com.sun.glass," + "include=com.sun.openpisces," + "include=com.sun.pisces," + "include=com.sun.prism," + "include=com.sun.scenario," + "include=com.sun.webkit," + "exclude=com," + "exclude=java," + "exclude=javax," + "exclude=\"**.test\"," + "exclude=\"**.*Test\"," + "file=build/reports/jcov/report.xml," + "merge=merge"; test.jvmArgs("-javaagent:${p.configurations.testCompile.files.find { it.name.startsWith('jcov') }}=$jcovJVMArgument"); p.mkdir p.file("build/reports/jcov") } test.doLast { def reportFile = p.file("build/reports/jcov/report.xml") if (reportFile.exists()) { p.javaexec { workingDir = p.file("build/reports/jcov") classpath = p.files(p.configurations.testCompile.files.find { it.name.startsWith('jcov') }) main = "com.sun.tdk.jcov.Helper" args = [ "RepGen", "-exclude", "\"**.test\"", "-exclude", "\"**.*Test\"", "-output", ".", "-source", p.sourceSets.main.java.srcDirs.collect{p.file(it)}.join(":"), "report.xml" ] } } } } allprojects { // We want to configure all projects as java projects and use the same compile settings // etc, except for the root project which we just want to ignore (and for now media) if (project == rootProject) { return } if (project.path.startsWith(":apps")) { // Lets handle the apps tree differently, as it is a collection of ant builds, // and the ant importer collides with the 'apply plugin:java' return } // All of our projects are java projects apply plugin: "java" sourceCompatibility = 1.9 // Setup the repositories that we'll download libraries from. Maven Central is // just easy for most things. The custom "ivy" repo is for downloading SWT. The way it // works is to setup the download URL such that it will resolve to the actual jar file // to download. See SWT_FILE_NAME for the name of the jar that will be used as the // "artifact" in the pattern below. Note that the closed builds use different repositories // so if you are debugging a closed-build artifact related build issue, check out the // closed gradle file instead. if (!BUILD_CLOSED) { repositories { mavenCentral() ivy { url "http://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/plugins/" layout "pattern", { artifact "[artifact].[ext]" } } } } // By default all of our projects require junit for testing so we can just // setup this dependency here. dependencies { testCompile group: "junit", name: "junit", version: "4.8.2" if (BUILD_CLOSED && DO_JCOV) { testCompile name: "jcov" } } compileJava.dependsOn verifyJava // At the moment the ASM library shipped with Gradle that is used to // discover the different test classes fails on Java 8, so in order // to have sourceCompatibility set to 1.8 I have to also turn scanForClasses off // and manually specify the includes / excludes. At the moment we use // Java 7 but when we switch to 8 this will be needed, and probably again when // we start building with Java 9. test { executable = JAVA; enableAssertions = true; testLogging.exceptionFormat = "full"; scanForTestClasses = false; include("**/*Test.*"); if (BUILD_CLOSED && DO_JCOV) { addJCov(project, test) } if (IS_HEADLESS_TEST) { systemProperty 'glass.platform', 'Monocle' systemProperty 'monocle.platform', 'Headless' systemProperty 'prism.order', 'sw' systemProperty 'com.sun.javafx.gestures.zoom', 'true' systemProperty 'com.sun.javafx.gestures.rotate', 'true' systemProperty 'com.sun.javafx.gestures.scroll', 'true' } systemProperty 'unstable.test', IS_UNSTABLE_TEST } compileTestJava { } } // These strings define the module-source-path to be used in compilation. // They need to contain the full paths to the sources and the * will be // used to infer the module name that is used. project.ext.defaultModuleSourcePath = cygpath(rootProject.projectDir.path + '/modules/*/src/main/java') + File.pathSeparator + cygpath(rootProject.projectDir.path + '/modules/*/build/gensrc/{java,jsl-decora,jsl-prism}') // graphics pass one project.ext.defaultModuleSourcePath_GraphicsOne = cygpath(rootProject.projectDir.path + '/modules/*/src/main/java') + File.pathSeparator + cygpath(rootProject.projectDir.path + '/modules/*/build/gensrc/{java,jsl-decora,jsl-prism}') // web pass one project.ext.defaultModuleSourcePath_WebOne = cygpath(rootProject.projectDir.path + '/modules/*/src/main/java') // Compiling the test shim files too. project.ext.defaultModuleSourcePathShim = cygpath(rootProject.projectDir.path + '/modules/*/src/{main,shims}/java') + File.pathSeparator + cygpath(rootProject.projectDir.path + '/modules/*/build/gensrc/{java,jsl-decora,jsl-prism}') // The "base" project is our first module and the most basic one required for // all other modules. It is useful even for non-GUI applications. project(":base") { project.ext.buildModule = true project.ext.includeSources = true project.ext.moduleRuntime = true project.ext.moduleName = "javafx.base" sourceSets { main shims test } dependencies { testCompile group: "junit", name: "junit", version: "4.8.2" } commonModuleSetup(project, [ 'base' ]) project.ext.moduleSourcePath = defaultModuleSourcePath project.ext.moduleSourcePathShim = defaultModuleSourcePathShim // We need to take the VersionInfo.java file and replace the various // properties within it def replacements = [ "BUILD_TIMESTAMP": BUILD_TIMESTAMP, "HUDSON_JOB_NAME": HUDSON_JOB_NAME, "HUDSON_BUILD_NUMBER": HUDSON_BUILD_NUMBER, "PROMOTED_BUILD_NUMBER": PROMOTED_BUILD_NUMBER, "PRODUCT_NAME": PRODUCT_NAME, "RELEASE_VERSION": RELEASE_VERSION, "RELEASE_SUFFIX": RELEASE_SUFFIX]; task processVersionInfo(type: Copy, description: "Replace params in VersionInfo and copy file to destination") { doFirst { mkdir "$buildDir/gensrc/java" } from "src/main/version-info" into "$buildDir/gensrc/java/com/sun/javafx/runtime" filter {line-> replacements.each() {k, v -> line = line.replace("@$k@", v.toString()); } line } } // if (IS_COMPILE_JFR) { // sourceSets.main.java.srcDirs += "src/main/java-jfr" // } // Make sure to include $buildDir/gensrc/java that we previously created. // We DO NOT want to include src/main/version-info sourceSets.main.java.srcDirs += "$buildDir/gensrc/java" compileJava.dependsOn processVersionInfo } // The graphics module is needed for any graphical JavaFX application. It requires // the base module and includes the scene graph, layout, css, prism, windowing, etc. // This is a fairly complicated module. There are many different types of native components // that all need to be compiled. project(":graphics") { project.ext.buildModule = true project.ext.includeSources = true project.ext.moduleRuntime = true project.ext.moduleName = "javafx.graphics" getConfigurations().create("antlr"); sourceSets { jslc // JSLC gramar subset main shims shaders // generated shaders (prism & decora) test stub } dependencies { stubCompile group: "junit", name: "junit", version: "4.8.2" antlr group: "org.antlr", name: "antlr-complete", version: "3.5.2" } project.ext.moduleSourcePath = defaultModuleSourcePath_GraphicsOne project.ext.moduleSourcePathShim = defaultModuleSourcePathShim commonModuleSetup(project, [ 'base', 'graphics' ]) List decoraAddExports = [ '--add-exports=javafx.graphics/com.sun.scenario.effect=ALL-UNNAMED', '--add-exports=javafx.graphics/com.sun.scenario.effect.light=ALL-UNNAMED', '--add-exports=javafx.graphics/com.sun.scenario.effect.impl.state=ALL-UNNAMED' ] /* Graphics compilation is "complicated" by the generated shaders. We have two shader groups - Decora and Prism. The shader groups each will generate a custom compiler that then genarates the shader code. These compilers rely on the JSLC gramar parser which is antlr generated and compile separately. The decora compiler relies on compileJava - which is sourceSet.main.java It also accesses module private packages, so will need add-exports Once the shader java code is generated, we can compileFullJava After that, we can generate the required native header and then build the native code */ project.task("processShaders") { // an empty task to hang the prism and decora shaders on } project.task("processShimsShaders") { // an empty task to hang the prism and decora shaders on } compileShimsJava.dependsOn("processShimsShaders") // Generate the JSLC support grammar project.task("generateGrammarSource", type: JavaExec) { // use antlr to generate our grammar. // note: the antlr plugin creates some issues with the other compiles // so we will do this by hand File wd = file(project.projectDir.path + "/src/jslc/antlr") executable = JAVA classpath = project.configurations.antlr workingDir = wd main = "org.antlr.Tool" args = [ "-o", "$buildDir/gensrc/antlr", "com/sun/scenario/effect/compiler/JSL.g" ] inputs.dir wd outputs.dir file("$buildDir/gensrc/antlr") } sourceSets.jslc.java.srcDirs += "$buildDir/gensrc/antlr" // and compile the JSLC support classes compileJslcJava.dependsOn(generateGrammarSource) compileJslcJava.classpath = project.configurations.antlr compileJava.dependsOn(compileJslcJava) // this task is the "second pass" compile of all of the module classes project.task("compileFullJava", type: JavaCompile, dependsOn: processShaders) { description = "Compile all of the graphics java classes - main and shaders" classpath = configurations.compile source = project.sourceSets.main.java.srcDirs source += "$buildDir/gensrc/java" source += project.sourceSets.shaders.output destinationDir = project.sourceSets.main.output.classesDir options.compilerArgs.addAll([ '-h', "$buildDir/gensrc/headers/", // Note: this creates the native headers '-implicit:none', '--module-source-path', defaultModuleSourcePath ] ) } classes.dependsOn(compileFullJava) project.sourceSets.shims.java.srcDirs += project.sourceSets.shaders.output project.sourceSets.shims.java.srcDirs += "$buildDir/gensrc/jsl-prism" project.sourceSets.shims.java.srcDirs += "$buildDir/gensrc/jsl-decora" compileShimsJava.dependsOn(compileFullJava) // Create a single "native" task which will depend on all the individual native tasks for graphics project.ext.nativeAllTask = task("native", group: "Build", description: "Compiles and Builds all native libraries for Graphics"); project.ext.cleanNativeAllTask = task("cleanNative", group: "Build", description: "Clean all native libraries and objects for Graphics"); // Add tasks for native compilation addNative(project, "glass"); addNative(project, "prism") addNative(project, "prismSW") addNative(project, "font") addNative(project, "iio") addNative(project, "prismES2") if (IS_COMPILE_PANGO) { addNative(project, "fontFreetype") addNative(project, "fontPango") } if (IS_WINDOWS) { addNative(project, "prismD3D") // TODO need to hook this up to be executed only if PassThroughVS.h is missing or PassThroughVS.hlsl is changed task generateD3DHeaders(group: "Build") { enabled = IS_WINDOWS inputs.file "src/main/native-prism-d3d/hlsl/Mtl1PS.hlsl" inputs.file "src/main/native-prism-d3d/hlsl/Mtl1VS.hlsl" inputs.file "src/main/native-prism-d3d/PassThroughVS.hlsl" outputs.dir "$buildDir/headers/PrismD3D/" outputs.dir "$buildDir/headers/PrismD3D/hlsl/" description = "Generate headers by compiling hlsl files" doLast { mkdir file("$buildDir/headers/PrismD3D/hlsl") def PS_3D_SRC = file("src/main/native-prism-d3d/hlsl/Mtl1PS.hlsl") def VS_3D_SRC = file("src/main/native-prism-d3d/hlsl/Mtl1VS.hlsl") def PASSTHROUGH_VS_SRC = file("src/main/native-prism-d3d/PassThroughVS.hlsl") def jobs = [ ["$FXC", "/nologo", "/T", "vs_3_0", "/Fh", "$buildDir/headers/PrismD3D/PassThroughVS.h", "/E", "passThrough", "$PASSTHROUGH_VS_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS.h", "/DSpec=0", "/DSType=0", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_i.h", "/DSpec=0", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1n.h", "/DSpec=1", "/DSType=0", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2n.h", "/DSpec=2", "/DSType=0", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3n.h", "/DSpec=3", "/DSType=0", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1t.h", "/DSpec=1", "/DSType=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2t.h", "/DSpec=2", "/DSType=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3t.h", "/DSpec=3", "/DSType=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1c.h", "/DSpec=1", "/DSType=2", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2c.h", "/DSpec=2", "/DSType=2", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3c.h", "/DSpec=3", "/DSType=2", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1m.h", "/DSpec=1", "/DSType=3", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2m.h", "/DSpec=2", "/DSType=3", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3m.h", "/DSpec=3", "/DSType=3", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1n.h", "/DSpec=1", "/DSType=0", "/DBump=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2n.h", "/DSpec=2", "/DSType=0", "/DBump=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3n.h", "/DSpec=3", "/DSType=0", "/DBump=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1t.h", "/DSpec=1", "/DSType=1", "/DBump=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2t.h", "/DSpec=2", "/DSType=1", "/DBump=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3t.h", "/DSpec=3", "/DSType=1", "/DBump=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1c.h", "/DSpec=1", "/DSType=2", "/DBump=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2c.h", "/DSpec=2", "/DSType=2", "/DBump=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3c.h", "/DSpec=3", "/DSType=2", "/DBump=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b1m.h", "/DSpec=1", "/DSType=3", "/DBump=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b2m.h", "/DSpec=2", "/DSType=3", "/DBump=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_b3m.h", "/DSpec=3", "/DSType=3", "/DBump=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1ni.h", "/DSpec=1", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2ni.h", "/DSpec=2", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3ni.h", "/DSpec=3", "/DSType=0", "/DIllumMap=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1ti.h", "/DSpec=1", "/DSType=1", "/DIllumMap=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2ti.h", "/DSpec=2", "/DSType=1", "/DIllumMap=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3ti.h", "/DSpec=3", "/DSType=1", "/DIllumMap=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1ci.h", "/DSpec=1", "/DSType=2", "/DIllumMap=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2ci.h", "/DSpec=2", "/DSType=2", "/DIllumMap=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3ci.h", "/DSpec=3", "/DSType=2", "/DIllumMap=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s1mi.h", "/DSpec=1", "/DSType=3", "/DIllumMap=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s2mi.h", "/DSpec=2", "/DSType=3", "/DIllumMap=1", "$PS_3D_SRC"], ["$FXC", "/nologo", "/T", "ps_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1PS_s3mi.h", "/DSpec=3", "/DSType=3", "/DIllumMap=1", "$PS_3D_SRC"], ["$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"], ["$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"], ["$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"], ["$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"], ["$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"], ["$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"], ["$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"], ["$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"], ["$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"], ["$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"], ["$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"], ["$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"], ["$FXC", "/nologo", "/T", "vs_2_0", "/Fh", "$buildDir/headers/PrismD3D/hlsl/Mtl1VS_Obj.h", "/DVertexType=ObjVertex", "$VS_3D_SRC"] ] final ExecutorService executor = Executors.newFixedThreadPool(Integer.parseInt(project.NUM_COMPILE_THREADS.toString())); final CountDownLatch latch = new CountDownLatch(jobs.size()); List futures = new ArrayList(); jobs.each { cmd -> futures.add(executor.submit(new Runnable() { @Override public void run() { try { exec { commandLine cmd } } finally { latch.countDown(); } } })); } latch.await(); // Looking for whether an exception occurred while executing any of the futures. // By calling "get()" on each future an exception will be thrown if one had occurred // on the background thread. futures.each {it.get();} } } ccWinPrismD3D.dependsOn generateD3DHeaders } // The Decora and Prism JSL files have to be generated in a very specific set of steps. // 1) Compile the *Compile.java classes. These live in src/main/jsl-* and will be // output to $buildDir/classes/jsl-compilers/* (where * == decora or prism). // 2) Generate source files from the JSL files contained in src/main/jsl-*. These // will be output to $buildDir/gensrc/jsl-* // 3) Compile the JSL Java sources in $buildDir/gensrc/jsl-* and put the output // into classes/jsl-* // 4) Compile the native JSL sources in $buildDir/gensrc/jsl-* and put the obj // files into native/jsl-* and the resulting library into libs/jsl-*.dll|so|dylib // 5) Modify the jar step to include classes/jsl-* // The native library must be copied over during SDK creation time in the "sdk" task. In // addition to these steps, the clean task is created. Note that I didn't bother to create // a new task for each of the decora files, preferring instead just to create a rule?? Also // need "clean" tasks for each compile task. addJSL(project, "Decora", "com/sun/scenario/effect/impl/hw/d3d/hlsl", decoraAddExports) { sourceDir, destinationDir -> [[fileName: "ColorAdjust", generator: "CompileJSL", outputs: "-all"], [fileName: "Brightpass", generator: "CompileJSL", outputs: "-all"], [fileName: "SepiaTone", generator: "CompileJSL", outputs: "-all"], [fileName: "PerspectiveTransform", generator: "CompileJSL", outputs: "-all"], [fileName: "DisplacementMap", generator: "CompileJSL", outputs: "-all"], [fileName: "InvertMask", generator: "CompileJSL", outputs: "-all"], [fileName: "Blend", generator: "CompileBlend", outputs: "-all"], [fileName: "PhongLighting", generator: "CompilePhong", outputs: "-all"], [fileName: "LinearConvolve", generator: "CompileLinearConvolve", outputs: "-hw"], [fileName: "LinearConvolveShadow", generator: "CompileLinearConvolve", outputs: "-hw"]].each { settings -> javaexec { executable = JAVA workingDir = project.projectDir main = settings.generator classpath = configurations.compile + configurations.antlr classpath += files(project.sourceSets.jslc.output.classesDir) classpath += files("${project.projectDir}/src/jslc/resources") classpath += files("$buildDir/classes/main") classpath += files("$buildDir/classes/jsl-compilers/decora") jvmArgs += decoraAddExports args += ["-i", sourceDir, "-o", destinationDir, "-t", "-pkg", "com/sun/scenario/effect", "$settings.outputs", "$settings.fileName"] } } } task nativeDecora(dependsOn: compileDecoraHLSLShaders, group: "Build") { description = "Generates JNI headers, compiles, and builds native dynamic library for Decora" } task cleanNativeDecora(type: Delete, group: "Build") { description = "Clean native objects for Decora" } def headerDir = file("$buildDir/gensrc/headers/javafx.graphics") def nativeRootDir = project.file("$project.buildDir/native/jsl-decora") def libRootDir = project.file("$project.buildDir/libs/jsl-decora") // For each compile target, create cc and link tasks compileTargets { t -> def target = t.name def upperTarget = t.upper def capitalTarget = t.capital def targetProperties = rootProject.ext[upperTarget]; def library = targetProperties.library def properties = targetProperties.get('decora') def nativeDir = file("$nativeRootDir/$target"); def variants = properties.containsKey("variants") ? properties.variants : [""]; variants.each { variant -> def variantProperties = variant == "" ? properties : properties.get(variant) def capitalVariant = variant.capitalize() def ccOutput = variant == "" ? nativeDir : file("$nativeDir/$variant") def ccTask = task("compileDecoraNativeShaders$capitalTarget$capitalVariant", type: CCTask ) { description = "Compiles Decora SSE natives for ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}" matches = ".*\\.cc" source file("$buildDir/gensrc/jsl-decora") source file(project.projectDir.path + "/src/main/native-decora") headers = headerDir params.addAll(variantProperties.ccFlags) output(ccOutput) compiler = variantProperties.compiler cleanNativeDecora.delete ccOutput } def linkTask = task("linkDecoraNativeShaders$capitalTarget$capitalVariant", type: LinkTask, dependsOn: ccTask) { description = "Creates native dynamic library for Decora SSE ${t.name}${capitalVariant != '' ? ' for variant ' + capitalVariant : ''}" objectDir = ccOutput linkParams.addAll(variantProperties.linkFlags) lib = file("$libRootDir/$t.name/${library(variantProperties.lib)}") linker = variantProperties.linker cleanNativeDecora.delete "$libRootDir/$t.name/" } if (IS_WINDOWS && target == "win") { def rcTask = project.task("rcDecoraNativeShaders$capitalTarget$capitalVariant", type: CompileResourceTask) { description = "Compiles native sources for Decora SSE" matches = ".*\\.rc" compiler = variantProperties.rcCompiler source(variantProperties.rcSource) if (variantProperties.rcFlags) { rcParams.addAll(variantProperties.rcFlags) } output(ccOutput) } linkTask.dependsOn rcTask; } nativeDecora.dependsOn(linkTask) } } // Prism JSL addJSL(project, "Prism", "com/sun/prism/d3d/hlsl", null) { sourceDir, destinationDir -> def inputFiles = fileTree(dir: sourceDir) inputFiles.include "**/*.jsl" inputFiles.each { file -> javaexec { executable = JAVA workingDir = project.projectDir main = "CompileJSL" classpath = configurations.compile + configurations.antlr classpath += files(project.sourceSets.jslc.output.classesDir) classpath += files(project.sourceSets.jslc.resources) classpath += files("$buildDir/classes/jsl-compilers/prism", project.projectDir.path + "/src/main/jsl-prism") // for the .stg args = ["-i", sourceDir, "-o", destinationDir, "-t", "-pkg", "com/sun/prism", "-d3d", "-es2", "-name", "$file"] } } } nativePrism.dependsOn compilePrismHLSLShaders; project.nativeAllTask.dependsOn nativeDecora project.cleanNativeAllTask.dependsOn cleanNativeDecora assemble.dependsOn nativeDecora processResources.dependsOn processDecoraShaders, processPrismShaders test { def cssDir = file("$buildDir/classes/main/javafx") jvmArgs "-Djavafx.toolkit=test.com.sun.javafx.pgstub.StubToolkit", "-DCSS_META_DATA_TEST_DIR=$cssDir" enableAssertions = true testLogging.exceptionFormat = "full" scanForTestClasses = false include "**/*Test.*" if (BUILD_CLOSED && DO_JCOV) { addJCov(project, test) } } // To enable the IDEs to all be happy (no red squiggles) we need to have the libraries // available in some known location. Maybe in the future the Gradle plugins to each // of the IDEs will be good enough that we won't need this hack anymore. classes << { // Copy all of the download libraries to the libs directory for the sake of the IDEs File libsDir = rootProject.file("build/libs"); // In some IDEs (Eclipse for example), touching these libraries // cauese a full build within the IDE. When gradle is used // outside of the IDE, for example to build the native code, // a full rebuild is caused within the IDE. The fix is to check // for the presence of the target files in the lib directory // and not copy the files if all are present. libsDir.mkdirs(); def allLibsPresent = true def libNames = [ "antlr-complete-3.5.2.jar" ] libNames.each { name -> File f = new File(libsDir, name) if (!f.exists()) allLibsPresent = false } if (allLibsPresent) return; for (File f : [configurations.compile.files, configurations.antlr.files].flatten()) { copy { into libsDir from f.getParentFile() include "**/antlr-complete-3.5.2.jar" includeEmptyDirs = false } } } } project(":controls") { project.ext.buildModule = true project.ext.includeSources = true project.ext.moduleRuntime = true project.ext.moduleName = "javafx.controls" sourceSets { main shims test } project.ext.moduleSourcePath = defaultModuleSourcePath project.ext.moduleSourcePathShim = defaultModuleSourcePathShim commonModuleSetup(project, [ 'base', 'graphics', 'controls' ]) dependencies { testCompile project(":graphics").sourceSets.test.output testCompile project(":base").sourceSets.test.output } test { def cssDir = file("$buildDir/classes/main/javafx") jvmArgs "-Djavafx.toolkit=test.com.sun.javafx.pgstub.StubToolkit", "-DCSS_META_DATA_TEST_DIR=$cssDir" } // TODO JDK-8174944 Css2Bin really should be moved out and put into buildSrc if it can be // TODO could change script to dynamically locate all .css files and create bss for them, probably better // TODO also not sure there is any benefit to having css files in the the runtime modules at all processResources << { ["$moduleDir/com/sun/javafx/scene/control/skin/caspian/caspian.css", "$moduleDir/com/sun/javafx/scene/control/skin/caspian/caspian-no-transparency.css", "$moduleDir/com/sun/javafx/scene/control/skin/caspian/embedded-qvga.css", "$moduleDir/com/sun/javafx/scene/control/skin/caspian/embedded.css", "$moduleDir/com/sun/javafx/scene/control/skin/caspian/fxvk.css", "$moduleDir/com/sun/javafx/scene/control/skin/caspian/highcontrast.css", "$moduleDir/com/sun/javafx/scene/control/skin/modena/modena.css", "$moduleDir/com/sun/javafx/scene/control/skin/modena/modena-no-transparency.css", "$moduleDir/com/sun/javafx/scene/control/skin/modena/touch.css"].each { css -> javaexec { executable = JAVA workingDir = project.projectDir jvmArgs += patchModuleArgs main = "com.sun.javafx.css.parser.Css2Bin" args css } } } // TODO - if the above TODO regarding Css2Bin is fixed, this should also // be fixed. processShimsResources.dependsOn(project.task("copyShimBss", type: Copy) { from project.moduleDir into project.moduleShimsDir include "**/*.bss" }) } project(":swing") { /* should not be built, but needed in JMX tasks.all { if (!COMPILE_SWING) it.enabled = false } */ project.ext.buildModule = COMPILE_SWING project.ext.includeSources = true project.ext.moduleRuntime = true project.ext.moduleName = "javafx.swing" sourceSets { main //shims // no test shims needed test } project.ext.moduleSourcePath = defaultModuleSourcePath project.ext.moduleSourcePathShim = defaultModuleSourcePathShim commonModuleSetup(project, [ 'base', 'graphics', 'swing' ]) dependencies { } test { enabled = IS_FULL_TEST && IS_AWT_TEST } } project(":swt") { tasks.all { if (!COMPILE_SWT) it.enabled = false } // javafx.swt is an automatic module project.ext.buildModule = false commonModuleSetup(project, [ 'base', 'graphics' ]) dependencies { compile name: SWT_FILE_NAME } classes << { // Copy all of the download libraries to libs directory for the sake of the IDEs File libsDir = rootProject.file("build/libs"); File swtLib = new File(libsDir, "swt-debug.jar") libsDir.mkdirs(); // Skip copy if file is present. if (swtLib.exists()) return; for (File f : configurations.compile.files) { // Have to rename the swt jar because it is some platform specific name but // for the sake of the IDEs we need to have a single stable name that works // on every platform copy { into libsDir from f.getParentFile() include "**/*swt*.jar" includeEmptyDirs = false rename ".*swt.*jar", "swt-debug\\.jar" } } } compileJava.options.compilerArgs.addAll([ "--add-exports=javafx.graphics/com.sun.glass.ui=ALL-UNNAMED", "--add-exports=javafx.graphics/com.sun.javafx.cursor=ALL-UNNAMED", "--add-exports=javafx.graphics/com.sun.javafx.embed=ALL-UNNAMED", "--add-exports=javafx.graphics/com.sun.javafx.stage=ALL-UNNAMED", "--add-exports=javafx.graphics/com.sun.javafx.tk=ALL-UNNAMED", ]) test { //enabled = IS_FULL_TEST && IS_SWT_TEST enabled = false // FIXME: JIGSAW -- support this with modules logger.info("JIGSAW Testing disabled for swt") if (IS_MAC) { enabled = false logger.info("SWT tests are disabled on MAC, because Gradle test runner does not handle -XstartOnFirstThread properly (https://issues.gradle.org/browse/GRADLE-3290).") } } } project(":fxml") { project.ext.buildModule = true project.ext.includeSources = true project.ext.moduleRuntime = true project.ext.moduleName = "javafx.fxml" sourceSets { main shims test } project.ext.moduleSourcePath = defaultModuleSourcePath project.ext.moduleSourcePathShim = defaultModuleSourcePathShim commonModuleSetup(project, [ 'base', 'graphics', 'swing', 'controls', 'fxml' ]) dependencies { testCompile project(":graphics").sourceSets.test.output testCompile project(":base").sourceSets.test.output } test { // StubToolkit is not *really* needed here, but because some code inadvertently invokes performance // tracker and this attempts to fire up the toolkit and this looks for native libraries and fails, // we have to use the stub toolkit for now. jvmArgs "-Djavafx.toolkit=test.com.sun.javafx.pgstub.StubToolkit" // FIXME: change this to also allow JDK 9 boot jdk classpath += files("$JDK_HOME/jre/lib/ext/nashorn.jar") } } project(":jmx") { project.ext.buildModule = false project.ext.moduleRuntime = false project.ext.moduleName = "javafx.jmx" commonModuleSetup(project, [ 'base', 'graphics', 'swing', 'controls', 'media', 'jmx' ]) dependencies { } // Tests are permanently disabled test.enabled = false compileJava.options.compilerArgs.addAll([ "--add-exports=javafx.graphics/com.sun.javafx.jmx=ALL-UNNAMED", "--add-exports=javafx.graphics/com.sun.scenario.animation=ALL-UNNAMED", "--add-exports=javafx.graphics/com.sun.scenario.animation.jmx=ALL-UNNAMED", "--add-exports=javafx.graphics/com.sun.javafx.stage=ALL-UNNAMED", "--add-exports=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED", "--add-exports=javafx.graphics/com.sun.javafx.tk=ALL-UNNAMED", "--add-exports=javafx.media/com.sun.media.jfxmedia=ALL-UNNAMED", "--add-exports=javafx.media/com.sun.media.jfxmedia.events=ALL-UNNAMED", ]) } project(":fxpackagerservices") { project.ext.buildModule = COMPILE_FXPACKAGER project.ext.includeSources = true project.ext.moduleRuntime = false project.ext.moduleName = "jdk.packager.services" sourceSets { main //shims // no test shims needed test } project.ext.moduleSourcePath = defaultModuleSourcePath project.ext.moduleSourcePathShim = defaultModuleSourcePathShim commonModuleSetup(project, [ 'base', 'graphics', 'controls' ]) tasks.all { if (!COMPILE_FXPACKAGER) it.enabled = false } compileTestJava.enabled = false // FIXME: JIGSAW -- support this with modules test { enabled = false // FIXME: JIGSAW -- support this with modules logger.info("JIGSAW Testing disabled for fxpackagerservices") } } project(":fxpackager") { project.ext.buildModule = COMPILE_FXPACKAGER project.ext.includeSources = true project.ext.moduleRuntime = false project.ext.moduleName = "jdk.packager" sourceSets { main //shims // no test shims needed test } project.ext.moduleSourcePath = defaultModuleSourcePath project.ext.moduleSourcePathShim = defaultModuleSourcePathShim commonModuleSetup(project, [ 'base', 'graphics', 'controls', 'fxpackagerservices', 'fxpackager' ]) manifest { attributes( "Main-Class": "com.sun.javafx.tools.packager.Main" ) } tasks.all { if (!COMPILE_FXPACKAGER) it.enabled = false } sourceSets { main antplugin { java { compileClasspath += main.output runtimeClasspath += main.output } } test } // fxpackager has a dependency on ant in order to build the ant jar, // and as such needs to point to the apache binary repository if (!BUILD_CLOSED) { repositories { maven { url "https://repository.apache.org" } } } dependencies { antpluginCompile group: "org.apache.ant", name: "ant", version: "1.8.2" testCompile project(":controls"), group: "org.apache.ant", name: "ant", version: "1.8.2", sourceSets.antplugin.output } //Note: these should be reflected in the module-info additions passed to the JDK compileJava.options.compilerArgs.addAll([ "--add-exports=java.base/sun.security.timestamp=jdk.packager", "--add-exports=java.base/sun.security.x509=jdk.packager", "--add-exports=jdk.jdeps/com.sun.tools.jdeps=jdk.packager", "--add-exports=jdk.jlink/jdk.tools.jlink.internal.packager=jdk.packager", // Note: not in extras... "--add-exports=java.base/sun.security.pkcs=jdk.packager", "--add-exports=java.logging/java.util.logging=jdk.packager", ]) compileAntpluginJava.dependsOn([ compileJava, processResources ]) compileAntpluginJava.options.compilerArgs.addAll( computeModulePathArgs("antlib", project.moduleChain, false)) task buildVersionFile() { File dir = new File("${project.projectDir}/build/resources/antplugin/resources"); File versionFile = new File(dir, "/version.properties"); doLast { dir.mkdirs() if (!versionFile.exists()) { versionFile << "version=$RELEASE_VERSION\n" } } outputs.file(versionFile) } // When producing the ant-javafx.jar, we need to relocate a few class files // from their normal location to a resources/classes or resources/web-files // location task antpluginJar(type: Jar, dependsOn: [ compileJava, jar, compileAntpluginJava, buildVersionFile ]) { includeEmptyDirs = false archiveName = "ant-javafx.jar" from (sourceSets.antplugin.output) { eachFile { FileCopyDetails details -> if (details.path.startsWith("com/javafx/main")) { details.path = "resources/classes/$details.path" } } } from (sourceSets.main.resources) { includes = [ "com/sun/javafx/tools/ant/**" ] } from (sourceSets.main.output.resourcesDir) { includes = [ "resources/web-files/**" ] } } assemble.dependsOn(antpluginJar) // The "man" task will create a $buildDir/man containing the man // files for the system being built task man(type: Copy) { includeEmptyDirs = false enabled = (IS_LINUX || IS_MAC) && COMPILE_FXPACKAGER from "src/main/man" into "$buildDir/man" exclude "**/*.html" if (IS_MAC) exclude "**/ja_JP.UTF-8/**" } processResources.dependsOn man String buildClassesDir = "${sourceSets.main.output.classesDir}/${moduleName}" // Compile the native launchers. These are included in jdk.packager.jmod. if (IS_WINDOWS && COMPILE_FXPACKAGER) { task buildWinLauncher(type: CCTask, group: "Build") { description = "Compiles native sources for the application co-bundle launcher"; matches = "WinLauncher\\.cpp"; params.addAll(WIN.launcher.ccFlags); output(file("$buildDir/native/WinLauncher")); source(file("src/main/native/launcher/win")); compiler = WIN.launcher.compiler exe = true; linkerOptions.addAll(WIN.launcher.linkFlags); } task copyWinLauncher(type: Copy, group: "Build", dependsOn: buildWinLauncher) { from "$buildDir/native/WinLauncher/WinLauncher.exe" from "$MSVCR" from "$MSVCP" into "${buildClassesDir}/com/oracle/tools/packager/windows" } task compileWinLibrary(type: CCTask, group: "Build") { description = "Compiles native sources for the application co-bundle launcher library"; matches = ".*\\.cpp" source(file("src/main/native/library/common")); params.addAll(WIN.launcherlibrary.ccFlags) output(file("$buildDir/native/WinLauncher/obj")); compiler = WIN.launcherlibrary.compiler } task linkWinLibrary(type: LinkTask, group: "Build", dependsOn: compileWinLibrary) { description = "Links native sources for the application co-bundle launcher library"; objectDir = file("$buildDir/native/WinLauncher/obj") linkParams.addAll(WIN.launcherlibrary.linkFlags); lib = file("$buildDir/native/WinLauncher/packager.dll") linker = WIN.launcherlibrary.linker } task copyWinLibrary(type: Copy, group: "Build", dependsOn: linkWinLibrary) { from "$buildDir/native/WinLauncher/packager.dll" into "${buildClassesDir}/com/oracle/tools/packager/windows" } task buildWinLauncherSvc(type: CCTask, group: "Build") { description = "Compiles native sources for the application co-bundle launcher"; matches = "WinLauncherSvc\\.cpp"; params.addAll(WIN.launcher.ccFlags); output(file("$buildDir/native/WinLauncherSvc")); source(file("src/main/native/service/win")); compiler = WIN.launcher.compiler exe = true; linkerOptions.addAll(WIN.launcher.linkFlags); } task copyWinLauncherSvc(type: Copy, group: "Build", dependsOn: buildWinLauncherSvc) { from "$buildDir/native/WinLauncherSvc/WinLauncherSvc.exe" into "${buildClassesDir}/com/oracle/tools/packager/windows" } task compileLauncher(dependsOn: [copyWinLauncher, copyWinLibrary, copyWinLauncherSvc]) } else if (IS_MAC && COMPILE_FXPACKAGER) { task buildMacLauncher(type: CCTask, group: "Build") { description = "Compiles native sources for the application co-bundle launcher" matches = ".*\\.m" source file("src/main/native/launcher/mac") params.addAll(MAC.launcher.ccFlags) compiler = MAC.launcher.compiler output(file("${buildClassesDir}/com/oracle/tools/packager/mac")) outputs.file(file("${buildClassesDir}/main/com/oracle/tools/packager/mac/JavaAppLauncher")) eachOutputFile = { f -> return new File(f.getParent(), "JavaAppLauncher") } } task compileMacLibrary(type: CCTask, group: "Build") { description = "Compiles native sources for the application co-bundle launcher library" matches = ".*\\.cpp|.*\\.mm" source file("src/main/native/library/common"); params.addAll(MAC.launcherlibrary.ccFlags) compiler = MAC.launcherlibrary.compiler output(file("$buildDir/native/maclauncher/obj")) } task linkMacLibrary(type: LinkTask, group: "Build", dependsOn: compileMacLibrary) { description = "Links native sources for the application co-bundle launcher library" objectDir = file("$buildDir/native/maclauncher/obj") linkParams.addAll(MAC.launcherlibrary.linkFlags) linker = MAC.launcherlibrary.linker lib = file("${buildClassesDir}/com/oracle/tools/packager/mac/libpackager.dylib") } task compileLauncher(dependsOn: [buildMacLauncher, linkMacLibrary]) } else if (IS_LINUX && COMPILE_FXPACKAGER) { task compileLinuxLauncher(type: CCTask, group: "Build") { description = "Compiles native sources for the application co-bundle launcher" matches = ".*\\.cpp" source file("src/main/native/launcher/linux") params.addAll(LINUX.launcher.ccFlags) compiler = LINUX.launcher.compiler output(file("$buildDir/native/linuxlauncher/launcherobj")) } task linkLinuxLauncher(type: LinkTask, dependsOn: compileLinuxLauncher, group: "Build") { description = "Links native dynamic library for the application co-bundle launcher" objectDir = file("$buildDir/native/linuxlauncher/launcherobj") linkParams.addAll(LINUX.launcher.linkFlags) linker = LINUX.launcher.linker lib = file("${buildClassesDir}/com/oracle/tools/packager/linux/JavaAppLauncher") } task compileLinuxLibrary(type: CCTask, group: "Build") { description = "Compiles native sources for the application co-bundle launcher library" matches = ".*\\.cpp" source file("src/main/native/library/common") params.addAll(LINUX.launcherlibrary.ccFlags) compiler = LINUX.launcherlibrary.compiler output(file("$buildDir/native/linuxlauncher/obj")) } task linkLinuxLibrary(type: LinkTask, dependsOn: compileLinuxLibrary, group: "Build") { description = "Links native dynamic library for the application co-bundle launcher library" objectDir = file("$buildDir/native/linuxlauncher/obj") linkParams.addAll(LINUX.launcherlibrary.linkFlags) linker = LINUX.launcherlibrary.linker lib = file("${buildClassesDir}/com/oracle/tools/packager/linux/libpackager.so") } task compileLauncher(dependsOn: [linkLinuxLauncher, linkLinuxLibrary]) } // Builds the javapackager executable. For everything other than windows, // this is simply moving the existing shell script and ensuring it has proper // permissions. For Windows, this includes compiling the native executable if (IS_WINDOWS && COMPILE_FXPACKAGER){ task setupCompileJavaPackager(type: Copy, group: "Build") { mkdir "$buildDir/native" mkdir "$buildDir/native/javapackager" from file("src/main/native/javapackager/win/javapackager.manifest") into file("$buildDir/native/javapackager") filter { line-> line = line.replace("FXVERSION", RELEASE_VERSION_PADDED) } } task compileJavaPackager(type: CCTask, group: "Build", dependsOn: setupCompileJavaPackager) { description = "Compiles native sources for javapackager.exe" matches = ".*\\.cpp" params.addAll(WIN.fxpackager.ccFlags) compiler = WIN.fxpackager.compiler output(file("$buildDir/native/javapackager/obj")) source WIN.fxpackager.nativeSource doLast { mkdir "$buildDir/native" exec { environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT) commandLine(WIN.fxpackager.rcCompiler) args(WIN.fxpackager.rcFlags) args("/fo$buildDir/native/javapackager/javapackager.res") args(WIN.fxpackager.rcSource) } } } task linkJavaPackager(type: LinkTask, dependsOn: compileJavaPackager, group: "Build") { description = "Links javapackager.exe" objectDir = file("$buildDir/native/javapackager/obj") linkParams.addAll(WIN.fxpackager.linkFlags); lib = file("$buildDir/native/javapackager/javapackager.exe") linker = WIN.fxpackager.linker doLast { exec({ commandLine("$MC", "-manifest", "$buildDir/native/javapackager/javapackager.manifest", "-outputresource:$buildDir/native/javapackager/javapackager.exe") environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT) }) } } task copyJavaPackager(type: Copy, group: "Build", dependsOn: linkJavaPackager) { from file("$buildDir/native/javapackager/javapackager.exe") into file("$buildDir/javapackager") } task buildJavaPackager(dependsOn: [copyJavaPackager]) } else { task buildJavaPackager(type: Copy, group: "Build") { enabled = COMPILE_FXPACKAGER from "src/main/native/javapackager/shell" into "$buildDir/javapackager" fileMode = 0755 } } assemble.dependsOn compileLauncher; assemble.dependsOn buildJavaPackager classes << { // Copy all of the download libraries to libs directory for the sake of the IDEs File libsDir = rootProject.file("build/libs"); File antLib = new File(libsDir, "ant-1.8.2.jar") libsDir.mkdirs(); // Skip copy if file is present. if (antLib.exists()) return; for (File f : configurations.compile.files) { copy { into libsDir from f.getParentFile() include "**/ant-1.8.2.jar" includeEmptyDirs = false } } } task setupPackagerFakeJar(type: Copy) { from "$projectDir/src/main/resources/com/oracle/tools/packager/linux/javalogo_white_48.png" from "$projectDir/src/main/resources/com/oracle/tools/packager/mac/GenericAppHiDPI.icns" from "$projectDir/src/main/resources/com/oracle/tools/packager/windows/javalogo_white_48.ico" from "$projectDir/src/test/resources/hello/java-logo2.gif" from "$projectDir/src/test/resources/hello/small.ico" from "$projectDir/src/test/resources/hello/test.icns" from "$projectDir/src/test/resources/hello/LICENSE-RTF.rtf" from "$projectDir/../../LICENSE" into project.file("$projectDir/build/tmp/tests/appResources") } task setupPackagerFakeJarLicense(type: Copy) { from "$projectDir/../../LICENSE" into project.file("$projectDir/build/tmp/tests/appResources") rename '(.*)LICENSE', '$1LICENSE2' } task packagerFakeJar(type: Jar, dependsOn: [setupPackagerFakeJar, setupPackagerFakeJarLicense]) { dependsOn compileTestJava from compileTestJava.destinationDir include "hello/**" destinationDir project.file("build/tmp/tests/appResources") archiveName "mainApp.jar" manifest { attributes( "Main-Class": "hello.HelloRectangle", "Custom-Attribute": " Is it stripped?" ) } } task packagerFXPackagedJar(type: Jar) { dependsOn packagerFakeJar from compileTestJava.destinationDir include "hello/**" destinationDir project.file("build/tmp/tests/appResources") archiveName "packagedMainApp.jar" manifest { attributes( "JavaFX-Application-Class": "hello.TestPackager", ) } } if (!DO_BUILD_SDK_FOR_TEST) { def antJavafxJar = new File(rootProject.buildDir, "modular-sdk/modules_libs/${project.ext.moduleName}/ant-javafx.jar") [compileTestJava, test].each { it.classpath = files(antJavafxJar) + it.classpath } } compileTestJava.enabled = false // FIXME: JIGSAW -- support this with modules test { enabled = false // FIXME: JIGSAW -- support this with modules logger.info("JIGSAW Testing disabled for fxpackager") dependsOn packagerFXPackagedJar systemProperty "RETAIN_PACKAGER_TESTS", RETAIN_PACKAGER_TESTS systemProperty "TEST_PACKAGER_DMG", TEST_PACKAGER_DMG systemProperty "FULL_TEST", FULL_TEST executable = JAVA; } def packagerDevOpts = [] try { packagerDevOpts.addAll(PACKAGER_DEV_OPTS.split(' ')) } catch (MissingPropertyException ignore) { packagerDevOpts.addAll("image") } task packagerDev(dependsOn: [jar, testClasses, packagerFakeJar], type:JavaExec) { workingDir = project.file("build/tmp/tests/appResources/") executable = JAVA classpath = project.files("build/libs/ant-javafx.jar", "build/classes/test", "build/resources/test") main = "hello.SimpleBundle" args = [ '--module-path', JDK_JMODS, '-o', "$projectDir/build/dev", '-all', packagerDevOpts ].flatten() } task copyRedistributableFiles(type: Copy) { def projectDir = "tools/java/legacy" def sourceDir = "src/$projectDir" def buildDir = "build/$projectDir" def resourceDir = "${moduleDir}/jdk/packager/internal/resources/tools/legacy" from "$sourceDir/jre.list" into project.file("$resourceDir") } processResources.dependsOn copyRedistributableFiles task copyDTtoPackager(type: Copy) { def destDt = "${moduleDir}/com/sun/javafx/tools/resource" from (sourceSets.main.output.resourcesDir) { includes = [ "resources/web-files/**" ] } into new File("$destDt", "dtoolkit") } processResources.dependsOn copyDTtoPackager } project(":media") { configurations { media } project.ext.buildModule = true project.ext.includeSources = true project.ext.moduleRuntime = true project.ext.moduleName = "javafx.media" sourceSets { main //shims // no test shims needed test tools { java.srcDir "src/tools/java" } } project.ext.moduleSourcePath = defaultModuleSourcePath project.ext.moduleSourcePathShim = defaultModuleSourcePathShim commonModuleSetup(project, [ 'base', 'graphics', 'media' ]) dependencies { } compileJava.dependsOn updateCacheIfNeeded compileJava { // generate the native headers during compile options.compilerArgs.addAll([ '-h', "${project.buildDir}/gensrc/headers" ]) } compileToolsJava { enabled = IS_COMPILE_MEDIA options.compilerArgs.addAll(project.modulePathArgs) options.compilerArgs.addAll([ '--add-exports', 'javafx.media/com.sun.media.jfxmedia=ALL-UNNAMED', ]) } project.ext.makeJobsFlag = IS_WINDOWS && IS_DEBUG_NATIVE ? "-j1" : "-j5"; project.ext.buildType = IS_DEBUG_NATIVE ? "Debug" : "Release"; def nativeSrcDir = file("${projectDir}/src/main/native") def generatedHeadersDir = file("${buildDir}/gensrc/headers/${project.moduleName}") task generateMediaErrorHeader(dependsOn: [compileToolsJava, compileJava]) { enabled = IS_COMPILE_MEDIA def headerpath = file("$generatedHeadersDir/jfxmedia_errors.h"); doLast { def classpath = files(sourceSets.tools.output); def sourcepath = sourceSets.main.java.srcDirs; def srcRoot = (sourcepath.toArray())[0]; mkdir generatedHeadersDir; exec { commandLine("$JAVA"); args += patchModuleArgs args += [ '--add-exports=javafx.media/com.sun.media.jfxmedia=ALL-UNNAMED' ] args += [ '-classpath', "${classpath.asPath}" ] args += [ "headergen.HeaderGen", "$headerpath", "$srcRoot" ] } } outputs.file(project.file("$headerpath")) } task buildNativeTargets { enabled = IS_COMPILE_MEDIA } compileTargets { t-> def targetProperties = project.rootProject.ext[t.upper] def nativeOutputDir = file("${buildDir}/native/${t.name}") def projectDir = t.name.startsWith("arm") ? "linux" : t.name def mediaProperties = targetProperties.media // Makefile for OSX needs to know if we're building for parfait def compileParfait = IS_COMPILE_PARFAIT ? "true" : "false" def buildNative = task("build${t.capital}Native", dependsOn: [generateMediaErrorHeader]) { enabled = targetProperties.compileMediaNative if (!targetProperties.compileMediaNative) { println("Not compiling native Media for ${t.name} per configuration request"); } doLast { exec { commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/jfxmedia/projects/${projectDir}") args("JAVA_HOME=${JDK_HOME}", "GENERATED_HEADERS_DIR=${generatedHeadersDir}", "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=jfxmedia", "COMPILE_PARFAIT=${compileParfait}", IS_64 ? "ARCH=x64" : "ARCH=x32", "CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}") if (t.name == "win") { environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT) args( "RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.jfxmediaRcFile}") } else { if (t.name.startsWith("arm")) { args("EXTRA_CFLAGS=${mediaProperties.extra_cflags}", "EXTRA_LDFLAGS=${mediaProperties.extra_ldflags}") } else { args("HOST_COMPILE=1") } } } } } // check for the property disable${name} = true def boolean disabled = targetProperties.containsKey('disableMedia') ? targetProperties.get('disableMedia') : false if (!disabled) { // Building GStreamer def buildGStreamer = task("build${t.capital}GStreamer") { enabled = IS_COMPILE_MEDIA doLast { exec { commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/gstreamer-lite") args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=gstreamer-lite", IS_64 ? "ARCH=x64" : "ARCH=x32", "CC=${mediaProperties.compiler}", "AR=${mediaProperties.ar}", "LINKER=${mediaProperties.linker}") if (t.name == "win") { environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT) args("RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.gstreamerRcFile}") } } } } def buildPlugins = task("build${t.capital}Plugins", dependsOn: buildGStreamer) { enabled = IS_COMPILE_MEDIA if (!project.ext.properties.containsKey("ON2_SRCDIR")) { project.ext.ON2_SRCDIR = ""; } if (!project.ext.properties.containsKey("ON2_LIB")) { project.ext.ON2_LIB = ""; } doLast { exec { commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/fxplugins") args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=fxplugins", "ON2_SRCDIR=${project.ext.ON2_SRCDIR}", "ON2_LIB=${project.ext.ON2_LIB}", IS_64 ? "ARCH=x64" : "ARCH=x32", "CC=${mediaProperties.compiler}", "AR=${mediaProperties.ar}", "LINKER=${mediaProperties.linker}") if (t.name == "win") { Map winEnv = new HashMap(WINDOWS_NATIVE_COMPILE_ENVIRONMENT) String sdkDir = System.getenv("BASECLASSES_SDK_DIR"); if (sdkDir == null) { sdkDir = "C:/Program Files/Microsoft SDKs/Windows/v7.1" // Default value winEnv["BASECLASSES_SDK_DIR"] = sdkDir } environment(winEnv) args("RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.fxpluginsRcFile}") } } } } buildNative.dependsOn buildPlugins if (t.name == "linux") { def buildAVPlugin = task( "buildAVPlugin", dependsOn: [buildPlugins]) { enabled = IS_COMPILE_MEDIA doLast { if (project.ext.properties.containsKey("libav")) { project.ext.libav.versions.each { version -> def libavDir = "${project.ext.libav.basedir}-${version}" File dir = file(libavDir) if (dir.exists()) { exec { commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/linux/avplugin") args("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}", "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=avplugin", "VERSION=${version}", "LIBAV_DIR=${libavDir}", "SUFFIX=", IS_64 ? "ARCH=x64" : "ARCH=x32") } } } project.ext.libav.ffmpeg.versions.each { version -> def libavDir = "${project.ext.libav.ffmpeg.basedir}-${version}" File dir = file(libavDir) if (dir.exists()) { exec { commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/linux/avplugin") args("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}", "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=avplugin", "VERSION=${version}", "LIBAV_DIR=${libavDir}", "SUFFIX=-ffmpeg", IS_64 ? "ARCH=x64" : "ARCH=x32") } } } } else { // Building fxavcodec plugin (libav plugin) exec { commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/linux/avplugin") args("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}", "OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=avplugin", IS_64 ? "ARCH=x64" : "ARCH=x32") } } } } buildNative.dependsOn buildAVPlugin } if (t.name == "win") { def buildResources = task("buildResources") << { def rcOutputDir = "${nativeOutputDir}/${buildType}" mkdir rcOutputDir exec { environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT) commandLine (WIN.media.rcCompiler) args(WIN.media.glibRcFlags) args("/Fo${rcOutputDir}/${WIN.media.glibRcFile}", WIN.media.rcSource) } exec { environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT) commandLine (WIN.media.rcCompiler) args(WIN.media.gstreamerRcFlags) args("/Fo${rcOutputDir}/${WIN.media.gstreamerRcFile}", WIN.media.rcSource) } exec { environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT) commandLine (WIN.media.rcCompiler) args(WIN.media.fxpluginsRcFlags) args("/Fo${rcOutputDir}/${WIN.media.fxpluginsRcFile}", WIN.media.rcSource) } exec { environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT) commandLine (WIN.media.rcCompiler) args(WIN.media.jfxmediaRcFlags) args("/Fo${rcOutputDir}/${WIN.media.jfxmediaRcFile}", WIN.media.rcSource) } } def buildGlib = task("build${t.capital}Glib", dependsOn: [buildResources]) { enabled = IS_COMPILE_MEDIA doLast { exec { environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT) commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/glib-lite") args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=glib-lite", IS_64 ? "ARCH=x64" : "ARCH=x32", "RESOURCE=${nativeOutputDir}/${buildType}/${WIN.media.glibRcFile}", "CC=${mediaProperties.compiler}", "AR=${mediaProperties.ar}", "LINKER=${mediaProperties.linker}") } } } buildGStreamer.dependsOn buildGlib } else if (t.name == "mac") { def buildGlib = task("build${t.capital}Glib") { enabled = IS_COMPILE_MEDIA doLast { exec { commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/libffi") args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=ffi") args ("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}", "AR=${mediaProperties.ar}") } exec { commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/glib-lite") args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=glib-lite") args ("CC=${mediaProperties.compiler}", "LINKER=${mediaProperties.linker}") } } } buildGStreamer.dependsOn buildGlib } } buildNativeTargets.dependsOn buildNative } jar { exclude("headergen/**") dependsOn compileJava if (IS_COMPILE_MEDIA) { dependsOn buildNativeTargets } } } project(":web") { configurations { webkit } project.ext.buildModule = true project.ext.includeSources = true project.ext.moduleRuntime = true project.ext.moduleName = "javafx.web" sourceSets { main shims test } project.ext.moduleSourcePath = defaultModuleSourcePath project.ext.moduleSourcePathShim = defaultModuleSourcePathShim commonModuleSetup(project, [ 'base', 'graphics', 'controls', 'media', 'web' ]) dependencies { } compileJava.dependsOn updateCacheIfNeeded task webArchiveJar(type: Jar) { from (project.file("$projectDir/src/test/resources/test/html")) { include "**/archive-*.*" } archiveName = "webArchiveJar.jar" destinationDir = file("$buildDir/testing/resources") } def gensrcDir = "${buildDir}/gensrc/java" // add in the wrappers to the compile sourceSets.main.java.srcDirs += "${gensrcDir}" if (IS_COMPILE_WEBKIT) { compileJava { // generate the native headers during compile // only needed if we are doing the native compile options.compilerArgs.addAll([ '-h', "${project.buildDir}/gensrc/headers" ]) } } else { // Instead of compiling native wrappers, use a pre-generated version // Copy these to a common location in the moduleSourcePath def copyWrappers = project.task("copyPreGeneratedWrappers", type: Copy) { enabled = (!IS_COMPILE_WEBKIT) from "src/main/java-wrappers" into "${gensrcDir}" } compileJava.dependsOn(copyWrappers); } test { // Run web tests in headless mode systemProperty 'glass.platform', 'Monocle' systemProperty 'monocle.platform', 'Headless' systemProperty 'prism.order', 'sw' dependsOn webArchiveJar def testResourceDir = file("$buildDir/testing/resources") jvmArgs "-DWEB_ARCHIVE_JAR_TEST_DIR=$testResourceDir" } // generate some headers that are not part of our build task generateHeaders(dependsOn: compileJava) { doLast { def dest = file("$buildDir/gensrc/headers/${project.moduleName}"); mkdir dest; exec { commandLine("$JAVAH", "-d", "$dest",); args("java.lang.Character", "java.net.IDN", ); } } } task compileGenerated() compileTargets { t -> def targetProperties = project.rootProject.ext[t.upper] def classifier = (t.name != "linux" && t.name != "win") ? t.name : IS_64 ? "${t.name}-amd64" : "${t.name}-i586" dependencies { webkit group: "com.sun.webkit", name: "webview-deps", version: "1.3.2", classifier: "$classifier", ext: "zip" } def webkitOutputDir = cygpath("$buildDir/${t.name}") def webkitConfig = IS_DEBUG_NATIVE ? "Debug" : "Release" def compileNativeTask = task("compileNative${t.capital}", dependsOn: [generateHeaders, compileJava]) { println "Building Webkit configuration /$webkitConfig/ into $webkitOutputDir" enabled = (IS_COMPILE_WEBKIT) outputs.upToDateWhen { false } outputs.dir("$webkitOutputDir/$webkitConfig/DerivedSources/WebCore/nativeJava/java") doLast { def dependencyFile = configurations.webkit.filter( { File f -> f.getName().contains(classifier) } ).getSingleFile() ant.unzip(src: dependencyFile, dest: webkitOutputDir) exec { workingDir("$projectDir/src/main/native") commandLine("perl", "Tools/Scripts/set-webkit-configuration", "--$webkitConfig") environment(["WEBKIT_OUTPUTDIR" : webkitOutputDir]) } exec { workingDir("$projectDir/src/main/native") def cmakeArgs = "-DENABLE_TOOLS=1" if (t.name == "win") { String parfaitPath = IS_COMPILE_PARFAIT ? System.getenv().get("PARFAIT_PATH") + ";" : ""; Map environmentSettings = new HashMap(WINDOWS_NATIVE_COMPILE_ENVIRONMENT) environmentSettings["PATH"] = parfaitPath + "$WINDOWS_VS_PATH" /* To build with ICU: 1. Download http://javaweb.us.oracle.com/jcg/fx-webrevs/RT-17164/WebKitLibrariesICU.zip and unzip it to WebKitLibraries folder. 2. Copy DLLs from WebKitLibrariesICU.zip\WebKitLibraries\import\runtime to %windir%\system32 3. Uncomment the line below */ // args("--icu-unicode") } else if (t.name == "mac") { // Add any osx specific flags. } else if (t.name == "linux") { if (!IS_64) { cmakeArgs = "-DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32" } } else if (t.name.startsWith("arm")) { fail("ARM target is not supported as of now.") } if (IS_COMPILE_PARFAIT) { environment([ "COMPILE_PARFAIT" : "true" ]) cmakeArgs = "-DCMAKE_C_COMPILER=parfait-gcc -DCMAKE_CXX_COMPILER=parfait-g++" } environment([ "JAVA_HOME" : JDK_HOME, "WEBKIT_OUTPUTDIR" : webkitOutputDir, ]) def targetCpuBitDepthSwitch = "" if (IS_64) { targetCpuBitDepthSwitch = "--64-bit" } else { targetCpuBitDepthSwitch = "--32-bit" } commandLine("perl", "Tools/Scripts/build-webkit", "--java", "--icu-unicode", targetCpuBitDepthSwitch, "--cmakeargs=${cmakeArgs}") } } } def copyDumpTreeNativeTask = task("copyDumpTreeNative${t.capital}", type: Copy, dependsOn: [ compileNativeTask]) { def library = rootProject.ext[t.upper].library from "$webkitOutputDir/$webkitConfig/lib/${library('DumpRenderTreeJava')}" into "$buildDir/test/${t.name}" } def copyNativeTask = task("copyNative${t.capital}", type: Copy, dependsOn: [compileNativeTask, , copyDumpTreeNativeTask]) { enabled = (IS_COMPILE_WEBKIT) def library = rootProject.ext[t.upper].library from "$webkitOutputDir/$webkitConfig/lib/${library('jfxwebkit')}" into "$buildDir/libs/${t.name}" } if (IS_WINDOWS && t.name == "win") { def webkitProperties = project.rootProject.ext[t.upper].webkit def rcTask = project.task("rc${t.capital}", type: CompileResourceTask) { compiler = webkitProperties.rcCompiler source(webkitProperties.rcSource) if (webkitProperties.rcFlags) { rcParams.addAll(webkitProperties.rcFlags) } output(file("$webkitOutputDir/$webkitConfig/WebCore/obj")) } compileNativeTask.dependsOn rcTask } def copyGeneratedDomTask = task("copyGeneratedDom${t.capital}", type: Copy, dependsOn: [compileJava, compileNativeTask, copyNativeTask]) { enabled = (IS_COMPILE_WEBKIT) from "$projectDir/src/main/java-wrappers/com/sun/webkit/dom/EventListenerImpl.java" into "${gensrcDir}/com/sun/webkit/dom" } def copyGeneratedTask = task("copyGenerated${t.capital}", type: Copy, dependsOn: [compileJava, compileNativeTask, copyNativeTask, copyGeneratedDomTask]) { enabled = (IS_COMPILE_WEBKIT) from "$webkitOutputDir/$webkitConfig/DerivedSources/WebCore/nativeJava/java" into "${gensrcDir}" } def compileGeneratedTask = task("compileGenerated${t.capital}", type: JavaCompile, dependsOn: [copyGeneratedDomTask, copyGeneratedTask]) { destinationDir = file("$buildDir/classes/main") classpath = configurations.compile source = project.sourceSets.main.java.srcDirs options.compilerArgs.addAll([ '-implicit:none', '--module-source-path', defaultModuleSourcePath ]) } compileGenerated.dependsOn compileGeneratedTask if (!targetProperties.compileWebnodeNative) { println("Not compiling native Webkit for ${t.name} per configuration request"); compileNativeTask.enabled = false } } def drtClasses = "com/sun/javafx/webkit/drt/**" jar.exclude(drtClasses) task drtJar(type: Jar, dependsOn: compileJava) { archiveName = "drt.jar" destinationDir = file("$buildDir/test") from "$buildDir/classes/main" include drtClasses } if (IS_COMPILE_WEBKIT) { assemble.dependsOn compileGenerated, drtJar } } // This project is for system tests that need to run with a full SDK. // Most of them display a stage or do other things that preclude running // them in a shared JVM or as part of the "smoke test" run (which must // not pop up any windows or use audio). As such, they are only enabled // when FULL_TEST is specified, and each test runs in its own JVM project(":systemTests") { sourceSets { test // Source sets for standalone test apps (used for launcher tests) testapp1 testapp2 } project.ext.buildModule = false project.ext.moduleRuntime = false project.ext.moduleName = "systemTests" dependencies { testCompile project(":graphics").sourceSets.test.output testCompile project(":base").sourceSets.test.output testCompile project(":controls").sourceSets.test.output testCompile project(":swing").sourceSets.test.output } commonModuleSetup(project, [ 'base', 'graphics', 'controls', 'media', 'web', 'swing', 'fxml' ]) File testJavaPolicyFile = new File(rootProject.buildDir, TESTJAVAPOLICYFILE); File testRunArgsFile = new File(rootProject.buildDir,TESTRUNARGSFILE); File stRunArgsFile = new File(project.buildDir,"st.run.args"); def sts = task("systemTestSetup") { outputs.file(stRunArgsFile) doLast() { stRunArgsFile.delete() logger.info("Creating patchmodule.args file ${stRunArgsFile}") // Create an argfile with the information needed to launch // the stand alone system unit tests. //First add in all of the patch-module args we use for the //normal unit tests, copied from test.run.args testRunArgsFile.eachLine { str -> stRunArgsFile << "${str}\n" } // Now add in the working classpath elements (junit, test classes...) stRunArgsFile << "-cp \"\\\n" test.classpath.each() { elem -> def e = cygpath("${elem}") stRunArgsFile << " ${e}${File.pathSeparator}\\\n" } stRunArgsFile << "\"\n" } } test.dependsOn(sts) test.dependsOn(createTestArgfiles); // Tasks to create standalone test applications for the launcher tests def testapp1JarName = "testapp1.jar" task createTestapp1Jar1(type: Jar) { dependsOn compileTestapp1Java enabled = IS_FULL_TEST destinationDir = file("$buildDir/testapp1") archiveName = testapp1JarName includeEmptyDirs = false from project.sourceSets.testapp1.output.classesDir include("testapp/**") include("com/javafx/main/**") manifest { attributes( "Main-Class" : "com.javafx.main.Main", "JavaFX-Version" : "2.2", "JavaFX-Application-Class" : "testapp.HelloWorld", "JavaFX-Class-Path" : "jar2.jar" ) } } task createTestapp1Jar2(type: Jar) { dependsOn compileTestapp1Java enabled = IS_FULL_TEST destinationDir = file("$buildDir/testapp1") archiveName = "jar2.jar"; includeEmptyDirs = false from project.sourceSets.testapp1.output.classesDir include("pkg2/**") } def List testApp2SourceDirs = [] project.sourceSets.testapp2.java.srcDirs.each { dir -> testApp2SourceDirs += dir } compileTestapp2Java.options.compilerArgs.addAll([ '-implicit:none', '--module-source-path', testApp2SourceDirs.join(File.pathSeparator) ] ) task createTestApps() { dependsOn(createTestapp1Jar1) dependsOn(createTestapp1Jar2) dependsOn(compileTestapp2Java) } test.dependsOn(createTestApps); test { enabled = IS_FULL_TEST // Properties passed to launcher tests systemProperties 'launchertest.testapp1.jar': "build/testapp1/$testapp1JarName" systemProperties 'launchertest.testapp2.module.path': project.sourceSets.testapp2.output.classesDir // Properties passed to test.util.Util systemProperties 'worker.debug': IS_WORKER_DEBUG systemProperties 'worker.patchmodule.file': cygpath(stRunArgsFile.path) systemProperties 'worker.patch.policy': cygpath(testJavaPolicyFile.path) systemProperties 'worker.java.cmd': JAVA if (!IS_USE_ROBOT) { // Disable all robot-based visual tests exclude("test/robot/**"); } if (!IS_AWT_TEST) { // Disable all AWT-based tests exclude("**/javafx/embed/swing/*.*"); exclude("**/com/sun/javafx/application/Swing*.*"); } forkEvery = 1 } } allprojects { // The following block is a workaround for the fact that presently Gradle // can't set the -XDignore.symbol.file flag, because it appears that the // javac API is lacking support for it. So what we'll do is find any Compile // task and manually provide the options necessary to fire up the // compiler with the right settings. tasks.withType(JavaCompile) { compile -> if (compile.options.hasProperty("useAnt")) { compile.options.useAnt = true compile.options.useDepend = IS_USE_DEPEND } else if (compile.options.hasProperty("incremental")) { compile.options.incremental = IS_INCREMENTAL } compile.options.debug = true // we always generate debugging info in the class files compile.options.debugOptions.debugLevel = IS_DEBUG_JAVA ? "source,lines,vars" : "source,lines" compile.options.fork = true compile.options.forkOptions.executable = JAVAC compile.options.warnings = IS_LINT compile.options.compilerArgs += ["-XDignore.symbol.file", "-encoding", "UTF-8"] // If I am a module.... if (project.hasProperty('moduleSourcePath') && (project.hasProperty('buildModule') && project.buildModule)) { project.compileJava { options.compilerArgs.addAll([ '-implicit:none', '--module-source-path', project.moduleSourcePath ]) } // no jars needed for modules project.jar.enabled = false // and redirect the resources into the module project.processResources.destinationDir = project.moduleDir } // we use a custom javadoc command project.javadoc.enabled = false // Add in the -Xlint options if (IS_LINT) { LINT.split("[, ]").each { s -> compile.options.compilerArgs += "-Xlint:$s" } } } // tasks with javaCompile if (project.hasProperty('moduleSourcePathShim') && project.sourceSets.hasProperty('shims')) { // sync up the obvious source directories with the shims // others (like the shaders in graphics) should be added in there project.sourceSets.shims.java.srcDirs += project.sourceSets.main.java.srcDirs project.sourceSets.shims.java.srcDirs += "$buildDir/gensrc/java" project.compileShimsJava { options.compilerArgs.addAll([ '-implicit:none', '--module-source-path', project.moduleSourcePathShim ]) } project.compileShimsJava.dependsOn(project.compileJava) def copyGeneratedShimsTask = task("copyGeneratedShims", type: Copy, dependsOn: [compileShimsJava, processShimsResources]) { from project.sourceSets.shims.output.classesDir into "${rootProject.buildDir}/shims" exclude("*/module-info.class") } project.processShimsResources.dependsOn(project.processResources) // shims resources should have the main resouces as a base project.sourceSets.shims.resources.srcDirs += project.sourceSets.main.resources.srcDirs // and redirect the resources into the module project.processShimsResources.destinationDir = project.moduleShimsDir compileTestJava.dependsOn(copyGeneratedShimsTask) } if (project.hasProperty('modulePathArgs')) { project.compileJava.options.compilerArgs.addAll(modulePathArgs) } if (project.hasProperty('testModulePathArgs')) { project.compileTestJava.options.compilerArgs.addAll(testModulePathArgs) } if (project.hasProperty('testPatchModuleArgs')) { project.test.jvmArgs += testPatchModuleArgs } if (project.hasProperty('addExports')) { project.compileTestJava.options.compilerArgs.addAll(addExports); project.test.jvmArgs += addExports } if (rootProject.hasProperty("EXTRA_TEST_ARGS") && project.hasProperty('test')) { EXTRA_TEST_ARGS.split(' ').each() { e -> project.test.jvmArgs += e } } if (rootProject.hasProperty("EXTRA_COMPILE_ARGS") && project.hasProperty('compileJava')) { project.compileJava.options.compilerArgs.addAll(EXTRA_COMPILE_ARGS.split(' ')) } if (rootProject.hasProperty("EXTRA_COMPILE_ARGS") && project.hasProperty('compileTestJava')) { project.compileTestJava.options.compilerArgs.addAll(EXTRA_COMPILE_ARGS.split(' ')) } } /****************************************************************************** * * * Top Level Tasks * * * * These are the tasks which are defined only for the top level project and * * not for any sub projects. These are generally the entry point that is * * used by Hudson and by the continuous build system. * * * *****************************************************************************/ task clean() { group = "Basic" description = "Deletes the build directory and the build directory of all sub projects" getSubprojects().each { subProject -> dependsOn(subProject.getTasksByName("clean", true)); } doLast { delete(buildDir); } } task cleanAll() { group = "Basic" description = "Scrubs the repo of build artifacts" dependsOn(clean) doLast { //delete(".gradle"); This causes problems on windows. delete("buildSrc/build"); } } task createMSPfile() { group = "Build" File mspFile = new File(rootProject.buildDir,MODULESOURCEPATH) outputs.file(mspFile) doLast { mspFile.delete() mspFile << "--module-source-path\n" mspFile << defaultModuleSourcePath mspFile << "\n" } } task javadoc(type: Javadoc, dependsOn: createMSPfile) { group = "Basic" description = "Generates the JavaDoc for all the public API" executable = JAVADOC def projectsToDocument = [ project(":base"), project(":graphics"), project(":controls"), project(":media"), project(":swing"), /*project(":swt"),*/ project(":fxml"), project(":web")] source(projectsToDocument.collect({ [it.sourceSets.main.java] })); setDestinationDir(new File(buildDir, 'javadoc')); exclude("com/**/*", "Compile*", "javafx/builder/**/*", "javafx/scene/accessibility/**/*"); options.tags("moduleGraph:X") options.windowTitle("${javadocTitle}") options.header("${javadocHeader}") options.bottom("${javadocBottom}") if (BUILD_CLOSED) { options.linksOffline(JDK_DOCS, JDK_DOCS_CLOSED); } else { options.links(JDK_DOCS); } options.addBooleanOption("XDignore.symbol.file").setValue(true); options.addBooleanOption("Xdoclint:${DOC_LINT}").setValue(IS_DOC_LINT); options.addBooleanOption("javafx").setValue(true); options.addBooleanOption("use").setValue(true); options.setOptionFiles([ new File(rootProject.buildDir,MODULESOURCEPATH) ]); doLast { projectsToDocument.each { p -> copy { from "$p.projectDir/src/main/docs" into "$buildDir/javadoc" } } } dependsOn(projectsToDocument.collect { project -> project.getTasksByName("classes", true)}); } task sdk() { if (DO_BUILD_SDK_FOR_TEST) { rootProject.getTasksByName("test", true).each { t -> if (t.enabled) t.dependsOn(sdk) } } } task appsjar() { dependsOn(sdk) // Note: the jar dependencies get added elsewhere see project(":apps") } // these are empty tasks, allowing us to depend on the task, which may have other // real work items added later. task copyAppsArtifacts() { dependsOn(appsjar) } task apps() { dependsOn(sdk) dependsOn(appsjar) dependsOn(copyAppsArtifacts) } task findbugs() { dependsOn(sdk) doLast { if (!BUILD_CLOSED) { println "findbugs task is only run for a closed build" } } } // create the zip file of modules for a JDK build task jdkZip { dependsOn(sdk) } // The following tasks are for the closed build only. They are a no-op for the open build task checkCache() { dependsOn(updateCacheIfNeeded) } // TODO: consider moving the "public-sdk" portion of this task here task publicExports() { dependsOn(sdk, apps, javadoc, jdkZip) } task perf() { dependsOn(sdk, apps) doLast { if (!BUILD_CLOSED) { println "perf task is only run for a closed build" } } } task zips() { dependsOn(sdk, javadoc, apps, jdkZip, publicExports, perf) } task all() { dependsOn(sdk,publicExports,apps,perf,zips) } // Construct list of subprojects that are modules ext.moduleProjList = [] subprojects { if (project.hasProperty("buildModule") && project.ext.buildModule) { rootProject.ext.moduleProjList += project println "module: $project (buildModule=YES)" } else { println "module: $project (buildModule=NO)" } } // Define the sdk task, which also produces the javafx.swt modular jar compileTargets { t -> def javafxSwtTask = task("javafxSwt$t.capital", type: Jar) { enabled = COMPILE_SWT group = "Basic" description = "Creates the javafx-swt.jar for the $t.name target" archiveName = "${project(":swt").buildDir}/libs/javafx-swt.jar"; includeEmptyDirs = false from("${project(":swt").buildDir}/classes/main"); include("**/javafx/embed/swt/**") dependsOn( project(":swt").compileJava, project(":swt").processResources, // note: assemble and classes are not enough for DidWork project(":swt").classes, // classes is needed for a jar copy ) onlyIf { dependsOnTaskDidWork() } } // FIXME: do we really need the index task for this modular jar? def javafxSwtIndexTask = task("javafxSwtIndex$t.capital") { //the following is a workaround for the lack of indexing in gradle 1.4 through 1.7 dependsOn(javafxSwtTask) onlyIf { dependsOnTaskDidWork() } doLast() { ant.jar (update: true, index: true, destfile: javafxSwtTask.archiveName) } } def sdkTask = task("sdk$t.capital") { group = "Basic" dependsOn(javafxSwtIndexTask) } sdk.dependsOn(sdkTask) } project(":apps") { // The apps build is Ant based, we will exec ant from gradle. compileTargets { t -> List params = [] params << "-DtargetBld=$t.name" if (!rootProject.ext[t.upper].compileSwing) { params << "-DJFX_CORE_ONLY=true" } params << "-Dplatforms.JDK_1.9.home=${rootProject.ext.JDK_HOME}" params << "-Dcompile.patch=@${rootProject.buildDir}/${COMPILEARGSFILE}" params << "-Drun.patch=@${rootProject.buildDir}/${RUNARGSFILE}" def appsJar = project.task("appsJar${t.capital}") { dependsOn(sdk) doLast() { ant(t.name, projectDir.path, "appsJar", params); } } rootProject.appsjar.dependsOn(appsJar) def appsClean = project.task("clean${t.capital}") { doLast() { ant(t.name, project.projectDir.path, "clean", params); } } rootProject.clean.dependsOn(appsClean) } } /****************************************************************************** * * * Modules * * * *****************************************************************************/ ext.moduleDependencies = [file("dependencies")] task buildModules { } // Combine the classes, lib, and bin for each module compileTargets { t -> def targetProperties = project.ext[t.upper] def platformPrefix = targetProperties.platformPrefix def modularSdkDirName = "${platformPrefix}modular-sdk" def modularSdkDir = "${rootProject.buildDir}/${modularSdkDirName}" def modulesDir = "${modularSdkDir}/modules" def modulesCmdsDir = "${modularSdkDir}/modules_cmds" def modulesLibsDir = "${modularSdkDir}/modules_libs" def modulesSrcDir = "${modularSdkDir}/modules_src" def modulesConfDir = "${modularSdkDir}/modules_conf" def modulesLegalDir = "${modularSdkDir}/modules_legal" def modulesMakeDir = "${modularSdkDir}/make" final File runArgsFile = file("${rootProject.buildDir}/${RUNARGSFILE}") final File compileArgsFile = file("${rootProject.buildDir}/${COMPILEARGSFILE}") project.files(runArgsFile); def buildModulesTask = task("buildModules$t.capital", group: "Build") { // Copy dependencies/*/module-info.java.extra // merging as needed, removing duplicates // only lines with 'exports' will be copied def dependencyRoots = moduleDependencies if (rootProject.hasProperty("closedModuleDepedencies")) { dependencyRoots = [dependencyRoots, closedModuleDepedencies].flatten() } // Create the inputs/outputs list first to support UP-TO-DATE ArrayList outputNames = new ArrayList() dependencyRoots.each { root -> FileTree ft = fileTree(root).include('**/*.extra') ft.each() { e-> inputs.file(e) String usename = e.path String filePath = e.getAbsolutePath() String folderPath = root.getAbsolutePath() if (filePath.startsWith(folderPath)) { usename = filePath.substring(folderPath.length() + 1); } if (! outputNames.contains(usename) ) { outputNames.add(usename) } } } outputNames.each() { e-> File f = new File(modulesSrcDir, e) outputs.file(f) } def outputPolicyDir = "${modulesConfDir}/java.base/security" def outputPolicyFile = file("${outputPolicyDir}/java.policy.extra") outputs.file(outputPolicyFile) moduleProjList.each { project -> def policyDir = "${project.projectDir}/src/main/conf/security" def policyFile = file("${policyDir}/java.policy") if (policyFile.exists()) { inputs.file(policyFile) } } doLast { Map extras = [:] dependencyRoots.each { root -> FileTree ft = fileTree(root).include('**/*.extra') ft.each() { e-> String usename = e.path String filePath = e.getAbsolutePath() String folderPath = root.getAbsolutePath() if (filePath.startsWith(folderPath)) { usename = filePath.substring(folderPath.length() + 1); } if (extras.containsKey(usename)) { List lines = extras.get(usename) e.eachLine { line -> line = line.trim() if (line.length() > 1 && Character.isLetter(line.charAt(0))) { lines << line } } } else { List lines = [] e.eachLine { line -> line = line.trim() if (line.length() > 1 && Character.isLetter(line.charAt(0))) { lines << line } } extras.put(usename,lines) } } } extras.keySet().each() { e-> File f = new File(modulesSrcDir, e) f.getParentFile().mkdirs() f.delete() extras.get(e).unique().each() { l-> f << l f << "\n" } } // concatecate java.policy files into a single file // mkdir outputPolicyDir outputPolicyFile.delete() moduleProjList.each { project -> def policyDir = "${project.projectDir}/src/main/conf/security" def policyFile = file("${policyDir}/java.policy") if (policyFile.exists()) outputPolicyFile << policyFile.text } } } buildModules.dependsOn(buildModulesTask) moduleProjList.each { project -> // Copy classes, bin, and lib directories def moduleName = project.ext.moduleName def buildDir = project.buildDir def srcClassesDir = "${buildDir}/${platformPrefix}module-classes" def dstClassesDir = "${modulesDir}/${moduleName}" def copyClassFilesTask = project.task("copyClassFiles$t.capital", type: Copy, dependsOn: project.assemble) { from srcClassesDir into dstClassesDir exclude("module-info.class") } def srcCmdsDir = "${buildDir}/${platformPrefix}module-bin" def dstCmdsDir = "${modulesCmdsDir}/${moduleName}" def copyBinFilesTask = project.task("copyBinFiles$t.capital", type: Copy, dependsOn: copyClassFilesTask) { from srcCmdsDir into dstCmdsDir } def srcLibsDir = "${buildDir}/${platformPrefix}module-lib" def dstLibsDir = "${modulesLibsDir}/${moduleName}" def copyLibFilesTask = project.task("copyLibFiles$t.capital", type: Copy, dependsOn: copyBinFilesTask) { from srcLibsDir into dstLibsDir } // Copy module sources // FIXME: javafx.swt sources? def copySources = project.hasProperty("includeSources") && project.includeSources def copySourceFilesTask = project.task("copySourceFiles$t.capital", type: Copy, dependsOn: copyLibFilesTask) { if (copySources) { from "${project.projectDir}/src/main/java" if (project.name.equals("base")) { from "${project.projectDir}/build/gensrc/java" } if (project.name.equals("web")) { from "${project.projectDir}/src/main/java-wrappers" } } else { from "${project.projectDir}/src/main/java/module-info.java" } into "${modulesSrcDir}/${moduleName}" include "**/*.java" if (project.hasProperty("sourceFilter")) { filter(project.sourceFilter) } } // Copy .html and other files needed for doc bundles def copyDocFiles = project.task("copyDocFiles$t.capital", type: Copy, dependsOn: copySourceFilesTask) { if (copySources) { from "${project.projectDir}/src/main/java" from "${project.projectDir}/src/main/docs" into "${modulesSrcDir}/${moduleName}" exclude "**/*.java" } } // Copy make/build.properties def srcMakeDir = "${project.projectDir}/make" def dstMakeDir = "${modulesMakeDir}/${moduleName}" def copyBuildPropertiesTask = project.task("copyBuildProperties$t.capital", type: Copy, dependsOn: copyDocFiles) { from srcMakeDir into dstMakeDir } // Copy legal files def srcLegalDir = "${project.projectDir}/src/main/legal" def dstLegalDir = "${modulesLegalDir}/${moduleName}" def copyLegalTask = project.task("copyLegal$t.capital", type: Copy, dependsOn: copyBuildPropertiesTask) { from srcLegalDir into dstLegalDir // Exclude ANGLE since we (currently) do not use it exclude("angle.md") } buildModulesTask.dependsOn( copyClassFilesTask, copyLibFilesTask, copySourceFilesTask, copyDocFiles, copyBuildPropertiesTask, copyLegalTask) } def buildRunArgsTask = task("buildRunArgs$t.capital", group: "Build", dependsOn: buildModulesTask) { outputs.file(runArgsFile); doLast() { Listlibpath = [] Listmodpath = [] moduleProjList.each { project -> def moduleName = project.ext.moduleName def dstModuleDir = cygpath("${modulesDir}/${moduleName}") modpath << "${moduleName}=${dstModuleDir}" } writeRunArgsFile(runArgsFile, computeLibraryPath(true), modpath) writeRunArgsFile(compileArgsFile, null, modpath) } } buildModules.dependsOn(buildRunArgsTask) def isWindows = IS_WINDOWS && t.name == "win"; def isMac = IS_MAC && t.name == "mac"; // Create layout for modular classes moduleProjList.each { project -> def buildModuleClassesTask = project.task("buildModule$t.capital", group: "Build", type: Copy) { dependsOn(project.assemble) def buildDir = project.buildDir def sourceBuildDirs = [ "${buildDir}/classes/main/${project.moduleName}", ] def moduleClassesDir = "$buildDir/${platformPrefix}module-classes" includeEmptyDirs = false sourceBuildDirs.each { d -> from d } into moduleClassesDir // Exclude obsolete, experimental, or non-shipping code exclude("version.rc") exclude("com/sun/glass/ui/swt") exclude("com/sun/javafx/tools/ant") exclude("com/javafx/main") if (!IS_INCLUDE_NULL3D) { exclude ("com/sun/prism/null3d") } if (!IS_INCLUDE_ES2) { exclude("com/sun/prism/es2", "com/sun/scenario/effect/impl/es2") } // Exclude platform-specific classes for other platforms if (!isMac) { exclude ("com/sun/media/jfxmediaimpl/platform/osx", "com/sun/prism/es2/MacGL*", "com/sun/glass/events/mac", "com/sun/glass/ui/mac", ) } if (!isWindows) { exclude ("**/*.hlsl", "com/sun/glass/ui/win", "com/sun/prism/d3d", "com/sun/prism/es2/WinGL*", "com/sun/scenario/effect/impl/hw/d3d" ) } if (!targetProperties.includeGTK) { //usually IS_LINUX exclude ( "com/sun/glass/ui/gtk", "com/sun/prism/es2/EGL*", "com/sun/prism/es2/X11GL*" ) } if (!targetProperties.includeEGL) { exclude ("com/sun/prism/es2/EGL*") } if (!targetProperties.includeLens) { exclude ("com/sun/glass/ui/lens") } if (!targetProperties.includeMonocle) { exclude ("com/sun/glass/ui/monocle") exclude("com/sun/prism/es2/Monocle*") } if (t.name != 'ios') { exclude ("com/sun/media/jfxmediaimpl/platform/ios", "com/sun/glass/ui/ios", "com/sun/prism/es2/IOS*" ) } if (t.name != 'android' && t.name != 'dalvik') { exclude ("com/sun/glass/ui/android") } // Filter out other platform-specific classes if (targetProperties.containsKey('jfxrtJarExcludes')) { exclude(targetProperties.jfxrtJarExcludes) } /* FIXME: JIGSAW -- handle this in the module itself String webbld = project(":web").buildDir.path String ctrlbld = project(":controls").buildDir.path if (t.name == 'android') { from ("${webbld}/classes/android", "${webbld}/resources/android", "${ctrlbld}/classes/android", "${ctrlbld}/resources/android") } else if (t.name == 'ios') { from ("${webbld}/classes/ios", "${webbld}/resources/ios") } else { from ("${webbld}/classes/main", "${webbld}resources/main") } */ } buildModulesTask.dependsOn(buildModuleClassesTask) } def buildModuleLibsTask = task("buildModuleLibs$t.capital") { group = "Basic" def baseProject = project(":base"); def graphicsProject = project(":graphics"); def mediaProject = project(":media"); def webProject = project(":web"); dependsOn(webProject.assemble) def swtProject = project(":swt"); def packagerProject = project(":fxpackager"); dependsOn(packagerProject.assemble) dependsOn(packagerProject.jar) dependsOn(project(":fxpackagerservices").jar) def library = targetProperties.library def useLipo = targetProperties.containsKey('useLipo') ? targetProperties.useLipo : false def modLibDest = targetProperties.modLibDest def moduleNativeDirName = "${platformPrefix}module-$modLibDest" def buildModuleBaseTask = task("buildModuleBase$t.capital", dependsOn: baseProject.assemble) { group = "Basic" description = "creates javafx.base property files" def moduleLibDir = "${baseProject.buildDir}/${platformPrefix}module-lib" final File javafxProperties = file("${moduleLibDir}/javafx.properties") outputs.file(javafxProperties) doLast { mkdir moduleLibDir javafxProperties.delete() javafxProperties << "javafx.version=$RELEASE_VERSION_SHORT"; javafxProperties << "\n" javafxProperties << "javafx.runtime.version=$RELEASE_VERSION_LONG"; javafxProperties << "\n" javafxProperties << "javafx.runtime.build=$PROMOTED_BUILD_NUMBER"; javafxProperties << "\n" // Include any properties that have been defined (most likely in // one of the various platform gradle files) if (targetProperties.containsKey("javafxProperties")) { javafxProperties << targetProperties.javafxProperties javafxProperties << "\n" } // Embedded builds define this file as well if (targetProperties.containsKey("javafxPlatformProperties")) { final File javafxPlatformProperties = file("${moduleLibDir}/javafx.platform.properties") outputs.file(javafxPlatformProperties) javafxPlatformProperties.delete() javafxPlatformProperties << targetProperties.javafxPlatformProperties javafxPlatformProperties << "\n" } } } def buildModuleGraphicsTask = task("buildModuleGraphics$t.capital", type: Copy, dependsOn: graphicsProject.assemble) { group = "Basic" description = "copies javafx.graphics native libraries" into "${graphicsProject.buildDir}/${moduleNativeDirName}" from("${graphicsProject.buildDir}/libs/jsl-decora/${t.name}/${library(targetProperties.decora.lib)}") def libs = ['font', 'prism', 'prismSW', 'glass', 'iio'] if (IS_INCLUDE_ES2) { libs += ['prismES2']; } if (IS_COMPILE_PANGO) { libs += ['fontFreetype', 'fontPango']; } libs.each { lib -> def variants = targetProperties[lib].containsKey('variants') && !useLipo ? targetProperties[lib].variants : [null] variants.each { variant -> def variantProperties = variant ? targetProperties[lib][variant] : targetProperties[lib] from ("${graphicsProject.buildDir}/libs/$lib/$t.name/${library(variantProperties.lib)}") } } if (IS_WINDOWS) { from ("${graphicsProject.buildDir}/libs/prismD3D/${t.name}/${library(targetProperties.prismD3D.lib)}"); } } def buildModuleMediaTask = task("buildModuleMedia$t.capital", type: Copy, dependsOn: mediaProject.assemble) { group = "Basic" description = "copies javafx.media native libraries" into "${mediaProject.buildDir}/${moduleNativeDirName}" def mediaBuildType = project(":media").ext.buildType if (IS_COMPILE_MEDIA) { [ "fxplugins", "gstreamer-lite", "jfxmedia" ].each { name -> from ("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}/${library(name)}") } if (t.name == "mac") { // OSX media natives [ "jfxmedia_qtkit", "jfxmedia_avf", "glib-lite" ].each { name -> from ("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}/${library(name)}") } } else if (t.name == "linux") { from("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}") { include "libavplugin*.so" } } else from ("${mediaProject.buildDir}/native/${t.name}/${mediaBuildType}/${library("glib-lite")}") } else { if (t.name != "android" && t.name != "dalvik" ) { [ "fxplugins", "gstreamer-lite", "jfxmedia" ].each { name -> from ("$MEDIA_STUB/${library(name)}") } } if (t.name == "mac") { // copy libjfxmedia_{avf,qtkit}.dylib if they exist [ "jfxmedia_qtkit", "jfxmedia_avf", "glib-lite" ].each { name -> from ("$MEDIA_STUB/${library(name)}") } } else if (t.name == "linux") { from(MEDIA_STUB) { include "libavplugin*.so" } } else if (t.name != "android" && t.name != "dalvik" ) { from ("$MEDIA_STUB/${library("glib-lite")}") } } } def buildModuleWeb = task("buildModuleWeb$t.capital", type: Copy, dependsOn: webProject.assemble) { group = "Basic" description = "copies javafx.web native libraries" into "${webProject.buildDir}/${moduleNativeDirName}" if (IS_COMPILE_WEBKIT) { from ("${webProject.buildDir}/libs/${t.name}/${library('jfxwebkit')}") } else { if (t.name != "android" && t.name != "ios" && t.name != "dalvik") { from ("$WEB_STUB/${library('jfxwebkit')}") } } } def buildModuleSWT = task("buildModuleSWT$t.capital", type: Copy) { group = "Basic" description = "copies SWT JAR" // FIXME: the following is a hack to workaround the fact that there // is no way to deliver javafx-swt.jar other than in one of the // existing runtime modules. dependsOn(buildModuleGraphicsTask) // we copy to the graphics module if (COMPILE_SWT) { def javafxSwtIndexTask = tasks.getByName("javafxSwtIndex${t.capital}"); dependsOn(javafxSwtIndexTask) //enabled = COMPILE_SWT } // Copy javafx-swt.jar to the javafx-graphics module lib dir from "${swtProject.buildDir}/libs/javafx-swt.jar" into "${graphicsProject.buildDir}/${platformPrefix}module-lib" } def buildModulePackagerLibs = task("buildModulePackagerLibs$t.capital", type: Copy, dependsOn: [ packagerProject.assemble, project(":fxpackagerservices").assemble ]) { group = "Basic" description = "copies jdk.packager libraries" from "${packagerProject.buildDir}/libs" into "${packagerProject.buildDir}/${platformPrefix}module-lib" } def buildModulePackagerExes = task("buildModulePackagerExe$t.capital", type: Copy, dependsOn: [ packagerProject.assemble, project(":fxpackagerservices").assemble ]) { group = "Basic" description = "copies jdk.packager executable" // Copy over the javapackager executable enabled = (t.name == "win" || t.name == "linux" || t.name == "mac") from "${packagerProject.buildDir}/javapackager" into "${packagerProject.buildDir}/${platformPrefix}module-bin" } dependsOn( buildModuleBaseTask, buildModuleGraphicsTask, buildModuleMediaTask, buildModuleWeb, buildModuleSWT, buildModulePackagerLibs, buildModulePackagerExes ) } buildModulesTask.dependsOn(buildModuleLibsTask) def zipTask = project.task("buildModuleZip$t.capital", type: Zip, group: "Build", dependsOn: buildModulesTask ) { // FIXME: JIGSAW -- this should be moved to a sub-directory so we can keep the same name def jfxBundle = "${platformPrefix}javafx-exports.zip" doFirst() { file("${rootProject.buildDir}/${jfxBundle}").delete() } archiveName = jfxBundle destinationDir = file("${rootProject.buildDir}") includeEmptyDirs = false from "${modularSdkDir}" } jdkZip.dependsOn(zipTask) Task testArgFiles = task("createTestArgfiles${t.capital}") { File testRunArgsFile = new File(rootProject.buildDir, TESTRUNARGSFILE) //test (shimed) version File testCompileArgsFile = new File(rootProject.buildDir, TESTCOMPILEARGSFILE) // And a test java.policy file File testJavaPolicyFile = new File(rootProject.buildDir, TESTJAVAPOLICYFILE) // and the non-test version to go with run.args File runJavaPolicyFile = new File(rootProject.buildDir, RUNJAVAPOLICYFILE); outputs.file(testRunArgsFile) outputs.file(testCompileArgsFile) outputs.file(testJavaPolicyFile) outputs.file(runJavaPolicyFile) doLast() { rootProject.buildDir.mkdir() List projNames = [] moduleProjList.each { project -> projNames << project.name } // And the test (shimed) variation... testRunArgsFile.delete() testCompileArgsFile.delete() testJavaPolicyFile.delete() runJavaPolicyFile.delete() List modpath = [] moduleProjList.each { project -> if (project.hasProperty("moduleName") && project.buildModule) { File dir; if (project.sourceSets.hasProperty('shims')) { dir = new File(rootProject.buildDir, "shims/${project.ext.moduleName}") } else { dir = new File(rootProject.buildDir, "modular-sdk/modules/${project.ext.moduleName}") } def dstModuleDir = cygpath(dir.path) modpath << "${project.ext.moduleName}=${dstModuleDir}" String themod = dir.toURI() testJavaPolicyFile << "grant codeBase \"${themod}\" {\n" + " permission java.security.AllPermission;\n" + "};\n" dir = new File(rootProject.buildDir, "modular-sdk/modules/${project.ext.moduleName}") themod = dir.toURI() runJavaPolicyFile << "grant codeBase \"${themod}\" {\n" + " permission java.security.AllPermission;\n" + "};\n" } } writeRunArgsFile(testCompileArgsFile, null, modpath) writeRunArgsFile(testRunArgsFile, computeLibraryPath(true), modpath) } } sdk.dependsOn(testArgFiles) createTestArgfiles.dependsOn(testArgFiles) def sdkTask = tasks.getByName("sdk${t.capital}"); sdkTask.dependsOn(buildModulesTask) } sdk.dependsOn(buildModules) task checkrepo() { doLast { logger.info("checking for whitespace (open)"); exec { if (IS_WINDOWS) { commandLine 'bash', 'tools/scripts/checkWhiteSpace' } else { commandLine 'bash', 'tools/scripts/checkWhiteSpace', '-x' } } } } task checkrepoall() { doLast { logger.info("checking for all whitespace (open)"); exec { if (IS_WINDOWS) { commandLine 'bash', 'tools/scripts/checkWhiteSpace', '-a' } else { commandLine 'bash', 'tools/scripts/checkWhiteSpace', '-x', '-a' } } } } /****************************************************************************** * * * BUILD_CLOSED * * * * This next section should remain at the end of the build script. It allows * * for a "supplemental" gradle file to be used to extend the normal build * * structure. For example, this is used for passing a supplemental gradle * * file for producing official JavaFX builds. * * * *****************************************************************************/ if (BUILD_CLOSED) { apply from: supplementalBuildFile } task showFlags { } compileTargets { t -> // Every platform must define these variables def props = project.ext[t.upper]; showFlags.dependsOn( project.task("showFlags$t.upper") { doLast() { println "Properties set for $t.upper" props.each { println it } } } ) }