Instructions pour créer un paquet QGIS avec le connecteur Oracle Spatial sous Debian Jessie🔗

Posted by Médéric Ribreux 🗓 In blog/ Qgis/

Introduction

A la suite de mes différents articles sur l'installation et l'empaquetage du client Oracle, il est temps de passer à l'objectif final de ces opérations: installer le provider Oracle Spatial (que j'appelle aussi connecteur Oracle Spatial) pour QGIS sous Debian Jessie.

Nous allons récupérer les sources de QGIS, basculer sur une branche stable, effectuer nos petites modifications pour inclure les bibliothèques Oracle et créer les différents paquets. À l'issue de cette procédure, nous disposerons d'une installation complète de QGIS avec la possibilité de se connecter à un serveur Oracle Spatial, que ce soit pour un usage station de travail ou pour utiliser QGIS Server.

Mode opératoire

Pour ma part, j'effectue l'empaquetage dans une machine virtuelle. En effet, cette opération d'empaquetage de QGIS nécessite d'installer une sacrée liste de paquets et je ne souhaite pas alourdir ma station de travail avec des paquets qui ne me serviront qu'une seule fois (ou dans tous les cas assez peu souvent).

Récupérer les sources et pointer vers la bonne version de QGIS

$ mkdir -p ~/packaging
$ git clone https://github.com/qgis/QGIS.git
$ cd ~/packaging
$ git clone ../QGIS
$ git checkout final-2_10_0

C'est la version 2.10 qui sera utilisée dans la suite de cet article mais les instructions doivent fonctionner aussi bien pour les versions ultérieures que pour les versions antérieures, à partir de la version 2.8.

Paquets à installer

Avant de pouvoir empaqueter QGIS, il va vous falloir un sacré paquet de paquets !

Voici la liste:

apt install build-essential ca-certificates devscripts fakeroot bison cmake \
  debhelper flex grass-dev libexpat1-dev libfcgi-dev libgdal-dev libgeos-dev \
  libgsl0-dev libpq-dev libproj-dev libqt4-dev libqt4-opengl-dev libqtwebkit-dev \
  libqwt-dev libspatialite-dev libsqlite3-dev libspatialindex-dev pkg-config \
  pyqt4-dev-tools python-all-dev python-dev python-qt4-dev python-sip-dev txt2tags \
  doxygen python-qscintilla2 pyqt4.qsci-dev libosgearth-dev libopenscenegraph-dev \
  libqscintilla2-dev graphviz xvfb xauth xfonts-base xfonts-100dpi xfonts-75dpi \
  xfonts-scalable spawn-fcgi lighttpd poppler-utils python-pyspatialite \
  qt4-doc-html libqt4-sql-sqlite python-matplotlib osgearth-data python-psycopg2 \
  python-httplib2 python-jinja2 python-markupsafe liblwgeom-2.1.7 qt4-designer

Si vous avez suivi mon précédent article, vous pourrez bien entendu, installer les paquets oracle-instantclient et oracle-instantclient-dev pour pouvoir compiler le provider Oracle. Vous pouvez également simplement installer le client Oracle à la main.

Modification du fichier debian/control.in

Le fichier debian/control.in est un fichier modèle pour le fichier debian/control. Pour ceux qui font régulièrement de la fabrication de paquet Debian, ce fichier ne devrait pas avoir de secret. QGIS présente la particularité de mettre à part la construction du paquet dédié au connecteur Oracle Spatial. En effet, le client et le SDK Oracle étant non libres, ils ne sont pas empaquetés dans la distribution Debian.

Vous devez donc modifier le fichier debian/control.in pour générer le paquet du provider Oracle. Si vous l'omettez, le paquet ne sera pas construit et le connecteur ne sera pas disponible même si l'icône d'accès à la boîte de dialogue de sélection des couches sera présente dans l'interface de QGIS. Ajoutez les éléments à la fin du fichier:

Package: qgis-oracle-provider
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, oracle-instantclient
Section: contrib/database
Description: QGIS oracle provider
  QGIS is a Geographic Information System (GIS) which manages, analyzes and
  display databases of geographic information.
  .
  This package contains the QGIS oracle provider.

Pensez à supprimer la dépendance vers oracle-instantclient si vous n'avez pas installé le client Oracle via le paquet non officiel que j'ai présenté dans cet article.

Modification du fichier debian/rules

Une fois le paquet du connecteur Oracle correctement déclaré, il reste à modifier le fichier debian/rules. En effet, par défaut, le fichier rules indique de ne fabriquer le paquet que sous la distribution sid-oracle. Or, nous sommes sous Jessie. Par défaut, la construction de paquet ne saura pas fabriquer le connecteur Oracle.

Vous devez modifier la variale CMAKE_OPTS et y inclure la directive -DWITH_ORACLE=TRUE, comme dans ce qui suit:

…
CMAKE_OPTS := \
	-DBUILDNAME=$(DEB_BUILD_NAME) \
	-DCMAKE_VERBOSE_MAKEFILE=1 \
	-DCMAKE_INSTALL_PREFIX=/usr \
	-DGRASS_PREFIX=/usr/lib/$(GRASS) \
	-DBINDINGS_GLOBAL_INSTALL=TRUE \
	-DPEDANTIC=TRUE \
	-DWITH_QSPATIALITE=TRUE \
	-DWITH_SERVER=TRUE \
	-DWITH_SERVER_PLUGINS=TRUE \
	-DSERVER_SKIP_ECW=TRUE \
