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)...

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 :)


Michael

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email


Reply via email to