[mono-api-info] Add `mono-api-info -L`, `mono-api-info -r`
authorJonathan Pryor <jonpryor@vt.edu>
Wed, 16 Dec 2015 15:59:06 +0000 (10:59 -0500)
committerJonathan Pryor <jonpryor@vt.edu>
Wed, 16 Dec 2015 18:02:19 +0000 (13:02 -0500)
commit4e45904553c949f353926f26ddbb444102da9d87
tree483b9ee6cc52b96ec5c4ce4708d228a7be712bf0
parentcd62639d9c8074fd1ccf56f5847d2faf33e4d40a
[mono-api-info] Add `mono-api-info -L`, `mono-api-info -r`

**The Scenario**: `mono-api-info` and `mono-api-html`, together, are a
useful way to track API changes over time, specifically to check for
accidental API breakage:

# Have a "known good" assembly version;
# keep reference/assembly.xml in version control
$ mono-api-info assembly.dll > reference/assembly.xml

# ...then on every new build, check for breakage:
$ mono-api-info assembly.dll > new-assembly.xml
$ mono-api-html reference/assembly.xml new-assembly.xml > assembly-diff.html
$ if grep '<p>Removed' assembly-diff.html > /dev/null ; then \
echo "ABI BREAK IN assembly.dll" ; \
cat assembly-diff.html ; \
fi

This is a very nice workflow, and has been used in Xamarin.Android to
track accidental API breakage for some time.

**The problem** with the above workflow are *implicit* references:
`mono-api-info` will happily look for dependencies in the same
directory as `assembly`, but it will *also* look for assembly
references in various system-specific directories, which is fine...

...until it *isn't* fine, e.g. if you have your own version of
mscorlib.dll that you need to use, *not* the system one, as your own
version may have API differences from the system mscorlib.dll which
are "percolated" into `mono-api-info` output. For example, on
"desktop" profiles, System.Attribute implements
System.Runtime.InteropServices._Attribute, and thus *all* custom
attribute types will have _Attribute listed as an implemented
interface. The Xamarin.iOS and Xamarin.Android mscorlib.dll,
meanwhile, does *not* have System.Attribute implementing _Attribute.
Consequently, changing the mscorlib.dll which is used while processing
an assembly will change `mono-api-info` output, resulting in "API
breakage" which doens't actually exist, because the wrong mscorlib.dll
was used to generate the original API description in the first place.

We need a way to control which mscorlib.dll/etc. are used. This can be
done by allowing specification of the assembly search directories, so
that we can "override" the default system-specific directory location.

**The solution**: Add a `mono-api-info -L PATH` option which adds PATH
to the list of directories that `mono-api-info` will search when
resolving assembly references. This allows "overriding" the system
directory location, as PATH will be searched for mscorlib.dll before
the system directory location.

Additionally, add a `mono-api-info -r ASSEMBLY` option, which will
pre-process ASSEMBLY (and all dependencies) and add the directory
which contains ASSEMBLY to the assembly search paths.

These two options are conceptually similar to `mcs -L` and `mcs -r`.

Finally, while adding support for these options, add support for
`mono-api-info --help`, so that we don't need to use only the man page
to get option information.
mcs/tools/corcompare/Makefile
mcs/tools/corcompare/mono-api-info.cs