On 18/04/2013, at 11:39 PM, Luke Daley <luke.da...@gradleware.com> wrote:
> > On 15/03/2013, at 1:38 AM, Adam Murdoch <adam.murd...@gradleware.com> wrote: > >> Hi, >> >> There's now a first cut of the new source set DSL in master. Right now, it >> pretty much just mirrors the old structure: a project has a set of >> 'functional source sets', and each functional source set has a single >> 'language source set' for each supported language. The next step is to >> introduce some flexibility in this model, so that you can use it to model >> other structures. In particular, we want to be able to group source in more >> interesting ways: >> >> - Group multiple source sets of a given language to be compiled together. >> For example, when building the 'release' variant of my Android application, >> I want to take the 'main' java source and the 'release' java source and >> compile them together as a single batch. >> - Group multiple source sets of different languages to be compiled together. >> For example, I want to take my 'main' java source and my 'main' groovy >> source and compile them together as a single (logical) batch. >> - Group multiple source sets together to form some logical thing. For >> example, I want to take my 'main' java source and 'main' resource and 'main' >> groovy source and bundle them together in a 'main' source set that I can >> pass around as a single thing and add as input to various things or publish >> or whatever. >> >> When we add a source set to a binary, we need to be able to turn it into the >> language specific views in order to compile it (or whatever it is we need to >> do with it). For example, for Java source we need to know the Java language >> level that the source conforms to and the compile dependencies that the >> source has, plus some general stuff like the character encoding that the >> source files use. >> >> Ideally, this language specific view is read-only (and even better if it is >> immutable) and somewhat more general than the view you would use to >> configure the source sets. >> >> The current plan is to have language-independent composite source sets and >> language-specific (and strongly typed) source sets. The language source sets >> are the 'atomic' groups of source, which you can combine in whichever way >> you like by creating a composite source set and adding the appropriate >> source sets to it. A composite source set would accept both language and >> composite source sets. These source sets would all be configurable. >> >> In addition to this, we would have a separate set of strongly typed >> interfaces that define the language specific stuff you need to consume the >> source. You can ask a source set to turn itself into one of these views (it >> may just return `this`). The aim here is to keep separate the consumption of >> source set from how they are defined and configured, and so allow many >> different ways that source sets can be defined and built, but a consistent >> way to plug them in as inputs to something else. >> >> Things get a bit tricky when source sets need to be combined into a single >> set, as the strategy for merging the language-specific stuff is, itself, >> language-specific. There are a few approaches we could take: >> >> 1. Composite source sets know how to combine language source sets. They >> would need help from the language specific plugins for this, possibly by a >> language plugin registering a converter of some kind. >> >> 2. Composite source sets are just dumb collections of source sets. When you >> add a composite source set to a binary, it is equivalent to adding each of >> its children separately. A language plugin may make available a language >> source set implementation that can combine other language source sets of the >> same type, and you need to wire these up yourself. >> >> 3. Composite source sets are just dumb collections of source sets as for #2, >> and all language source sets can contain other language source set of the >> same type. >> >> At this stage, I think we'll probably go with #1, as it means that the >> aggregation is completely the source set's business (though the source set >> may ask some plugins for help), and nothing to do with the consumer. >> >> Regardless, for any of these options, to add support for a new language you >> need to provide a language specific source set, plus some strategy for >> merging the language source sets, plus some rules for what to do when the >> language source sets are added to a binary. > > Why do we need to try and do this dynamically? How dynamic really is this > situation? Only certain different language source sets are combinable. Also, > there may be different strategies for composition. For example, compilation > options that are only relevant when joint compiling. I was actually talking about composing source sets of the same language for joint compilation: how do we express this in the DSL, how do we merge the various language-specific meta-data, how do we expose this to consumers, etc? But yes, you're right that there's only certain combinations of different languages that we're interested in composing into a single logical thing, and those combinations are relatively static. We're more interested here in extensibility, so that a given language does not need to know about all the other languages it can be jointly compiled with. It's not really that tricky to make this work. A plugin simply needs to tell us that it can either generate Java stubs from its source or that it can parse (but not compile) Java source, then we can coordinate the rest. -- Adam Murdoch Gradle Co-founder http://www.gradle.org VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting http://www.gradleware.com Join us at the Gradle Summit 2013, June 13th and 14th in Santa Clara, CA: http://www.gradlesummit.com