Compilation de MapScript .NET

Author:Tamas Szekeres
Contact:szekerest at gmail.com

Compilation

Avant de compiler MapScript C#, vous devez compiler MapServer avec les options selon vos besoins. Pour plus d’informations sur la compilation de MapServer, merci de lire le guide de compilation et d’installation Win32. Il est fortement recommandé de limiter les dépendances de la bibliothèque de votre application, ainsi quand vous compilez MapServer activez seulement les fonctionnalités vraiment nécessaires. Pour compiler les bindings C#, SWIG 1.3.31 ou plus récent est requis.

Avertissement

Ce document peut se référer à des versions de bibliothèques un peu anciennes. Vous voudrez peut être essayer d’utiliser des versions plus récentes des bibliothèques pour votre compilation.

Compilation Win32 pour le framework 1.1 de MS.NET

Vous devez compiler MapServer, MapScript et toutes les bibliothèques associées en utilisant Visual Studio 2003. Téléchargez et décompressez la dernière version de SWIGWIN qui contient le binaire swig.exe précompilé. Ouvrez la ligne de commande de Visual Studio .NET 2003 et allez dans le répertoire /mapscript/csharp. Editer makefile.vc et définissez la variable SWIG à l’emplacement de votre swig.exe

Usage:

nmake -f makefile.vc

pour compiler mapscript.dll et mapscript_csharp.dll.

Compilation Win32 pour le framework 2.0 de MS.NET

Vous devez compiler MapServer, MapScript et toutes les bibliothèques associées en utilisant Visual Studio 2005. Téléchargez et décompressez la dernière version de SWIGWIN qui contient le binaire swig.exe précompilé. Ouvrez la ligne de commande de Visual Studio 2005 et allez dans le répertoire /mapscript/csharp. Editer makefile.vc et définissez la variable SWIG à l’emplacement de votre swig.exe

Usage:

nmake -f makefile.vc

pour compiler mapscript.dll et mapscript_csharp.dll.

Compilation sous Win32 pour le framework MONO

Avant la compilation, vous devez télécharger et installer le paquet d’installation récent mono pour Win32 (comme mono-1.1.13.2-gtksharp-2.8.1-win32-1.exe) Editer makefile.vc et définir la variable CSC à l’emplacement de votre mcs.exe. Alternativement, vous pouvez définir:

MONO = YES

dans votre fichier nmake.opt

Vous devez utiliser le même compilateur pour compiler MapScript que celui utilisé pour la compilation de MapServer. Pour compiler MapScript, ouvrez la ligne de commande fournie par votre compilateur et utilisez:

nmake -f makefile.vc

pour compiler mapscript.dll et mapscript_csharp.dll.

Méthodes de compilations alternatives sous Windows

A partir de la version de MapServer 4.8.3, vous pouvez appeler la compilation C# depuis votre répertoire MapServer en dé-commentant DOT_NET dans nmake.opt:

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# .NET/C# MapScript
# ----------------------------------------------------------------------
# .NET will of course only work with MSVC 7.0 and 7.1.  Also note that
# you will definitely want USE_THREAD defined.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#DOT_NET = YES

et en invoquant la compilation par:

nmake -f makefile.vc csharp

Vous pouvez aussi utiliser:

nmake -f makefile.vc install

pour effectuer la compilation et copier les cibles dans un répertoire de sortie commun

Tester la compilation

Pour tester la compilation et l’environnement d’exécution, vous pouvez utiliser:

nmake -f makefile.vc test

à l’intérieur du répertoire csharp pour démarrer les applications exemple compilées antérieurement. Avant de faire le test, l’emplacement des bibliothèques correspondantes doivent être incluses dans le PATH système.

Compilation Linux avec le framework MONO

Avant la compilation, vous devez télécharger et installer le paquet récent de Mono pour Linux. Certaines distributions ont des binaires précompilés à installer, mais pour utiliser la dernière version vous voulez peut-être compiler et installer Mono depuis les sources. Téléchargez et décompressez la dernière version de SWIG. Vous devez probablement l’installer depuis les sources si des binaires précompilés ne sont pas disponibles pour votre plateforme.

Before compiling MapScript, MapServer should be configured and compiled. Beginning from MapServer 4.8.2 during configuration the mapscript/csharp/Makefile will be created according to the configuration options. Edit this file and set the SWIG and CSC for the corresponding executable paths if the files could not be accessed by default. To compile at a console step into the /mapscript/csharp directory use:

make

pour compiler libmapscript.so et mapscript_csharp.dll.

Pour tester la compilation et l’environnement d’exécution, vous pouvez utiliser:

make test

