Building an RCP application with Hudson and Buckminster

From Eclipsepedia

Revision as of 10:16, 8 August 2009 by Mail.jutzig.de (Talk | contribs)

Jump to: navigation, search
This article is currently a draft and not all necessary resources are in place yet.
The following paths and scripts are written for Linux systems. Other operating systems might require minor adjustments

This tutorial will show how to set up a cross platform build of an RCP application with Buckminster and Hudson. The application to be built will be the Buckminster MailApp RCP which can be found in the Subversion Repository.


Contents

Prerequisites

Before attempting this tutorial you need several things up and running

Project Layout

The MailApp shows all the necessary parts to make a P2 enabled product buildable with Buckminster.

org.eclipse.buckminster.tutorial.mailapp

This is the actual PlugIn. It contains the source code of the example application as well as all product customizations like the splashscreen and the product extension.

org.eclipse.buckminster.tutorial.rcpp2.feature

This feature project includes all the necessary plugins to make the resulting RCP self-managed (i.e. enable the p2 update manager)

org.eclipse.buckminster.tutorial.product.feature

This feature will be the main feature to be installed. It contains the actual plugin, the product definition, all necessary dependencies and a build script along with a CSPECX to make this build script known to Buckminster. A product definition is similar to a feature in a way that both aggregate features and plugins. However, a product definition can only be feature-based, or plugin-based, not both at the same time, whereas a feature can have both included plugins and features. That's why it is common practice to have your product feature-based and delegate all the work to the single feature you are including in your product.

Make sure that 'The product includes native launcher artifacts' is selected if you want an executable application

Note that the feature contains the org.eclipse.equinox.executable feature besides the plugin itself, org.eclipse.rcp and org.eclipse.buckminster.tutorial.rcpp2.feature. This feature is necessary for all products that contain native launcher artifacts and it is included in the Delta Pack.

Buckminster will create an update site from that feature that contains all the plugins, features and binary artifacts. Once that is done, the build script will then utilize the p2 director application to create the actual product from the update site's content. To make this action known to Buckminster a CSPECX is required for that feature.

<?xml version="1.0" encoding="UTF-8"?>
<cspecExtension
	xmlns:com="http://www.eclipse.org/buckminster/Common-1.0"
	xmlns="http://www.eclipse.org/buckminster/CSpec-1.0">
	<actions>
		<public name="create.product" actor="ant">
            <actorProperties>
                <property key="buildFile" value="build/product.ant"/>
                <property key="targets" value="create.product"/>
            </actorProperties>
            <properties>
                <property key="profile" value="MailProfile"/>
                <property key="iu" value="org.eclipse.buckminster.tutorial.mailapp.product"/>
            </properties>
			<prerequisites alias="repository">
				<attribute name="site.p2"/>
			</prerequisites>
            <products alias="destination" base="${buckminster.output}">
            	<path path="MailApp/"/>
            </products>
		</public>
		<public name="create.product.zip" actor="ant">
            <actorProperties>
                <property key="buildFileId" value="buckminster.pdetasks"/>
                <property key="targets" value="create.zip"/>
            </actorProperties>
			<prerequisites alias="action.requirements">
				<attribute name="create.product"/>
			</prerequisites>
            <products alias="action.output" base="${buckminster.output}">
            	<path path="MailApp.zip"/>
            </products>
		</public>
	</actions>
</cspecExtension>

This will make the two actions (create.product and create.product.zip) known to Buckminster. If you materialized the MailApp Tutorial into your workspace and have the Delta Pack installed, you should have everything in place now to create the product with Buckminster just by right clicking on org.eclipse.buckminster.tutorial.mailapp.product.feature and selecting buckminster -> invoke action -> create.product.zip.

Configuring the Build Environment

In case you don't have a headless Buckminster installation just yet, follow the instructions in Getting started with Headless Buckminster. For convenience, these are essentially the steps to do:

director -r http://download.eclipse.org/tools/buckminster/headless-3.5/ -d BUCKMINSTER_INSTALL_DIRECTORY -p Buckminster -i org.eclipse.buckminster.cmdline.product
buckminster install http://download.eclipse.org/tools/buckminster/headless-3.5/ org.eclipse.buckminster.core.headless.feature
buckminster install http://download.eclipse.org/tools/buckminster/headless-3.5/ org.eclipse.buckminster.cvs.headless.feature
buckminster install http://download.eclipse.org/tools/buckminster/headless-3.5/ org.eclipse.buckminster.pde.headless.feature
buckminster install http://download.eclipse.org/tools/buckminster/headless-3.5/ org.eclipse.buckminster.maven.feature
buckminster install http://download.cloudsmith.com/buckminster/external/ org.eclipse.buckminster.subversive.headless.feature


Once this is done, configure the Buckminster installation in Hudson. To do so, open the Hudson web interface and navigate to 'Manage Hudson' -> 'Configure System' and press 'Add' at the Buckminster section.

Hudson Buckminster Location Configuration.png

Building a Target Platform

The Target Platform contains the set of features and plugins that your source is build against. Since the MailApp does not have many dependencies, you only need the org.eclipse.platform feature and the org.eclipse.equinox.executable feature. There are several ways to create a target platform. You could either just manually create an eclipse installation that contains all plugins and features that you want to be in the target platform, or you can build it on the fly. In this tutorial the target platform will be created on the fly by requesting Buckminster to import MSPECs into an empty location using the p2 materializer.

For the two required features org.eclipse.platform and org.eclipse.equinox.executable, we therefore create two CQUERYs and two MSPECs that point to those CSPECs.

