Skip to content

Commit

Permalink
Update AOTCompile task to handle cycles in up-to-date check (#20103)
Browse files Browse the repository at this point in the history
#### Background

While cyclic assembly references are unusual they are supported by the runtime and encountered in practice. In our project we use a version of Xamarin.Forms retargeted for a modern .NET (as a stopgap solution before an update to full MAUI stack). Xamarin.Forms historically come with such an assembly cycle: `Xamarin.Forms.Core.dll` -> `Xamarin.Forms.Platform.dll` -> `Xamarin.Forms.Platform.iOS.dll` -> `Xamarin.Forms.Core.dll`. This is produced by first compiling `Xamarin.Forms.Core.dll` against a dummy `Xamarin.Forms.Platform.dll` (`netstandard2.0` assembly). Then the Platform assemblies are built, and finally forwarder versions of `Xamarin.Forms.Platform.dll` are created for each platform. This is all packaged into NuGets in such a way that each TFM gets the same `Xamarin.Forms.Core.dll` but a different set of `Xamarin.Forms.Platform.dll` and `Xamarin.Forms.Platform.<platform>.dll` assemblies.

#### Problem

With current workloads each incremental rebuild fails with:

```
/usr/local/share/dotnet/packs/Microsoft.iOS.Sdk/16.4.7125/targets/Xamarin.Shared.Sdk.targets(1047,3): error : Encountered an assembly reference cycle related to the assembly obj/Debug/net7.0-ios/iossimulator-arm64/linked/Xamarin.Forms.Core.dll
```

#### Solution

The PR updates the algorithm in `AOTCompile` to detect cycles using [Tarjan's algorithm](https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm) for finding [strongly connected components](https://en.wikipedia.org/wiki/Strongly_connected_component) in a graph. When a cycle is detect any assembly in the cycle is considered up-to-date only if all the assemblies in the cycle are up-to-date.

With this change the project does incremental rebuilds correctly. I verified in the build output that the assembly cycle is considered up-to-date, and that any changes to the application assemblies still return `false` from the up-to-date check and get rebuilt.

---------

Co-authored-by: Filip Navara <[email protected]>
  • Loading branch information
filipnavara authored Feb 15, 2024
1 parent 282d107 commit d89b639
Show file tree
Hide file tree
Showing 28 changed files with 119 additions and 240 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1939,15 +1939,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";E7119" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Encountered an assembly reference cycle related to the assembly {0}.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Byl zjištěn cyklus odkazu na sestavení související se sestavením {0}.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";InvalidFramework" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Invalid framework: {0}]]></Val>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1939,15 +1939,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";E7119" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Encountered an assembly reference cycle related to the assembly {0}.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Es wurde ein Assemblyverweiszyklus gefunden, der mit der Assembly {0} verknüpft ist.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";InvalidFramework" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Invalid framework: {0}]]></Val>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1939,15 +1939,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";E7119" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Encountered an assembly reference cycle related to the assembly {0}.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Se encontró un ciclo de referencia de ensamblado relacionado con el ensamblado {0}.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";InvalidFramework" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Invalid framework: {0}]]></Val>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1939,15 +1939,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";E7119" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Encountered an assembly reference cycle related to the assembly {0}.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[A rencontré un cycle de référence d'assemblage lié à l'assemblage {0}.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";InvalidFramework" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Invalid framework: {0}]]></Val>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1939,15 +1939,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";E7119" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Encountered an assembly reference cycle related to the assembly {0}.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[È stato rilevato un ciclo di riferimento dell'assembly correlato all'assembly {0}.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";InvalidFramework" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Invalid framework: {0}]]></Val>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1939,15 +1939,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";E7119" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Encountered an assembly reference cycle related to the assembly {0}.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[アセンブリ {0} に関連するアセンブリ参照サイクルが発生しました。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";InvalidFramework" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Invalid framework: {0}]]></Val>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1939,15 +1939,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";E7119" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Encountered an assembly reference cycle related to the assembly {0}.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0} 어셈블리와 관련된 어셈블리 참조 주기를 발견했습니다.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";InvalidFramework" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Invalid framework: {0}]]></Val>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1939,15 +1939,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";E7119" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Encountered an assembly reference cycle related to the assembly {0}.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Napotkano cykl odwołania do zestawu powiązany z zestawem {0}.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";InvalidFramework" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Invalid framework: {0}]]></Val>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1939,15 +1939,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";E7119" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Encountered an assembly reference cycle related to the assembly {0}.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Foi encontrado um ciclo de referência de assembly relacionado ao assembly {0}.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";InvalidFramework" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Invalid framework: {0}]]></Val>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1939,15 +1939,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";E7119" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Encountered an assembly reference cycle related to the assembly {0}.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Обнаружен цикл ссылки на сборку, связанный со сборкой {0}.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";InvalidFramework" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Invalid framework: {0}]]></Val>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1939,15 +1939,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";E7119" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Encountered an assembly reference cycle related to the assembly {0}.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0} bütünleştirilmiş koduyla ilgili bir bütünleştirilmiş kod başvuru döngüsüyle karşılaşıldı.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";InvalidFramework" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Invalid framework: {0}]]></Val>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1939,15 +1939,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";E7119" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Encountered an assembly reference cycle related to the assembly {0}.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[遇到与程序集 {0} 相关的程序集引用周期。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";InvalidFramework" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Invalid framework: {0}]]></Val>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1939,15 +1939,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";E7119" ItemType="0;.resx" PsrId="211" InstFlg="true" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Encountered an assembly reference cycle related to the assembly {0}.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[遇到與組件 {0} 相關的組件參考循環。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";InvalidFramework" ItemType="0;.resx" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Invalid framework: {0}]]></Val>
Expand Down
7 changes: 0 additions & 7 deletions msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1533,11 +1533,4 @@
{1}: the exit code of a process
</comment>
</data>

