On Mon, Oct 26, 2015 at 03:35:12PM -0700, marko kiiskila wrote:
> Hi,

[...]

> And 2nd (related) topic:
> At the moment there is libs/console/full and libs/console/stub.
> What kind of mechanism should we have for picking between
> these two implementation? What I’d need is a way for a builder
> of project to pick between these, and all eggs in the project
> to have include the header file for the right implementation.
> 
> But I also want to be able to specify within egg definition that
> the egg will make calls to console_printf(). Egg itself does not
> care which one of the implementations gets used.
> 
> Is there a way to do this kind of thing yet?

The newt tool supports the concept of "capabilities" which can address
this requirement.  There are two ways to express a dependency in an
egg's yml file:
    * Simple dependencies (egg.deps)
    * Required capabilities (egg.req_caps)

If egg X has a simple dependency on egg Y, the newt tool gives X access
to Y's include directories, and it ensures that Y gets compiled and linked
into the final product when the target is built.

Capabilities work a bit differently.  Whereas a simple dependency
expresses a relationship to a specific egg, a required capability
expresses a relationship to an *interface*.  Many different eggs can
expose the same capability (interface), while having different
implementations.  Furthermore, the egg which requires the capability
doesn't actually have to "know" which implementation it is being linked
with.  All that is required is that: a) the egg indicates that it
requires a particular capability, and b) some other egg pulled in by the
build process indicates that it supports that capability.

Below is an example of how the console feature might be handled.  In
this example:
    * There are two console eggs (stub and full)
    * The "peripheral" egg requires the console capability
    * The "myproject" project depends on a concrete console implementation.

    <libs/console/full/egg.yml>
        egg.name: "libs/console/full"
        egg.caps: console

    <libs/console/stub/egg.yml>
        egg.name: "libs/console/stub"
        egg.caps: console

    <libs/peripheral/egg.yml>
        egg.req_caps: console

    <project/myproject/myproject.yml>
        project.eggs:
            - libs/peripheral
            - libs/console/full

All that said, the capabilities feature isn't actually fully implemented
yet; the above is just how I might expect it to work once it is done :).

Here are a few more questions that I think need to be answered:

    * How does the "peripheral" egg include the appropriate console
      header files?  Even if both console eggs have identically named
      header files, newt needs to arrange for the appropriate include
      directory to be passed to the compiler.

    * What is an easy way to switch between the debug and full
      implementations.  The user should not need to modify the
      myproject.yml file to do this.  Perhaps the "identities" feature
      can be used here.

Chris

Reply via email to