On 30 Nov 2013, at 11:07 am, Michael Putters 
<michael.putt...@binarygenetics.com> wrote:

>  
> From: Adam Murdoch [mailto:adam.murd...@gradleware.com] 
> Sent: Thursday, November 28, 2013 11:52 PM
> 
> > 1. Primitive language source sets that contain source files of a given 
> > language. Headers and source files would live in different source sets.
> > 2. A way to declare dependencies between language source sets.
> > 3. A way to combine language source sets of a given type into a composite 
> > source set of the same type.
> > 4. A way to define a logical source set, where each logical source set 
> > represents some logical entity with an API and implementation. A logical 
> > source set would have, by convention, a public headers source set, a shared 
> > headers source set, and a bunch of implementation language source sets. Any 
> > of these can be empty. There would be, by convention, a dependency from 
> > each implementation source set on the shared headers and the public 
> > headers, and a dependency from the shared headers on the public headers. 
> > When you declare a dependency on a logical source set, the only thing you 
> > can see are the public headers.
> > 5. A library component has-a logical source set.
> > 6. An executable component has-a logical source set with no public headers.
>  
> > In other words, it’s just more of the same - a graph of things with 
> > dependencies between them, with some conventional wiring.
>  
> > As far as convention for a component goes, I’d do something like this:
>  
> > - A language source set for each implementation language.
> > - No language private headers. You’d be able to define them if you needed, 
> > by defining a new header source set and adding a dependency from the 
> > specific language source set on the header source set.
> > - Shared header source set contains any header files found in 
> > `src/${component.name}/include` (say)
> > - Public header source set contains ant headers found in 
> > `src/${component.name}/public` (say)
>  
> This graph is getting deep J
>  
> So what would the DSL look like for such a list? Because I think it’d be 
> easier to visualize through the DSL… Something like this (still fairly new to 
> Groovy so there is likely a better way/syntax in many cases, but I’m more 
> wondering about how well it’d fit the model)?
>  
> sources {
>     mylibrary {
>         // C++ sources (part 1)
>         cppsourcepart1(Language.Cpp) {
>             <typical source set stuff>
>         }
>  
>         // C++ sources (part 2)
>         cppsourcepart2(Language.Cpp) {
>             <typical source set stuff>
>         }
>  
>         // C++ sources (combined as in #3)
>         cppsource(Language.Cpp) {
>             sources cppsourcepart1, cppsourcepart2
>             include objcheaders // #2, but not needed in this case because of 
> the logical source set shared list
>         }
>  
>         // C++ headers (internal)
>         cppheaders(Language.Cpp) {
>             <typical source set stuff>
>         }
>  
>         // C++ headers (API)
>         cppapi(Language.Cpp) {
>             <typical source set stuff>
>         }
>  
>         // Objective-C sources
>         objcsource(Language.ObjectiveC) {
>             <typical source set stuff>
>         }
>  
>         // Objective-C headers
>         objcheaders(Language.ObjectiveC) {
>             <typical source set stuff>
>         }
>  
>         // Logical source set, #4
>         mylib {
>             implementation cppsource, objcsource
>             shared cppheaders, objcheaders
>             public cppapi
>         }
>     }
> }
>  
> There’s probably a way to make it less verbose, although most of it would be 
> behind the scenes if the source layout fits the conventions Gradle would use… 
> And obviously the names (implementation/shared/public) are just examples.
> I think this example also differs a bit from your description because you 
> mention having 0 or 1 public and shared source sets, and here there are 2 
> shared source sets…
>  
> And while talking about the DSL (and to continue something I started talking 
> about with operating systems in a previous email), I noticed the design 
> document mentions ARM, PowerPC and cross compilation.
> Right now there is just a single element that identifies the platform 
> (x86_64, armv7, armv8, …) but I think it would make sense to make it become a 
> family/type pair, so this:
>  
> architecture 'armv7'
>  
> Would be the same as:
>  
> architecture family: 'armv7' type: 'default'
>  
> Because just taking gcc as an example, on top of the many ARM architectures 
> it supports (via -arch), there are also a lot of target processor types (via 
> -mcpu). Cf http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html.
>  
> Now, while detecting all possible architectures (or at least the ones we want 
> to support) is not too hard, detecting all possible processor variants would 
> be a horrible task, especially considering how many manufacturers provide a 
> special gcc build that targets their own specific microprocessor. So it could 
> just be a string and then Gradle detects a set of known types. For example 
> for the Intel architecture it’d make it possible to know if we enable 
> optimizations for Pentium Pro, MMX, SSE, etc. If it’s not a recognized type, 
> it just gets passed to the compiler and worst case, the compile fails with an 
> error about an unsupported architecture.

We definitely want to move beyond strings and model architecture as a thing, in 
a similar way we want to do for operating system

The pattern would be that Gradle has a pretty general model for describing 
architecture, plus defines some conventional architectures that it understands 
well enough to do something useful. The set of architectures would be open, so 
that you can define your own.

Something that the DSL also needs to do is allow you to specify things with 
different levels of detail. For example you should be able to say: This 
component targets generic 64bit intel processors, vs this component targets 
core i7 processors specifically.

For the target architectures that Gradle (or rather the toolchain 
implementation) knows about, for example a generic 64bit intel, it can just do 
the right thing. For more specific architectures that the toolchain doesn’t 
know about, such as say core i7, you’d need to tell the toolchain what to do to 
invoke the various tools for this target.


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