<?xml version="1.0" encoding="UTF-8"?>
<cq:componentQuery xmlns:cq="http://www.eclipse.org/buckminster/CQuery-1.0" resourceMap="MailAppTargetPlatform.rmap">
    <cq:rootRequest name="org.eclipse.platform" componentType="eclipse.feature"/>
    <cq:advisorNode namePattern=".*" useTargetPlatform="false" useWorkspace="false"/>
    <cq:property key="target.arch" value="*"/>
    <cq:property key="target.os" value="*"/>
    <cq:property key="target.ws" value="*"/> 
</cq:componentQuery>
<?xml version="1.0" encoding="UTF-8"?>

<mspec xmlns="http://www.eclipse.org/buckminster/MetaData-1.0" name="Target Platform MSPEC" materializer="p2" installLocation="${targetPlatformPath}" url="org.eclipse.platform.cquery">

   <property key="target.arch" value="*"/>
   <property key="target.os" value="*"/>
   <property key="target.ws" value="*"/>

</mspec>

The CQUERY and MSPEC for the org.eclipse.equinox.feature looks exactly the same except for the component name. Note the Wildcard (*) for target.arch, target.os and target.ws. This will ensure that the materialized target platform works for all operating systems and architectures. The installLocation is set to ${targetPlatformPath} so this property has to be passed to the buckminster runtime to specify where the materialization should take place. The CQUERY also contains an Advisor Node. This Advisor Node will ensure that nothing is resolved from the current Buckminster Runtime, itself so that everything will be downloaded freshly.

Both querys use a resolver map to find the required components.  The RMAP is very simple in this case because all required features and plugins can be found in a single update site.

<?xml version="1.0" encoding="UTF-8"?>
<rmap xmlns="http://www.eclipse.org/buckminster/RMap-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:mp="http://www.eclipse.org/buckminster/MavenProvider-1.0"
	xmlns:pmp="http://www.eclipse.org/buckminster/PDEMapProvider-1.0"
	xmlns:bc="http://www.eclipse.org/buckminster/Common-1.0">
	<searchPath name="org.eclipse.platform">
		<provider readerType="eclipse.import" componentTypes="osgi.bundle,eclipse.feature" mutable="false" source="false">
			<uri format="http://download.eclipse.org/releases/galileo?importType=binary"/>
		</provider>
	</searchPath>
	<locator searchPathRef="org.eclipse.platform"/>
</rmap>

Creating the Hudson Job

Start with a new Free-Style project that will create and publish the target platform for the MailApp. The job needs two build steps: Execute Shell and Run Buckminster. The execute shell step will delete the directory where the target platform is materialized to ensure a clean build every time.

rm -Rf ${WORKSPACE}/targetPlatform

In the Run Buckminster build step you need to import the two MSPECs defined above:

import file:///home/build/mailApp/org.eclipse.platform.mspec
import file:///home/build/mailApp/org.eclipse.equinox.executable.mspec

Those MSPECs will materialize the target platform to the directory set in ${targetPlatformPath} so open the advanced section of the build step and set that property to directory in the workspace:

-DtargetPlatformPath=${WORKSPACE}/targetPlatform

The last thing that needs to be done in the target platform is archiving the build result and publishing it. In order to do so, activate the post build action "Archive and publish an Eclipse Target Platform", set the directory to the value of ${targetPlatformPath} and name the resulting artifact.

Now your configuration should look like this:

TargetPlatformJob-BuildSteps.png

TargetPlatformJob-PostBuildAction.png

Creating the Build Job

Next you need to create a new Job to build the product. This can be either a freestyle project for just one product, or a multiconfiguration project if you want to build your RCP for several different platforms at once. This tutorial will use the multiconfiguration project. First add an 'Execute Shell' build step into the Job configuration to always start with a clean workspace:

rm -Rf $WORKSPACE

The next build step will be 'Run Buckminster', where the actual work takes place. First select the target platform to build against. There should be only one available (the one published by the other hudson job). This will make the target platform available during the build run and also introduces the job that depends on the target platform as a downstream project of the project that publishes the target platform. Two commands need to be performed to build the RCP:

  1. resolve the MailApp (bring all pieces into the workspace)
  2. invoke the create.product.zip action

After those steps, you most likely want Hudson to archive the MailApp.zip artifact. This can be done with the following expression for the 'Archive Artifacts' post build action:

buckminster.output/org.eclipse.buckminster.tutorial.mailapp.product.feature*/MailApp.zip

This is what the result should look like now:

MailAppJobConfig.png

To stay informed about the build stability it is often a good idea to install the Warnings plugin for hudson and have it search the build output (a Buckminster parser is available)


Building for multiple platforms

The above configuration should already be sufficient to build your RCP with Hudson. However, so far it will only build for the platform Hudson is running on. To build for several different platforms you need to add three new axes to the multiconfiguration project. For example:

Axis Values
os win32, linux
ws win32, gtk
arch

x86, x86_64

Next, a combination filter needs to be added to filter out the impossible combinations:

!((os=="linux" && ws=="win32") || (os=="win32" && ws=="gtk"))

The multiconfiguration project will now execute the build steps with all possible combinations of the values of the three axes (except for the filtered ones). To pass the currently selected values to Buckminster, we simply need to add additional JVM properties in the 'Advanced' configuration of the Buckminster build step.

-Dtarget.os=${os}
-Dtarget.ws=${ws}
-Dtarget.arch=${arch}

Now everything should be in place to execute the job. Once it has successfully completed, the configuration matrix should show the following result:

Hudson Configuration Matrix For MailApp.png

Clicking on of the executed combinations will reveal the built artifact for this platform configuration

Hudson Build x86 linux gtk.png