Our packages work exactly the way you describe: a module which can build anything you like, and which has references to other packages for its dependencies.
Apters build steps let you run an arbitrary command, commonly a shell script. For more common cases (a C package with autotools, Java with Ant, etc), you can import a module which knows how to build them, and let it do all the work. (That module is versioned too.)
The language looks something like this:
let env = merge [deps.libfoo, deps.libbar, deps.gcc, prefix "src" (deps.source)]
in extract "/installpath" (build env "/buildscript")
This would merge together some dependencies, including the source code, run a build script in that environment, and extract the installation path from the result. /buildscript would likely contain something like "make DESTDIR=/installpath install".
deps.libfoo and deps.libbar get mapped to other Apters packages via a dependency list.
We handle incremental builds through caching: any build step with identical inputs (by hash) will use a cached result.
Our packages work exactly the way you describe: a module which can build anything you like, and which has references to other packages for its dependencies.
Apters build steps let you run an arbitrary command, commonly a shell script. For more common cases (a C package with autotools, Java with Ant, etc), you can import a module which knows how to build them, and let it do all the work. (That module is versioned too.)
The language looks something like this:
This would merge together some dependencies, including the source code, run a build script in that environment, and extract the installation path from the result. /buildscript would likely contain something like "make DESTDIR=/installpath install".deps.libfoo and deps.libbar get mapped to other Apters packages via a dependency list.
We handle incremental builds through caching: any build step with identical inputs (by hash) will use a cached result.