Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Xamarin.Android.Build.Tasks] fix cases of missing @(Reference) #7642

Merged
merged 2 commits into from
Jan 4, 2023

Conversation

jonathanpeppers
Copy link
Member

Fixes: dotnet/maui#10154

If you have a solution setup with:

  • ApplicationA project reference ->
  • LibraryB reference ->
  • LibraryC

The app will crash at runtime, due to a missing LibraryC.dll.

You can solve the problem by changing @(Reference) to a @(ProjectReference). However, it appears the same situation works in a .NET 7 self-contained console app:

dotnet publish --self-contained -r win-x64
...
ls -n .\bin\Debug\net7.0\win-x64\publish\LibraryC.dll
LibraryC.dll

The underlying issue appears to be:

https://github.com/dotnet/msbuild/blob/a2490dd3f78cce4abc8f9e6f1b5268437332818f/src/Tasks/Microsoft.Common.CurrentVersion.targets#L2322

In the console app, $(BuildingProject) is true and $(_FindDependencies) is empty.

In the android app, $(BuildingProject) is false and $(_FindDependencies) is false.

It appears the BuildOnlySettings target should be running in Android apps when we do an "inner" build per $(RuntimeIdentifier). Simply adding a dependency for the _ComputeFilesToPublishForRuntimeIdentifiers MSBuild target solves this issue.

This likely might fix other issues, such as:

dotnet/maui#11364

I added a test for this scenario.

Fixes: dotnet/maui#10154

If you have a solution setup with:

* `ApplicationA` project reference ->
* `LibraryB` reference ->
* `LibraryC`

The app will crash at runtime, due to a missing `LibraryC.dll`.

You can solve the problem by changing `@(Reference)` to a
`@(ProjectReference)`. However, it appears the same situation works in
a .NET 7 self-contained console app:

    dotnet publish --self-contained -r win-x64
    ...
    ls -n .\bin\Debug\net7.0\win-x64\publish\LibraryC.dll
    LibraryC.dll

The underlying issue appears to be:

https://github.com/dotnet/msbuild/blob/a2490dd3f78cce4abc8f9e6f1b5268437332818f/src/Tasks/Microsoft.Common.CurrentVersion.targets#L2322

In the console app, `$(BuildingProject)` is `true` and
`$(_FindDependencies)` is empty.

In the android app, `$(BuildingProject)` is `false` and
`$(_FindDependencies)` is `false`.

It appears the `BuildOnlySettings` target *should* be running in
Android apps when we do an "inner" build per `$(RuntimeIdentifier)`.
Simply adding a dependency for the `_ComputeFilesToPublishForRuntimeIdentifiers`
MSBuild target solves this issue.

This likely might fix other issues, such as:

dotnet/maui#11364

I added a test for this scenario.
@jonathanpeppers
Copy link
Member Author

The MissingSatelliteAssemblyInLibrary test fails with:

