/* * Copyright (c) 2013, 2018, 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, etc * - Support building with no known JDK location, as long as javac, 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 } /** * Converts cygwin file paths for java executables to windows style * executable paths by changing forward slashes to back slashes and * adding the '.exe' extension. * 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 cygpathExe(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 + ".exe" } 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' // the file containing "extra" --add-exports ext.EXTRAADDEXPORTS = 'buildSrc/addExports' 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", cygpathExe("$JDK_HOME/bin/java")) defineProperty("JAVAC", cygpathExe("$JDK_HOME/bin/javac")) defineProperty("JAVADOC", cygpathExe("$JDK_HOME/bin/javadoc")) defineProperty("JMOD", cygpathExe("$JDK_HOME/bin/jmod")) defineProperty("JDK_DOCS", "https://docs.oracle.com/javase/10/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]) defineProperty("libAVRepositoryURL", "https://libav.org/releases/") defineProperty("FFmpegRepositoryURL", "https://www.ffmpeg.org/releases/") loadProperties("$projectDir/build.properties") 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) // JFX_DEPS_URL specifies the optional location of an alternate local repository defineProperty("JFX_DEPS_URL", "") // JDK_DOCS_LINK specifies the optional URL for offline javadoc linking defineProperty("JDK_DOCS_LINK", "") // 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) // BUILD_LIBAV_STUBS specifies whether to download and build libav/ffmpeg libraries defineProperty("BUILD_LIBAV_STUBS", "false") ext.IS_BUILD_LIBAV_STUBS = IS_LINUX ? Boolean.parseBoolean(BUILD_LIBAV_STUBS) : false // BUILD_WORKING_LIBAV specifies whether to build libav/ffmpeg libraries with // decoder, demuxer, etc. required to run media. Valid only if BUILD_LIBAV_STUBS is true. defineProperty("BUILD_WORKING_LIBAV", "false") ext.IS_BUILD_WORKING_LIBAV = IS_LINUX ? Boolean.parseBoolean(BUILD_WORKING_LIBAV) : false // 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", "false") 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.105.3.v20170228-0512" : IS_WINDOWS && IS_64 ? "org.eclipse.swt.win32.win32.x86_64_3.105.3.v20170228-0512" : IS_WINDOWS && !IS_64 ? "org.eclipse.swt.win32.win32.x86_3.105.3.v20170228-0512" : IS_LINUX && IS_64 ? "org.eclipse.swt.gtk.linux.x86_64_3.105.3.v20170228-0512" : IS_LINUX && !IS_64 ? "org.eclipse.swt.gtk.linux.x86_3.105.3.v20170228-0512" : "" // 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") defineProperty("MILESTONE_FCS", "false") ext.IS_MILESTONE_FCS = Boolean.parseBoolean(MILESTONE_FCS) // 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 = IS_MILESTONE_FCS ? "" : 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 = false if (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") }) } // 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(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"); // Determine whether the javafx.* modules are present in the JDK. To do this, // we will execute "java --list-modules" and search for javafx.base. // Also, check if jdk.unsupported.desktop module is present in JDK to ensure // javafx.swing do not use internal JDK classes directly. ext.HAS_JAVAFX_MODULES = false; ext.HAS_UNSUPPORTED_DESKTOP = false; def inStream2 = new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.ProcessBuilder(JAVA, "--list-modules").start().getInputStream())); try { String v; while ((v = inStream2.readLine()) != null) { v = v.trim(); if (v.startsWith("javafx.base")) ext.HAS_JAVAFX_MODULES = true; if (v.startsWith("jdk.unsupported.desktop")) ext.HAS_UNSUPPORTED_DESKTOP = true; } } finally { inStream2.close(); } // The HAS_JAVAFX_MODULES flag will be used to determine the mode for building // and running the applications and tests. // If HAS_JAVAFX_MODULES is true, then we will build / test javafx modules // for exporting to a JDK build. If HAS_JAVAFX_MODULES is false, then we will // build / test a standalone sdk for running with a JDK that does not include // the javafx modules. /** * 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 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[conf.trim().toUpperCase()] args("-Dcross.platform=$conf") if (targetProperties.containsKey('arch')) { args("-Dcross.platform.arch=${targetProperties.arch}") } } if (params != null) { params.each() { s-> args(s) } } if (IS_MILESTONE_FCS) { args('-Djfx.release.suffix=""') } args(target); } } List computeLibraryPath(boolean working) { List lp = [] if (HAS_JAVAFX_MODULES) { List modsWithNative = [ 'graphics', 'media', 'web' ] // the build/modular-sdk area def platformPrefix = "" def bundledSdkDirName = "${platformPrefix}modular-sdk" def bundledSdkDir = "${rootProject.buildDir}/${bundledSdkDirName}" def modulesLibsDir = "${bundledSdkDir}/modules_libs" modsWithNative.each() { m -> lp << cygpath("${modulesLibsDir}/javafx.${m}") } } else { def platformPrefix = "" def standaloneSdkDirName = "${platformPrefix}sdk" def standaloneSdkDir = "${rootProject.buildDir}/${standaloneSdkDirName}" def modulesLibName = IS_WINDOWS ? "bin" : "lib" def modulesLibsDir = "${standaloneSdkDir}/${modulesLibName}" lp << cygpath("${modulesLibsDir}") } return lp } // Return list with the arguments needed for --patch-module or --module-path // for the provided projects. Used with Java executables ie. tests List computePatchModuleArgs(List deps, boolean test, boolean includeJLP) { List pma = [] if (HAS_JAVAFX_MODULES) { 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}" } } } else { String mp = null deps.each { String projname -> def proj = project(projname) if (proj.hasProperty("moduleName")) { String moduleName = proj.ext.moduleName File dir; if (test && proj.sourceSets.hasProperty('shims')) { dir = file("${rootProject.buildDir}/shims/${moduleName}") } else { dir = file("${rootProject.buildDir}/sdk/lib/${moduleName}.jar") } 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 } pma += '--module-path' pma += mp String addm = null deps.each {String projname -> def proj = project(projname) if (proj.hasProperty("moduleName") && proj.buildModule) { if (addm == null) { addm = proj.moduleName } else { addm = addm + "," + proj.moduleName } } } if (addm != null) { pma += "--add-modules=${addm}" } } if (includeJLP) { pma += "-Djava.library.path=" + computeLibraryPath(true).join(File.pathSeparator) } return pma } // Return a list containing the --upgrade-module-path or --module-path // used with Javac List computeModulePathArgs(String pname, List deps, boolean test) { List mpa = HAS_JAVAFX_MODULES ? [ '--upgrade-module-path' ] : [ '--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.java.outputDir, proj.ext.moduleName); } else { dir = new File(proj.sourceSets.main.java.outputDir, 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 if (!HAS_JAVAFX_MODULES) { String addm = 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))) { if (addm == null) { addm = proj.moduleName } else { addm = addm + "," + proj.moduleName } } } if (addm != null) { mpa += "--add-modules=${addm}" } } return mpa } void writeRunArgsFile(File dest, List libpath, List modpath, List modules) { 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" } if (HAS_JAVAFX_MODULES) { modpath.each { e -> dest << "--patch-module=\"" dest << e dest << "\"\n" } } else { if (modpath.size() == 1) { dest << "--module-path=\"" dest << modpath[0] dest << "\"\n" } else { dest << "--module-path=\"\\\n" modpath.each() { e-> dest << " " dest << e dest << File.pathSeparator dest << "\\\n" } dest << " \"\n" } } if (modules != null) { dest << "--add-modules=" dest << modules.join(",") dest << "\n" } } void appendQualExports(File dest, List qualExports) { qualExports.each { exp -> dest << exp 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.java.outputDir, "${p.moduleName}") if (p.sourceSets.hasProperty('shims')) { p.ext.moduleShimsDir = new File (p.sourceSets.shims.java.outputDir, "${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(""))) { ae += line.split(' ') } } p.ext.testAddExports = ae.flatten() } // read in the temporary addExports file EXTRAADDEXPORTS) // // These extra --add-exports will be used in two places and so we // create/modify two items: // p.testAddExports - add the extra items so they are included in test builds // // p.extraAddExports - for use in any other place where we don't automatically update // for example any non modular, non 'test' compile, any compile that does not // use a module-source-path that includes the dependent modules // // Note that we don't modify the modular build (main, shims) because they use // module-info directly, and we don't want to cover up any missing items there. // if (!rootProject.hasProperty("EXTRA_ADDEXPORTS_ARGS")) { List extraAddExportsList = [] String fullae = "" File tmpaddExportsFile = new File(rootProject.projectDir, EXTRAADDEXPORTS) if (tmpaddExportsFile.exists()) { String nl = System.getProperty("line.separator") tmpaddExportsFile.eachLine { line -> line = line.trim() fullae += line + nl if (!(line.startsWith("#") || line.equals(""))) { extraAddExportsList += line.split(' ') } } } // This string is used in the creation of the build/*.args files // so we preserve comments if (!extraAddExportsList.isEmpty()) { rootProject.ext.EXTRA_ADDEXPORTS_STRING = fullae } rootProject.ext.EXTRA_ADDEXPORTS_ARGS = extraAddExportsList } if (HAS_JAVAFX_MODULES) { // use this variable, because it shows we have a non empty addition if (rootProject.hasProperty("EXTRA_ADDEXPORTS_STRING")) { p.ext.extraAddExports = EXTRA_ADDEXPORTS_ARGS.flatten() if (p.hasProperty("testAddExports")) { p.testAddExports += EXTRA_ADDEXPORTS_ARGS.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 && HAS_JAVAFX_MODULES && 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('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!") } // 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 4.8, error if < 4.3. if (gradle.gradleVersion != "4.8") { def ver = gradle.gradleVersion.split("[\\.]"); def gradleMajor = Integer.parseInt(ver[0]); def gradleMinor = Integer.parseInt(ver[1].split("[^0-9]")[0]); def err = ""; if (gradleMajor < 4 || (gradleMajor == 4 && gradleMinor < 3)) { err = "Gradle version too old: ${gradle.gradleVersion}; must be at least 4.3" } if (IS_GRADLE_VERSION_CHECK && err != "") { fail(err); } logger.warn("*****************************************************************"); logger.warn("Unsupported gradle version $gradle.gradleVersion in use."); logger.warn("Only version 4.8 is supported. Use this version at your own risk"); if ( err != "") logger.warn(err); logger.warn("*****************************************************************"); } // Look for stub runtime in bundled sdk, standalone sdk, or boot JDK def String cachedBundledRuntime = cygpath("$projectDir") + "/../caches/modular-sdk" def String cachedStandaloneRuntime = cygpath("$projectDir") + "/../caches/sdk" def String jdkStubRuntime = cygpath("$JDK_HOME") def defaultStubRuntime = "" if (file(cachedBundledRuntime).exists()) { defaultStubRuntime = cachedBundledRuntime } else if (file(cachedStandaloneRuntime).exists()) { defaultStubRuntime = cachedStandaloneRuntime } else if (BUILD_CLOSED) { defaultStubRuntime = cachedBundledRuntime } else { defaultStubRuntime = jdkStubRuntime } defineProperty("STUB_RUNTIME", defaultStubRuntime) if (STUB_RUNTIME.endsWith("/modular-sdk")) { 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) } ext.UPDATE_STUB_CACHE = (BUILD_CLOSED && STUB_RUNTIME != "" && !file(STUB_RUNTIME).isDirectory()) /****************************************************************************** * * * 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("HAS_JAVAFX_MODULES: $HAS_JAVAFX_MODULES") logger.quiet("HAS_UNSUPPORTED_DESKTOP: $HAS_UNSUPPORTED_DESKTOP") 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") logger.quiet("UPDATE_STUB_CACHE: $UPDATE_STUB_CACHE") /****************************************************************************** * * * Definition of Native Code Compilation Tasks * * * * - CCTask compiles native code. Specifically it will compile .m, .c, * * .cpp, or .cc files. It uses the headers provided by running * * 'javac -h' 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 cc, link, and "native" tasks in the given project. These * tasks are parameterized by name, so that we can produce, for example, 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 cc / link pair 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 modulePath = "${project.sourceSets.main.java.outputDir}" modulePath += File.pathSeparator + "${rootProject.projectDir}/modules/javafx.base/build/classes/java/main" def compileCompilers = project.task("compile${name}Compilers", type: JavaCompile, dependsOn: project.compileJava) { description = "Compile the $name JSL Compilers" classpath = project.files(project.sourceSets.jslc.java.outputDir) + project.configurations.antlr source = [project.file("src/main/jsl-$lowerName")] destinationDir = project.file("$project.buildDir/classes/jsl-compilers/$lowerName") options.compilerArgs.addAll([ "-implicit:none", "--module-path", modulePath, "--add-modules=javafx.graphics" ]) 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 { // Setup the repositories that we'll download libraries from. // By default we use Maven Central 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. // If JFX_DEPS_URL is set, then that overrides the default // repositories. This allows the dependencies to be cached locally. if (JFX_DEPS_URL != "") { repositories { ivy { url JFX_DEPS_URL layout "pattern", { artifact "[artifact]-[revision](-[classifier]).[ext]" artifact "[artifact].[ext]" } } } } if (JFX_DEPS_URL == "") { repositories { mavenCentral() ivy { url "http://download.eclipse.org/eclipse/updates/4.6/R-4.6.3-201703010400/plugins/" layout "pattern", { artifact "[artifact].[ext]" } } } } if (JFX_DEPS_URL == "" && IS_BUILD_LIBAV_STUBS) { repositories { ivy { url libAVRepositoryURL layout "pattern", { artifact "[artifact].[ext]" } } ivy { url FFmpegRepositoryURL layout "pattern", { artifact "[artifact].[ext]" } } } } // 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 // 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 { } } // Qualified exports needed by javafx.swing def qualExportsSwing = [ "--add-exports=java.desktop/java.awt.dnd.peer=javafx.swing", "--add-exports=java.desktop/sun.awt=javafx.swing", "--add-exports=java.desktop/sun.awt.dnd=javafx.swing", "--add-exports=java.desktop/sun.awt.image=javafx.swing", "--add-exports=java.desktop/sun.java2d=javafx.swing", "--add-exports=java.desktop/sun.swing=javafx.swing", ] // 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 } } // 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 = [ "-Xconversiontimeout", "30000", "-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.java.outputDir 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. def modulePath = "${project.sourceSets.main.java.outputDir}" modulePath += File.pathSeparator + "${rootProject.projectDir}/modules/javafx.base/build/classes/java/main" 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.java.outputDir) classpath += files("${project.projectDir}/src/jslc/resources") classpath += files("$buildDir/classes/jsl-compilers/decora") jvmArgs += "--module-path=$modulePath" jvmArgs += "--add-modules=javafx.graphics" 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.java.outputDir) 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/java/main/${moduleName}/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 { doLast { // 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/java/main/${moduleName}/javafx") jvmArgs "-Djavafx.toolkit=test.com.sun.javafx.pgstub.StubToolkit", "-DCSS_META_DATA_TEST_DIR=$cssDir" } def modulePath = "${project.sourceSets.main.java.outputDir}" modulePath += File.pathSeparator + "${rootProject.projectDir}/modules/javafx.graphics/build/classes/java/main" modulePath += File.pathSeparator + "${rootProject.projectDir}/modules/javafx.base/build/classes/java/main" processResources { doLast { def cssFiles = fileTree(dir: "$moduleDir/com/sun/javafx/scene/control/skin") cssFiles.include "**/*.css" cssFiles.each { css -> logger.info("converting CSS to BSS ${css}"); javaexec { executable = JAVA workingDir = project.projectDir jvmArgs += patchModuleArgs jvmArgs += "--module-path=$modulePath" jvmArgs += "--add-modules=javafx.graphics" main = "com.sun.javafx.css.parser.Css2Bin" args css } } } } processShimsResources.dependsOn(project.task("copyShimBss", type: Copy) { from project.moduleDir into project.moduleShimsDir include "**/*.bss" }) } project(":swing") { 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 if (!HAS_JAVAFX_MODULES) { jvmArgs += qualExportsSwing } } sourceSets.main.java.srcDirs += "$buildDir/gensrc/java" sourceSets.main.java { if (!HAS_UNSUPPORTED_DESKTOP) { exclude("com/sun/javafx/embed/swing/newimpl/**") } } task copyModuleInfo(type: Copy, description: "copy module-info file to gensrc") { from "src/main/module-info/module-info.java" into "$buildDir/gensrc/java/" filter { line-> !HAS_UNSUPPORTED_DESKTOP && line.contains('jdk.unsupported.desktop') ? null : line } } compileJava.dependsOn copyModuleInfo compileJava.options.compilerArgs.addAll(qualExportsSwing) } 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 { doLast { // 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', '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(":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 antplugin { java { compileClasspath += main.output runtimeClasspath += main.output } } 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 } // 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 (JFX_DEPS_URL == "") { 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", // Note: retain jdk.jlink qualified export for cases where the JDK does // not contain the jdk.packager module. "--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.java.outputDir}/${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 } } if (COMPILE_FXPACKAGER) { assemble.dependsOn compileLauncher; assemble.dependsOn buildJavaPackager } classes { doLast { // 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 createPackagerServicesModule(type: Jar) { if (project.hasProperty("DEBUGJDK_HOME")) { def dir = file("$DEBUGJDK_HOME/newmodules") dir.mkdirs() includeEmptyDirs = false archiveName = "jdk.packager.services.jar" destinationDir = dir from (project.file("$rootProject.buildDir/modular-sdk/modules/jdk.packager.services")) { include "**" } from (project.file("$rootProject.buildDir/../modules/jdk.packager/build/classes/java/main/jdk.packager.services")) { include "module-info.class" } } } task createPackagerModule(type: Jar) { if (project.hasProperty("DEBUGJDK_HOME")) { def dir = file("$DEBUGJDK_HOME/newmodules") dir.mkdirs() includeEmptyDirs = false archiveName = "jdk.packager.jar" destinationDir = dir from (project.file("$rootProject.buildDir/modular-sdk/modules/jdk.packager")) { include "**" } from (project.file("$rootProject.buildDir/../modules/jdk.packager/build/classes/java/main/jdk.packager")) { include "module-info.class" } } } task createRunScript() { def TEXT = "DEBUG_ARG=\"-J-Xdebug:\"\n" + "\n" + "# Argument parsing.\n" + "ARGS=()\n" + "for i in \"\$@\"; do\n" + " if [[ \"\$i\" == \${DEBUG_ARG}* ]]; then\n" + " ADDRESS=\${i:\${#DEBUG_ARG}}\n" + " DEBUG=\"-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=\${ADDRESS}\"\n" + " else\n" + " ARGS+=(\"\$i\")\n" + " fi\n" + "done\n" + "\n" + "\${JAVA_HOME}/bin/java.original --upgrade-module-path \${JAVA_HOME}/newmodules \$(IFS=\$\' \'; echo \"\${ARGS[*]}\")\n" doLast { new File("$DEBUGJDK_HOME/bin").mkdirs() def runscript = new File("$DEBUGJDK_HOME/bin/java")//.withWriter('utf-8') //{ runscript.write(TEXT) } doLast { exec { commandLine('chmod', '+x', "$DEBUGJDK_HOME/bin/java") } } } task createBuildScript() { def TEXT = "DEBUG_ARG=\"-J-Xdebug:\"\n" + "\n" + "# Argument parsing.\n" + "ARGS=()\n" + "for i in \"\$@\"; do\n" + " if [[ \"\$i\" == \${DEBUG_ARG}* ]]; then\n" + " ADDRESS=\${i:\${#DEBUG_ARG}}\n" + " DEBUG=\"-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=\${ADDRESS}\"\n" + " else\n" + " ARGS+=(\"\$i\")\n" + " fi\n" + "done\n" + "\n" + "\${JAVA_HOME}/bin/javac.original --upgrade-module-path \${JAVA_HOME}/newmodules \$(IFS=\$\' \'; echo \"\${ARGS[*]}\")\n" doLast { new File("$DEBUGJDK_HOME/bin").mkdirs() def buildscript = new File("$DEBUGJDK_HOME/bin/javac")//.withWriter('utf-8') //{ buildscript.write(TEXT) } doLast { exec { commandLine('chmod', '+x', "$DEBUGJDK_HOME/bin/javac") } } } task createDebugJDK(dependsOn: [createPackagerModule, createPackagerServicesModule, createRunScript, createBuildScript]) { def EXE = IS_WINDOWS ? ".exe" : "" doLast { copy { from SOURCEJDK_HOME into DEBUGJDK_HOME exclude("*/ant-javafx.jar") exclude("*/javapackager$EXE") exclude("*/java$EXE") exclude("*/javac$EXE") exclude("*/jdk.packager.services.jmod") } copy { from "$SOURCEJDK_HOME/bin/java$EXE" into "$DEBUGJDK_HOME/bin" rename "java$EXE", "java.original$EXE" } copy { from "$SOURCEJDK_HOME/bin/javac$EXE" into "$DEBUGJDK_HOME/bin" rename "javac$EXE", "javac.original$EXE" } copy { from "$rootProject.buildDir/modular-sdk/modules_libs/jdk.packager/ant-javafx.jar" into "$DEBUGJDK_HOME/lib" } copy { from "$rootProject.buildDir/modular-sdk/modules_cmds/jdk.packager/javapackager$EXE" into "$DEBUGJDK_HOME/bin" } copy { from "$DEBUGJDK_HOME/newmodules/jdk.packager.services.jar" into "$DEBUGJDK_HOME/jmods" } } } 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 { if (IS_BUILD_LIBAV_STUBS) { media name: "libav-9.14", ext: "tar.gz" media name: "libav-11.4", ext: "tar.gz" media name: "libav-12.1", ext: "tar.gz" media name: "ffmpeg-3.3.3", ext: "tar.gz" } } compileJava.dependsOn updateCacheIfNeeded compileJava { // generate the native headers during compile options.compilerArgs.addAll([ '-h', "${project.buildDir}/gensrc/headers" ]) } compileToolsJava { enabled = IS_COMPILE_MEDIA def modulePath = "${project.sourceSets.main.java.outputDir}" options.compilerArgs.addAll([ "--module-path=$modulePath", "--add-modules=javafx.media", '--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: [compileJava, compileToolsJava]) { 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; def modulePath = "${project.sourceSets.main.java.outputDir}" modulePath += File.pathSeparator + "${rootProject.projectDir}/modules/javafx.graphics/build/classes/java/main" modulePath += File.pathSeparator + "${rootProject.projectDir}/modules/javafx.base/build/classes/java/main" exec { commandLine("$JAVA"); args += patchModuleArgs args += [ "--module-path=$modulePath" ] args += [ "--add-modules=javafx.media" ] 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 doLast { exec { commandLine ("make", "${makeJobsFlag}", "-C", "${nativeSrcDir}/gstreamer/projects/${projectDir}/fxplugins") args("OUTPUT_DIR=${nativeOutputDir}", "BUILD_TYPE=${buildType}", "BASE_NAME=fxplugins", 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") { // Pre-defined command line arguments def cfgCMDArgs = ["sh", "configure"] def commonCfgArgs = ["--enable-shared", "--disable-debug", "--disable-static", "--disable-yasm", "--disable-doc", "--disable-programs", "--disable-everything"] def codecsCfgArgs = ["--enable-decoder=aac,mp3,mp3float,h264", "--enable-parser=aac,h264", "--enable-demuxer=aac,h264,mpegts,mpegtsraw"] def copyLibAVStubs = {String fromDir, String toDir -> FileCollection config = files("config.h") FileCollection libavcodec = files("avcodec.h", "avfft.h", "dxva2.h", "vaapi.h", "vda.h", "vdpau.h", "version.h", "xvmc.h", "old_codec_ids.h") FileCollection libavdevice = files("avdevice.h", "version.h") FileCollection libavfilter = files("avfiltergraph.h", "avfilter.h", "buffersink.h", "buffersrc.h", "version.h"); FileCollection libavformat = files("avformat.h", "avio.h", "version.h") FileCollection libavresample = files("avresample.h", "version.h") FileCollection libavutil = files("adler32.h", "blowfish.h", "error.h", "log.h", "pixfmt.h", "aes.h", "bswap.h", "eval.h", "lzo.h", "random_seed.h", "attributes.h", "buffer.h", "fifo.h", "macros.h", "rational.h", "audio_fifo.h", "channel_layout.h", "file.h", "mathematics.h", "samplefmt.h", "avassert.h", "common.h", "frame.h", "md5.h", "sha.h", "avconfig.h", "imgutils.h", "mem.h", "time.h", "avstring.h", "cpu_internal.h", "intfloat.h", "opt.h", "version.h", "avutil.h", "crc.h", "intreadwrite.h", "parseutils.h", "xtea.h", "base64.h", "dict.h", "lfg.h", "pixdesc.h", "intfloat_readwrite.h", "old_pix_fmts.h", "audioconvert.h", "cpu.h") FileCollection libavutil_x86 = files("cpu.h") // Use cpu.h from x86 instead of libavutil root if exist FileCollection libswscale = files("swscale.h", "version.h") def copyLibAVFiles = {FileCollection files, String fDir, String tDir -> File dir = file(tDir) dir.mkdirs() files.each { File file -> copy { from fDir into tDir include file.name } } } copyLibAVFiles(config, fromDir, "${toDir}/include") copyLibAVFiles(libavcodec, "${fromDir}/libavcodec", "${toDir}/include/libavcodec") copyLibAVFiles(libavdevice, "${fromDir}/libavdevice", "${toDir}/include/libavdevice") copyLibAVFiles(libavfilter, "${fromDir}/libavfilter", "${toDir}/include/libavfilter") copyLibAVFiles(libavformat, "${fromDir}/libavformat", "${toDir}/include/libavformat") copyLibAVFiles(libavresample, "${fromDir}/libavresample", "${toDir}/include/libavresample") copyLibAVFiles(libavutil, "${fromDir}/libavutil", "${toDir}/include/libavutil") copyLibAVFiles(libavutil_x86, "${fromDir}/libavutil/x86", "${toDir}/include/libavutil") copyLibAVFiles(libswscale, "${fromDir}/libswscale", "${toDir}/include/libswscale") // Copy libs FileTree libs = fileTree(dir: "${fromDir}", include: "**/*.so*") libs.each {File file -> copy { from file into "${toDir}/lib" } } } def buildLibAVStubs = task("buildLibAVStubs", dependsOn: []) { enabled = IS_BUILD_LIBAV_STUBS doLast { project.ext.libav = [:] project.ext.libav.basedir = "${buildDir}/native/linux/libav" project.ext.libav.versions = [ "9.14", "11.4", "12.1" ] project.ext.libav.versionmap = [ "9.14" : "54", "11.4" : "56", "12.1" : "57" ] libav.versions.each { version -> def libavDir = "${libav.basedir}/libav-${version}" for (File f : configurations.media.files) { if (f.name.startsWith("libav-${version}")) { File dir = file(libavDir) dir.mkdirs() def libavTar = "${libav.basedir}/libav-${version}.tar" ant.gunzip(src: f, dest: libavTar) ant.untar(src: libavTar, dest: libav.basedir) } } } libav.versions.each { version -> def libavDir = "${libav.basedir}/libav-${version}" File dir = file(libavDir) if (dir.exists()) { def configFile = "${libav.basedir}/libav-${version}/config.h" File cfgFile = file(configFile) if (!cfgFile.exists()) { // Add execute permissions to version.sh, otherwise build fails exec { workingDir("$libavDir") commandLine("chmod", "+x", "version.sh") } exec { workingDir("$libavDir") if (IS_BUILD_WORKING_LIBAV) { commandLine(cfgCMDArgs + commonCfgArgs + codecsCfgArgs) } else { commandLine(cfgCMDArgs + commonCfgArgs) } } } exec { workingDir("$libavDir") commandLine("make") } } } libav.versions.each { version -> def fromDir = "${libav.basedir}/libav-${version}" def majorVersion = libav.versionmap[version] def toDir = "${libav.basedir}/libav-${majorVersion}" copyLibAVStubs(fromDir, toDir) } } } def buildLibAVFFmpegStubs = task("buildLibAVFFmpegStubs", dependsOn: []) { enabled = IS_BUILD_LIBAV_STUBS def extraCfgArgs = ["--build-suffix=-ffmpeg"] doLast { project.ext.libav = [:] project.ext.libav.basedir = "${buildDir}/native/linux/libavffmpeg" project.ext.libav.versions = [ "11.4" ] project.ext.libav.versionmap = [ "11.4" : "56" ] libav.versions.each { version -> def libavDir = "${libav.basedir}/libav-${version}" for (File f : configurations.media.files) { if (f.name.startsWith("libav-${version}")) { File dir = file(libavDir) dir.mkdirs() def libavTar = "${libav.basedir}/libav-${version}.tar" ant.gunzip(src: f, dest: libavTar) ant.untar(src: libavTar, dest: libav.basedir) } } } libav.versions.each { version -> def libavDir = "${libav.basedir}/libav-${version}" File dir = file(libavDir) if (dir.exists()) { def configFile = "${libav.basedir}/libav-${version}/config.h" File cfgFile = file(configFile) if (!cfgFile.exists()) { // Patch *.v files, so we have *_FFMPEG_$MAJOR instead of *_$MAJOR, otherwise library will not be loaded FileTree vfiles = fileTree(dir: "${libavDir}", include: "**/*.v") vfiles.each {File file -> String data = file.getText("UTF-8") data = data.replace("_\$MAJOR", "_FFMPEG_\$MAJOR") file.write(data, "UTF-8") } // Add execute permissions to version.sh, otherwise build fails exec { workingDir("$libavDir") commandLine("chmod", "+x", "version.sh") } exec { workingDir("$libavDir") if (IS_BUILD_WORKING_LIBAV) { commandLine(cfgCMDArgs + commonCfgArgs + codecsCfgArgs + extraCfgArgs) } else { commandLine(cfgCMDArgs + commonCfgArgs + extraCfgArgs) } } } exec { workingDir("$libavDir") commandLine("make") } } } libav.versions.each { version -> def fromDir = "${libav.basedir}/libav-${version}" def majorVersion = libav.versionmap[version] def toDir = "${libav.basedir}/libav-${majorVersion}" copyLibAVStubs(fromDir, toDir) // Special case to copy *-ffmpeg.so to *.so FileTree libs = fileTree(dir: "${fromDir}", include: "**/*-ffmpeg.so") libs.each {File file -> copy { from file into "${toDir}/lib" rename { String fileName -> fileName.replace("-ffmpeg", "") } } } } } } def buildFFmpegStubs = task("buildFFmpegStubs", dependsOn: []) { enabled = IS_BUILD_LIBAV_STUBS doLast { project.ext.libav = [:] project.ext.libav.basedir = "${buildDir}/native/linux/ffmpeg" project.ext.libav.versions = [ "3.3.3" ] project.ext.libav.versionmap = [ "3.3.3" : "57" ] libav.versions.each { version -> def libavDir = "${libav.basedir}/ffmpeg-${version}" for (File f : configurations.media.files) { if (f.name.startsWith("ffmpeg-${version}")) { File dir = file(libavDir) dir.mkdirs() def libavTar = "${libav.basedir}/ffmpeg-${version}.tar" ant.gunzip(src: f, dest: libavTar) ant.untar(src: libavTar, dest: libav.basedir) } } } libav.versions.each { version -> def libavDir = "${libav.basedir}/ffmpeg-${version}" File dir = file(libavDir) if (dir.exists()) { def configFile = "${libav.basedir}/ffmpeg-${version}/config.h" File cfgFile = file(configFile) if (!cfgFile.exists()) { // Add execute permissions to version.sh, otherwise build fails exec { workingDir("$libavDir") commandLine("chmod", "+x", "version.sh") } exec { workingDir("$libavDir") if (IS_BUILD_WORKING_LIBAV) { commandLine(cfgCMDArgs + commonCfgArgs + codecsCfgArgs) } else { commandLine(cfgCMDArgs + commonCfgArgs) } } } exec { workingDir("$libavDir") commandLine("make") } } } libav.versions.each { version -> def fromDir = "${libav.basedir}/ffmpeg-${version}" def majorVersion = libav.versionmap[version] def toDir = "${libav.basedir}/ffmpeg-${majorVersion}" copyLibAVStubs(fromDir, toDir) } } } def buildAVPlugin = task( "buildAVPlugin", dependsOn: [buildPlugins, buildLibAVStubs, buildLibAVFFmpegStubs, buildFFmpegStubs]) { enabled = IS_COMPILE_MEDIA doLast { if (IS_BUILD_LIBAV_STUBS) { project.ext.libav = [:] project.ext.libav.basedir = "${buildDir}/native/linux/libav/libav" project.ext.libav.versions = [ "53", "54", "55", "56", "57" ] project.ext.libav.libavffmpeg = [:] project.ext.libav.libavffmpeg.basedir = "${buildDir}/native/linux/libavffmpeg/libav" project.ext.libav.libavffmpeg.versions = [ "56" ] project.ext.libav.ffmpeg = [:] project.ext.libav.ffmpeg.basedir = "${buildDir}/native/linux/ffmpeg/ffmpeg" project.ext.libav.ffmpeg.versions = [ "57" ] 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.libavffmpeg.versions.each { version -> def libavDir = "${project.ext.libav.libavffmpeg.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") } } } 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") { doLast { 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" ]) } } // Copy these to a common location in the moduleSourcePath def copyWrappers = project.task("copyPreGeneratedWrappers", type: Copy) { from "src/main/native/Source/WebCore/bindings/java/dom3/java" into "${gensrcDir}" } compileJava.dependsOn(copyWrappers); test { doFirst { if (!IS_COMPILE_WEBKIT) { println "*****************************************************" println "WARNING: running web tests without building webkit." println "The webkit native library will be copied from the JDK," println "which might lead to failures in some web tests." println "To avoid these failures, you should either build" println "webkit locally, copy the native webkit library from a" println "recent build, or skip execution of web test cases with" println "'-x :web:test'" println "*****************************************************" } } // 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" } task compileJavaDOMBinding() compileTargets { t -> def targetProperties = project.rootProject.ext[t.upper] def webkitProperties = targetProperties.webkit def classifier = (t.name != "linux" && t.name != "win") ? t.name : IS_64 ? "${t.name}-amd64" : "${t.name}-i586" def webkitOutputDir = cygpath("$buildDir/${t.name}") def webkitConfig = IS_DEBUG_NATIVE ? "Debug" : "Release" File nativeBuildDir = new File("${webkitOutputDir}") nativeBuildDir.mkdirs() def compileNativeTask = task("compileNative${t.capital}", dependsOn: [compileJava]) { println "Building Webkit configuration /$webkitConfig/ into $webkitOutputDir" enabled = (IS_COMPILE_WEBKIT) doLast { exec { workingDir("$webkitOutputDir") commandLine("perl", "$projectDir/src/main/native/Tools/Scripts/set-webkit-configuration", "--$webkitConfig") environment(["WEBKIT_OUTPUTDIR" : webkitOutputDir]) } exec { workingDir("$webkitOutputDir") 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") // To enable ninja build on Windows environment(WINDOWS_NATIVE_COMPILE_ENVIRONMENT + ['CC' : 'cl', 'CXX' : 'cl']) } else if (t.name == "mac") { cmakeArgs = "-DCMAKE_OSX_DEPLOYMENT_TARGET=$MACOSX_MIN_VERSION -DCMAKE_OSX_SYSROOT=$MACOSX_SDK_PATH" } else if (t.name == "linux") { cmakeArgs = "-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_C_COMPILER=${webkitProperties.compiler}" if (IS_64) { cmakeArgs = "$cmakeArgs -DCMAKE_SYSTEM_PROCESSOR=x86_64" } else { cmakeArgs = "$cmakeArgs -DCMAKE_SYSTEM_PROCESSOR=i586" } // TODO: Use cflags and ldflags from all platforms def cFlags = webkitProperties.ccFlags?.join(' ') ?: '' def lFlags = webkitProperties.linkFlags?.join(' ') ?: '' // -shared flag should be omitted while creating executable. def exeFlags = webkitProperties.linkFlags?.join(' ')?.replace('-shared', '') ?: '' cmakeArgs = "$cmakeArgs -DCMAKE_C_FLAGS='${cFlags}' -DCMAKE_CXX_FLAGS='${cFlags}'" cmakeArgs = "$cmakeArgs -DCMAKE_SHARED_LINKER_FLAGS='${lFlags}' -DCMAKE_EXE_LINKER_FLAGS='${exeFlags}'" } 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, "PYTHONDONTWRITEBYTECODE" : "1", ]) def targetCpuBitDepthSwitch = "" if (IS_64) { targetCpuBitDepthSwitch = "--64-bit" } else { targetCpuBitDepthSwitch = "--32-bit" } cmakeArgs += " -DJAVAFX_RELEASE_VERSION=${jfxReleaseMajorVersion}" commandLine("perl", "$projectDir/src/main/native/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 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 compileJavaDOMBindingTask = task("compileJavaDOMBinding${t.capital}", type: JavaCompile, dependsOn: [compileJava, compileNativeTask, copyNativeTask]) { destinationDir = file("$buildDir/classes/java/main") classpath = configurations.compile source = project.sourceSets.main.java.srcDirs options.compilerArgs.addAll([ '-implicit:none', '--module-source-path', defaultModuleSourcePath ]) } compileJavaDOMBinding.dependsOn compileJavaDOMBindingTask if (!targetProperties.compileWebnodeNative) { println("Not compiling native Webkit for ${t.name} per configuration request"); compileNativeTask.enabled = false } } def drtClasses = "**/com/sun/javafx/webkit/drt/**" task drtJar(type: Jar, dependsOn: compileJava) { archiveName = "drt.jar" destinationDir = file("$buildDir/test") from "$buildDir/classes/java/main/javafx.web/" include drtClasses includeEmptyDirs = false } if (IS_COMPILE_WEBKIT) { assemble.dependsOn compileJavaDOMBinding, 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 // Modular applications testapp2 testapp3 testapp4 testapp5 testapp6 } 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 } def dependentProjects = [ 'base', 'graphics', 'controls', 'media', 'web', 'swing', 'fxml' ] commonModuleSetup(project, dependentProjects) 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 if (project.hasProperty('testModulePathArgs')) { compileTestapp1Java.options.compilerArgs.addAll(testModulePathArgs) } dependentProjects.each { e -> compileTestapp1Java.dependsOn(rootProject.project(e).testClasses) } 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.java.outputDir 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.java.outputDir include("pkg2/**") } task createTestApps() { dependsOn(createTestapp1Jar1) dependsOn(createTestapp1Jar2) } test.dependsOn(createTestApps); def modtestapps = [ "testapp2", "testapp3", "testapp4", "testapp5", "testapp6" ] modtestapps.each { testapp -> def testappCapital = testapp.capitalize() def copyTestAppTask = task("copy${testappCapital}", type: Copy) { from project.sourceSets."${testapp}".java.outputDir from project.sourceSets."${testapp}".output.resourcesDir into "${project.buildDir}/modules/${testapp}" } def List testAppSourceDirs = [] project.sourceSets."${testapp}".java.srcDirs.each { dir -> testAppSourceDirs += dir } def testappCompileTasks = project.getTasksByName("compile${testappCapital}Java", true); def testappResourceTasks = project.getTasksByName("process${testappCapital}Resources", true); testappCompileTasks.each { appCompileTask -> appCompileTask.options.compilerArgs.addAll([ '-implicit:none', '--module-source-path', testAppSourceDirs.join(File.pathSeparator), ] ) if (project.hasProperty('testModulePathArgs')) { appCompileTask.options.compilerArgs.addAll(testModulePathArgs) } dependentProjects.each { e -> appCompileTask.dependsOn(rootProject.project(e).testClasses) } copyTestAppTask.dependsOn(appCompileTask) } testappResourceTasks.each { appResourceTask -> copyTestAppTask.dependsOn(appResourceTask) } createTestApps.dependsOn(copyTestAppTask) } test { enabled = IS_FULL_TEST // Parse testPatchModuleArgs looking for "--module-path". // Save path if found so we can pass it to the module launcher tests def pendingModulePath = false testPatchModuleArgs.each { str -> if (pendingModulePath) { project.ext.launcherModulePath = str; pendingModulePath = false } else if (str == "--module-path") { pendingModulePath = true } } // Properties passed to launcher tests systemProperty "launchertest.testapp1.jar", "build/testapp1/$testapp1JarName" modtestapps.each { testapp -> systemProperty "launchertest.${testapp}.module.path", "${project.buildDir}/modules/${testapp}" } // Properties passed to test.util.Util systemProperties 'worker.debug': IS_WORKER_DEBUG systemProperties 'worker.patchmodule.file': cygpath(stRunArgsFile.path) if (project.hasProperty("launcherModulePath")) { systemProperties 'worker.module.path': launcherModulePath } 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_UNSTABLE_TEST) { // JDK-8196607 Don't run monocle test cases exclude("test/robot/com/sun/glass/ui/monocle/**"); } if (!IS_AWT_TEST) { // Disable all AWT-based tests exclude("**/javafx/embed/swing/*.*"); exclude("**/com/sun/javafx/application/Swing*.*"); } if (!HAS_JAVAFX_MODULES) { jvmArgs += qualExportsSwing } 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"] // 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 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 } 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.java.outputDir into "${rootProject.buildDir}/shims" if (HAS_JAVAFX_MODULES) { 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 } /* Note: we should not have to add extraAddExports to the normal * modular compile, as it contains all of the module-info files. * In fact doing so might cover up a module-info issue. * so we don't do it, and I will leave this commented out * block as a reminder of this fact. if (project.hasProperty('extraAddExports')) { project.compileJava.options.compilerArgs.addAll(extraAddExports); } */ if (project.hasProperty('testAddExports')) { project.compileTestJava.options.compilerArgs.addAll(testAddExports); project.test.jvmArgs += testAddExports } 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" if (!HAS_JAVAFX_MODULES) { appendQualExports(mspFile, qualExportsSwing) } } } 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("apiNote:a:API Note:") options.tags("implSpec:a:Implementation Requirements:") options.tags("implNote:a:Implementation Note:") options.tags("param") options.tags("return") options.tags("throws") options.tags("moduleGraph:X") options.tags("since") options.tags("version") options.tags("serialData") options.tags("factory") options.tags("see") options.windowTitle("${javadocTitle}") options.header("${javadocHeader}") options.bottom("${javadocBottom}") options.locale("en"); if (JDK_DOCS_LINK != "") { options.linksOffline(JDK_DOCS, JDK_DOCS_LINK); } else { options.links(JDK_DOCS); } options.addBooleanOption("XDignore.symbol.file").setValue(true); options.addBooleanOption("Xdoclint:${DOC_LINT}").setValue(IS_DOC_LINT); options.addBooleanOption("html5").setValue(true); 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") { include "**/*.html" filter { line-> line = line.replace("@FXVERSION@", RELEASE_VERSION) } } from("$p.projectDir/src/main/docs") { exclude "**/*.html" } 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 jmods() { dependsOn(sdk) // real work items added later. } 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) } task publicExports() { dependsOn(sdk, jmods, apps, javadoc, jdkZip) // note the real work is below in the compileTargets } task perf() { dependsOn(sdk, apps) doLast { if (!BUILD_CLOSED) { println "perf task is only run for a closed build" } } } task zips() { dependsOn(sdk, jmods, javadoc, apps, jdkZip, publicExports, perf) // note the real work is below in the compileTargets } 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/java/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 ) } // 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) 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. // Download the Lucene libraries needed for the Ensemble8 app getConfigurations().create("lucene"); dependencies { lucene group: "org.apache.lucene", name: "lucene-core", version: "7.1.0" lucene group: "org.apache.lucene", name: "lucene-grouping", version: "7.1.0" lucene group: "org.apache.lucene", name: "lucene-queryparser", version: "7.1.0" } // Copy Lucene libraries into the Ensemble8/lib directory File ensembleLibDir = rootProject.file("apps/samples/Ensemble8/lib"); def libNames = [ "lucene-core-7.1.0.jar", "lucene-grouping-7.1.0.jar", "lucene-queryparser-7.1.0.jar" ] task getLucene(type: Copy) { doFirst { ensembleLibDir.mkdirs(); } into ensembleLibDir includeEmptyDirs = false configurations.lucene.files.each { f -> libNames.each { name -> if (name == f.getName()) { from f.getPath() } } } } 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, getLucene) 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); delete(ensembleLibDir); } } rootProject.clean.dependsOn(appsClean) } } // Tasks to create the disk layout for the sdk, jmods, and docs // in the artifacts directory (publicExports), and zip them up in // artifacts/bundles (zips) // These tasks are only used for the standalone SDK. compileTargets { t -> if (!HAS_JAVAFX_MODULES) { def targetProperties = rootProject.ext[t.upper] def platformPrefix = targetProperties.platformPrefix def artifactsDir = "${rootProject.buildDir}/artifacts" def bundlesDir = "${artifactsDir}/bundles" def sdkDirName = "${platformPrefix}sdk" def sdkDir = "${rootProject.buildDir}/${sdkDirName}" def sdkBundleName = "javafx-sdk-${RELEASE_VERSION}" def sdkArtifactsDir = "${artifactsDir}/${sdkBundleName}" def docsDirName = "javadoc" def docsDir = "${rootProject.buildDir}/${docsDirName}" def docsBundleName = "javafx-docs-${RELEASE_VERSION}" def docsArtifactsDir = "${artifactsDir}/${docsBundleName}" def jmodsDirName = "jmods" def jmodsDir = "${rootProject.buildDir}/${jmodsDirName}" def jmodsBundleName = "javafx-jmods-${RELEASE_VERSION}" def jmodsArtifactsDir = "${artifactsDir}/${jmodsBundleName}" def publicExportsTask = task ("publicExportsStandalone${t.capital}") { group = "Basic" description = "Creates the disk layout for sdk, jmods, and docs" } publicExports.dependsOn(publicExportsTask) def copyArtifactsSdkTask = task("copyArtifactsSdk$t.capital", type: Copy, dependsOn: [sdk,jmods,apps,javadoc]) { from sdkDir into sdkArtifactsDir } publicExportsTask.dependsOn(copyArtifactsSdkTask) // Need to modify file permissions Windows to make sure that the // execute bit is set, and that the files are world readable def chmodArtifactsSdkTask = task("chmodArtifactsSdk$t.capital", dependsOn: copyArtifactsSdkTask) { if (IS_WINDOWS) { doLast { exec { workingDir(sdkArtifactsDir) commandLine("chmod", "-R", "755", ".") } } } } publicExportsTask.dependsOn(chmodArtifactsSdkTask) def copyArtifactsDocsTask = task("copyArtifactsDocs$t.capital", type: Copy, dependsOn: chmodArtifactsSdkTask) { from docsDir into "${docsArtifactsDir}/api" } publicExportsTask.dependsOn(copyArtifactsDocsTask) def copyArtifactsJmodsTask = task("copyArtifactsJmods$t.capital", type: Copy, dependsOn: copyArtifactsDocsTask) { from jmodsDir into "${jmodsArtifactsDir}" } publicExportsTask.dependsOn(copyArtifactsJmodsTask) def zipsTask = task ("zipsStandalone${t.capital}") { group = "Basic" description = "Creates the public zip bundles" } zips.dependsOn(zipsTask) // Use native zip tool so that file permissions are preserved on Windows def zipSdkTask = task("zipSdk$t.capital", dependsOn: publicExportsTask) { doLast { def outZipFile = "${bundlesDir}/${sdkBundleName}.zip" mkdir bundlesDir exec { workingDir(artifactsDir) commandLine("zip", "-q", "-r", outZipFile, sdkBundleName) } } } zipsTask.dependsOn(zipSdkTask) def zipDocsTask = task("zipDocs$t.capital", type: Zip, dependsOn: zipSdkTask) { destinationDir = file("${bundlesDir}") archiveName = "${docsBundleName}.zip" includeEmptyDirs = false from docsArtifactsDir into "${docsBundleName}" } zipsTask.dependsOn(zipDocsTask) def zipJmodsTask = task("zipJmods$t.capital", type: Zip, dependsOn: zipDocsTask) { destinationDir = file("${bundlesDir}") archiveName = "${jmodsBundleName}.zip" includeEmptyDirs = false from jmodsArtifactsDir into "${jmodsBundleName}" } zipsTask.dependsOn(zipJmodsTask) } } /****************************************************************************** * * * 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 bundledSdkDirName = "${platformPrefix}modular-sdk" def bundledSdkDir = "${rootProject.buildDir}/${bundledSdkDirName}" def modulesDir = "${bundledSdkDir}/modules" def modulesCmdsDir = "${bundledSdkDir}/modules_cmds" def modulesLibsDir = "${bundledSdkDir}/modules_libs" def modulesSrcDir = "${bundledSdkDir}/modules_src" def modulesConfDir = "${bundledSdkDir}/modules_conf" def modulesLegalDir = "${bundledSdkDir}/modules_legal" def modulesMakeDir = "${bundledSdkDir}/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") { // BUNDLED SDK // 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) // BUNDLED SDK 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") || project.name.equals("swing")) { from "${project.projectDir}/build/gensrc/java" } if (project.name.equals("web")) { from "${project.projectDir}/src/main/native/Source/WebCore/bindings/java/dom3/java" } } else { from "${project.projectDir}/src/main/java/module-info.java" } into "${modulesSrcDir}/${moduleName}" include "**/*.java" if (!HAS_UNSUPPORTED_DESKTOP) { exclude("com/sun/javafx/embed/swing/newimpl/**") } 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/docs") { include "**/*.html" filter { line-> line = line.replace("@FXVERSION@", RELEASE_VERSION) } } from("${project.projectDir}/src/main/docs") { exclude "**/*.html" } from("${project.projectDir}/src/main/java") { exclude "**/*.java" } into "${modulesSrcDir}/${moduleName}" } } // 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 standaloneSdkDirName = "${platformPrefix}sdk" def standaloneSdkDir = "${rootProject.buildDir}/${standaloneSdkDirName}" def standaloneLibDir = "${standaloneSdkDir}/lib" def libDest=targetProperties.libDest def standaloneNativeDir = "${standaloneSdkDir}/${libDest}" def standaloneLegalDir = "${standaloneSdkDir}/legal" def standaloneSrcZipName = "src.zip" // STANDALONE SDK moduleProjList.each { project -> // Copy classes, bin, and lib directories def moduleName = project.ext.moduleName def buildDir = project.buildDir // Create modular jars def srcClassesDir = "${buildDir}/${platformPrefix}module-classes" def dstModularJarDir = "${standaloneLibDir}" def modularJarName = "${moduleName}.jar" def modularJarTask = project.task("modularJarStandalone$t.capital", type: Jar, dependsOn: project.assemble) { destinationDir = file("${dstModularJarDir}") archiveName = modularJarName includeEmptyDirs = false from srcClassesDir } // Copy native libraries def srcNativeDir = "${buildDir}/${platformPrefix}module-lib" def dstNativeDir = "${standaloneNativeDir}" def copyNativeFilesTask = project.task("copyNativeFilesStandalone$t.capital", type: Copy, dependsOn: modularJarTask) { from srcNativeDir into dstNativeDir include("*.dll") } // Copy other lib files def srcLibsDir = "${buildDir}/${platformPrefix}module-lib" def dstLibsDir = "${standaloneLibDir}" def copyLibFilesTask = project.task("copyLibFilesStandalone$t.capital", type: Copy, dependsOn: copyNativeFilesTask) { from srcLibsDir into dstLibsDir exclude("*.dll") } // Copy legal files def licenseFiles = [ "ADDITIONAL_LICENSE_INFO", "ASSEMBLY_EXCEPTION", "LICENSE" ] def srcLegalDir = "${project.projectDir}/src/main/legal" def dstLegalDir = "${standaloneLegalDir}/${moduleName}" def copyLegalTask = project.task("copyLegalStandalone$t.capital", type: Copy, dependsOn: copyLibFilesTask) { def rtDir = rootProject.file('.') licenseFiles.each { lFile -> from "${rtDir}/${lFile}" } from srcLegalDir into dstLegalDir // Exclude ANGLE since we (currently) do not use it exclude("angle.md") } buildModulesTask.dependsOn( modularJarTask, copyNativeFilesTask, copyLibFilesTask, copyLegalTask) } // Zip module sources for standalone SDK // // NOTE: the input is taken from the modular-sdk/modules_src dir // so that we don't have to duplicate the logic and create another // temporary directory. This is somewhat inelegant, since the bundled sdk // and the standalone sdk should be independent of one another, but seems // better than the alternatives. def zipSourceFilesTask = project.task("zipSourceFilesStandalone$t.capital", type: Zip, dependsOn: buildModulesTask) { destinationDir = file("${standaloneLibDir}") archiveName = standaloneSrcZipName includeEmptyDirs = false from modulesSrcDir include "**/*.java" } buildModules.dependsOn(zipSourceFilesTask) // ============================================================ def buildRunArgsTask = task("buildRunArgs$t.capital", group: "Build", dependsOn: buildModulesTask) { outputs.file(runArgsFile); inputs.file(EXTRAADDEXPORTS); doLast() { Listmodpath = [] Listmodnames = [] moduleProjList.each { project -> def moduleName = project.ext.moduleName def dstModuleDir = cygpath("${modulesDir}/${moduleName}") if (HAS_JAVAFX_MODULES) { modpath << "${moduleName}=${dstModuleDir}" } else { modnames << moduleName } } if (HAS_JAVAFX_MODULES) { writeRunArgsFile(runArgsFile, computeLibraryPath(true), modpath, null) writeRunArgsFile(compileArgsFile, null, modpath, null) if (rootProject.hasProperty("EXTRA_ADDEXPORTS_STRING")) { runArgsFile << EXTRA_ADDEXPORTS_STRING compileArgsFile << EXTRA_ADDEXPORTS_STRING } } else { modpath = [ cygpath("${standaloneLibDir}") ] writeRunArgsFile(runArgsFile, null, modpath, modnames) writeRunArgsFile(compileArgsFile, null, modpath, modnames) } } } 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/java/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") exclude("com/sun/javafx/webkit/drt") 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.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/java/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) if (targetProperties.containsKey("javafxPlatformProperties")) { final File javafxPlatformProperties = file("${moduleLibDir}/javafx.platform.properties") outputs.file(javafxPlatformProperties) } 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") 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)}"); targetProperties.VS2017DLLs.each { vslib -> from ("$vslib"); } targetProperties.WinSDKDLLs.each { winsdklib -> from ("$winsdklib"); } } } 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 "${bundledSdkDir}" } 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) inputs.file(EXTRAADDEXPORTS); 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 = [] if (HAS_JAVAFX_MODULES) { 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, null) writeRunArgsFile(testRunArgsFile, computeLibraryPath(true), modpath, null) if (rootProject.hasProperty("EXTRA_ADDEXPORTS_STRING")) { testCompileArgsFile << EXTRA_ADDEXPORTS_STRING testRunArgsFile << EXTRA_ADDEXPORTS_STRING } } else { def modnames = [] moduleProjList.each { project -> if (project.hasProperty("moduleName") && project.buildModule) { modnames << project.ext.moduleName File dir; if (project.sourceSets.hasProperty('shims')) { dir = new File(rootProject.buildDir, "shims/${project.ext.moduleName}") } else { dir = new File(rootProject.buildDir, "sdk/lib/${project.ext.moduleName}.jar") } def dstModuleDir = cygpath(dir.path) modpath << "${dstModuleDir}" String themod = dir.toURI() testJavaPolicyFile << "grant codeBase \"${themod}\" {\n" + " permission java.security.AllPermission;\n" + "};\n" dir = new File(rootProject.buildDir, "sdk/lib/${project.ext.moduleName}.jar") themod = dir.toURI() runJavaPolicyFile << "grant codeBase \"${themod}\" {\n" + " permission java.security.AllPermission;\n" + "};\n" } } writeRunArgsFile(testCompileArgsFile, null, modpath, modnames) writeRunArgsFile(testRunArgsFile, computeLibraryPath(true), modpath, modnames) appendQualExports(testCompileArgsFile, qualExportsSwing) appendQualExports(testRunArgsFile, qualExportsSwing) } } } sdk.dependsOn(testArgFiles) createTestArgfiles.dependsOn(testArgFiles) def sdkTask = tasks.getByName("sdk${t.capital}"); sdkTask.dependsOn(buildModulesTask) } sdk.dependsOn(buildModules) // Build the jmod for each module for the standalone SDK only. compileTargets { t -> if (!HAS_JAVAFX_MODULES) { def targetProperties = project.ext[t.upper] def platformPrefix = targetProperties.platformPrefix def jmodsDirName = "${platformPrefix}jmods" def jmodsDir = "${rootProject.buildDir}/${jmodsDirName}" def standaloneSdkDirName = "${platformPrefix}sdk" def standaloneSdkDir = "${rootProject.buildDir}/${standaloneSdkDirName}" def standaloneLegalDir = "${standaloneSdkDir}/legal" moduleProjList.each { project -> def moduleName = project.ext.moduleName def buildDir = project.buildDir def srcClassesDir = "${buildDir}/${platformPrefix}module-classes" def srcLibDir = "${buildDir}/${platformPrefix}module-lib" def srcLegalDir = "${standaloneLegalDir}/${moduleName}" def jmodName = "${moduleName}.jmod" def jmodFile = "${jmodsDir}/${jmodName}" def jmodTask = project.task("jmod$t.capital", group: "Build", dependsOn: sdk) { doLast { mkdir jmodsDir delete(jmodFile); exec { commandLine(JMOD) args("create") args("--class-path") args(srcClassesDir) // Not all modules have a "lib" dir if (file(srcLibDir).isDirectory()) { args("--libs") args(srcLibDir) } args("--legal-notices") args(srcLegalDir) args(jmodFile) } } } jmods.dependsOn(jmodTask) } } } 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 } } } ) }