microsoftgraph / msgraph-sdk-dotnet

Microsoft Graph Client Library for .NET!
https://graph.microsoft.com
Other
695 stars 246 forks source link

Trying out v5. UWP App does not build in Release mode. ILT0005 and RHBIND : error RHB0002: Failed to write PDB. #1696

Open myokeeh opened 1 year ago

myokeeh commented 1 year ago

Describe the bug I was able to get my app updated to v5 and works in Debug mode, but now that I'm trying to run/build in Release mode, I'm getting the following:

ILT0005: 'C:\Program Files (x86)\Microsoft SDKs\UWPNuGetPackages\runtime.win10-x64.microsoft.net.native.compiler\2.2.12-rel-31116-00\tools\x64\ilc\Tools\rhbind.exe @"C:\Users\Me\Source\Repos\App\obj\x64\Release\ilc\intermediate\rhbindargs.APP.rsp"' returned exit code 2
RHBIND : error RHB0002: Failed to write PDB.

This was the only major change to the app, so I'm currently assuming V5 is the culprit. Release build time is much longer than normal and takes a while to get the above errors. I will try to roll back changes and try rebuilding with an older version.

To Reproduce

  1. Upgrade to v5
  2. Update code to work with v5
  3. Run in release mode

Expected behavior App should build and run

Desktop (please complete the following information):

myokeeh commented 1 year ago

For additional context, I have the following in my csproj files:

<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
<OutOfProcPDB>true</OutOfProcPDB>
<Use64Bitcompiler>true</Use64Bitcompiler>

I also just updated to 5.1.0 and now getting this instead:

Internal compiler error: Exception of type 'System.OutOfMemoryException' was thrown.
myokeeh commented 1 year ago

I just rolled back to 4.54.0 and the app builds on Release mode again.

myokeeh commented 1 year ago

@andrueastman any clue why this might be happening?

myokeeh commented 1 year ago

I just converted another app and it has the same issue.

bkaankose commented 1 year ago

I can reproduce and confirm this. My best guess is .NET Native compiler needs to know about runtime directives that Graph SDK uses via reflection.

bkaankose commented 1 year ago

Here is the thing, and it's frustrating. ILT0005 internally maps to Out Of Memory. RHBIND fails to generate PDB mappings since including Microsoft.Graph requires .NET Native compiler to do to quite expensive analysis. This gets out of hand at some point, and rhbind goes out of memory. There are 2 ways to handle this

  1. Easy way: Put some compiler flags into your csproj and hope for the best.
  2. Hard way: Manually craft your Default.rd runtime directive file configuration in UWP application by removing the "Application*" line and adding exactly what you need to use in the app from other libraries.

Easy way

Put these in your csproj for all Release configurations in UWP project, and try to compile. FYI: Arm64 builds never finished for me with these configuration. Also, this is not a guaranteed way. It's kind of a luck thing, but it may succeed with this flags.

    <PreferredToolArchitecture>x64</PreferredToolArchitecture>
    <SingleThreadNUTC>true</SingleThreadNUTC>
    <UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
    <EnableGatekeeperAnalysis>true</EnableGatekeeperAnalysis>
    <ShortcutGenericAnalysis>true</ShortcutGenericAnalysis>
    <OutOfProcPDB>true</OutOfProcPDB>

Hard way

Remove the following line in your Default.rd file

<Assembly Name="*Application*" Dynamic="Required All" />

This line is added by default when you create the project and it tells compiler to basically include everything which you may or may not use at runtime. Once we have Microsoft.Graph SDK, this goes beyond what .NET Native compiler can handle. After this you may try to run the app and see if behaves correctly without errors. You need to manually test every part of your app to see whether you receive any MissingMetadataException or TypeLoadException.

Observe each .dll in this location "obj[architecture]\Release\ilc\in" and take all of their names. Remove the file extension ".dll" part and add a new line in your Default.rd as the following

<Assembly Name="YourAssemblyName" Dynamic=”Required All”/>

replace YourAssemblyName with the name of the file. You may have bunch of runtime directive at this point, but compiler will warn you about the ones it couldn't bind once you start compiling, you may remove them later on.

I tried the easy way and never get it work for all architectures. Easy way also increases build time, so testing gets more frustrating with this error. Hard way was also frustrating, but eventually worked for me. I applied both solutions. Added the compiler flags and manually crafted my Default.rd. Getting rid of using the shared assembly framework package may also help, but they say it'll create more harm than good, so it's not recommended. It works if it works for you though, maybe it'll help you get the compilation done without any runtime errors.

