## What is PDE Build?

PDE Build is a plug-in that helps users build their own plug-ins. The term build here is related to deployment and not development. PDE Build takes an Eclipse Plug-in Project, its plugin.xml and build.properties files and generates a build.xml script to be run by Ant. Building plug-ins, fragments or features consists of the 3 stages: fetch, generate scripts and build that are described bellow.

Fetch
Consists of taking the interesting elements from a repository to the build machine. These elements can be plug-ins, fragments or features. "Directory files" or "map files" are responsible for identifying where, how and which plug-ins should go to the build machine. These files are basically Java properties files where the entries have the following format:

`element@element_id=tag,:connection_type:user@host:repository`

The current implementation of fetch only works against CVS repositories and there are no plans for supporting different kinds. Skipping or substituting this step should not be hard for users of other VCM systems or other kind of storage.

Examples:

`plugin@org.eclipse.pde.build=v20020717, :pserver:anonymous@dev.eclipse.org:/home/eclipse,
fragment@org.eclipse.core.resources.win32=v20020627, :pserver:anonymous@dev.eclipse.org:/home/eclipse,
plugin@org.eclipse.platform=v20020820, :pserver:anonymous@dev.eclipse.org:/home/eclipse,
`

Generate Ant buildfiles
Once the plug-ins, fragments and features are in place, we need to generate the build.xml scripts. These Ant buildfiles drive the build process. In order to generate them, PDE Build takes as input the plugin.xml, fragment.xml, feature.xml and build.properties files. The complete description of the first three files are elsewhere in the Eclipse documentation. Here we will only fully describe the build.properties file and relevant parts of the others.

Build
This step is basically executed by Ant. One important thing here is to know exactly what targets to call in order to get the desired result.

## How do I use PDE Build?

### Fetch

This step is done by the `eclipse.fetch` Ant task provided by PDE Build. Here is an example:

    <eclipse.fetch
        scriptName="fetch.xml"
        elements="feature@org.eclipse.platform-feature"
        directory="${basedir}/test.map"
        install="${basedir}/source"
        children="true"
    />

The above task generates an Ant buildfile called fetch.xml. It consists of Ant CVS tasks that retrieve the Eclipse Platform feature and all its plug-ins and fragments.

## Generate Scripts

Once features, plug-ins and fragments are downloaded you need to generate their Ant buildfiles. This step is done by the `eclipse.buildScripts` Ant task provided by PDE Build. Here is an example:

    <eclipse.buildScript
        elements="feature@org.eclipse.platform-feature"
        install="${basedir}/source"
        children="true"
    />

The above task will generate Ant buildfiles for the Eclipse Platform feature and all its plug-ins and fragments.

build.properties
The build mechanism is driven by a build specification. The specification for an individual plug-in, fragment, or feature is found in a build.properties file in the corresponding element (feature, plug-in or fragment). It is a simple properties file that describes, for example, where to find the source code for the element. Other entries describe which files should be included/excluded in/from various forms of distribution (e.g., binary, source). The possible entries are described bellow:

`custom = yes`
Tells the script generator that no script is necessary for the current element. It is usually used when a custom build.xml script is provided. The build.xml script has to be in the root folder of the element.

bin.includes =
bin.excludes =

source.<jar_name>=<source_locations>
Indicates, for the specified jar, where to find its source. The source_locations is a comma-separated list of [element-relative?] locations. Plug-ins [elements?] requiring compilation must define this entry.
Example:
source.resources.jar = src/

jars.compile.order = <comma separated list of JARs>
Specifies in what order the JARs should be compiled. Should be used to solve build dependencies within the same plug-in/fragment.

Example:

jars.compile.order=resources.jar,lib/resources-ant.jar

## Build

The generated build.xml scripts from the previous step have many targets. The public ones described bellow. These are the targets that a custom build.xml script must implement.

Feature targets:

all.children
Calls plugin-template and fragment-template.

all.plugins
Delegates target calls to all the feature's plug-ins.

all.fragments
Delegates target calls to all the feature's fragments.

build.jars
Generates the required jars for the feature and its children.

build.sources
Creates all the *src.zip files corresponding to this feature's jars and its children. E.g. for startup.jar, it creates startupsrc.zip .

build.update.jar
Creates a jar file containing a binary build of the feature. Source is not included. The jar is in a format supported by install/update.

