Skip to content

Commit 5eeb287

Browse files
jonpryorradekdoulik
authored andcommitted
[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
1 parent 68233f9 commit 5eeb287

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

src/Xamarin.Android.Cecil/Xamarin.Android.Cecil.targets

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,16 @@
88
<CecilOutputPath>$([System.IO.Path]::GetFullPath ($(CecilOutputPath)))</CecilOutputPath>
99
<CecilAssemblies>$(OutputPath)\Xamarin.Android.Cecil.dll;$(OutputPath)\Xamarin.Android.Cecil.Mdb.dll</CecilAssemblies>
1010
</PropertyGroup>
11+
<ItemGroup>
12+
<_CecilProject Include="$(CecilDirectory)\Mono.Cecil.csproj" />
13+
<_CecilProject Include="$(CecilDirectory)\symbols\mdb\Mono.Cecil.Mdb.csproj" />
14+
<_CecilSource Include="$(CecilDirectory)\**\*.cs" />
15+
</ItemGroup>
1116
<Target Name="BuildCecil"
17+
Inputs="@(_CecilSource)"
1218
Outputs="$(CecilAssemblies)">
1319
<MSBuild
14-
Projects="$(CecilDirectory)\Mono.Cecil.csproj;$(CecilDirectory)\symbols\mdb\Mono.Cecil.Mdb.csproj"
20+
Projects="@(_CecilProject)"
1521
Targets="Clean;Build"
1622
StopOnFirstFailure="True"
1723
Properties="Configuration=net_4_0_Debug;OutputPath=$(CecilOutputPath);BuildingSolutionFile=false" />
@@ -20,4 +26,12 @@
2026
<Target Name="Build" DependsOnTargets="BuildCecil" Returns="$(CecilOutputPath)\$(AssemblyName).dll">
2127
<MakeDir Directories="obj\$(Configuration)" />
2228
</Target>
29+
<Target Name="Clean" Returns="$(CecilOutputPath)\$(AssemblyName).dll">
30+
<MSBuild
31+
Projects="@(_CecilProject)"
32+
Targets="Clean"
33+
StopOnFirstFailure="True"
34+
Properties="Configuration=net_4_0_Debug;OutputPath=$(CecilOutputPath);BuildingSolutionFile=false"
35+
/>
36+
</Target>
2337
</Project>

0 commit comments

Comments
 (0)