<UseDotNetNativeSharedAssemblyFrameworkPackage>false</UseDotNetNativeSharedAssemblyFrameworkPackage>

At this point, I don't know if this is something that Microsoft Graph should/can fix. It is literally due to lack of not having 64-bit rhbinder from .NET Native team. The tool is outdated, potentially UWP driver is abandoned etc.

myokeeh commented 1 year ago

@bkaankose, thanks for your effort. I'm trying the easy way now.

bkaankose commented 1 year ago

@myokeeh I asked .NET Native External Feedback group about this exact situation, and Tom proposed to add following line to disable dynamic serialization for Graph SDK.

<Assembly Name="Microsoft.Graph" Serialize="Excluded" />

add this on top of the default values in Default.rd, and give it a try as well. Also you can get rid of all the additional tags I mentioned earlier.

myokeeh commented 1 year ago

@bkaankose, that last suggestion is what's allowing it to build in Release mode for me.

LucaZiegler commented 1 year ago

Here is the thing, and it's frustrating. ILT0005 internally maps to Out Of Memory. RHBIND fails to generate PDB mappings since including Microsoft.Graph requires .NET Native compiler to do to quite expensive analysis. This gets out of hand at some point, and rhbind goes out of memory. There are 2 ways to handle this

  1. Easy way: Put some compiler flags into your csproj and hope for the best.
  2. Hard way: Manually craft your Default.rd runtime directive file configuration in UWP application by removing the "Application*" line and adding exactly what you need to use in the app from other libraries.

Easy way

Put these in your csproj for all Release configurations in UWP project, and try to compile. FYI: Arm64 builds never finished for me with these configuration. Also, this is not a guaranteed way. It's kind of a luck thing, but it may succeed with this flags.

    <PreferredToolArchitecture>x64</PreferredToolArchitecture>
    <SingleThreadNUTC>true</SingleThreadNUTC>
    <UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
    <EnableGatekeeperAnalysis>true</EnableGatekeeperAnalysis>
    <ShortcutGenericAnalysis>true</ShortcutGenericAnalysis>
    <OutOfProcPDB>true</OutOfProcPDB>

Hard way

Remove the following line in your Default.rd file

<Assembly Name="*Application*" Dynamic="Required All" />

This line is added by default when you create the project and it tells compiler to basically include everything which you may or may not use at runtime. Once we have Microsoft.Graph SDK, this goes beyond what .NET Native compiler can handle. After this you may try to run the app and see if behaves correctly without errors. You need to manually test every part of your app to see whether you receive any MissingMetadataException or TypeLoadException.

  • If the app works fine, you are lucky.
  • If app behaves different or you get some crashes, you need to manually import each Assembly you reference, and trim them out one by one to get the app working.

Observe each .dll in this location "obj[architecture]\Release\ilc\in" and take all of their names. Remove the file extension ".dll" part and add a new line in your Default.rd as the following

<Assembly Name="YourAssemblyName" Dynamic=”Required All”/>

replace YourAssemblyName with the name of the file. You may have bunch of runtime directive at this point, but compiler will warn you about the ones it couldn't bind once you start compiling, you may remove them later on.

I tried the easy way and never get it work for all architectures. Easy way also increases build time, so testing gets more frustrating with this error. Hard way was also frustrating, but eventually worked for me. I applied both solutions. Added the compiler flags and manually crafted my Default.rd. Getting rid of using the shared assembly framework package may also help, but they say it'll create more harm than good, so it's not recommended. It works if it works for you though, maybe it'll help you get the compilation done without any runtime errors.

<UseDotNetNativeSharedAssemblyFrameworkPackage>false</UseDotNetNativeSharedAssemblyFrameworkPackage>

At this point, I don't know if this is something that Microsoft Graph should/can fix. It is literally due to lack of not having 64-bit rhbinder from .NET Native team. The tool is outdated, potentially UWP driver is abandoned etc.

I got still this:

ILT0005: 'C:\Users\XXX.nuget\packages\runtime.win10-x64.microsoft.net.native.compiler\2.2.12-rel-31116-00\tools\x64\ilc\Tools\nutc_driver.exe @"C:\VS\XXX\XXX\XXX.UWP\obj\x64\Release\ilc\intermediate\MDIL\XXX.UWP.rsp"' returned exit code 1

tony683 commented 1 year ago

Any update on this...its failing in release mode for me also.. Is there any lighter version of this api available... i just want to use this api to sync my events with outlook ..

LucaZiegler commented 1 year ago