(_BuildApkEmbed target) -> 
error XABBA7009: System.InvalidOperationException: Duplicate assemblies encountered
error XABBA7009:    at Xamarin.Android.Tasks.AssemblyStore.WriteIndex(BinaryWriter blobWriter, StreamWriter manifestWriter, List`1 globalIndex)
error XABBA7009:    at Xamarin.Android.Tasks.AssemblyStore.WriteIndex(BinaryWriter blobWriter, String manifestPath, List`1 globalIndex)
error XABBA7009:    at Xamarin.Android.Tasks.AssemblyStore.WriteIndex(List`1 globalIndex)
error XABBA7009:    at Xamarin.Android.Tasks.AssemblyStoreGenerator.Generate(String outputDirectory)
error XABBA7009:    at Xamarin.Android.Tasks.BuildApk.AddAssemblies(ZipArchiveEx apk, Boolean debug, Boolean compress, IDictionary`2 compressedAssembliesInfo, String assemblyStoreApkName)
error XABBA7009:    at Xamarin.Android.Tasks.BuildApk.ExecuteWithAbi(String[] supportedAbis, String apkInputPath, String apkOutputPath, Boolean debug, Boolean compress, IDictionary`2 compressedAssembliesInfo, String assemblyStoreApkName)
error XABBA7009:    at Xamarin.Android.Tasks.BuildApk.RunTask()
error XABBA7009:    at Microsoft.Android.Build.Tasks.AndroidTask.Execute() in /Users/builder/azdo/_work/1/s/xamarin-android/external/xamarin-android-tools/src/Microsoft.Android.Build.BaseTasks/AndroidTask.cs:line 17

So need to investigate that.

@jonathanpeppers jonathanpeppers marked this pull request as draft December 16, 2022 14:41
It appears that after we fixed `BuildOnlySettings` in the inner
builds, that satellite assemblies for assembly references are now
automatically found by the .NET SDK.

Conditionally add to `@(_AndroidResolvedSatellitePaths)` to avoid
duplicate satellite assemblies in .NET 6+.
@jonathanpeppers jonathanpeppers marked this pull request as ready for review December 16, 2022 22:21
@jonpryor
Copy link
Member

jonpryor commented Jan 3, 2023

Draft commit message:

Fixes: https://github.com/dotnet/maui/issues/10154

Context? https://github.com/dotnet/maui/issues/11364

If you have a solution setup with:

  * `ApplicationA.csproj` has a `@(ProjectReference)` to
    `LibraryB.csproj`.
  * `LibraryB.csproj` which has a `@(Reference)` to `LibraryC.dll`,
    built by-
  * `LibraryC.csproj`

The app will crash at runtime, due to a missing `LibraryC.dll`.

The workaround is for `LibraryB.csproj` to use `@(ProjectReference)`
to `LibraryC.csproj` instead of `@(Reference)` to `LibraryC.dll`.

However, it appears the same situation works in a .NET 7
self-contained console app:

	% dotnet publish --self-contained -r win-x64
	
	% ls -1 .\bin\Debug\net7.0\win-x64\publish\LibraryC.dll
	LibraryC.dll

The underlying issue appears to be due to [`$(_FindDependencies )`][0]:

	<_FindDependencies Condition="'$(BuildingProject)' != 'true' and '$(_ResolveReferenceDependencies)' != 'true'">false</_FindDependencies>

In the console app, `$(BuildingProject)`=true and
`$(_FindDependencies)` is empty.

In the Android app, `$(BuildingProject)`=false and
`$(_FindDependencies)` is `false`.

It appears that the `BuildOnlySettings` target *should* be running in
Android apps when we do an "inner" build per `$(RuntimeIdentifier)`.
Simply updating `_ComputeFilesToPublishForRuntimeIdentifiers` so that
the `BuildOnlySettings` target is in `DependsOnTargets` fixes this.
However, this also causes satellite assemblies to now be automatically
found by the .NET SDK.  Update `@(_AndroidResolvedSatellitePaths)` so
that `@(ReferenceSatellitePaths)` is only included on Classic builds,
preventing duplicate entries.

[0]: https://github.com/dotnet/msbuild/blob/a2490dd3f78cce4abc8f9e6f1b5268437332818f/src/Tasks/Microsoft.Common.CurrentVersion.targets#L2322

@jonpryor
Copy link
Member

jonpryor commented Jan 3, 2023

@jonathanpeppers: given that BuildOnlySettings is now built by _ComputeFilesToPublishForRuntimeIdentifiers ,
does this suggest that $(SignAndroidPackageDependsOn) does not need to mention BuildOnlySettings anymore? i.e. can we/should we "partially revert" the Xamarin.Android.Common.targets change in d298fda?

@jonathanpeppers
Copy link
Member Author

No, we need BuildOnlySettings to run twice. This one is for the "inner" build per runtime identifier.

@@ -1972,7 +1972,8 @@ because xbuild doesn't support framework reference assemblies.
DependsOnTargets="_ResolveAssemblies"
>
<ItemGroup>
<_AndroidResolvedSatellitePaths Include="@(ReferenceSatellitePaths)" />
<!-- In .NET 6+, the .NET SDK locates these files -->
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick: Should this be .NET 8+ since we are not releasing this fix for .NEt 6?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think we should actually send this to 7, could also consider 6?

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we put stuff in 6 still?

@jonpryor jonpryor merged commit 22f2001 into dotnet:main Jan 4, 2023
@jonathanpeppers jonathanpeppers deleted the ProjectDependencies branch January 4, 2023 17:40
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this pull request Jan 5, 2023
…tnet#7642)

Fixes: dotnet/maui#10154

Context? dotnet/maui#11364

If you have a solution setup with:

  * `ApplicationA.csproj` has a `@(ProjectReference)` to
    `LibraryB.csproj`.
  * `LibraryB.csproj` which has a `@(Reference)` to `LibraryC.dll`,
    built by-
  * `LibraryC.csproj`

The app will crash at runtime, due to a missing `LibraryC.dll`.

The workaround is for `LibraryB.csproj` to use `@(ProjectReference)`
to `LibraryC.csproj` instead of `@(Reference)` to `LibraryC.dll`.

However, it appears the same situation works in a .NET 7
self-contained console app:

	% dotnet publish --self-contained -r win-x64
	…
	% ls -1 .\bin\Debug\net7.0\win-x64\publish\LibraryC.dll
	LibraryC.dll

The underlying issue appears to be due to [`$(_FindDependencies)`][0]:

	<_FindDependencies Condition="'$(BuildingProject)' != 'true' and '$(_ResolveReferenceDependencies)' != 'true'">false</_FindDependencies>

In the console app, `$(BuildingProject)`=true and
`$(_FindDependencies)` is empty.

In the Android app, `$(BuildingProject)`=false and
`$(_FindDependencies)` is `false`.

It appears that the `BuildOnlySettings` target *should* be running in
Android apps when we do an "inner" build per `$(RuntimeIdentifier)`.
Simply updating `_ComputeFilesToPublishForRuntimeIdentifiers` so that
the `BuildOnlySettings` target is in `DependsOnTargets` fixes this.
However, this also causes satellite assemblies to now be automatically
found by the .NET SDK.  Update `@(_AndroidResolvedSatellitePaths)` so
that `@(ReferenceSatellitePaths)` is only included on Classic builds,
preventing duplicate entries.

[0]: https://github.com/dotnet/msbuild/blob/a2490dd3f78cce4abc8f9e6f1b5268437332818f/src/Tasks/Microsoft.Common.CurrentVersion.targets#L2322
grendello added a commit to grendello/xamarin-android that referenced this pull request Jan 17, 2023
* main:
  [Xamarin.Android.Build.Tasks] skip XA1034 logic in some cases (dotnet#7680)
  [ci] Move OneLocBuild task to scheduled pipeline (dotnet#7679)
  [Mono.Android] ServerCertificateValidationCallback() and redirects (dotnet#7662)
  Bump to xamarin/Java.Interop/main@cf80deb7 (dotnet#7664)
  Localized file check-in by OneLocBuild (dotnet#7668)
  [api-merge] Correctly compute //method/@deprecated-since (dotnet#7645)
  [Xamarin.Android.Build.Tasks] _Microsoft.Android.Resource.Designer (dotnet#6427)
  [Xamarin.Android.Build.Tasks] downgrade d8/r8 `warning` messages to `info` (dotnet#7643)
  [Xamarin.Android.Build.Tasks] fix cases of missing `@(Reference)` (dotnet#7642)
  [Xamarin.Android.Build.Tasks] delay ToJniName calls in ManifestDocument (dotnet#7653)
  [Xamarin.Android.Build.Tasks] fast path for `<CheckClientHandlerType/>` (dotnet#7652)
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this pull request Jan 20, 2023
…ce)` (dotnet#7642)"

This reverts commit 22f2001.

.NET MAUI is hitting a build failure such as:

    Unable to open file 'obj\Release\net8.0-android\android-x64\aot\x86_64\Microsoft.Maui.Controls.resources\temp.s': Permission denied

In 22f2001, we began passing satellite assemblies to the AOT compiler,
on accident? I am unsure how a test in xamarin-android didn't catch
this, but it may be something that only happens via a
`@(ProjectReference)` as occurred in .NET MAUI.

For now, let's revert the change and revisit later.

We should reopen dotnet/maui#10154 after
this is merged.
jonathanpeppers added a commit that referenced this pull request Jan 22, 2023
…ce)` (#7642)" (#7726)

This reverts commit 22f2001.

.NET MAUI is hitting a build failure such as:

    Unable to open file 'obj\Release\net8.0-android\android-x64\aot\x86_64\Microsoft.Maui.Controls.resources\temp.s': Permission denied

In 22f2001, we began passing satellite assemblies to the AOT compiler,
on accident? I am unsure how a test in xamarin-android didn't catch
this, but it may be something that only happens via a
`@(ProjectReference)` as occurred in .NET MAUI.

For now, let's revert the change and revisit later.

We should reopen dotnet/maui#10154 after
this is merged.
grendello added a commit to grendello/xamarin-android that referenced this pull request Jan 26, 2023
* main: (32 commits)
  [monodroid] Replace `exit()` with `abort()` in native code (dotnet#7734)
  Bump to xamarin/Java.Interop/main@8a1ae57 (dotnet#7738)
  [build] bump `$(AndroidNet7Version)` (dotnet#7737)
  Bump to xamarin/Java.Interop/main@1366d99 (dotnet#7718)
  [Xamarin.Android.Build.Tasks] fix AndroidGenerateResourceDesigner (dotnet#7721)
  Bump to xamarin/monodroid@50faac94 (dotnet#7725)
  Revert "[Xamarin.Android.Build.Tasks] fix cases of missing `@(Reference)` (dotnet#7642)" (dotnet#7726)
  [marshal methods] Properly support arrays of arrays (dotnet#7707)
  Bump to dotnet/installer@9962c6a 8.0.100-alpha.1.23063.11 (dotnet#7677)
  [Actions] Add action to bump the hash used for the unified pipeline (dotnet#7712)
  Bump to xamarin/xamarin-android-tools/main@099fd95 (dotnet#7709)
  [ci] Move build stages into yaml templates (dotnet#7553)
  [Xamarin.Android.Build.Tasks] fix NRE in `<GenerateResourceCaseMap/>` (dotnet#7716)
  [ci] Pass token when building Designer tests (dotnet#7715)
  [Mono.Android] Android.Telecom.InCallService.SetAudioRoute() + enum (dotnet#7711)
  [Mono.Android] Fix some incorrect enums. (dotnet#7670)
  [Xamarin.Android.Build.Tasks] _Microsoft.Android.Resource.Designer namespace (dotnet#7681)
  LEGO: Merge pull request 7713
  [Xamarin.Android.Build.Tasks] lazily populate Resource lookup (dotnet#7686)
  [Xamarin.Android.Build.Tasks] skip XA1034 logic in some cases (dotnet#7680)
  ...
grendello added a commit to grendello/xamarin-android that referenced this pull request Jan 30, 2023
* main:
  Revert "[Xamarin.Android.Build.Tasks] fix cases of missing `@(Reference)` (dotnet#7642)" (dotnet#7726)
@github-actions github-actions bot locked and limited conversation to collaborators Jan 23, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Assembly load error in Android app referencing another project referencing a DLL assembly
3 participants