Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Xamarin.Android.Cecil] Fix project rebuilds
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
- Loading branch information