基于PDE的RCP项目自动构建

持续集成包括软件项目的持续构建与发布,经过持续性地编译与构建,完成项目的不断集成。持续集成一般应用与WEB开发领域,对于RCP项目的持续集成目前业界较少。对于RCP项目的持续集成,就是经过按期执行项目自动构建程序来完成项目版本的集成与发布,重点在于项目的自动化构建。通过笔者的研究与学习,经过本文向你们介绍一种基于PDERCP项目自动化构建方式,但愿你们多多交流。php

1、简介java

PDE (Plug-in Development Environment) headless-build是一种基于 Ant 脚本的构建方式,它主要适用于Eclipse plug-in与 Eclipse RCP项目的导出。因为headless-build是特定于 Eclipse 插件的构建平台,而 Eclipse 插件的编译构建都离不开Eclipse自己的类库与资源,于是运行headless-build以前,必须已经安装好带有PDE环境的Eclipse SDK以及相应的插件PDE做为Eclipse的一个插件项目存在于Eclipse中,且不一样EclipsePDE实现的方式略有不一样,本文以Eclipse3.5.1为例,介绍PDE headless-build实现自动化构建的原理及示例。app

2、原理less

(一)headless-build核心库文件eclipse

headless-build核心脚本文件都存储于 Eclipse 的 PDE 插件中。以Eclipse3.5.1为例,PDE build 插件位于 plugins 目录下的 org.eclipse.pde.build 插件目录中。在此目录的 lib 文件夹中包含有 pde build 库的核心类文件,其中包括了绝大多数和 PDE build 相关的 Ant task 的实现,有兴趣的读者能够在 org.eclipse.pde.source 源代码插件中看到相应的代码ide

对于咱们的 build 任务,PDE headless-build 的核心脚本文件位于 scripts 和 templates 两个目录下。工具

scripts 文件夹中提供了 headless-build 的基础控制脚本。事实上不管是使用 headless-build 仍是IDE 导出,咱们都间接地经过执行这些脚本完成了一系列的过程。其中的 build.xml 文件是 build 过程的主脚本文件,在以前的启动命令中的 –buildfile 后的值就是此 build.xml 文件的路径。而 genericTargets.xml 则定义了在 build 过程的各个子过程的行为。学习

templates 文件夹中则提供了一系列的模板库。您可在 templates 下的 headless-build 目录中找到前面所说的 allElements.xmlbuild.propertiescustomTargets.xml 文件的模板。您能够方便地将其拷贝和修改,用做您本身的构建配置文件。fetch

(二)headless-build 的工做流程和通知机制ui

customTargets.xml 提供了对 headless-build 流程的多个节点的控制。而事实上 PDE 将 headless-build 分为多个子过程。customTargets.xml 正是针对了此些子过程提供了回调接口,以通知和触发用户定制的脚本被执行。如下是 headless-build 总体流程的简图。

在其中,您须要提供的是最初的引入脚本(Ant 文件,批处理文件或命令行指令),以后 Eclipse 宿主会被启动并调用您指定的一般位于 PDE 插件 scripts 目录下的 build.xml,而此文件则会相应找到您在配置目录中定义的 customTargets.xml 文件,执行用户设定的回调脚本,并经过 customTargets.xml 调用 PDE 插件 scripts 下的 genericTargets.xml 启动 PDE 内部的各项子过程的执行代码。而在 genericTargets 中则定义了 headless-build 4个子过程fetchgenerateprocess 和 assemble,下面咱们对他们作简单的介绍。

1Fetch

Fetch负责从源控制中下载所需构建的插件项目的源文件。其过程以下:

正如前文所述,customTargets.xml中包含了headless build执行全部过程的预置以及回调接口,开发者能够在其中本身编写所需的自定义脚本。Fetch操做主要在于fetchElement操做,它会根据PreBuild中用户定义的源文件库的文件及地址映射的MAP来以次获取须要构建的项目源码。同时,fetch taeget中有一个unless=skipFetch的属性,该属性代表当shipFetch存在时,fetch过程能够被跳过。

