[Mono-list] Understanding versions

Jonathan Pryor jonpryor@vt.edu
Thu, 31 Mar 2005 07:46:45 -0500


On Wed, 2005-03-30 at 10:33 -0800, Bill Medland wrote: 
> Can anyone help me understand all this please?

History may be beyond understanding... :-)

> I am working under Linux (Red Hat Enterprise Linux 3), building from the 
> anonymous svn.
> I have a user, mono, which I use for building.  In /home/mono/svnversion I 
> have a libgdiplus, mcs and mono directory, containing the source from svn.
> I see that I also have /usr/local/lib/mono which contains a 1.0 and a 2.0 
> directory and a gac directory containing a directory per assembly, containing 
> a 1.0.500.0_... and 2.0.36000.0_... directory containing the actual assembly.  
> The /usr/local/lib/mono/1.0/<assembly> links to the one in gac.
> 
> Surely there should be some sort of 1.1 directory structure too?

No.  Or yes.  Maybe?

This was discussed recently (this year) on mono-hackers.  The consensus
was basically this: $prefix/lib/mono/VERSION is interpreted to be for
the major version number of .NET that Mono targets; minor version
numbers are currently ignored.  Hence we use 1.0 and 2.0, not 1.0, 1.1,
and 2.0.

Why?  Laziness.  History.  Compatibility.  And Mono doesn't currently
build a 1.0 profile (1.1 is the default, and who wants a 1.0 profile
anymore?).  And it might break someone if we changed the directory
names.

Could this be done better?  Certainly, but there are more important
things to worry about than the sanity of $prefix/lib/mono/VERSION.

> System.Environment.Version returns 1.1.4322.573
> mcs --version returns 1.1.5.0
> mono --version returns 1.1.5
> 
> I presume that since this is the latest source I am actually building version 
> 1.1.5 which is presumably a build of 1.1

Now you're confusing things.  Perhaps because Mono confuses things.

We have two different versions running around: the profile version
(which version of .NET we're targeting -- 1.0, 1.1, 2.0...), and the
Mono version.

THESE HAVE NO RELATION.  Mono 1.0.x targets .NET 1.0/1.1/2.0.  Mono 1.1
also targets .NET 1.0/1.1/2.0.

Mono follows the Linux-kernel/Gnome versioning conventions, which is
this: for an X.Y version number, if Y is even, it's a stable release; if
Y is odd, it's a development release.  If X changes, then binary
compatibility was broken in some way.

Thus Gnome 1.4 is binary incompatible with Gnome 2.0.  Gnome 2.1 was the
development branch of Gnome 2.2, which is binary compatible with Gnome
2.0.

All "Mono 1.1" means is that it's a development branch for the next
stable release of Mono, which will be 1.2.  (The "minor detail" that
Mono 1.1 is better tested and more stable than 1.0 is beside the point;
it's still considered a development branch, even if we are recommending
its use over 1.0.6.)

With the above in mind, we can say this:

System.Environment.Version returns the version of the .NET profile that
is targeted.  This is often the same version as what .NET would return.
As such, it will return 2.0.X.Y when running under the 2.0 profile, even
though it's running under Mono 1.1. :-)

`mono --version` and `mcs --version` return the version of the Mono
distribution.

> So. 
> a. If I use mcs to compile a simple program and then use mono to run it, which 
> version of the assemblies will it use (e.g. which System.Windows.Forms.dll)

It will use the version that is sym-linked in
$preflix/lib/mono/1.0/System.Windows.Forms.dll, which will be the 1.0
version of System.Windows.Forms.dll.

If you used gmcs instead, you'd get the 2.0 version of
System.Windows.Forms.dll, since gmcs targets the 2.0 profile.

> b. If I use svn update to get the latest code and then run make and make 
> install in the mono directory how does it decide which version it is making 
> and where to place the assembly?

Mono will *always* place a copy into the
$prefix/lib/mono/gac/ASSEMBLY/1.0.5000... directory.  So you'll
overwrite the previous version of System.dll et. al.

If you configured your mono checkout with --with-preview=yes, make
install will *also* place a copy into
$prefix/lib/mono/gac/ASSEMBLY/2.0.3600..., overwriting whatever file was
previously there.

In other words, you can only ever have two versions of any Mono
assemblies, both of which will be overwritten by Mono during make
install.  Which means that Mono isn't parallel-installable with itself
(you have to choose a different prefix if you want a different version
of Mono).

(Note that the 1.0 library and the 2.0 library will differ; during
`make` these libraries are built once for each profile, setting various
#defines for each profile.  The versioned assemblies are placed into
mcs/class/lib/PROFILE, and it's the PROFILE/ASSEMBLY file which is
placed into $prefix/lib/mono/gac/ASSEMBLY/VERSION...)

Why is this the case?  Because Mono doesn't choose the version number
for those assemblies, Microsoft does, and for compatibility we need to
choose the same version numbers so that when Mono compiles a
program .NET will be able to load the correct assemblies when running
under .NET.  Compatibility trumps all.

 - Jon