You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A problem with any build system are "cascading rebuilds": when a
project changes and is rebuilt, that requires that all projects which
depend on it are *also* rebuilt. The end result is that if a "core"
project changes, everything else in the solution will need to be
rebuilt, *just in case* something "important" changed.
MSBuild (and make!) use file timestamps to determine whether or not
targets should be re-executed. Consequently, the way to avoid
cascading rebuilds is to ensure that assembly timestamps don't change
unless they have to, e.g. they were actually rebuilt.
[The MSBuild `<Target/>` element][0] can use the `@Inputs` and
`@Outputs` attributes to control when a target is run, relying on file
timestamps to determine when a target needs to be rerun.
Enter `Xamarin.Android.Cecil.targets`'s `BuildCecil` target:
<Target Name="BuildCecil"
Outputs="$(CecilAssemblies)">
...
*This is a bug*: It provides the `@Outputs` attribute but not the
`@Inputs` attribute. In this scenario, MSBuild treats the target as if
the outputs are *always* "older" than the inputs, and thus *always*
re-executes the target:
$ xbuild /nologo /v:quiet src/Xamarin.Android.Cecil/Xamarin.Android.Cecil.csproj
$ ls -l bin/Debug/Xamarin.Android.Cecil.dll
-rw-r--r-- 1 jon staff 374784 Apr 3 13:46 bin/Debug/Xamarin.Android.Cecil.dll
$ xbuild /nologo /v:quiet src/Xamarin.Android.Cecil/Xamarin.Android.Cecil.csproj
$ ls -l bin/Debug/Xamarin.Android.Cecil.dll
-rw-r--r-- 1 jon staff 374784 Apr 3 13:47 bin/Debug/Xamarin.Android.Cecil.dll
This is the foundation for cascading rebuilds: *Nothing has changed*,
yet the timestamp is updated. This in turn requires that everything
which depends on `Xamarin.Android.Cecil.dll` -- which is **A LOT** --
also needs to be rebuilt.
Fix `Xamarin.Android.Cecil.targets` so that the `BuildCecil` target
has an `@Inputs` attribute specified. This allows the `BuildCecil`
target to be *skipped* if nothing has changed.
This also *greatly* decreases the time for rebuilds:
# pre patch; note: times are roughly the same:
$ time xbuild /nologo /v:quiet src/Xamarin.Android.Cecil/Xamarin.Android.Cecil.csproj
real 0m4.574s
user 0m5.829s
sys 0m1.755s
$ time xbuild /nologo /v:quiet src/Xamarin.Android.Cecil/Xamarin.Android.Cecil.csproj
real 0m4.552s
user 0m5.617s
sys 0m1.833s
# post patch: `BuildCecil` takes 1/10 the time!
$ time xbuild /nologo /v:quiet src/Xamarin.Android.Cecil/Xamarin.Android.Cecil.csproj
real 0m4.707s
user 0m5.655s
sys 0m1.793s
$ time xbuild /nologo /v:quiet src/Xamarin.Android.Cecil/Xamarin.Android.Cecil.csproj
real 0m0.492s
user 0m0.399s
sys 0m0.074s
[0]: https://msdn.microsoft.com/en-us/library/t50z2hka.aspx
0 commit comments