Hi,

What I'm reading below looks exactly like Maven, except for the scope of the
dependencies. Just for fun, I'll try to make the differences in your system and maven more concrete. Correct me if I get anything wrong. In Maven we have 2 types of 'dependencies': artifact dependencies, which control build order (amongst other things), and 'mojo dependencies', which
hook into the lifecycle and make sure that certain things are executed.

Your system only has 1 type of (build order) dependency, which depends on
phases/goals in all projects in your system. If you were to depend on
the 'install' phase of other projects only, you'd have the Maven <dependency>
thing.

In maven, if you specify a <dependency>, you implicitly specify a dependency
on the install/deploy phase (depending on wheter the artifact's project is in
the reactor). In your system you can specify a dependency on 
'generate-resources',
but you can't specify for what project that is. So basically your entire 
project tree
can be built using just 1 lifecycle, where for each lifecycle phase, that phase 
is executed
for all projects - and all hooks to that phase from all projects are executed.

I bet your system only works for a monolithic project tree, since you require 
access to
files in artifacts that have not been completely built. I don't know if you 
have a 'deploy'
kind of phase, but is it possible for you to just build a sub-tree of your 
project tree,
and if that sub tree requires some icon, can that icon be pulled from a remote 
repo?

Snippet:

The key to make this simple was "inversion of dependency". In my project (module) I don't say "my new phase depends on generate" but "generate depends on my new phase". When the build tool decides to look at "generate", it first considers all the phases which "pre-depend" on it. Like so:

## generate:: generate-includes

This can be done in Maven: in the project that has a 'generate-includes' 
requirement
just adds a mojo for that to the 'generate-sources' phase. Other projects don't need to know about that Depending projects just know that if they were to depend on a project that has 'generate-sources' executed, then that project has taken care of generating everything needed for that project.
You don't even have to know it generates includes or icons or whatever.

Now, MetaMake will look for projects which define "generate-includes" (or new dependencies for it) and runs those phases/goals/targets first.

Basically the same as in maven, though it doesn't search for 
'generate-includes', it just
executes 'generate-sources'.

If you were to run 'mvn generate-resources' in a maven project tree you'd get 
the same
results as with MetaMake.


The difference here is more of a philosophical nature: in Maven, if you depend 
on some
icon resource, you'd specify a dependency on the project that creates it. But 
your system
looks like it was meant for C development, and linking there also includes 
processing .res files
for GUI elements that embed icons (something like that?). In maven this would 
be a bit more complicated,
but there are several solutions for this (which I'm not going to enumerate).


Btw, I've run across a problem that's kind of related to this: i just made a 
plugin
that creates a bill of materials from an assembly: it scans the directory 
created
by assembly:directory, creates a listing for all files and lists the details for
all jars by looking at the embedded pom.xml in the artifacts.
But that file needs to be inside the assembly itself. So it only works if you
run assembly:directory first. The problem is that you could also run it on some
assembly archive, and then somehow add the file to the assembly afterwards. I 
can't just
run it in 'generate-resources' or something since the directory structure 
generated from the assembly
needs to be in the file too. Also, updating a tar.gz is not ideal (gunzip, tar 
uvf, gzip).

So in this case, I would actually require writing a plugin for the assembly 
plugin itself, that
scans the directory just after it's created and just before it's converted to 
an archive. But this
is only possible if there's a complete unzipped directory, which isn't the case 
if dependencies
are added to the archive directly from the local repository.

So, 2 solutions I can think of:
1) let the assembly plugin support plugins for itself; this is not generic 
enough..
2) split the assembly plugin up, binding it to 2 executions, and let the bill 
of materials plugin
execute between the 2 executions.

Btw, in your MetaMake system, how would you solve this?
-- Kenney

[EMAIL PROTECTED] wrote:
Jason van Zyl <[EMAIL PROTECTED]> schrieb am 04.12.2006 17:43:29:

As I said before, I've had very good results with a build system in which you can specify arbitrary phases and say "this phase depends on that one".
And how much luck have you had showing that system to other people? And how much luck have other people had looking at what you've made without them having to consult you?

It's about as hard to explain and understand as the Maven dependency system. It's just an odd idea at first glance.

You see, just like Maven, we have several "big" phases ("generate", "compile", "link", "site").

Eventually, we added generate-includes, generate-source, generate-scripts, generate-makefiles, ...

The key to make this simple was "inversion of dependency". In my project (module) I don't say "my new phase depends on generate" but "generate depends on my new phase". When the build tool decides to look at "generate", it first considers all the phases which "pre-depend" on it. Like so:

## generate:: generate-includes

Now, MetaMake will look for projects which define "generate-includes" (or new dependencies for it) and runs those phases/goals/targets first.

This way, each developer can create their own little world, making sure all their phases are called in the correct order. You need a second "generate include" phase? No problem. Hooking them into the big world is also simple because of the predefined phases which are always there.

The implementation was dead simple (4h in plain C) and worked reliable at the first attempt. We only had to add caching because searching 20'000 Makefiles for targets was bit slow :-) My project (AROS) is using this build system for several years, now. Currently, we have roughly 5'000 phases which, oddly enough, makes the build more *simple*.

Let me explain. You have a big maven project with hundreds of modules (we have about 200). How do you make sure that module X is built and ready before module Y? Or, say, I need a generated file from a module now but not all of it? In current Maven, you have to move things around in the parent POMs. The dependencies "leak".

In our world, I say:

Project X:

## install:: workbench-icon
## workbench-icon:: icon-generator-install
... create the workbench icon ...

Project Y:

## site: workbench-icon
... use the icon ...

Let's imagine I have a clean checkout and want to see the website. Even though workbench hasn't been completely yet, the single icon file can be generated after the icon generator has been installed. When I say "mmake site", it will compile and install the icon generator, generate the workbench icon and then the HTML files.

In maven, this level of detail is probably not possible. Maven projects are more encapsulated than ours and I don't think it's even necessary to go to such lengths in Maven. Operating systems usually have many small components with heavy dependencies between them, that's why we choose the approach described above.

What I would like to see is a simple way to "'install' depends on my new phase/target/goal" in a Mojo and in the execute-elements in the POM. That way, I could do extra work before something is installed, without influencing the standard lifecycle, other projects or plugins.

Creating a system where you have random interaction can potentially create a system with extremely high infrastructural costs. Shared infrastructure means lower costs and that means a predictable system.

Random? Since when is the maven dependency resolution "random"? I haven't seen the code but from what I see, it probebly works exactly like the MetaMake target resolution.

Regards,


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to