On 2 Dec 2013, at 8:30 pm, Michael Putters <michael.putt...@binarygenetics.com> wrote:
> On 2013-12-02 00:40, Adam Murdoch wrote: >> Good question. There’s 4 things the DSL needs to do: >> 1. Allow you to define a source set of a given type and configure it, >> e.g. to set the source directories or whatever. >> 2. Allow you to declare dependencies between source sets (and other >> things). >> 3. Allow you to combine source sets into a component. >> 4. Allow plugins to do these things as a convention and allow you to >> change what the convention has done. >> One option is to flatten the whole thing out, so that definition and >> wiring and composition are all separate things. For example, to wire >> up the source for a library ‘mylib’ the plugins might do something >> like: >> sources { >> // headers and source files are separate things >> mylibApi(HeaderSet) { >> srcDirs = ‘src/mylib/public’ >> } >> mylibShared(HeaderSet) { >> srcDirs = ‘src/mylib/include’ >> dependsOn mylibApi >> } >> mylibCpp(CppSourceSet) { >> srcDirs = ’src/mylib/cpp’ >> dependsOn mylibShared >> } >> mylibC(CSourceSet) { >> srcDirs = ‘src/mylib/c’ >> dependsOn mylibShared >> } >> mylib(NativeLibrarySourceSet) { >> api mylibApi >> source mylibCpp, mylibC >> } >> } >> libraries { >> mylib { >> source = sources.mylib >> } >> } >> You’d be able to navigate to things via their relationships in order >> to configure them and query them: >> libraries { >> mylib { >> sources { >> cpp { >> srcDirs = ‘…’ >> dependsOn libraries.someOtherLib >> } >> } >> } >> } >> To wire in more source sets, you’d do something like: >> // a generated source set >> sources { >> mylibGeneratedC(CSourceSet) { >> generatedBy someTask >> dependsOn libraries.someLib >> } >> mylib { >> source mylibGeneratedC >> } >> } >> // some private headers visible only to the C source files >> sources { >> mylibCHeaders(HeaderSet) { >> srcDirs = ‘…' >> } >> mylibC { >> dependsOn mylibCHeaders >> } >> } >> // windows specific cpp >> sources { >> mylibWindowsCpp(CppSourceSet) { >> srcDirs = ‘src/mylib/windows/cpp’ >> dependsOn operatingSystems.windows >> } >> mylib { source mylibWindowsCpp } >> } >> That is, most stuff happens at the source set level. This is flexible >> but ignores that, from most people’s point of view, the component is >> the more important concept. >> So, another option is to combine definition and aggregation. The >> plugins would do something like: >> libraries { >> mylib { >> sources { >> api(HeaderSet) { >> srcDirs = ‘src/mylib/public’ >> } >> shared(HeaderSet) { >> srcDirs = ‘src/mylib/include’ >> dependsOn api >> } >> cpp(CppSourceSet) { >> srcDirs = ’src/mylib/cpp’ >> dependsOn shared >> } >> c(CSourceSet) { >> srcDirs = ‘src/mylib/c’ >> dependsOn shared >> } >> } >> } >> api = sources.api >> } >> Each source set could probably be visible as a separate thing via the >> sources container: >> sources { >> mylibApi { // tweaks the libraries.mylib.sources.api source set } >> } >> To wire in more source sets, you’d do something like: >> // a generated source set >> libraries { >> mylib { >> sources { >> generatedC(CSourceSet) { >> generatedBy someTask >> dependsOn libraries.someLib >> } >> } >> } >> } >> // some private headers visible only to the C source files >> libraries { >> mylib { >> sources { >> cHeaders(HeaderSet) { >> srcDirs = ‘…' >> } >> c { >> dependsOn cHeaders >> } >> } >> } >> } >> // windows specific cpp >> libraries { >> mylib { >> sources { >> windowsCpp(CppSourceSet) { >> srcDirs = ‘src/mylib/windows/cpp’ >> dependsOn operatingSystems.windows >> } >> } >> } >> } >> This approach seems more natural for most use cases, but is more rigid >> because source sets can only be defined as part of a native component, >> and this isn’t always the reality. >> We might also combine the two approaches, so you can define source >> sets either at the top level or as part of a component, or wherever it >> makes sense, and refer to them from either context: >> sources { >> someArbitrarySourceSet(CSourceSet) { >> dependsOn libraries.myotherlib >> dependsOn sources.someSourceSet >> dependsOn libraries.mylib.sources.cpp >> } >> } >> libraries { >> mylib { >> // An alias for >> libraries.mylib.sources.add(project.sources.someArbitrarySourceSet) >> buildFrom sources.someArbitrarySourceSet >> } >> myotherlib { >> buildFrom sources.someSourceSet >> } >> } > > Hm I wouldn't mind working on that (assuming nobody is already doing it)… That would be great. > > First on the source level approach then expand it so the combined approach is > also possible. > > But I believe it might be still be a a bit big for a single pull request > (especially considering I'm still quite new to the codebase), how do you > think this task could best be split up so that it can become multiple pull > requests? Unless it's actually not that big and will look simple once I dive > in :) I think we should do this as a series of pull requests. I’ve fleshed out a bit of a plan for how we could do this: https://github.com/gradle/gradle/blob/master/design-docs/continuous-delivery-for-c-plus-plus.md#feature-flexible-source-sets There are 3 stories, each with a couple of steps. -- Adam Murdoch Gradle Co-founder http://www.gradle.org VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting http://www.gradleware.com