Hi,

Now that we're looking at adding some experimental javascript support, we now 
have 2 non-JVM languages we need to model. The current SourceSet model does not 
really work for these new languages (and there are problems with the JVM 
languages, too).

Some issues with SourceSet:

* Has a runtimeClasspath. This doesn't make sense when we're not targeting the 
JVM. C++ and javascript source do have runtime dependencies, but these 
dependencies do not end up as a classpath. For both C++ and javascript, we're 
also interested in building different variants, where each variant can 
potentially have a different set of resolved dependencies. Supporting variants 
also makes a lot of sense in the JVM world too (groovy-1.7 vs groovy-1.8, for 
example).

* SourceSetOutput effectively represents a set of JVM byte code. This is the 
same as the issue above. Modelling the compiled source as byte code doesn't 
make sense when we're not targeting the JVM. Also, each variant of the same 
source will generally end up with different compiled output.

* Has a compileClasspath. As above. Also assumes that we're actually compiling 
something. And that all languages share the same compile classpath.

* Has a (possibly empty) set of Java source to be compiled and included in the 
runtime classpath. This doesn't make any sense if there's no Java source  in 
the project.

* Has a set of resources to be included in the runtime classpath. This doesn't 
make any sense if we're not targeting the JVM.

There are also some language specific issues:

* Java should have a source language level, and an annotation-processor 
classpath.

* Groovy should have a source language level, and separate compile, 
language-runtime, compile-implementation, and transformer class paths. Scala 
should have something similar.

* The ANTLR plugin assumes we're generating a parser to run on the JVM. The 
tooling may run on the JVM, but the generated source may not.

* For each language, we should distinguish between generated and non-generated 
source.

I think I'd like to turn the current 
SourceSet/SourceSetOutput/GroovySourceSet/ScalaSourceSet/CppSourceSet into 
something like this:

* Interfaces that represent language-specific set of source, and specifies 
output-independent meta-data about the source: things like source directories 
and include/exclude patterns, compile and runtime dependencies, language level, 
and so on. So, we'd have a JavaSourceSet, GroovySourceSet, ScalaSourceSet, 
CppSourceSet, JavaScriptSourceSet and so on.

* An interface that represents a composite set of source files. This would be 
used to group language-specific sets to describe their purpose. This type would 
be used for 'sourceSets.main' and 'sourceSets.test'.

* Interfaces that represent runtime-specific set of executable files. These 
would be used to represent the output of the source sets, one per variant that 
we can build. For JVM languages, we'd use something that represents a tree of 
class and resource files. For native languages, we'd use something that 
represents a set of object files. For javascript, we'd use a JavaSourceSet.

* All of the above would extend Buildable. This better models generated source 
(but doesn't quite solve the problem on its own), allows a separate processing 
pipeline to be assembled to build the output for each variant, and allows us to 
handle executable files that we don't build, but need to bundle or publish.

* There would be some way to navigate between the outputs of a source set and 
the source set itself. Not sure exactly how that should look. Each language 
source set ends up built into one or more output. Each runtime output is built 
from one or more language source sets. Maybe the association is only by name.


--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com

Reply via email to