[Mono-dev] Resolving dependencies while compiling

Grzegorz Sobanski silk at boktor.net
Wed May 20 11:23:29 EDT 2009

* Jonathan Pryor <jonpryor at vt.edu> [2009-05-20 15:59]:
[cut everything about extra copies and referencing]
> 	gmcs -t:library -lib:b/bin/Debug,a/bin/Debug c/c.cs -r:b.dll -r:a.dll

Yeap, all the above is true. And is the same for both VS and Mono.

But I think, that paszczi in his original mail missed the real problem:

> Now, if you don't want to specify the entire assembly dependency chain
> (e.g. you only want to specify b.dll or X.dll, not both a.dll+b.dll or
> X.dll+Y.dll), then you *must* have a copy/symlink:

The "must" is (un)fortunately not true for VS.
> 	cp a/bin/Debug/a.dll b/bin/Debug
> 	gmcs -t:library c/c.cs -r:b/bin/Debug/b.dll

It is only true if c.cs (c.dll) uses types from a.dll.

Ex: if a.dll contains class LibA {...}
And b.dll contains 
class LibB {
  public string Met1 () { return "hey!"; }
  public LibA Met2 () { return new LibA (); }

I can sucessfully compile c.dll in VS if it only calls Met1, without
referencing a.dll, and without having any copies of a.dll laying around.
(after compiling b.dll I have deleted all a.dll files)
And I can even execute c.dll without having a.dll (as dependecies
are resolved at call time not at startup time. It is the same in Mono
I believe).

Unfortunately to compile c.dll in gmcs I need a a.dll even if c.dll
does not use any type from a.dll.

(If b.dll is referencing a.dll but does not have anything from a.dll
in it's public contract, then c.dll will compile fine in gmcs)

Now, some real-life example.
We are building modular software and using a bunch of libraries, for
example: Castle.MicroKernel, Castle.ActiveRecord, etc. (let's call them
tier 1)
They reference some more libaries. Iesi.Collections, NHibernate (tier 0)

We build modules (tier 2): ModuleA, ModuleB referencing and using a lot 
of tier 1 libraries (Castle.* mainly).

And those modules are used by some applications (tier 3). Now even if 
application is not using any types from Tier1 they are still needed
at compile time (in mono, not in VS). What's more, even dlls from Tier0
are needed.

There are different solutions we could use:
1) gmcs could compile like VS, not knowing the types from Tier0/1 -
2) reference all dll's from Tier0/1 in application - bad
3) copy (symlink) all dll's from Tier0/1 to directory of every Module* (Tier2)
   - that's what we've been using until now. But it started to be 
     a real maintenance problem.
4) put all dll's from all Tiers to one directory - we want to avoid that
5) use MONO_PATH= during compilation to show directories where Tier0/1
   dll's can be found - we are using it now (I know it is 'not
   recommended' :P)
6) use -lib instead of MONO_PATH - but that would still mean adding to
   every project from Tier3 every directory from Tier0/1.
To sum up - problem is when I'm using b.dll which has something
from a.dll in it's public API, but I'm not consuming it. I would
like to skip a reference to a.dll in c.dll then.

(We can ensure in some other way that all needed dll's from tier0/1 
will be available at runtime).

Uff, a long mail ;P


More information about the Mono-devel-list mailing list