-DQGIS_CGIBIN_SUBDIR=/usr/lib/cgi-bin \
	-DWITH_APIDOC=TRUE \
	-DWITH_CUSTOM_WIDGETS=TRUE \
	-DWITH_ORACLE=TRUE \
	-DWITH_GLOBE=TRUE \
	-DWITH_INTERNAL_HTTPLIB2=FALSE \
	-DWITH_INTERNAL_JINJA2=FALSE \
	-DWITH_INTERNAL_MARKUPSAFE=FALSE \
	-DWITH_INTERNAL_PYGMENTS=FALSE \
	-DWITH_INTERNAL_DATEUTIL=FALSE \
	-DWITH_INTERNAL_PYTZ=FALSE \
	-DWITH_INTERNAL_SIX=FALSE
…

Modification de la configuration de CMake

Il faut modifier le fichier src/providers/oracle/ocispatial/cmake/FindOCI.cmake pour indiquer le répertoire du client Oracle et de son SDK. Si vous utilisez les paquets Debian du client Oracle OCI dont j'ai décris la réalisation, vous n'avez rien à faire. Si vous avez installé manuellement le client Oracle dans /opt, voici comment vous devez modifier le fichier:

FIND_PATH(OCI_INCLUDE_DIR oci.h
  PATHS
  /opt/oracle/instantclient_11_2/sdk/include
  $ENV{OSGEO4W_ROOT}/include
  $ENV{ORACLE_HOME}/rdbms/public
)

FIND_LIBRARY(OCI_LIBRARY clntsh oci
  PATHS
  /opt/oracle/instantclient_11_2/
  $ENV{OSGEO4W_ROOT}/lib
  $ENV{ORACLE_HOME}/lib
)

Création des paquets

Vous avez fait le plus dur ! Il ne reste qu'à lancer dpkg-buildpackage -us -uc -b et attendre ! Je vous conseille plutôt de lancer la commande qui suit:

DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -us -uc -b

L'option nocheck permet de ne pas jouer la batterie de tests à la suite de la compilation. Sachez que les tests prennent facilement une bonne demi-heure… QGIS est assez long à empaqueter comme ça (compter au moins une demi-heure sur une machine récente) !

Si jamais le processus échoue à un moment donné, il vous reste à "hacker" dans le répertoire debian et ailleurs pour voir ce qui manque. En règle générale, il s'agit d'un problème de dépendances. Pour éviter que dpkg-buildpackage ne relance toute la compilation from scratch, utilisez l'option -nc qui permet de ne pas nettoyer l'arborescence des sources. C'est très utile si vous avez un problème au moment de la création du paquet avec dh_shlibdeps par exemple.

À la fin du processus et si tout se passe bien, vous aurez une liste impressionnante de paquets deb dans le répertoire ~/packaging dont le fameux qgis-oracle-provider_2.10.0_amd64.deb !

Pour installer en mode brutal:

dpkg -i ~/packaging/*.deb

Tests

Lancez le client QGIS et tentez de créer une connexion Oracle Spatial. Si tout se passe bien, vous aurez accès à la liste de vos couches et vous pourrez en ajouter une dans le canevas de cartes.

Si ce n'est pas le cas, il va vous falloir "hacker" un peu plus. Le principal coupable sera sans doute le fichier tnsnames.ora. Lors de mon précédent article, j'avais indiqué qu'il fallait paramétrer une variable d'environnement TNS_ADMIN. Mais cette dernière n'est disponible que via un appel à Bash. Si vous lancez QGIS depuis le bureau (via les suckless-tools bien sûr), cette variable n'est pas initialisée et aucune connexion ne fonctionnera.

Vérifiez votre fichier ~/.profile pour voir s'il contient bien la variable TNS_ADMIN:

export TNS_ADMIN=~/.oracle

Une dernière recommandation

Pour assurer de bonnes performances sous Oracle Spatial, utilisez absolument les index spatiaux. Contrairement à PostGIS, les index spatiaux sont pratiquement des pré-requis sous Oracle Spatial car un très grand nombre de fonctions ne sont pas utilisables sans.

En plus de la création de l'index, vous devez vous assurer que l'utilisateur qui accède à vos données disposent également des droits de lecture sur les tables d'index (tables dont le nom commence par MDRT) sinon le provider Oracle de QGIS ne pourra pas utiliser les fonctions d'index. Voici un petit script en PL/SQL pour vous assurer de ces droits une fois tous vos index créés (remplacez utilisateur par le nom du compte Oracle à qui vous voulez donner accès à vos index, ce script doit être lancé par l'utilisateur propriétaire du schéma Oracle):

set serveroutput on
DECLARE
  tbName VARCHAR2(200);
  CURSOR mdrtTables IS
  SELECT SDO_INDEX_TABLE FROM ALL_SDO_INDEX_METADATA;
BEGIN
  -- We need to scan all the Index tables
  FOR tb in mdrtTables
  LOOP
    DBMS_OUTPUT.PUT_LINE('Table: ' || tb.SDO_INDEX_TABLE);
    EXECUTE IMMEDIATE 'GRANT SELECT ON ' || tb.SDO_INDEX_TABLE || ' TO utilisateur';
   END LOOP;
END;
/
EXIT

Conclusion

Grâce à l'empaquetage Debian, il est possible d'inclure le connecteur Oracle de QGIS en modifiant quelques fichiers. Au final, le processus n'est pas si simple, car il faut installer le client Oracle et recréer le paquet Debian à la main alors que si vous aviez un serveur PostgreSQL/PostGIS, tout serait prêt "out-of-the-box".

Mais bon, parfois, on n'a pas le choix ! J'ai bien galéré à trouver une méthode suffisamment propre et automatisée pour ce travail étant donné la complexité du projet QGIS et surtout la difficulté amenée par le provider Oracle qui s'appuie sur du logiciel non libre, mal intégré sous Debian.

Néanmoins, les entités qui souhaiteraient installer QGIS Server sous Debian et qui n'ont que des données géographiques disponibles sous Oracle pourront aller un peu plus loin grâce à ces instructions…