Steps to reproduce the behavior:

  1. Create a new Xamarin Forms Project (only) with UWP
  2. Add for example the Microsoft.Graph NuGet package to the shared Xamarin Forms Project
  3. Right click on the UWP project => Publish => Create App Packages
  4. Select Sideloading => No, signing =>Select e.g. only x64 and Release (x64) => Click create
  5. Then I got following output and error message:
    Build started...
    1>------ Build started: Project: XamarinFormsTest, Configuration: Release Any CPU ------
    1>XamarinFormsTest -> C:\Users\lucaz\Source\Repos\LucaZiegler\XamarinFormsTest\XamarinFormsTest\XamarinFormsTest\bin\Release\netstandard2.0\XamarinFormsTest.dll
    2>------ Build started: Project: XamarinFormsTest.UWP, Configuration: Release x64 ------
    2>  XamarinFormsTest.UWP -> C:\Users\lucaz\Source\Repos\LucaZiegler\XamarinFormsTest\XamarinFormsTest\XamarinFormsTest.UWP\bin\x64\Release\XamarinFormsTest.UWP.exe
    2>  Processing application code
    2>  Computing application closure and generating interop code
    2>    Loading 131 modules...
    2>    Generating code...
    2>    Interop code generated.
    2>  Generating serialization code
    2>  Compiling interop code
    2>  Generating System.Reflection.DispatchProxy proxy code.
    2>  Cleaning up unreferenced code
    2>  Generating native code
    2>C:\Program Files (x86)\Microsoft SDKs\UWPNuGetPackages\microsoft.net.native.compiler\2.2.12-rel-31116-00\tools\Microsoft.NetNative.targets(809,5): error : Internal Compiler Error
    2>C:\Program Files (x86)\Microsoft SDKs\UWPNuGetPackages\microsoft.net.native.compiler\2.2.12-rel-31116-00\tools\Microsoft.NetNative.targets(809,5): error : ILT0005: 'C:\Program Files (x86)\Microsoft SDKs\UWPNuGetPackages\runtime.win10-x64.microsoft.net.native.compiler\2.2.12-rel-31116-00\tools\x64\ilc\Tools\nutc_driver.exe @"C:\Users\lucaz\Source\Repos\LucaZiegler\XamarinFormsTest\XamarinFormsTest\XamarinFormsTest.UWP\obj\x64\Release\ilc\intermediate\MDIL\XamarinFormsTest.UWP.rsp"' returned exit code 1
    ========== Build: 1 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    ========== Build started at 12:15 and took 17:52,604 minutes ==========
    ========== Package: 0 succeeded, 1 failed ===========
LucaZiegler commented 9 months ago

@myokeeh Did you find a bug fix?

myokeeh commented 6 months ago

I'm getting this again on version 5.45.0 and 5.46.0.

YZahringer commented 5 months ago

Fixed installing the last Microsoft.Net.Native.Compiler nuget preview: dotnet add package Microsoft.Net.Native.Compiler --version 2.2.12-rel-33220-00

myokeeh commented 5 months ago

@YZahringer, another thing I ran into with 5.45.0+ is when I removed the <Assembly Name="*Application*" Dynamic="Required All" /> line, build would complete, but the app I distribute via Microsoft Store ended up crashing on launch.

I wonder if what you said fixes that too. Testing.

Edit: after installing Microsoft.Net.Native.Compiler on the main project, I'm still getting the RHBIND error.

myokeeh commented 4 months ago

@andrueastman any updates on this? Still a problem on 5.53.0

vinhdp195 commented 3 months ago

@myokeeh I am also having the same issue on version 5.54.0 Do you have any solution for this issue?

myokeeh commented 3 months ago

@vinhdp195 no. Still waiting for someone to acknowledge there's a problem.

vinhdp195 commented 3 months ago

@myokeeh I think you can just set UseDotNetNativeToolchain to false , which means don't use .NET Native <UseDotNetNativeToolchain>false</UseDotNetNativeToolchain>

vinhdp195 commented 3 months ago

@myokeeh Another method: You can try putting the code below at the bottom of the default.rd file <Assembly Name="Microsoft.Graph" Dynamic="Auto" />

myokeeh commented 3 months ago

@myokeeh Another method: You can try putting the code below at the bottom of the default.rd file <Assembly Name="Microsoft.Graph" Dynamic="Auto" />

@vinhdp195 That got it working again! Thanks!

TheKurdishProgrammer commented 2 months ago

@myokeeh Another method: You can try putting the code below at the bottom of the default.rd file <Assembly Name="Microsoft.Graph" Dynamic="Auto" />

Thank you very much, this fixed the release build for us.