pour démarrer les applications exemples compilés précédemment.

Compilation sous OSX avec le framework MONO

À partir de la version 4.10.0, le csharp/Makefile gère la compilation sous Mac OSX. Avant de lancer la compilation, le paquet récent de MONO doit être installé sur votre système.

Before compiling MapScript, MapServer should be configured and compiled. Beginning from MapServer 4.8.2 during configuration the mapscript/csharp/Makefile will be created according to the configuration options. Edit this file and set the SWIG and CSC for the corresponding executable paths if the files could not be accessed by default. To compile at a console step into the /mapscript/csharp directory use:

make

pour compiler libmapscript.dylib et mapscript_csharp.dll.

Pour tester la compilation et l’environnement d’exécution, vous pouvez utiliser:

make test

pour démarrer les applications exemples compilés précédemment.

Pour lancer les applications, mapscript_csharp.dll.config est nécessaire avec le fichier mapscript_csharp.dll. Ce fichier est créé pendant le processus make

Installation

Les fichiers requis pour votre application devraient être installés manuellement. Il est fortement recommandé de copier les fichiers dans le même dossier que là où les éxécutables sont présents.

Problèmes connus

Visual Studio 2005 nécessite un fichier manifest pour charger le “CRT native assembly wrapper”

Si vous avez compilé MapServer pour utiliser les bibliothèques CRT et que vous utilisez le framework MS.NET 2.0 comme “runtime”, vous devriez fournir un fichier manifest avec votre exécutable, comme:

<?xml version="1.0" encoding="utf-8"?>
<assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1
 assembly.adaptive.xsd" manifestVersion="1.0"
 xmlns:asmv1="urn:schemas-microsoft-com:asm.v1"
 xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
 xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"
 xmlns="urn:schemas-microsoft-com:asm.v1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity name="drawmap.exe" version="1.0.0.0" type="win32" />
<dependency>
<dependentAssembly asmv2:dependencyType="install"
 asmv2:codebase="Microsoft.VC80.CRT.manifest" asmv2:size="522">
<assemblyIdentity name="Microsoft.VC80.CRT" version="8.0.50608.0"
 publicKeyToken="1fc8b3b9a1e18e3b" processorArchitecture="x86"
 type="win32" />
<hash xmlns="urn:schemas-microsoft-com:asm.v2">
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<dsig:DigestValue>UMOlhUBGeKRrrg9DaaPNgyhRjyM=</dsig:DigestValue>
</hash>
</dependentAssembly>
</dependency>
</assembly>

Cela informera le CLR (Common Language Runtime) que votre exécutable dépend du CRT (C Run Time) et que le wrapper de l’assembly est présent pour être utilisé. Si vous utilisez l’IDE, le fichier manifest peut être prégénéré en ajoutant une référence à Microsoft.VC80.CRT.manifest dans le répertoire /Microsoft Visual Studio 8/VC/redist/x86/Microsoft.VC80.CRT.

Les manifests pour les dlls doivent être encapsulées comme une ressource

Selon le makefile windows, la cible de compilation MapScript (mapscript.dll) est liée avec l’option /MD. Dans ce cas, le linker VS2005 générera un fichier manifest contenant la dépendance de l’assembly non managé. Les contenus exemple du fichier manifest sont:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.VC80.CRT'
 version='8.0.50608.0' processorArchitecture='x86'
 publicKeyToken='1fc8b3b9a1e18e3b' />
</dependentAssembly>
</dependency>
</assembly>

Comme mentionné précédemment si vous créez une application windows, le CLR (Common Language Runtime) cherchera un fichier manifest pour l’application. Le nom du fichier manifest devrait être le même comme l’exécutable ajoute et se termine avec une extension .manifest. Cependant, si le processus hôte n’est pas contrôlé par vous (comme une application de cartographie en ligne utilisant aspnet_wp.exe comme processus hôte), vous ne serez pas certain que le processus hôte (.exe) aura un manifest contenant une référence au wrapper CRT. Dans ce cas, vous devrez peut être encapsulé le manifest dans la dll en tant que ressource en utilisant l’outil mt comme:

mt /manifest mapscript.dll.manifest /outputresource:mapscript.dll;#2

the common language runtime will search for the embedded resource and load the CRT assembly properly.

Normallement, il est suffisant de charger le CRT avec la dll racine (mapscript.dll), mais ce n’est pas dangereux d’encapsuler le manifest dans les bibliothèques dépendantes également.

Problème avec regex et Visual Studio 2005

Quand vous compilez avec Microsoft Visual Studio 2005, une collision de nom de variable peut avoir lieu entre regex.c et crtdefs.h. Pour plus de détails, voir:

