How to install CrossGen to optimize .NET Core Library in ci/cd

2.1k views Asked by At

I am attempting to pre-jit/Ahead-Of-Time (AOT) compile a .NET Core 5 Library to a Native Image using Microsoft's CrossGen utility as described here to improve start up time.

However the instructions for Getting CrossGen are vague:

If you install CoreCLR using a NuGet package, you can find CrossGen in the tools folder of the NuGet package.

How do I install CrossGen via NuGet?

What I've tried so far:

  1. Create a build script that writes deleteme.csproj to disk and has a <PackageReference Include="Microsoft.NETCore.App.Runtime.win-x64" Version="3.1.6" />

  2. Run dotnet restore deleteme.csproj. This will download the Crossgen nuget package to local cache.

  3. I can now run ~/.nuget/packages/microsoft.netcore.app.runtime.win-x64\3.1.6\tools\crossgen.exe

NOTE: I know I can use the ReadyToRun feature for Self-Contained Deployment executable (as described here) HOWEVER I need to optimize a Class Library, so ReadyToRun doesn't work.

Problem

  1. The Nuget package has a big warning:

Internal implementation package not meant for direct consumption. Please do not reference directly. 2. Installation like this seems incorrect. I'd expect CrossGen to be installed as a dotnet tool rather than needing to create a dummy project and run dotnet restore in order to download a copy of a nuget package in cache.

Is there a correct way to pre-jit a .NET Core 5 Library during a ci/cd build?

2

There are 2 answers

2
sj13 On

in case that you have not found a solution to this problem, first of all, crossgen now has a new implement named crossgen2, for getting crossgen2 you can build it as it is open source or just download and unzip it as all nuget files are zip files. crossgen is an internal tool for MSBuild so if you want to use it separately you have to use the command line, fortunately, crossgen has a built-in help page so you hopefully get to know what you want to do. by the way, why won't you just use R2R? R2R contains both IL and AOT your app is optimized with R2R, the downside is as Tomas Says here: https://devblogs.microsoft.com/dotnet/conversation-about-ready-to-run/

Tomas: The version resiliency concept and automatic switch-over to runtime JIT upon a mismatch also mean that a given R2R app can silently experience a perf degradation that may be hard to understand for an end-user.

I assume you don't want to use R2R because of double size as it contains both IL and AOT native images. in that case with a combine of Trim, compressed single file a blank dotnet self-contained program drops from 70 MB to 20 MB.

0
Fabian Schmied On

AntonLapounov answered your question on Github:

<PublishReadyToRun>true</PublishReadyToRun> does work for libraries when targeting netcoreapp3.1, net5.0, and the upcoming net6.0 framework. If you run the following commands in an empty directory:

dotnet new classlib
dotnet publish -p:PublishReadyToRun=True -c Release -r win-x64 -v:n

you will see the crossgen.exe command line. The r2rdump.exe utility can be used to see generated native code placed into the managed DLL.

On my machine, it's indeed %USERPROFILE%\.nuget\packages\microsoft.netcore.app.runtime.win-x64\5.0.13\tools\crossgen.exe. It seems the .NET SDK installs that package automatically.