(2)Generate

Generate为每一个插件分别生成自身的构建脚本。其过程以下:

一样能够自定义预置及回调操做,generate的主要过程在于generateScript操做。该操做使用eclipse.buildScript方法为每一个插件分别生成自身的构建脚本

(3)Process 

process经过运行 generate 中生成的脚本,完成对每一个插件的构建。其过程以下:

Process过程主要调用prcessElement操做,该操做经过processViaFeatureprocessFlat两个过程完成对各个插件以及依赖插件的构建。

(4)Assemble

assemble将 process 过程当中生成的插件打包。其过程以下:

调用了assembleElement过程,根据Manifest清单中的依赖,把相关的插件集成到一块儿,打包发布为一个ZIP文件,该文件解压后点击.exe文件可运行。(打包后的的插件会被自动集成到宿主平台中)

3、示例

了解了PDE headless build的实现原理,咱们能够为其量身打造本身的构建脚本。为了直接突出核心,咱们对于获取代码管理工具上源码的部分就取消了,在配置文件中将SkitFetchskipMap设置为true便可,接下来将把本地的RCP项目完成自动化构建。

(1)新建一个Plug-in Project,项目名称为com.rcpquickstart.helloworld,模板选择“RCP Helloworld,新建的步骤不作详细讲解,顺着向导操做便可。

(2)新建一个Feature Project,名称为com.rcpquickstart.helloworld.feature,其插件选择com.rcpquickstart.helloworld,新建的步骤不作详细讲解,顺着向导操做便可,完成的Feature结构以下:

(3)com.rcpquickstart.helloworld项目中新建一个Product Configratiuon,名称为helloworld.product,新建完之后打开文件进行以下配置。

接着为product添加功能部件(Feature),点击选项卡“Dependencies”,添加“com.rcpquickstart.helloworld.feature”和“org.eclipse.rcp”两个功能部件便可。到目前为止,咱们的RCP产品项目配置完毕。

(4)新建一个Java Project,名称为com.rcpquickstart.helloworld.build,接着再新建两个文件“build.xml”和“build.properties”。该项目为自动构建插件项目,使用ant脚本。

(5)编辑build.xml内容以下:

<projectname="com.rcpquickstart.helloworld.build"default="build">

<propertyfile="build.properties"/>

<targetname="init">

<mkdirdir="${buildDirectory}"/>

<mkdirdir="${buildDirectory}/plugins"/>

<mkdirdir="${buildDirectory}/features"/>

<copytodir="${buildDirectory}/plugins">

<filesetdir="../">

<includename="com.rcpquickstart.helloworld/**"/>

</fileset>

</copy>

<copytodir="${buildDirectory}/features">

<filesetdir="../">

<includename="com.rcpquickstart.helloworld.feature/**"/>

</fileset>

</copy>

</target>

<targetname="pde-build">

<javaclassname="org.eclipse.equinox.launcher.Main"fork="true"failonerror="true">

<argvalue="-application"/>

<argvalue="org.eclipse.ant.core.antRunner"/>

<argvalue="-buildfile"/>

<argvalue="${eclipseLocation}/plugins/org.eclipse.pde.build_${pdeBuildPluginVersion}/scripts/productBuild/productBuild.xml"/>

<argvalue="-Dtimestamp=${timestamp}"/>

<classpath>

<pathelementlocation="${eclipseLocation}/plugins/org.eclipse.equinox.launcher_${equinoxLauncherPluginVersion}.jar"/>

</classpath>

</java>

</target>

<targetname="clean">

<deletedir="${buildDirectory}"/>

</target>

<targetname="build"depends="clean, init, pde-build"/>

</project>

从脚本能够看出,执行过程分为Cleaninitpde-build三部,Clean为清理构建的目标目录,即产品构建目录,init为新建构建目录结构,同时,将所需构建的插件项目以及其feature拷贝到相应的目录下(若是是依赖多个插件的话都须要执行拷贝)。Pde-build则是启动一个Eclipse进程调用pde构建。

(6)build.properties内容以下:

