in Code & IT

Merging assemblies with ILRepack

Typically, in .NET, to merge assemblies you would use ILMerge. ILRepack is another project you can use and that has had updates recently (and a lot of activity on Github).

I’ve found it useful to merge the lot of Dlls and Exe that can compose a simple app into a single executable file (think containers but without Docker), which facilitates using and distributing it. The new .csproj file format is a great simplification and allows for tasks (as in the previous versions) in a smaller more understandable file.

To use ILRepack in a project, here are the steps you can perform to include the task during your build:

1 – add the ILRepack package to the project you wish to merge files in
2 – validate that the AssemblyName element is defined in the property groups in your .csproj file
3 – in the .csproj, add the following target element

<Target Name="ILRepack" AfterTargets="Build">
<!-- The ILRepack task will grab all build ouput assemblies
and merge them into a single exe file for easy distribution and integration
-->
<ItemGroup>
<ILRepackPackage Include="$(NuGetPackageRoot)\ilrepack\*\tools\ilrepack.exe" />
<NetStandardLocation Include="$(NuGetPackageRoot)NETStandard.Library\2.0.1\build\netstandard2.0\ref" />
</ItemGroup>

<Error Condition="!Exists(@(ILRepackPackage->'%(FullPath)'))" Text="You are trying to use the ILRepack
 package, but it is not installed or at the correct location" />
<Exec Command="@(ILRepackPackage->'%(fullpath)') /out:$(OutputPath)merged\$(AssemblyName).exe 
/wildcards /lib:@(NetStandardLocation) /target:exe $(OutputPath)$(AssemblyName).exe $(OutputPath)*.dll" />
</Target>

3.1 – the NetStandardLocation element is only required if you are targeting it or including a package that targets it.
3.2 – the /lib:@(NetStandardLocation) argument in the Exec command is only required by 3.1
3.3 – adjust the /out argument in the command to whatever you require.

4 – If you want to include the output in a package, define the package elements in a propertyGroup and include:

<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<!--we do not want build outputs integrated into the resulting package, only the IL merged file -->
<IsTool>True</IsTool>
<IncludeBuildOutput>False</IncludeBuildOutput>
</PropertyGroup>

<ItemGroup>
<!-- nuget package files info: -->
<!--we do not want build outputs integrated into the resulting package, only the IL merged file -->
<Content Include="$(OutputPath)merged\$(AssemblyName).exe" PackagePath="tools\" />
</ItemGroup>

And that’s pretty much it. If you run build, ILRepack will be executed and build the merged file, and MSBuild will also wrap it in a NuGet package if you include the packaging step.

Write a Comment

Comment

 

This blog is kept spam free by WP-SpamFree.