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

Create managed version of llvm-objcopy #9692

Open
jpobst opened this issue Jan 17, 2025 · 7 comments
Open

Create managed version of llvm-objcopy #9692

jpobst opened this issue Jan 17, 2025 · 7 comments
Labels
Area: App+Library Build Issues when building Library projects or Application projects. Area: Performance Issues with performance. enhancement Proposed change to current functionality.
Milestone

Comments

@jpobst
Copy link
Contributor

jpobst commented Jan 17, 2025

Context: #9455

For each assembly/pdb/config/others file we wrap as a .so in order to place in the /lib directory of an APK, we shell out twice to llvm-objcopy:

llvm-objcopy.EXE --add-section payload=obj\Debug\net9.0-android\android\assets\arm64-v8a\myproject.dll obj\Debug\net9.0-android\android-arm64\wrapped\lib_myproject.dll.so
llvm-objcopy.EXE --set-section-flags payload=readonly,data --set-section-alignment payload=16384 obj\Debug\net9.0-android\android-arm64\wrapped\lib_myproject.dll.so

There is considerable overhead to this process.

In this example we spend ~42 seconds in this step:

dotnet new android
dotnet build -p:EmbedAssembliesIntoApk=true

A managed version that did not need to shell out to external processes of this would likely be faster.

Some potential options:

@jpobst jpobst added Area: App+Library Build Issues when building Library projects or Application projects. Area: Performance Issues with performance. labels Jan 17, 2025
@jpobst jpobst added this to the .NET 10 milestone Jan 17, 2025
@dotnet-policy-service dotnet-policy-service bot added the needs-triage Issues that need to be assigned. label Jan 17, 2025
@jpobst jpobst added enhancement Proposed change to current functionality. and removed needs-triage Issues that need to be assigned. labels Jan 17, 2025
@filipnavara
Copy link
Member

Can you post an example of the input and output files? This seems to be simple enough operation that could likely be easily written by reusing the code from NativeAOT ELF ObjWriter.

@jpobst
Copy link
Contributor Author

jpobst commented Jan 30, 2025

The inputs and outputs can be found in any .NET for Android project, ie:

  • Inputs: obj\Debug\net10.0-android\android\assets\arm64-v8a\Microsoft.CSharp.dll
  • Outputs: in the .apk: lib\arm64-v8a\lib_Microsoft.CSharp.dll.so

example.zip

@filipnavara
Copy link
Member

Here's a rough implementation of the code to append the payload section to the template:
ElfAppendPayloadSection.zip

It compiles with both .NET 9.0 and .NET 4.8. Not everything is written as efficiently as it could be. I compared the output with the one you provided. It differs in the contents of .note.gnu.build-id section but I believe that's an artifact of not using the exact same template as the input.

@filipnavara
Copy link
Member

filipnavara commented Jan 31, 2025

Notably, you could also shave off some time if you create the payload section in the actual template (either through the same llvm-objcopy commands or a just adding it as assembly source code during the build). Then it would already have the right flags/alignment and you can reduce the number of invocations to half by using llvm-objcopy --update-section.

@jpobst
Copy link
Contributor Author

jpobst commented Jan 31, 2025

can you, by any chance, share the libarchive-dso-stub.so that was used for
#9692 (comment)

It looks like these come from:

C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\35.0.39\tools\dsostubs

Here is the android-arm64 one:

libarchive-dso-stub.zip

@filipnavara
Copy link
Member

The build-id of libarchive-dso-stub.so differs for each build of the Android workload. The one you uploaded doesn't seem to match the previous build. That said, I run llvm-objcopy locally and verified that it doesn't do any rewriting of the build-id (unless told to do so). That makes the code linked above match the the llvm-objcopy output for this particular use case.

@jpobst
Copy link
Contributor Author

jpobst commented Jan 31, 2025

A quick and dirty test of this code seems very promising:

Debug - EmbedAssembliesInApk - android

Scenario (WrapAssembliesAsSharedLibraries Task) main This PR
Full 40.6 s 14.37 s

Tested by:

  • Converting ElfAppendPayloadSection.csproj to a netstandard2.0 .dll and adding it as a reference in Xamarin.Android.Build.Tasks.
  • Applying patch.txt
  • dotnet new android
  • dotnet build -p:EmbedAssembliesIntoApk=true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: App+Library Build Issues when building Library projects or Application projects. Area: Performance Issues with performance. enhancement Proposed change to current functionality.
Projects
None yet
Development

No branches or pull requests

2 participants