# Version of org.ecilpse.pdebuild

pdeBuildPluginVersion=3.5.1.R35x_20090820

# Version of org.eclipse.equinox.launcher

equinoxLauncherPluginVersion=1.0.201.R35x_v20090715

base=c:/helloworld-build-target

eclipseLocation=F:/Install/PDE/eclipse-SDK-3.5.1-win32/eclipse

############# PRODUCT/PACKAGING CONTROL #############

product=/com.rcpquickstart.helloworld/helloworld.product

runPackager=true

#Set the name of the archive that will result from the product build.

#archiveNamePrefix=

archivePrefix=helloworld

# The location underwhich all of the build output will be collected.

collectingFolder=${archivePrefix}

configs=win32, win32, x86

allowBinaryCycles = true

#Sort bundles depenedencies across all features instead of just within a given feature.

flattenDependencies = true

#Arguments to send to the zip executable

zipargs=

#Arguments to send to the tar executable

tarargs=

############## BUILD NAMING CONTROL ################

# The directory into which the build elements are fetched and where

# the build takes place.

buildDirectory=c:/helloworld-build

# Type of build.  Used in naming the build output.  Typically this value is

# one of I, N, M, S, ...

buildType=I

# ID of the build.  Used in naming the build output.

buildId=HelloWorld

# Label for the build.  Used in naming the build output

buildLabel=${buildType}.${buildId}

Timestamp for the build.  Used in naming the build output

timestamp=007

baseLocation=${base}/eclipse

filteredDependencyCheck=false

skipBase=true

eclipseURL=<url for eclipse download site>

eclipseBuildId=<Id of Eclipse build to get>

eclipseBaseURL=${eclipseURL}/eclipse-platform-${eclipseBuildId}-win32.zip

skipMaps=true

mapsRepo=:pserver:anonymous@example.com/path/to/repo

mapsRoot=path/to/maps

mapsCheckoutTag=HEAD

#tagMaps=true

mapsTagTag=v${buildId}

skipFetch=true

############# JAVA COMPILER OPTIONS ##############

# Specify the output format of the compiler log when eclipse jdt is used

logExtension=.log

# Whether or not to include debug info in the output jars

javacDebugInfo=false 

# Whether or not to fail the build if there are compiler errors

javacFailOnError=true

# Enable or disable verbose mode of the compiler

javacVerbose=true

须要注意几个关键配置:

pdeBuildPluginVersion

PDE BUILD的版本号,能够在Eclipse目录下的Plugin文件夹里找到org.eclipse.pde.build_3.5.1.R35x_20090820文件夹,文件夹名后面的字符为PDE版本;

equinoxLauncherPluginVersionequinoxLauncher版本号,用于Eclipse项目构建的进程,其在Eclipse目录下的Plugin文件夹里找到

org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar ,后面字符为其版本号;

BaseRCP runtime BinaryDelta Pack存放的目录路径,其两者包括了RCP运行时环境所需插件以及大量跨平台插件。

eclipseLocation:执行构建的Eclpise路径

Product:须要发布的Product文件

buildDirectory:执行构建的目标目录,包括了构建时产生的文件

skipMapstrue,跳过源文件的MAP获取。

skipFetchtrue,跳过从源代码管理工具获取源文件。

(7)准备构建环境。根据配置文件中配置路径,分别在C盘创建“helloworld-build”和“helloworld-build-target”两个文件夹,同时,从eclipse官网上下载“eclipse-RCP-3.5.1-win32.zip”和“eclipse-3.5.1-delta-pack.zip”压缩文件,将其解压到刚才的helloworld-build-target目录下(相同的文件能够覆盖),下载地址:

http://archive.eclipse.org/eclipse/downloads/drops/R-3.5.1-200909170800/index.php

(8)执行build.xml,待构建完成后,在“/helloworld-build/I.HelloWorld”目录下找到HelloWorld-win32.win32.x86.zip,其为构建好的RCP项目,解压后目录结构以下:

双击helloworld.exe可运行程序。

相关文章
相关标签/搜索