Hi,
One of the goals for our C++ support is to offer dependency management for
binary artifacts built from C/C++.
Ideally, we want to reuse the existing dependency dsl, rather than add a new
native-specific dsl. So, you'd do something like:
apply plugin: 'cpp'
apply plugin: 'native-executable'
dependencies {
compile 'someGroup:someProject:1.2'
}
This would imply that:
* The headers for the library are downloaded, and the appropriate -I flag add
to the compiler invocation.
* The library binary for the variant we are building is downloaded, and added
to the linker invocation.
* The dependency meta-data is included in the published dependency descriptor
for the binary we are building.
* Depending on its type, the library binary is made available at runtime when
running the tests, or building a distribution, or installing the binary.
There is also some transitive dependency management needed:
* Library headers may require headers from some of its dependencies to be
available when compiling.
* Library binaries require its runtime dependencies to be available at runtime.
There are several aspects where dependency management for native binaries is
different to what we current offer for the jvm:
* Different types of artifacts are required at different points in the build:
headers at compile time vs binaries at link time. It would be nice to also
solve this for building jvm based projects, so that a project can, for example,
publish an api jar for use when compiling, and an impl jar for use at runtime.
* Related to this, different sets of transitive dependencies are required at
different points in the build: header dependencies at compile time, nothing at
link time, and full transitive closure of runtime dependencies at runtime. But
this is also true for jvm projects, we just ignore the problem at the moment.
* There are multiple variants of a given artifact, and this is a
multi-dimensional: os, arch, debug, compiler, and so on. Again, it would be
nice to also solve this for jvm projects, so that a project can, for example,
publish groovy 1.7 and groovy 1.8 variants, or scala 2.7 and scala 2.8
variants. Or a java project with some jni native pieces can publish variants
for the different platforms it supports. Or a web app project can publish fat
and skinny variants. Or dev, qa and prod variants.
This also implies that for a given project, some artifacts will be
variant-specific (binaries, debug symbol tables), and some artifacts will be
variant independent (headers, source files, documentation).
* For a given dependency, there are potentially multiple compatible artifacts.
For example, on linux, we can link against either a debug or non-debug variant.
So, if we're building a debug variant, dependency resolution should prefer the
debug variant of a dependency, but can fall back to a non-debug variant if
that's the only one available. But, on windows, for example, we can't do this
substitution.
* Some tools are sensitive to the naming scheme we use for artifacts. For the
java tools, we pass the path to the artifact in the cache directly to the tool,
and this works fine pretty much regardless of the artifact name. However, for
example, we must not include the version number in the header file names, and
probably should not include it in shared library names when linking or
installing.
* Different variants may be built and published together, or may be built and
published at different times. For example, I might build and publish the linux
variants in one gradle invocation, and then later build and publish the windows
variants.
So, that's the problem we want to solve. Of course, I'm sure we can chop this
into smaller pieces and solve the problem incrementally.
Any thoughts you have on either the description of the problem, or possible
solutions are most welcome. I'll post my thoughts about how we solve the
problem in some later emails.
--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com