[MSBuild] Comment référencer l'assembly spécifique à l'architecture de la plateforme
By Michael DELVA on Friday 2 July 2010, 17:04 - Miscellaneous - Permalink
TweetCet article est destiné à ceux qui, comme moi, doivent jongler entre 2 versions d'une même assembly, selon que vous travailliez sur un poste en 32 bits ou en 64 bits. Dans mon cas, le fichier incriminé est System.Data.SQLite.dll, qui permet d'utiliser des bases de données sous SQLite, depuis le framework .NET. Cette assembly existe donc, vous l'aurez compris, en 2 exemplaires: 32 et 64 bits.
Les soucis ont commencé à arriver pour moi lorsque j'ai commencé à mettre en place mes tests unitaires pour tester le comportement de mes repositories. Car au début du développement, j'étais sur un PC 32bits, avec la DLL 32bits référencée, et tout allait bien. Mais, je me suis mis à travailler aussi bien sur une machine 32 bits que sur une machine en 64 bits, et à chaque fois je devais supprimer la référence vers l'assembly, et la remplacer par une référence vers l'assembly spécifique à la plateforme sur laquelle les tests étaient lancés.
Bien lourd donc...
Mais depuis, c'est fini! Et si vous avez également le même souci, sachez qu'il existe une solution. Que voici sans plus attendre...
La clé du succès dans notre cas est msbuild. Pour mener à bien notre tâche, nous allons en effet modifier la procédure de build des projets incriminés, et laisser à msbuild le soin de copier la bonne assembly au bon endroit.
Pour commencer, il nous faut modifier le fichier csproj du projet référençant l'assembly fautive, soit en l'ouvrant dans un éditeur de texte lambda, soit dans visual studio, en faisant un clic droit dessus dans l'explorateur de solution, puis en choisissant Unload Project puis Edit Project.
Nous allons commencer par ajouter un nouveau noeud au XML, tout en haut du fichier, juste après la racine Project:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ISx64Server>false</ISx64Server>
<ISx64Server Condition="'$(PROCESSOR_ARCHITECTURE)'=='AMD64' or '$(PROCESSOR_ARCHITEW6432)'=='AMD64'">true</ISx64Server>
</PropertyGroup>
On définit ici une propriété ISx64Server qui est à false par défaut, mais qui va passer à true si, vous l'aurez compris, l'une des variables globales $(PROCESSOR_ARCHITECTURE) ou $(PROCESSOR_ARCHITEW6432) est égale à AMD64.
La deuxième modification que nous allons effectuer se trouve maintenant tout en bas de ce fichier. Vous devriez avoir une zone commentée, avec ce texte à l'intérieur : To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets
C'est dans le noeud <Target Name="AfterBuild"> que nous allons ajouter notre copie de fichier:
<Target Name="AfterBuild">
<Copy Condition="'!$(ISx64Server)'" SourceFiles="..\..\..\lib\FluentNHibernate\System.Data.SQLite.dll" DestinationFolder="$(TargetDir)" />
<Copy Condition="'$(ISx64Server)'" SourceFiles="..\..\..\lib\FluentNHibernate\x64\System.Data.SQLite.dll" DestinationFolder="$(TargetDir)" />
</Target>
Rien de bien compliqué ici. Si la variable $(ISx64Server) que nous avons déclaré plus tôt est à false, nous allons copier la dll 32bits dans le répertoire de sortie. Si au contraire la variable est à true, nous allons cette fois copier la dll compilée pour du 64 bits.
Et à l'exécution, vous n'aurez plus aucun soucis.
Elle est pas belle la vie?