[Mono-dev] xbuild usability

Jonathan Pryor jonpryor at vt.edu
Tue Nov 3 14:04:42 EST 2009

I'm toying with migrating Mono.Rocks to rely exclusively on MSBuild
(it's the future!  plus it simplifies life for VS users).  This looks
like it'll largely be trivial, but that's not the point of this email.
This is just context.

The point is improving the usability of xbuild so that it approaches the
usability of make(1).

So, usability point number one is already taken care of.  What's the
most common thing to do with make?  Invoking the default target:

        $ make

Fortunately, xbuild also does this:

        $ xbuild

...unless you have more than one .sln and/or .csproj in a directory.

        rocks$ ls
        Mono.Rocks.csproj  Mono.Rocks.sln ...

Oops.  So already my usability with Mono.Rocks is hampered:

        rocks$ xbuild
        MSBUILD: error MSBUILD0005: Please specify the project or
        solution file to build, as more than one solution or project
        file was found in the current directory

Proposal Number 1: .sln files should have higher precedence over
other .*proj files, so if there is only one .sln file in a directory and
also one or more .csproj files, an "unqualified" xbuild command will
build the .sln file.

Otherwise I'd need to do:

        rocks$ xbuild Mono.Rocks.csproj

I'm lazy; I don't want to type that much if I can avoid it. :-)

Bonus: this is what MSBuild does as well -- 'msbuild' will runs
Mono.Rocks.sln and ignores Mono.Rocks.csproj.  So implementing Proposal
1 improves MSBuild compatibility.  Yay.

However, this raises us to the next "problem."  Makefiles make it easy
to provide one-off "helper" targets:

        # Makefile
        	csharp -r:lib/mono-rocks/Mono.Rocks.dll
        	nunit-console2 $(mrdir)/Mono.Rocks.Tests.dll
        # ...

These logically belong to the solution as a whole, and should be
executable from the topdir:

        rocks$ xbuild /t:shell
        rocks$ xbuild /t:check
The question then becomes, how do we support this?

If we follow the advice of Proposal # 1, the .sln will be executed,
but .sln files don't support inserting <Target/>s.  We could place the
<Target/>'s into a .csproj, but then we can't invoke the targets without
also specifying the .csproj file (and since I'm lazy, I don't want to do

There are several possible solutions here:

Proposal 2a: Just use make(1)!

Given that I'm attempting to stay within the confines of xbuild, this is
a non-answer, but it may be the most workable answer regardless.

Proposal 2b: Add support to xbuild to look for a .targets file which
will be loaded inserted into the generated .proj file.  This .targets
file would share the same basename as the .sln.  Thus rocks could have
solution-level targets by adding a Mono.Rocks.targets file.

Proposal 2c: Like 2b, except it looks for a .proj file instead of
a .targets file.

Proposal 2d: We could add a custom section to the .sln file file which
explicitly references the .targets file, e.g. a
CustomTargetsFile=foo.targets section.

Proposal 2e: We add the <Target/> to an existing .csproj which is
referenced by the .sln, and if the target specified on the command line
isn't found within the .sln then xbuild looks within all .csproj files
referenced by the .sln and executes the first matching <Target/>.

The problem with all of these is that they amount to an extension of
MSBuild.  I don't particularly care, though, as it would simplify
command-line usage, and (as we all know) VS users don't use the command
line, so these extensions wouldn't matter (as much). :-)

That said, it is worth considering Microsoft's stance.  Some Googling
time shows that the lack of "proper" solution support is biting *lots*
of people, to the extent that dropping .sln file and moving entirely
to .proj files within VS was the 3rd most requested feature for MSBuild:


.proj files, being "proper" MSBuild files, would allow adding <Target/>
elements directly, so long term this would be the sane thing to do (for
MSBuild and for xbuild), but it doesn't address what to do wrt .sln
files (aside from "replace them", which isn't an option for *current* VS

This does suggest that (2c) should be dropped (we don't want special
support for .proj files if .proj may become the new default) and (2e)
(rather complicated behavior that ankit wasn't thrilled with).

This leaves (2a) (suck it!), (2b) (sane), and (2d).  I don't like (2d)
because it requires mucking with a largely undocumented file format.

Ankit also seems to like the (2b) solution as well.


 - Jon

More information about the Mono-devel-list mailing list