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:
We distinguish between client API and builder API.
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: "".
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);
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.
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);
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.
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.