Tuesday, September 13, 2011

Buckminster RCP Build

In my previous post we were pubishing an update site via Buckminster. Now we are going to build our RCP product.There is a nice tutorial from Ralf Ebert on this topic and this post makes heavy use of it.

Source code for this tutorial is available on googlecode as a single zip archive, as a Team Project Set or you can checkout the SVN projects directly.

Step 1: Create target definition

Open the global preferences and navigate to Plug-in Development -> Target Platform. Create a new target with Add... and select Nothing: Start with an empty target definition. Add... components from a Software Site. Add the Indigo update site (http://download.eclipse.org/releases/indigo). Deselect Group by Category and Include required software. Check Include all environments and reactivate Include required software. Afterwards add
  • Eclipse Platform Launchers
  • Eclipse Platform SDK (not necessarily needed for you RCP)
  • Eclipse RCP SDK

Click Finish. You should end up with a target definition like this:



Name your target accordingly. After creation make sure your target is activated.


Step 2: Create product

Create a new Plug-in project called com.example.rcp.core. We do not want an Activator, contributions to the UI or create an RCP. So deactivate all of them.
Within the Plug-in create a new Product Configuration named example.product. Now we need to define our product in detail. Set the Name to "My RCP Example", then click on New... to create a Product Definition.
Set the Product ID to myproduct and the Application to org.eclipse.ui.ide.workbench.


By creating the Product Definition a plugin.xml file is created. Add it to your build.properties file.

Create a new Feature Project called com.example.rcp.feature and set the Feature Name to My Base Features. Add org.eclipse.platform to the included features. Add com.example.rcp.core to the Plug-ins.

Now back to our product: select the product configuration is based on features. On the Dependencies tab add
  • org.eclipse.platform
  • com.example.rcp.feature
Give it a try by launching your product from the overview tab.

Step 3: Create build environment

We are creating a separate project for release engineering and for opur build files. So create a new Feature Project called com.example.rcp.releng. Add com.example.rcp.feature to the Included Features.

Create a new file buckminster_product.properties and add following content:
# Where all the output should go
buckminster.output.root=${user.home}/Build/Example RCP

# Where the temp files should go
buckminster.temp.root=${user.home}/tmp

# How .qualifier in versions should be replaced
qualifier.replacement.*=generator:lastRevision

product.id=com.example.rcp.core.myproduct
product.profile=ExampleProfile

# Windows 32
target.os=win32
target.ws=win32
target.arch=x86

# Linux
#target.os=linux
#target.ws=gtk
#target.arch=x86
The product.id needs to match with the Product identifier from the Product Definition (highlighted red in the screenshot above).

Now we need a new action for buckminster. We create one by adding a file buckminster.cspex with following content:
<?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/createProduct.ant" />
                <property key="targets" value="create.product" />
            </actorProperties>
            <properties>
                <property key="profile" value="${product.profile}" />
                <property key="iu" value="${product.id}" />
            </properties>
            <prerequisites alias="repository">
                <attribute name="site.p2" />
            </prerequisites>
            <products alias="destination" base="${buckminster.output}">
                <path path="${target.ws}.${target.os}.${target.arch}/" />
            </products>
        </public>
    </actions>
</cspecExtension>
This action refers to an ant file build/createProduct.ant which we need to create now.
<project>
     <pathconvert property="equinox.launcher.jar">
       <first count="1">
         <sort>
           <fileset dir="${eclipse.home}/plugins" includes="**/org.eclipse.equinox.launcher_*.jar"/>
           <reverse xmlns="antlib:org.apache.tools.ant.types.resources.comparators">
             <date/>
           </reverse>
         </sort>
       </first>
     </pathconvert>

    <target name="create.product">
        <property name="destination" location="${sp:destination}"/>
        <delete dir="${destination}"/>
        <makeurl property="repository" file="${sp:repository}"/>
        <mkdir dir="${destination}"/>
        <echoproperties/>
        <echo message="Repository:  ${repository}"/>
        <echo message="Destination: ${destination}"/>
        <echo message="IU:          ${iu}"/>
        <java jar="${equinox.launcher.jar}" fork="true" failonerror="true" >
            <arg value="-application"/>
            <arg value="org.eclipse.equinox.p2.director"/>
            <arg value="-repository"/>
            <arg value="${repository}"/>
            <arg value="-destination"/>
            <arg value="${destination}"/>
            <arg value="-profile"/>
            <arg value="${profile}"/>
            <arg value="-profileProperties" />
            <arg value="org.eclipse.update.install.features=true" />
            <arg value="-installIU"/>
            <arg value="${iu}"/>
            <arg value="-p2.os" />
            <arg value="${target.os}" />
            <arg value="-p2.ws" />
            <arg value="${target.ws}" />
            <arg value="-p2.arch" />
            <arg value="${target.arch}" />
            <arg value="-consoleLog"/>
            <arg value="-roaming"/>
        </java>
    </target>
</project>
Step 4: Executing the build job

Right click on your com.example.rcp.releng project and select Buckminster -> Invoke Action... Select create.product and add the location of your buckminster_product.properties file. Hit OK and wait for the build to finish.

You can find your final product under

${user.home}/Build/Example RCP/com.example.rcp.releng_1.0.0-eclipse.feature/win32.win32.x86
The Installation Details list our product with its sub components as we declared them in our Product Configuration.


Details: How things work together

When the build process is started, buckminster first creates a P2 update site containing all the features and plugins referenced from the com.example.rcp.releng feature. This will create a repository for our RCP installation afterwards. If our RCP needs additional stuff, we need to take care that we add these dependencies to our releng feature.

Once the update site is done, buckminster calls the director app - a special eclipse application used for headless installs of installable units (IUs, like products or features) and installs the given product to a dedicated location. Therefore it uses the pre-built update site as install repository.

The buckminster create.product.action collects some parameters from the properties file, builds the P2 update site and then triggers the ant file which actually handles the install process.

Adapt to your own needs

Typically you would create your own product with its own dependencies. Once you have a runnable product, create a releng Feature Project like in step 3. Change the product.id in the buckminster_product.properties file and add your product dependencies to the Included Features of your releng Feature Project.


No comments:

Post a Comment