- 1 The CDT Build System Take 2
- 1.1 The Model
- 1.2 Scanner Discovery
- 1.3 Build Settings UI
- 1.4 Implementation
- 1.5 Examples
The CDT Build System Take 2
This is an attempt at taking a step back and mapping out what the CDT build system should be given all the requirements of the day and in an effort to simplify the existing system.
One thing to remember is that we'll need to maintain some level of backwards compatability, likely through a shim, to allow existing tool chain definitions to work.
(Note: historically, we could consider this takes 3 or 4. The original build system was the standard make which simply called out to an external build command. We then added the original implementation of managed make. This was then redone with the new Project Model).
These are the core classes that define the CDT build model.
The target platform describes the execution environment that the build output is intended to run on. Different target platforms use different tool chains and produce different kinds of build targets. They may also used different builder.
The target platform selects the binary parser used to find IBinary objects in the project.
A tool is a process that takes input targets and produces output targets. The targets can be resources or pseudo targets. Build Targets are selected from the collection of output targets. Pseudo input targets must also be output targets somewhere in the build. The targets are used to build up a dependency graph that is used to decide which tools to run in what order.
Tools have properties that control options in the behavior of the tool. Tools may be external utilities and the properties serve to generate command lines. Tools may also be internal utilities, although these can not be called from external builders (and probably should be discouraged or this ability dropped).
Tools have error parsers that are used to create markers from the output at build time to highlight warnings and errors in the code found by the tools.
Is the collection of tools used for a given build. A tool chain supports a given Target Platform. Predefined tool chains can be reused at project creation time. Tools can be added by the user, or automatically based on the resources in the project (e.g. a code generator for model files).
The builder is the component responsible for doing the build when Eclipse calls for one. The builder could call an external utility or utilities to do the build, or could be an internal builder that calls tools directly. The builder may also wish to generate files to the filesystem to manage the build. In this case the builder would register as a listener to resource changes or changes to the build settings.
Builders may or may not support different capabilities of tools. For example, external builders that take care of which tools to call and with what options would not use the tool properties. The build UI need to be able to adapt to that and hide the capability to set tool options. Also the build setting storage should not store unnecessary information in these scenarios either.
The builder is responsible for invoking the error parser associated with the tools used for a build. This could be done by grabbing the output of the invocation of the tool as in the case of the internal builder, or by sending the build output from an external build.
This is the end result of the build. Generally there is only one, but there could be more if the builder supports that. The build target can be a resource or a pseudo target. It should be possible to model 'make' targets with this class.
A configuration is a mapping of Builder, Build Target, and Tool Chain. Tool option settings are per configuration. Also files and folders can be excluded from the build in a given configuration oif the builder supports that. Predefined configurations can be reused at project creation time.
Templates are used to prepopulate the build settings and generate initial files for different kinds of project. They are essentially scripts that have access to the entire Eclipse and CDT API.
Scanner discovery is a service provided by the CDT to parse build output and extract tool options. Essentially, the build output parser works with the collection of tools defined in the tool chain to parse the build output.
The builder for a given configuration decides whether to use the service or not. If it does, the build output parser runs while the build output is incoming (not after) and adjusts the tool option settings on the fly.
Due to the amount of settings that could be gathered, care is taken to ensure the size of the information gathered is minimized. This is true whether you are using scanner discovery or not, but it is good to highlight here. Much of the complexity of the existing scanner discovery was a result of the effort to highly optimize size and to undo that complexity will require some of that optimization to be undone.
The existing scanner discovery also takes care of built-in calculations to provide complete scanner info. In this proposal, handling of built-ins is passed off to Tools, which may or may not use the existing capability.
The scanner info provider moves through the build system eventually to the Tools themselves to provide the scanner info for a given resource. Scanner discovery no longer stores info directly into the project descriptors and is no longer an automous system that can respond to these queries. It is simply a service used by the builders.
Build Settings UI
The build settings UI would be auto-generated as it is today based on tool definitions. Unlike today, the settings at project creation time would not reuse the project properties (that results in some really weird behavior in the resource system especially on cancel). This can be done with UI blocks that store the settings locally and added to the model only on Apply.
Tool properties have a type that is used to drive the UI for setting those properties. Properties also have categories to allow the UI to be structured (much as it is today, the difference being categories aren't objects in the model).
The original intent of using the Eclipse extension mechanism to define the build model was so that tools integrators didn't have to know Java to create their integrations. But over time, people wanted to start putting hooks into the build model to attach executable code to dynamically determine definitions and to control the UI behavior. And these hooks were added somewhat randomly as the need arose.
In the world we have to day, tools integrators need to know Java anyway and it would allow for full flexibility if they were able to define their tools integrations in Java. We can always add a Java implementation that still gets the information from the existing extension point and we will probably want to do that for the backwards compatability shim.
Tool definitions would be made by subclassing classes in the core build model. Instances of those classes would be created for the project instances. An extension point would be added to allow discovery of the definition classes. Work should be done such that the classes are only loaded if the user requires those definitions.
Here are examples of how the build model would be used in real life.
Windows MinGW (Wascana)
We would like to limit external dependencies in this environment so the internal builder would be used.
The tool chain selects the MinGW gcc compilers and binutils. The system is searched at known locations for the tool chain and sets the environment for the build to include them (as is done today).
Build targets include "Executable", "DLL", and "Library".
Predefined configurations for "Debug" and "Release" would be reused at project creation time. (Note these are selected to be familiar for VisualStudio users).
Templates would be defined for Executables that use the various libraries shipped as part of Wascana. The template may even prompt the users to install the libraries.
Linux Managed Make
To enable a cleaner integration with the library set on Linux (e.g. pkg-config based dependencies), we would use 'make' as the external build utility. We would generate Makefiles as resources are added/deleted and as build settings change. This allows the Makefiles to be checked into source control and reused by external build systems.
The tool chain selects the built-in gcc compilers and binutils, i.e. they are expected to already be on the path.
Alternative tool chains my be defined, e.g. the Intel or IBM compilers.
Build targets are "Executable", "Shared Library", and "Static Library".
Predefined configurations for "Debug" and "Optimize". ("Optimize" is more familiar to gcc users).
Templates defined as with Wascana (some of them would be the same since it's a subset of the Linux libraries).
Autotools would have it's own builder that would invoke the autotools and configure when necessary and finally 'make' on all builds.
Configurations would be defined for each build target generated by the configure script.
Templates could be defined to prepopulate the autotools conf files.
In this scenario, the external builder to be used is a build setting. Nothing is known by the CDT on how this builder actually performs the build. This is the Standard Make system, currently Makefile Projects, that we've had all along. Despite the name, these actually had little to do with 'make' itself.
Configurations are defined to manage the environment and the external build command. Each different combination of these is a different configuration.
Scanner discovery is used to capture build settings. To satisfy scanner discovery, a tool chain must be defined for the current configuration.
Android NDK (Native)
This scenario is an extension of the External Builder scenario. A specialized wizard is used to add CDT support to an Android Java project.
The Android NDK would be defined as a target platform that is used both for the Android Java projects and straight CDT projects for creating libraries that are used by the Android projects.
A template is defined that sets up the source and output folders and generate the Makefile. The template would also associate the Android tool chain with the Configuration to support scanner discovery.