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

InjectAvaloniaXamlOutput appears to mangle property IntermediateAssembly on multiple runs and prevents trimming #17099

Open
noorez opened this issue Sep 23, 2024 · 14 comments · Fixed by #17145 · May be fixed by #17539
Open

Comments

@noorez
Copy link

noorez commented Sep 23, 2024

Describe the bug

(For some reason this only appears on android builds..)

It looks like when InjectAvaloniaXamlOutput build target is run multiple times (for this case: (target "InjectAvaloniaXamlOutput" depends on it):) which has already run because "Compile" target required it, the path becomes mangled.

CompileAvaloniaXamlInputs=
 816620                            obj/Release/net8.0-android/Avalonia/project.dll
 816621                                    AvaloniaCompileOutput=obj/Release/net8.0-android/Avalonia/Avalonia/project.dll

notice how there are now two /Avalonia/Avalonia nested directories when in fact all the build objects are only in Avalonia.

This in turn causes the trimmer targets to not look in the correct location for the assemblies which need to be trimmed

To Reproduce

Compile android targets when trimming enabled.

Expected behavior

previous version on which this worked without issue for me 11.1.999-cibuild0045786-beta. expect that it should also work in recent versions too.

Avalonia version

11.1.2

OS

Android

Additional context

No response

@noorez noorez added the bug label Sep 23, 2024
@timunie
Copy link
Contributor

timunie commented Sep 24, 2024

Can you try latest nightly in a minimum sample? If it still is a bug for you, share the minimum sample please.

@TomEdwardsEnscape
Copy link
Contributor

The issue will be that PrepareToCompileAvaloniaXaml is running multiple times. But a target is not supposed to run twice.

In addition to a code sample, please compile with binary logging enabled and attach the .binlog output. Sample command: dotnet build -bl:MyLog.binlog.

@noorez
Copy link
Author

noorez commented Sep 26, 2024

https://github.com/noorez/AvaloniaTest17099 Test code which reproduces the issue

@noorez
Copy link
Author

noorez commented Sep 26, 2024

MyLog.log
attached the binlog requested.

Note, this didn't appear to produce any errors on output, however, Visual Studio and also msbuild from the console do produce the error

@noorez
Copy link
Author

noorez commented Sep 26, 2024

I think what might be throwing off the msbuild target is the <ApplicationIcon> directive in the android project you can see in the test project I uploaded...

edit: didn't format above correctly to show it seemed to be the addition of ApplicationIcon to the android project which exposed the issue...

@TomEdwardsEnscape
Copy link
Contributor

This is the problem: it's running inner builds, and overriding the path to the intermediate assembly with its own value:

image

The good news is that it also configures the SkipCompilerExecution property. We should be respecting this anyway, but aren't. By skipping the Avalonia XAML targets when that property is true we should be able to fix the issue.

@TomEdwardsEnscape
Copy link
Contributor

Please try with the build from the linked PR (once it has been generated).

@noorez
Copy link
Author

noorez commented Sep 27, 2024

pushed update to my test project to show that it works now (it also builds correctly on the actual project)

@noorez
Copy link
Author

noorez commented Sep 27, 2024

while the issue with building was fixed and it produced the various android binaries, the app crashed, and this was taken from adb. It appears that perhaps the patch skipped too much when trying to avoid the additional transformation of the msbuild properties?

9-27 10:09:17.197 14531 14531 E AndroidRuntime: Process: air.com.myapp, PID: 14531
09-27 10:09:17.197 14531 14531 E AndroidRuntime: android.runtime.JavaProxyThrowable: [Avalonia.Markup.Xaml.XamlLoadException]: No precompiled XAML found for myapp.Client.App, make sure to specify x:Class and include your XAML file as AvaloniaResource
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at Avalonia.Markup.Xaml.AvaloniaXamlLoader.Load(Unknown Source:0)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at myapp.Client.App.Initialize(Unknown Source:0)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at Avalonia.AppBuilder.SetupUnsafe(Unknown Source:0)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at Avalonia.AppBuilder.Setup(Unknown Source:0)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at Avalonia.AppBuilder.SetupWithLifetime(Unknown Source:0)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at Avalonia.Android.AvaloniaMainActivity.InitializeAvaloniaView(Unknown Source:0)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at Avalonia.Android.AvaloniaActivity.OnCreate(Unknown Source:0)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at PasswordServer.Client.Android.MainActivity.OnCreate(Unknown Source:0)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_(Unknown Source:0)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPL_V(Unknown Source:0)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at crc64ef7a11524a16ed7d.MainActivity.n_onCreate(Native Method)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at crc64ef7a11524a16ed7d.MainActivity.onCreate(MainActivity.java:41)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:8975)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:8944)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4146)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4322)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2685)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:106)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at android.os.Looper.loopOnce(Looper.java:230)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:319)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:8918)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
09-27 10:09:17.197 14531 14531 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)

@TomEdwardsEnscape
Copy link
Contributor

Please send another .binlog.

@noorez
Copy link
Author

noorez commented Sep 30, 2024

Attached is the new binlog (test repo updated as well).

dotnet publish .\AvaloniaApplication2.Android\AvaloniaApplication2.Android.csproj -c Release -p:ApplicationVersion=3003007 -p:ApplicationDisplayVersion=3.3.7 -o .\Packages\Android -bl:MyLog.binlog

MyLog.log

@TomEdwardsEnscape
Copy link
Contributor

I think I finally found where thing go wrong. First, the project is built and everything is fine. Then the Android SDK executes a target of its own called _ResolveAssemblies, which sets properties including SkipCompilerExecution and _OuterIntermediateAssembly and executes a project target which computes a list of files to publish.

As part of this second build, CopyFilesToOutputDirectory executes. But because of SkipCompilerExecution, we haven't replaced the original assembly with the one containing Avalonia XAML compilation...and despite being passed to the project, the value of _OuterIntermediateAssembly has NOT been applied, so the pre-XAML assembly is copied to the bin folder and used for the rest of the build.

This seems to be the root cause of the problem: the SDK sometimes applies this _OuterIntermediateAssembly value (causing the double-correction of the path if we inject our files) and at other times doesn't (causing the pre-XAML assembly to be copied to the output folder if we don't inject our files).

Either way something breaks.

@noorez
Copy link
Author

noorez commented Oct 23, 2024

any updates on how this can be fixed?

@TomEdwardsEnscape
Copy link
Contributor

I've not done anything more. Been busy with my actual job, and I'm also not well-placed to work on the issue as I don't have any of the bloated dependencies required to build and run Android applications.

@MrJul please reopen this issue.

@MrJul MrJul reopened this Oct 26, 2024
@MrJul MrJul linked a pull request Nov 17, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants