Skip to content

Conversation

@jonathanpeppers
Copy link
Member

@jonathanpeppers jonathanpeppers commented Jul 16, 2019

I've removed various MSBuild targets that copy assemblies into the
obj\Debug\linksrc directory, and instead just use
@(ResolvedUserAssemblies) or @(ResolvedAssemblies) directly

Things seem to work, I can build and deploy samples\HelloWorld and
the Xamarin.Forms app in this repo. Let's see what breaks?

The size of tests\Xamarin.Forms-Performance-Integration\Droid\obj\
is improved dramatically:

Before:
184.27 MB
After:
111.74 MB

~73MB savings.

These MSBuild tasks were completely removed:

  3 ms  _CopyMdbFiles                              1 calls
 43 ms  _CopyPdbFiles                              1 calls
127 ms  _CopyIntermediateAssemblies                1 calls

On a slower machine with Windows Defender enabled, these targets are
taking:

  6 ms  _CopyMdbFiles                              1 calls
 95 ms  _CopyPdbFiles                              1 calls
269 ms  _CopyIntermediateAssemblies                1 calls

On the slower machine, the overall time was even more drastic:

Before:
Time Elapsed 00:00:33.41
After:
Time Elapsed 00:00:29.92

With Windows Defender processes using the CPU, the overall build time
is improved by ~3.5 seconds?

Changes for jnimarshalmethod-gen

Because jnimarshalmethod-gen edits assemblies in linksrc in-place,
before the linker, I added an extra jnisrc directory to accommodate
for this. Then when _LinkAssembliesShrink runs, it operates on
assemblies in the jnisrc directory.

We can revisit this if $(AndroidGenerateJniMarshalMethods) ever
becomes default.

@jonathanpeppers
Copy link
Member Author

Unfortunately there is a problem here:

  1. jnimarshalmethod-gen.exe operates on assemblies in-place in linksrc
  2. We can't run this after the linker, because the Linker expects it to have been run: https://github.com/xamarin/xamarin-android/blob/05344f8d43293c794f3df2b533b71d339ef031f7/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MonoDroidMarkStep.cs#L35

With the current implementation of jnimarshalmethod-gen, we need an extra copy of the .NET assemblies on disk: linksrc. Need to think on this...

@jonathanpeppers jonathanpeppers force-pushed the linksrc-is-dead branch 2 times, most recently from d72750e to 04b1770 Compare August 1, 2019 20:47
@jonathanpeppers jonathanpeppers marked this pull request as ready for review August 7, 2019 21:49
@jonathanpeppers jonathanpeppers force-pushed the linksrc-is-dead branch 2 times, most recently from 707e52f to 47b4bf2 Compare August 9, 2019 02:15
radekdoulik added a commit to radekdoulik/java.interop that referenced this pull request Aug 13, 2019
Added -r --reference option to add information about processed
assemblies references.

Also make it possible to use response file with additional command
line arguments. The file can be specified by @response_file at the
command line.

That might help with dotnet/android#3359
radekdoulik added a commit to dotnet/java-interop that referenced this pull request Aug 13, 2019
Added -r --reference option to add information about processed
assemblies references.

Also make it possible to use response file with additional command
line arguments. The file can be specified by @response_file at the
command line.

That might help with dotnet/android#3359
I've removed various MSBuild targets that copy assemblies into the
`obj\Debug\linksrc` directory, and instead just use
`@(ResolvedUserAssemblies)` or `@(ResolvedAssemblies)` where
appropriate.

Things seem to *work*, I can build and deploy `samples\HelloWorld` and
the Xamarin.Forms app in this repo. Let's see what breaks?