https://github.com/mapserver/mapserver/issues/1651

Correspondance de nom de bibliothèque MapScript C# avec MONO

En utilisant l’interface MapScript créé par le générateur d’interface SWIG, la communication entre les classes du wrapper C# (mapscript_csharp.dll) et le code C (mapscript.dll) a lieu à l’aide d’appel de plateforme comme:

[DllImport("mapscript", EntryPoint="CSharp_new_mapObj")]
public static extern IntPtr new_mapObj(string jarg1);

La déclaration DllImport contient le nom de la bibliothèque, cependant la transformation du nom de la bibliothèque en nom de fichier est fonction du système. Sous Windows au nom de la bibliothèque est simplement ajouté l’extension .dll (mapscript.dll). Sous les systèmes Unix les noms de fichiers des bibliothèques démarrent avec le préfixe lib et se terminent avec l’extension .so (libmapscript.so).

L’enregistrement du nom de la bibliothèque au niveau du système peut être manuellement contrôlé en utilisant le fichier dll.config. Cela enregistre simplement le fichier de la bibliothèque que DllImport recherche dans son équivalent unix. Le fichier contient normalement les informations suivantes (mapscript_csharp.dll.config) :

<configuration>
  <dllmap dll="mapscript" target="libmapscript.so" />
</configuration>

et avec les build OSX:

<configuration>
  <dllmap dll="mapscript" target="libmapscript.dylib" />
</configuration>

Le fichier doit être placé en parallèle du fichier mapscript_csharp.dll correspondant, et sera créé par défaut durant le processus de make. Pour plus d’information voir :

https://github.com/mapserver/mapserver/issues/1596 http://www.mono-project.com/Interop_with_Native_Libraries

Problèmes avec les locales avec MONO/Linux

Selon le ticket https://github.com/mapserver/mapserver/issues/1762 MapServer peut ne pas opérer de la même façon sur différents paramétrages régionaux. Spécialement quand le séparateur de décimal est différent de ”.” dans la locale du processus qui peut entraîner des erreurs de lecture quand le mapfile contient des nombres flottants. Puisque le processus MONO prend en charge les paramètres régionaux de l’environnement, il est utile d’envisager de définir les paramètres régionaux par défaut à “C” du processus hébergé, par exemple

LC_ALL=C mono ./drawmap.exe ../../tests/test.map test_csharp.png

Erreurs les plus fréquentes

Ce chapitre résume les problèmes les plus fréquents sur lequel l’utilisateur peut tomber. Les problèmes sont collectés principalement de la liste -user et sur IRC.

Unable to load dll (MapScript)

Vous pouvez avoir ce problème sous Windows et dans la plupart des cas, il peut être dû à une bibliothèque partagée manquante ou impossible à charger. Le message d’erreur parle de mapscript.dll mais il manque surement une ou plusieurs dll-s dont le fichier libmap.dll dépend. Ainsi en premier lieu, vous devriez vérifier les dépendances de votre fichier libmap.dll dans votre répertoire d’application. Vous pouvez utiliser le logiciel Visual Studio Dependency Walker pour accomplir cette tâche. Vous pouvez aussi utiliser un outil de monitoring de fichiers (comme filemon fourni par SysInternal) pour détecter les dll-s qui ne peuvent pas être chargées. Je propose de stocker toutes les dll-s requises par votre application dans votre répertoire d’application. Si vous pouvez lancer les applications exemples C# drawmap avec votre mapfile, votre compilation devrait être correcte et toutes vos dlls seraient disponibles.

Vous allez peut être trouver que l’interface mapscript C# se comporte différemment pour les applications desktop et ASP.NET. Bien que vous puissiez lancer correctement l’exemple drawmap, vous rencontrerez peut-être le problème de chargement de dlls avec les applications ASP.NET. Quand vous créez un projet ASP.NET, votre répertoire d’application sera ‘Inetpubwwwroot[YourApp]bin’ par défaut. Le processus hôte de l’application sera aspnet_wp.exe ou w3wp.exe en fonction de votre système. L’application tournera dans un context de sécurité différent de l’utilisateur interactif (sous le contexte de l’utilisateur ASPNET par défaut). Quand vous placez les dll-s en dehors de votre répertoire d’application, vous devriez prendre en compte les différences de valeurs de la variable d’environnement PATH entre l’utilisateur interactif et ASPNET et/ou que nous n’ayiez pas assez de droits pour accéder à une dll en dehors de votre répertoire d’application.

Rapports de bugs

Si vous trouvez un problème associé à l’interface MapScript C# interface, h’ésitez pas à compléter un rapport de bug sur le gestionnaire de bugs.