...
- Cygwin. Some packages to make sure are installed are:
- openssh
- bison
- flex
- g++
- gperf
- make
- makedepend
- mercurial
- perl
- zip
- unzip
- DirectX SDK June 2010. Microsoft DirectX SDK (June 2010) headers are required for building the JavaFX SDK. This DirectX SDK can be downloaded from Microsoft DirectX SDK (June 2010). If the link above becomes obsolete, the SDK can be found from the Microsoft Download Site (search with "DirectX SDK June 2010"). The location of this SDK will normally be set with the environment variable DXSDK_DIR at installation time. The default location is normally "C:/Program Files/Microsoft DirectX SDK (June 2010)/". If DXSDK_DIR is not set, the build process may look for it in the default location or "C:/DXSDK/".
- Microsoft Visual Studio 10 SP1 (express edition works). The compiler and other tools are expected to reside in the location defined by the variableVS100COMNTOOLS which is set by the Microsoft Visual Studio installer.
...
Before diving directly into building OpenJFX, lets get our feet wet by learning what kinds of things we can call from the command line, and how to get help when we need it. The first command you should execute is tasks:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
rbair$ gradle tasks The CompileOptions.useAnt property has been deprecated and is scheduled to be removed in Gradle 2.0. There is no replacement for this property. :tasks ------------------------------------------------------------ All tasks runnable from root project ------------------------------------------------------------ Default tasks: assemble Basic tasks ----------- clean - Deletes the build directory and the build directory of all sub projects javadoc - Generates the JavaDoc for all the public API jfxrt - Creates the jfxrt.jar sdk - Creates an SDK Build tasks ----------- assemble - Assembles the outputs of this project. build - Assembles and tests this project. buildDependents - Assembles and tests this project and all projects that depend on it. buildNeeded - Assembles and tests this project and all projects it depends on. ccDecora - Compiles native sources for Decora ccGlass - Compiles native sources for Glass ccPrism - Compiles native sources for Prism ccPrismSW - Compiles native sources for PrismSW classes - Assembles the main classes. clean - Deletes the build directory. jar - Assembles a jar archive containing the main classes. javahDecora - Generates JNI Headers for Decora javahGlass - Generates JNI Headers for Glass javahPrism - Generates JNI Headers for Prism javahPrismSW - Generates JNI Headers for PrismSW linkDecora - Creates native dynamic library for Decora linkGlass - Creates native dynamic library for Glass linkPrism - Creates native dynamic library for Prism linkPrismSW - Creates native dynamic library for PrismSW native - Compiles and Builds all native libraries for Graphics nativeDecora - Generates JNI headers, compiles, and builds native dynamic library for Decora nativeGlass - Generates JNI headers, compiles, and builds native dynamic library for Glass nativePrism - Generates JNI headers, compiles, and builds native dynamic library for Prism nativePrismSW - Generates JNI headers, compiles, and builds native dynamic library for PrismSW stubClasses - Assembles the stub classes. testClasses - Assembles the test classes. Documentation tasks ------------------- javadoc - Generates Javadoc API documentation for the main source code. Help tasks ---------- dependencies - Displays all dependencies declared in root project 'javafx'. dependencyInsight - Displays the insight into a specific dependency in root project 'javafx'. help - Displays a help message projects - Displays the sub-projects of root project 'javafx'. properties - Displays the properties of root project 'javafx'. tasks - Displays the tasks runnable from root project 'javafx' (some of the displayed tasks may belong to subprojects). IDE tasks --------- cleanIdea - Cleans IDEA project files (IML, IPR) cleanIdeaWorkspace - Deletes the javafx.ipw file cleanNetBeans - Deletes generated NetBeans files idea - Generates IDEA project files (IML, IPR, IWS) netBeans - Creates the NetBeans project files for JavaFX Verification tasks ------------------ check - Runs all checks. test - Runs the unit tests. To see all tasks and more detail, run with --all. BUILD SUCCESSFUL Total time: 4.883 secs |
...
Gradle then tells us what the default tasks are. In this case, our default task is the 'sdk' task. This is the task that will be executed if you just call 'gradle' alone without providing any additional arguments. After this comes a listing of different tasks, broken out by group. The first group is the "Basic" group which contains the tasks you may find yourself using most often. These are all named and have a description provided. For example, if I wanted to execute the 'clean' task, then I would do so like this:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
rbair$ gradle clean |
Finally, the tasks task gives us a useful hint that we can pass the --all argument in order to see all of the tasks in more detail. This produces a lot more output, but really gives an in depth look at what tasks are available for you to call.
I mentioned above that our root project is called "javafx", and that we have sub-projects in the gradle build. To see all of the projects available to you, execute the projects task (which you will notice was in the "Help tasks" group produced by the tasks task). This lists not just what projects are available, but what their name is, and what the project hierarchy is.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
rbair$ gradle projects The CompileOptions.useAnt property has been deprecated and is scheduled to be removed in Gradle 2.0. There is no replacement for this property. :projects ------------------------------------------------------------ Root project ------------------------------------------------------------ Root project 'javafx' +--- Project ':base' +--- Project ':build-tools' +--- Project ':controls' +--- Project ':designTime' +--- Project ':fxml' +--- Project ':graphics' | +--- Project ':graphics:effects-jsl' | \--- Project ':graphics:prism-jsl' +--- Project ':swing' \--- Project ':swt' To see a list of the tasks of a project, run gradle <project-path>:tasks For example, try running gradle :base:tasks BUILD SUCCESSFUL Total time: 4.194 secs |
...
There are a couple other tricks-of-the-trade that you should be aware of. You can execute any gradle command with --info or --debug in order to get more output. Running in --info mode provides some additional debugging output that is very useful when things go wrong. In particular, our build system will output certain crucial variables that are being used to perform the build:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
rbair$ gradle projects Starting Build Settings evaluated using settings file '/Users/rbair/Projects/JavaFX/graphics-8.0/javafx/settings.gradle'. Projects loaded. Root project using build file '/Users/rbair/Projects/JavaFX/graphics-8.0/javafx/build.gradle'. Included projects: [root project 'javafx', project ':base', project ':build-tools', project ':controls', project ':designTime', project ':fxml', project ':graphics', project ':swing', project ':swt', project ':graphics:effects-jsl', project ':graphics:prism-jsl'] Evaluating root project 'javafx' using build file '/Users/rbair/Projects/JavaFX/graphics-8.0/javafx/build.gradle'. OS_NAME: mac os x JAVA_HOME: /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk_b81/Contents/Home/jre JDK_HOME: /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk_b81/Contents/Home BINARY_STUB: file:///Library/Java/JavaVirtualMachines/jdk1.8.0.jdk_b81/Contents/Home/jre/lib/ext/jfxrt.jar HUDSON_JOB_NAME: not_hudson HUDSON_BUILD_NUMBER: 0000 PROMOTED_BUILD_NUMBER: 00 PRODUCT_NAME: OpenJFX RAW_VERSION: 8.0.0 RELEASE_NAME: 8.0 RELEASE_MILESTONE: ea The CompileOptions.useAnt property has been deprecated and is scheduled to be removed in Gradle 2.0. There is no replacement for this property. Evaluating project ':base' using empty build file. Evaluating project ':build-tools' using empty build file. Evaluating project ':controls' using empty build file. Evaluating project ':designTime' using empty build file. Evaluating project ':fxml' using empty build file. Evaluating project ':graphics' using empty build file. Evaluating project ':swing' using empty build file. Evaluating project ':swt' using empty build file. Evaluating project ':graphics:effects-jsl' using empty build file. Evaluating project ':graphics:prism-jsl' using empty build file. All projects evaluated. Selected primary task 'projects' Tasks to be executed: [task ':projects'] :projects ------------------------------------------------------------ Root project ------------------------------------------------------------ Root project 'javafx' +--- Project ':base' +--- Project ':build-tools' +--- Project ':controls' +--- Project ':designTime' +--- Project ':fxml' +--- Project ':graphics' | +--- Project ':graphics:effects-jsl' | \--- Project ':graphics:prism-jsl' +--- Project ':swing' \--- Project ':swt' To see a list of the tasks of a project, run gradle <project-path>:tasks For example, try running gradle :base:tasks BUILD SUCCESSFUL Total time: 4.194 secs |
...
The simplest basic task to build is the sdk task. The sdk task will compile all Java sources and all native sources for your target platform. It is the default task which is executed if you do not supply a specific task to run. It will create the appropriate sdk directory and populate it with the native dynamic libraries and the jfxrt.jar. Because the SDK is not distributed with documentation, the javadocs are not created as part of the sdk task by default. Once the sdk task has completed, you will have and SDK distribution which you could run against (modulo any closed-bits) or give to somebody else to run.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
rbair$ gradle The CompileOptions.useAnt property has been deprecated and is scheduled to be removed in Gradle 2.0. There is no replacement for this property. :base:processVersion :build-tools:generateGrammarSource :build-tools:compileJava :build-tools:processResources :build-tools:classes :build-tools:jar :base:compileJava [snip out a whole bunch of stuff] :jfxrt :sdk BUILD SUCCESSFUL Total time: 1 mins 45.184 secs |
You can find the built SDK in the build directory:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
rbair$ pwd /Users/rbair/open-jfx/graphics/javafx rbair$ ls -l build/ drwxr-xr-x 3 rbair staff 102 Mar 23 17:39 sdk drwxr-xr-x 3 rbair staff 102 Mar 23 17:39 tmp rbair$ ls build/sdk/rt/lib/ ext/ libdecora-sse.dylib libprism-common.dylib javafx.properties libglass.dylib libprism-sw.dylib |
...
Cross Builds
The build is configured to support cross builds, that is, the ability to build an SDK for a platform other than the one you are building from. There are multiple gradle files located in buildSrc which represent specific compile targets. These include:
- win.gradle
- mac.gradle
- linux.gradle
- android.gradle
- ios.gradle
- armv6sf.gradle
- armv6hf.gradle
Each of these have specific prerequisites that must be met before they can be built. win.gradle can only be used on Windows, mac.gradle on Mac, and linux.gradle on Linux. Android can be cross built from Mac, Windows, or Linux so long as the Android SDK and NDK are installed and the build knows where to find them. iOS can be cross built on Mac. ARM (soft float and hard float) can be cross built from Linux.
By default, the OpenJFX build system will only build the SDK for the desktop platform you are building from. To ask it to build for a specific compile target, you must pass a COMPILE_TARGETS property to the build system, instructing it which to build. This is a comma separated list. Assuming you have already setup the prerequisites for building ARM (for example, when targeting the Raspberry PI), you would invoke gradle like this:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
rbair$ gradle -PCOMPILE_TARGETS=armv6hf |
Anchor | ||||
---|---|---|---|---|
|
The build can be customized fairly extensively through the use of Gradle properties. Gradle provides many ways to supply properties to the build system. However the most common approach will be to use a gradle.properties file located in the rt directory. Simply make a copy of gradle.properties.template and then edit the resulting gradle.properties file to customize your build.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
rbair$ cp gradle.properties.template gradle.properties |
The gradle.properties file that you have just created is heavily documented and contains information on all the different configuration options at your disposal. Some of the most common are:
- Enabling building of native source code (Prism, Glass, GStreamer, WebKit, etc)
- Specifying the build configuration (Release or Debug)
- Enabling building of JavaDoc
- Customizing the JDK_HOME
- Supplying compiler LINT options
Arguably the most important property in the build is the JDK_HOME property. Almost all other properties are derived automatically from this one. The JDK_HOME is by default based on the java.home System property, which is set automatically by the JVM based on which version of Java is executed. Typically, then, the version of Java you will be using to compile with will be the version of Java you have setup on your path. You can of course specify the JDK_HOME yourself. Note also that on Windows, the version of the JDK you have set as JDK_HOME will determine whether you build 32 or 64 bit binaries.
Testing
The next basic task which you may want to perform is test. The test task will execute the unit tests. You generally will execute the top level test because unlike with Ant, Gradle will only re-execute those tests which have changed (or were dependent on code that was changed) on subsequent runs. You can of course execute gradle cleanTest in order to clean all the test results so they will run fresh. Or, if you want to execute only those tests related to a single project, you can do so in the normal fashion:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
rbair$ gradle :base:test The CompileOptions.useAnt property has been deprecated and is scheduled to be removed in Gradle 2.0. There is no replacement for this property. :base:processVersion UP-TO-DATE :build-tools:generateGrammarSource UP-TO-DATE :build-tools:compileJava UP-TO-DATE :build-tools:processResources UP-TO-DATE :build-tools:classes UP-TO-DATE :build-tools:jar UP-TO-DATE :base:compileJava UP-TO-DATE :base:processResources UP-TO-DATE :base:classes UP-TO-DATE :base:compileTestJava UP-TO-DATE :base:processTestResources UP-TO-DATE :base:testClasses UP-TO-DATE > Building > :base:test > 3411 tests completed, 45 skipped |
Gradle gives helpful output during execution of the number of tests completed and the number skipped without dumping out lots of output to the console (unless you opt for --info). Also, once the tests complete, an HTML report is dumped to the project's build/reports/test directory (for example, modules/base/build/reports/test):
For the sake of performance, most of the tests are configured to run in the same VM. However some tests by design cannot be run in the same VM, and others cannot yet run in the same VM due to bugs or issues in the test. In order to improve the quality of the project we need to run as many tests as possible in the same VM. The more tests we can run on pre-integration the less likely we are to see failures leak into master. Being able to run 20,000 tests in a minute is extremely useful, but not possible, unless they run in the same VM. Something to keep in mind.
Overlay - JDK 8
After a successful build, the final step could be copying the results, overlaying them over an existing JDK. This step will replace any JavaFX/OpenJFX binaries in that runtime with your newly built binaries.
First execute the gradle task which creates an overlay bundle.
Code Block | ||
---|---|---|
| ||
rbair$ gradle [-PCOMPILE_TARGETS=armv6hf] zips # If you are cross compiling you will need the COMPILE_TARGETS flag # with the appropriate target # -PCOMPILE_TARGETS=armv6hf |
This will create a zip bundle containing the OpenJFX binaries and is designed to be extracted into a JDK or JRE.
The created bundle is located in build/[platform-]bundles/javafx-sdk-overlay.zip. [platform-] will only be present for a cross build, and will be the name of the cross platform (for example armv6hf-bundles).
Please note that there might be some differences in the contents of the runtime found in build/[platform-]sdk/ and the contents of the bundles. The overlay bundle is designed to match JavaFX in a production JDK.
Within a JDK there is a directory that contains the Java Runtime Environment, "./jre". The zip bundle is designed to be extracted in the directory that contains "./jre".
As zip bundles do not always preserve permissions, sometimes it is necessary to modify the file permissions to match the others in the JRE. In particular, check the permissions on the extracted native libraries.