gather.bin.parts
Copies all feature relevant parts (defined by bin.includes and bin.excludes) to ${destination}/install/features/${feature}.

gather.logs
Copies *.log files to ${destination}/install/features/${feature}.

gather.sources
Copies files generated by build.sources (*src.zip) to ${destination}/install/features/${feature}.

Plug-ins and fragments targets:

build.jars
Generates the required jars for this plugin/fragment.

build.sources
Creates all the *src.zip files corresponding to this element's jars. E.g. for resources.jar, it creates resourcessrc.zip .

build.update.jar
Creates a jar file containing a binary build of the element. Source is not included. The jar is in a format supported by install/update.

clean
Cleans all temp files and folders plus files created by the script targets (e.g. *.jar, *.zip, ...).

gather.bin.parts
Copies all plugin relevant parts (defined by bin.includes and bin.excludes) to ${destination}/(plugins | fragments)/(${plugin} | ${fragment}). E.g., ${destination}/plugins/${plugin}.

gather.logs
Copies *.log files to ${destination}/(plugins | fragments)/(${plugin} | ${fragment}). E.g., ${destination}/plugins/${plugin}.

gather.sources
Copies files generated by build.sources (*src.zip) to ${destination}/(plugins | fragments)/(${plugin} | ${fragment}). E.g., ${destination}/plugins/${plugin}.

## General notes on PDE Build

This section is not organized in any way. It just contains general knowledge on the use and implementation of the PDE Build plug-in. Although it should be up to date there is no guarantee about it. Check with your favorite pde build developer before making any assumptions based on it.

- units are features, plug-ins and fragments
- Ant is the base technology
- CVS is the supported repository for the fetch task
- The build basically consists of these steps: fetch, generate buildfiles and build. Te steps are triggered by Ant tasks defined by pde build.
- Besides the basic steps any other step can be included by the releng team. It will only depend on the bootstrap buildfile. This buildfile is not generated by the pde.build.
- Features, plug-ins and fragments can have custom build scripts as long as they conform with the API (automatically generated script).
- The Ant buildfiles generate by pde build have to run in 2 different environments correctly: headless (Eclipse releng style) and the Eclipse UI.
- When implementing a new functionality or changing an existing one there are two modes to consider. One is the build running headless like the releng does and the other is the script being executed by a user of Eclipse using the external tools UI. They can have completely different characteristics and point of views. If one assumption is correct for one of these scenarios it does not mean it is correct for the other. One of the fundamental differences is that there is no concept of "project" when running headless. PDE Build does not even know about the Resources plug-in.
- Buildfiles for features, plug-ins and fragments have to run independently of Eclipse since we also support source builds. If possible they should contain only the core Ant tasks. Any Eclipse relative task in a buildfile must not be a requirement. Only add those in optional targets when extra value for the user is needed (e.g. refresh local, JDT compiler, etc.).
- Changing the buildfile is almost like an API change since there are plug-ins using their own custom scripts (a good example is SWT). For example, renaming a target called build.jars to build.all.jars is a breaking change since SWT does not provide such target. Adding targets is also a breaking change. Again, it has to be handled like an API change.
- The Java runtime library can be defined by the user setting the bootclasspath property (e.g. <property name="bootclasspath" value="c:\runtime\rt.jar"/>. This is necessary, for example, when building an Eclipse Windows drop from a Linux machine.
- Compile paths in the buildfiles are represented as relative paths when possible and full paths otherwise. In order for source builds to work, ALL paths have to be relative since it has to be portable to any user that wants to build Eclipse. In order to achieve it, the fetch task retrieve the projects from CVS in a pre-defined structure. Many places in the pde build code will rely on this structure so that changes to it should be considered very carefully. The easiest way to understand the structure is to take a look at a recent generated fetch script.
- During the Eclipse Platform build the SWT plug-in and its fragments have to be built before the platform feature since it is a very special plug-in. All the JARs are placed in its platform specific fragments. For example, when building Eclipse Platform for Win32, if we build the platform feature first there will be no swt.jar since its JAR is built by the swt.win32 fragment and it is not part of the base platform feature (it is part of the win32 platform feature). So the eclipse.ui plug-in will not build since it depends on SWT and the JAR is not there yet.
- Plug-ins and fragments from one feature cannot depend on plug-ins from another feature unless one feature depends on the other. For example, a plug-in in the JDT feature can depend on a plug-in in the Platform feature but not the other way around.