The size of `tests\Xamarin.Forms-Performance-Integration\Droid\obj\`
is improved dramatically:

    Before:
    184.27 MB
    After:
    111.74 MB

~73MB savings.

These MSBuild tasks were completely removed:

      3 ms  _CopyMdbFiles                              1 calls
     43 ms  _CopyPdbFiles                              1 calls
    127 ms  _CopyIntermediateAssemblies                1 calls

I will need to retest this on a slower machine where I'm seeing
Windows Defender have an impact on build times.

~~ Changes for jnimarshalmethod-gen ~~

Because `jnimarshalmethod-gen` edits assemblies in `linksrc` in-place,
before the linker, I added an extra `jnisrc` directory to accommodate
for this.

The new behavior is:

* `jnimarshalmethod-gen` outputs assemblies to `jnisrc`, it outputs a
  subset of `@(ResolvedAssemblies)`.
* `_LinkAssembliesShrink` uses files form `jnisrc` if they exist and
  `@(ResolvedAssemblies)` otherwise.

I also use the new `-r` switch, so any needed assemblies can be loaded.
@jonathanpeppers
Copy link
Member Author

jonathanpeppers commented Aug 20, 2019

@radekdoulik after I've switched this around to use -o. I'm getting:

 Unhandled Exception:
  System.UnauthorizedAccessException: Access to the path "/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v10.0/Mono.Android.dll" is denied.

https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=2956832&view=logs&jobId=8556562a-ae5f-5bd1-7c4d-bf1af4b6f1e1&taskId=5076e147-fc66-561e-6c69-3aa777afefc5&lineStart=754&lineEnd=790&colStart=3&colEnd=138

This only happens because our tests on Azure DevOps are running against a system install.

Is jnimarshalmethod-gen.exe opening this file with write access?

@radekdoulik
Copy link
Member

Indeed, we were opening the assemblies with ReadWrite reader parameters even when using -o. It should be now fixed by dotnet/java-interop@d39699f

@jonathanpeppers
Copy link
Member Author

@radekdoulik got past that one, thanks.

There is a new error though 😞:

EXEC : error : jnimarshalmethod-gen: Unable to process assembly '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v10.0/Mono.Android.dll' [/Users/vsts/agent/2.155.1/work/1/s/src/Mono.Android/Test/Mono.Android-Tests.csproj]
  Access to the path "/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v10.0/Mono.Android-JniMarshalMethods.dll" is denied.
  System.UnauthorizedAccessException: Access to the path "/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v10.0/Mono.Android-JniMarshalMethods.dll" is denied.
    at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x001b7] in <b047284b444b4c74b59771ad4346b34a>:0 
    at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean isAsync, System.Boolean anonymous) [0x00000] in <b047284b444b4c74b59771ad4346b34a>:0 
    at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access) [0x00000] in <b047284b444b4c74b59771ad4346b34a>:0 
    at (wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode,System.IO.FileAccess)
    at System.Reflection.Emit.ModuleBuilder.Save () [0x001e5] in <b047284b444b4c74b59771ad4346b34a>:0 
    at System.Reflection.Emit.AssemblyBuilder.Save (System.String assemblyFileName, System.Reflection.PortableExecutableKinds portableExecutableKind, System.Reflection.ImageFileMachine imageFileMachine) [0x0022b] in <b047284b444b4c74b59771ad4346b34a>:0 
    at System.Reflection.Emit.AssemblyBuilder.Save (System.String assemblyFileName) [0x00000] in <b047284b444b4c74b59771ad4346b34a>:0 
    at Xamarin.Android.Tools.JniMarshalMethodGenerator.App.CreateMarshalMethodAssembly (System.String path) [0x0043d] in <3859ef09ce2c46b7b24c5a9fe9afd6b4>:0 
    at Xamarin.Android.Tools.JniMarshalMethodGenerator.App.ProcessAssemblies (System.Collections.Generic.List`1[T] assemblies) [0x001b0] in <3859ef09ce2c46b7b24c5a9fe9afd6b4>:0 

Is this Mono.Android-JniMarshalMethods.dll an assembly generated that should be going into the -o directory? I need also make sure it makes it into the linker step and the app?

@radekdoulik
Copy link
Member

Is this Mono.Android-JniMarshalMethods.dll an assembly generated that should be going into the -o directory? I need also make sure it makes it into the linker step and the app?

Definitely, it should be generated in the directory specified by -o. I will fix it as well.

The assembly itself is temporary.

@radekdoulik
Copy link
Member

dotnet/java-interop#483 should fix it.

Changes: dotnet/java-interop@60e85b0...8ed9677

Fixes for `-o` in `jnimarshalmethod-gen.exe`.
@jonathanpeppers
Copy link
Member Author

Ok, this actually looks green now. Jenkins looks like what we see on master.

@dellis1972 dellis1972 merged commit 2ea31e6 into dotnet:master Aug 22, 2019
@mjo151
Copy link

mjo151 commented Nov 21, 2019

We just upgraded to VS 2019 and this change appears to have broken obfuscation with our Xamarin.Android builds. We were performing obfuscation in the AfterBuild target, then copying our obfuscated assemblies into the linksrc directory after the _CopyIntermediateAssemblies target. Due to this change, this no longer works. Can you provide suggestions on which build target we should use to perform obfuscation? Also, where does the linker look for assemblies (e.g. where should be copy our obfuscated assemblies)?

@jonathanpeppers jonathanpeppers deleted the linksrc-is-dead branch November 21, 2019 22:04
@jonathanpeppers
Copy link
Member Author

@mjo151 the convention in MSBuild is that anything prefixed with an underscore is private. Meaning it might change from release to release. (MSBuild is all global variables otherwise)

https://github.com/xamarin/xamarin-android/blob/master/Documentation/guides/MSBuildBestPractices.md#naming

However, you can easily copy the files to a directory yourself and fix up the @(ResolvedAssemblies) and @(ResolvedUserAssemblies) item groups, we had to do a similar workaround for AndroidX.Migration: xamarin/XamarinAndroidXMigration#20

You can check if $(MonoAndroidLinkerInputDir) is blank to determine if it is a newer Xamarin.Android version where linksrc is gone.

@github-actions github-actions bot locked and limited conversation to collaborators Jan 29, 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.

5 participants