<data name="E7119" xml:space="preserve">
<value>Encountered an assembly reference cycle related to the assembly {0}.</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1237,10 +1237,4 @@
{1}: the exit code of a process
</comment>
</data>
<data name="E7119" xml:space="preserve">
<value>Byl zjištěn cyklus odkazu na sestavení související se sestavením {0}.</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1237,10 +1237,4 @@
{1}: the exit code of a process
</comment>
</data>
<data name="E7119" xml:space="preserve">
<value>Es wurde ein Assemblyverweiszyklus gefunden, der mit der Assembly {0} verknüpft ist.</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1237,10 +1237,4 @@
{1}: the exit code of a process
</comment>
</data>
<data name="E7119" xml:space="preserve">
<value>Se encontró un ciclo de referencia de ensamblado relacionado con el ensamblado {0}.</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1237,10 +1237,4 @@
{1}: the exit code of a process
</comment>
</data>
<data name="E7119" xml:space="preserve">
<value>A rencontré un cycle de référence d'assemblage lié à l'assemblage {0}.</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1237,10 +1237,4 @@
{1}: the exit code of a process
</comment>
</data>
<data name="E7119" xml:space="preserve">
<value>È stato rilevato un ciclo di riferimento dell'assembly correlato all'assembly {0}.</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1237,10 +1237,4 @@
{1}: the exit code of a process
</comment>
</data>
<data name="E7119" xml:space="preserve">
<value>アセンブリ {0} に関連するアセンブリ参照サイクルが発生しました。</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1237,10 +1237,4 @@
{1}: the exit code of a process
</comment>
</data>
<data name="E7119" xml:space="preserve">
<value>{0} 어셈블리와 관련된 어셈블리 참조 주기를 발견했습니다.</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1237,10 +1237,4 @@
{1}: the exit code of a process
</comment>
</data>
<data name="E7119" xml:space="preserve">
<value>Napotkano cykl odwołania do zestawu powiązany z zestawem {0}.</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1237,10 +1237,4 @@
{1}: the exit code of a process
</comment>
</data>
<data name="E7119" xml:space="preserve">
<value>Foi encontrado um ciclo de referência de assembly relacionado ao assembly {0}.</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1237,10 +1237,4 @@
{1}: the exit code of a process
</comment>
</data>
<data name="E7119" xml:space="preserve">
<value>Обнаружен цикл ссылки на сборку, связанный со сборкой {0}.</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1237,10 +1237,4 @@
{1}: the exit code of a process
</comment>
</data>
<data name="E7119" xml:space="preserve">
<value>{0} bütünleştirilmiş koduyla ilgili bir bütünleştirilmiş kod başvuru döngüsüyle karşılaşıldı.</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1237,10 +1237,4 @@
{1}: the exit code of a process
</comment>
</data>
<data name="E7119" xml:space="preserve">
<value>遇到与程序集 {0} 相关的程序集引用周期。</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1237,10 +1237,4 @@
{1}: the exit code of a process
</comment>
</data>
<data name="E7119" xml:space="preserve">
<value>遇到與組件 {0} 相關的組件參考循環。</value>
<comment>
{0}: the path to an assembly
</comment>
</data>
</root>
Loading

8 comments on commit d89b639

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 Failed to compute test summaries on VSTS: simulator tests 🔥

Failed to compute test summaries: Cannot bind argument to parameter 'StageDependencies' because it is an empty string..

Pipeline on Agent
Update AOTCompile task to handle cycles in up-to-date check (#20103)

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

Please sign in to comment.