Build an MSBuild Project Safely with xbuild
You will use the installed Mono xbuild command to build a project or solution, choose a target and property, validate the project file, and save a diagnostic log when something fails. The examples use a throwaway build directory and do not require administrator access. Allow about 10 minutes if the project and its dependencies are already present.
The route
Jump straight to the step you need, or tick off Done means at the end.
Before you start
This guide describes the xbuild supplied by the Debian package mono-xbuild on this machine. The installed package is version 6.8.0.105+dfsg-3.6ubuntu2, and the command reports XBuild Engine Version 14.0. xbuild is a legacy Mono tool; the command itself prints a deprecation notice recommending msbuild. That notice is useful context, but the options below are the options documented by this installed xbuild.
You need a readable MSBuild project or solution file, such as Example.csproj or Example.sln. Work from a copy if the build generates files inside the source tree. A normal build can run as your own user. Do not use sudo unless the project explicitly needs a privileged external tool: elevating a build gives project tasks unnecessary access to the machine.
1. Confirm the installed command
Check which executable will run and record its version. Keep the warning about deprecation; it is printed by this installation and is not a build failure by itself.
$ command -v xbuild
/usr/bin/xbuild
$ xbuild /version
XBuild Engine Version 14.0
Mono, Version 6.8.0.105
The option starts with a slash, as do the other xbuild switches in this guide. If your output names a different engine or Mono version, keep that difference in your notes when comparing results.
2. Select the project explicitly
Change to the directory containing the project and name the file. An explicit path prevents xbuild from silently choosing an arbitrary project. The command accepts a project or solution as its main argument.
$ cd /path/to/source-tree
$ xbuild Example.sln
If you omit the file, xbuild searches the current directory for a solution or project whose name ends in proj. That default is convenient in a small directory but easy to misread in a repository containing several projects. Prefer the explicit form when documenting a build or troubleshooting one.
A successful build ends with a zero exit status. Check it without hiding the build output:
$ xbuild Example.sln
$ test "$?" -eq 0 && echo "build succeeded"
build succeeded
Do not treat a visually quiet terminal as proof of success. The shell status is the reliable check for scripts.
3. Build a particular target
Use /target: when the project defines more than its default target. Multiple target names are separated by commas.
$ xbuild Example.csproj /target:Clean,Build
Target names belong to the project and its imported targets. If the requested name is not defined, xbuild reports an error rather than inventing a target. A clean target can remove generated outputs, so review the project before running it. If you only need a normal build, omit Clean.
4. Override a project property for one run
Use /property:Name=Value to supply a value on the command line. The documented long form is the least ambiguous choice.
$ xbuild Example.csproj /property:Configuration=Release
Command-line properties override values supplied by the project file. That makes them useful for a one-off release build, but it can also make a command differ from the checked-in configuration. Put the complete command in a build note or script if another person must reproduce it.
Quote values containing spaces or shell metacharacters. The quotes protect the shell; they are not part of the property value.
$ xbuild Example.csproj "/property:OutputPath=/tmp/example build/"
5. Validate the project before building
Use /validate to ask xbuild to validate the project file against its schema. This checks the project structure without turning schema validation into a replacement for a real build.
$ xbuild Example.csproj /validate
To name a schema explicitly, append it as documented:
$ xbuild Example.csproj /validate:YOUR_SCHEMA
Replace YOUR_SCHEMA with a schema identifier that exists in the installed xbuild environment. Do not copy this placeholder literally. If the project is XML-invalid or does not match the selected schema, stop and fix the project file rather than trying random toolset versions.
6. Make failures readable
Start with /verbosity:minimal or the default output. Increase verbosity only when the failure needs more context. The accepted levels are quiet, minimal, normal, detailed and diagnostic.
$ xbuild Example.sln /verbosity:detailed
For a durable log, add a file logger. The logger defaults to msbuild.log; give it a deliberate path so an old log is not mistaken for the current run.
$ xbuild Example.sln /fileloggerparameters:LogFile=/tmp/example-xbuild.log;Verbosity=normal
$ sed -n '1,80p' /tmp/example-xbuild.log
The semicolon is part of the logger parameter string. Quoting the whole argument is safer when the command is copied into a shell script:
$ xbuild Example.sln "/fileloggerparameters:LogFile=/tmp/example-xbuild.log;Verbosity=diagnostic"
A diagnostic log can contain source paths, property values and dependency details. Treat it as build data, not as a public attachment. Remove the temporary log when you have finished investigating:
$ rm -- /tmp/example-xbuild.log
That removal is irreversible. If the log may be needed for a bug report, copy it to an approved location first and check it for credentials or private paths.
7. Choose the toolset deliberately
Use /toolsversion:, or /tv:, when the project must use a particular xbuild toolset. This installed command documents versions 2.0, 3.0, 3.5 and 4.0.
$ xbuild Example.csproj /toolsversion:4.0
The switch overrides the toolset value in the project file and changes which common targets are used. It does not install that toolset or repair missing framework files. If changing the version changes the result, record both the command and the installed Mono package version.
Common traps
- Wrong file selected: run
pwdand list the candidate files before relying on xbuild's no-argument search. - Property changed unexpectedly: inspect the exact command for
/property:overrides before editing the project. - Missing reference: rerun with
/verbosity:detailed. IfXBUILD_LOG_REFERENCE_RESOLVERis set, xbuild logs search paths even for references it resolves; unset it again when the extra noise is no longer useful. - Solution debugging: set
XBUILD_EMIT_SOLUTIONonly when you need xbuild to emit the project it generates from a solution. This changes files, so use a disposable working copy and inspect the result before keeping it.
Done means
- You confirmed the executable and recorded the installed xbuild and Mono versions.
- You named the intended project or solution explicitly.
- The selected target and property overrides are deliberate and documented.
- The command returned status zero, or the failure has a captured log and a specific next repair.
- Temporary logs and any generated files are either retained intentionally or removed from the disposable workspace.