## Project Build Configurations

The platform provides Build Configurations to allow integrations to build a project in multiple orthogonal ways. All the functionality provided to an Incremental Project Builder is provided per Build Configuration.

Build configurations are very useful when a project's files can be built in more than one way. In statically compiled C/C++, for example, the preprocessor is used to re-write or conditionally compile a single source file to multiple object files. Users can build a project in a 'debug' configuration: including asserts, debug information, etc; or in a 'release' configuration which is optimised at compile time. When building these two (or more) configurations, the project builder needs to know which source files have changed since it was last invoked on the specific configuration.

Build configurations provide a mechanism to represent the different variants of the build. Build commands are run in the order defined on the Project, and the build resource delta is maintained between builds of the configuration. Build configurations allow the Incremental Project Builder to build only what needs to be built (based on the delta) when the builder is invoked.

Builders which don't care about build configurations work as before.

Build Configurations are simply a tuple: (project, build-config name). Names are domain/application specific strings. They should be human-readable as they may be displayed by the UI, for example: "Debug". Integrations should respect configurations created by other platform integrations. By default each project has one build configuration.

See IBuildConfiguration for more information.

API is provided:

- to create build configuration(s) on a Project
- set the active configuration on the Project
- to build particular build configuration(s)
- to create reference between build configurations
- for a builder to discover which build configuration is currently being built

We distinguish between client API and builder API.

### Client API

#### Creating and setting build configurations

Each project has one default build configuration with name equal to the empty string. Build configurations are set on the Project description:

      IProject project = ...
      IProjectDescription projDesc = project.getDescription();

      // Get the build configurations for a project
      IBuildConfiguration[] buildConfigs = project.getBuildConfigs();

      ...
      // Creating a build configuration
      ResourcesPlugin().getWorkspace().newBuildConfig(project.getName(), "myNewBuildConfig");
      ...
      // Set new build configurations on a project
      projDesc.setBuildConfigs(buildConfigs);

      // Set the description
      project.setDescription(projDesc, null);

As each project must have at least one build configuration, it's not possible to remove all configurations from a project. Doing so automatically re-adds the default build configuration, with name: "".

#### Active configuration

By default one configuration on the project is defined as 'active'. The active configuration is the one that is built when a build configurations isn't specified (e.g. when: IProject#build(kind, monitor) is called on the project). To set the active build configuration:

       projDesc.setActiveBuildConfig(String buildConfigName);

#### Creating references between build configurations

Build Configurations can reference each other. Much like project level references, this can be used to ensure that prerequisite build configurations are built before referencing build configurations.

      projDesc.setBuildConfigReferences(String configName, IBuildConfiguration[] references);

causes the named build configuration to reference the passed in build configurations.

Note: A referenced build configurations may have a null name. Such references map to the active build configuration of the referenced project when the project is built. Therefore a project level reference can be thought of as a build configuration reference to the active build configuration.

#### Building Project Build Configurations

New API exists on the workspace to allow building a build configuration and its references (if required):

      ResourcesPlugin.getWorkspace().build(IBuildConfiguration[] buildConfigs, int kind, boolean buildReferences, IProgressMonitor monitor);

API also exists on IProject to build a specific build configuration:

      project.build(IBuildConfiguration config, int kind, IProgressMonitor monitor);

### Builder API

From the point of view of an Incremental Project Builder the platform now builds build configurations, rather than projects. In simple cases the build configuration will be the default configuration, and the project will only have one configuration.

#### Which build configuration is being built

A builder can discover which configuration is being built via:

      	protected IProject[] build(int kind, Map<String,String> args, IProgressMonitor monitor) throws CoreException {
      	    IBuildConfiguration thisBuildConfig = getBuildConfig();
      	    ...
      	}

Note builders needn't necessarily care about build configurations. IncrementalProjectBuilder#getDelta(IProject) will continue to return the resource changes since the builder was last run for the current build configuration.