.NET, Architecture, ALM, Cloud

Publicité

ILMerge & MsBuild

 

Quand nous découpons nos projets en différents composant/assemblies, on obtient forcément au final plusieurs dlls comme livrable. 

Or lorsque nous voulons donner à un client une application ou un SDK, il est préférable de lui donner qu’une libraire ou un exécutable. Cela est surtout vrai pour un SDK.

Prenons l’exemple suivant. Nous avons 4 librairies représentant notre SDK :

  • - « Demo.Core.Tools.dll » : Dll utilitaire
  • - « Demo.Services.Contract » : Dll qui contient tous les contrats des services proposés par le SDK
  • - « Demo.Services.Client » (référençant « Demo.Core.Tools.dll »  et   « Demo.Services.Contract » ) : Dll permettant d’accéder aux apis.
  • - « Demo.SDK » (référençant - « Demo.Services.Client ») : Le SDK en question

 

solution

 

Nous obtiendrons donc comme livrables toutes les dlls : 
out

Comment obtenir qu’une librairie à fournir au client ? C’est simple il suffit de fusionner les dll en une seule et c’est l’outil proposé par Microsoft « IlMerge » qui va vous permettre d’effectuer cette opération. 
Tout d’abord télécharger et installer sur votre poste (et votre serveur de build si vous en disposez d’un)  l’outil à cette adresse :  http://www.microsoft.com/en-us/download/details.aspx?id=17630
Aller ensuite dans « C:\Program Files\MSBuild » (ou « Program Files (x86) ») et créer le fichier « Ilmerge.CSharp .targets » pour ajouter le contenu suivant : 

 

<ProjectDefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <
Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <
Target Name="AfterBuild">
    <
CreateItem Include="@(ReferencePath)" Condition="'%(CopyLocal)'=='true' and '%(ReferencePath.IlMerge)'=='true'">
      <
Output TaskParameter="Include" ItemName="IlmergeAssemblies"/>
    </
CreateItem>
    <
Message Text="MERGING: @(IlmergeAssemblies->'%(Filename)')" Importance="High" />
    <
Exec Command="&quot;$(ProgramFiles)\Microsoft\Ilmerge\Ilmerge.exe&quot;/out:@(MainAssembly) &quot;@(IntermediateAssembly)&quot; @(IlmergeAssemblies->'&quot;%(FullPath)&quot;', ' ')" />
  </
Target>
  <
Target Name="_CopyFilesMarkedCopyLocal"/>
</
Project>




Le Target « AfterBuild » va nous permettre de fusionner (en lançant une commande IlMerge.exe ) toutes les références du Projet qui ont un élément « IlMerge » à True.
Il nous faut donc décharger le projet « Demo.SDK.csproj » pour importer notre target « Ilmerge.CSharp .targets » et définir  les références à fusionner : 

 

<!--... -->
<
ItemGroup>
  <
ProjectReference Include="..\Demo.Core.Tools\Demo.Core.Tools.csproj">
    <
Project>{274635C4-07F8-4B47-A795-6C7983EE3119}</Project>
    <
Name>Demo.Core.Tools</Name>
    <
IlMerge>True</IlMerge>
  </
ProjectReference>
  <
ProjectReference Include="..\Demo.Services.Client\Demo.Services.Client.csproj">
    <
Project>{6684A57D-C072-4A5E-9C3A-8178B7A49DD6}</Project>
    <
Name>Demo.Services.Client</Name>
    <
IlMerge>True</IlMerge>
  </
ProjectReference>
  <
ProjectReference Include="..\Demo.Services.Contract\Demo.Services.Contract.csproj">
    <
Project>{9D68BA84-4E7C-46FF-A004-A136B1B6FE56}</Project>
    <
Name>Demo.Services.Contract</Name>
    <
IlMerge>True</IlMerge>
  </
ProjectReference>
</
ItemGroup>
<
Import Project="$(MSBuildExtensionsPath)\Ilmerge.CSharp.targets" />
<!--
... -->



En rechargeant votre projet, la compilation va donc lancer la commande ILMerge suivante : 
"C:\Program Files (x86)\Microsoft\Ilmerge\Ilmerge.exe" /out:bin\Debug\Demo.SDK.dll "obj\Debug\Demo.SDK.dll" "c:\ILMergeDemo\Demo.Core.Tools\bin\Debug\Demo.Core.Tools.dll" "c:\ILMergeDemo\Demo.Services.Client\bin\Debug\Demo.Services.Client.dll" "c:\ILMergeDemo\Demo.Services.Contract\bin\Debug\Demo.Services.Contract.dll"
 
Et nous obtenons bien à l’arrive une seule dll « Demo.SDK.dll » ! : 
out2

IlDasm nous confirme bien que nos trois références ont été fusionnées :

 

ildasm

 

Les différentes options proposées par IlMerge sont nombreuses : 

ilmerge [/lib:directory]* [/log[:filename]] [/keyfile:filename [/delaysign]] [/internalize[:filename]] [/t[arget]:(library|exe|winexe)] [/closed] [/ndebug] [/ver:version] [/copyattrs [/allowMultiple]] [/xmldocs] [/attr:filename] ([/targetplatform:<version>[,<platformdir>]]|v1|v1.1|v2|v4) [/useFullPublicKeyForReferences] [/zeroPeKind] [/wildcards] [/allowDup[:typename]]* [/allowDuplicateResources] [/union] [/align:n] /out:filename <primary assembly> [<other assemblies>...]

 

Vous pouvez donc personnaliser  votre fichier target « Ilmerge.CSharp .targets » pour notamment :

  •  - Spécifier un fichier où se trouve vos attributs globaux à l’assembly fusionné via l’option AttributeFile (/attr:filename
  •  - Signer votre librairie via l’option KeyFile (/keyfile:filename)
  •  - Etc…

 

Publicité
Retour à l'accueil
Partager cet article
Repost0
Pour être informé des derniers articles, inscrivez vous :
Commenter cet article