Logo Spiria

Créer une librairie NumPy compatible avec la librairie C de Visual Studio 2012

5 février 2016.
Dans l’article précédent, vous avez appris comment construire une chaîne de compilation Mingw-w64 liée à une version spécifique de la librairie C de Microsoft. Dans cet article, nous utiliserons cette même chaîne de compilation avec une version de Python installée en local. L’objectif est de générer une version de NumPy liée à msvcrt110.dll, compatible avec Maya 2016.

Dans l’article précédent, vous avez appris comment construire une chaîne de compilation Mingw-w64 liée à une version spécifique de la librairie C de Microsoft. Dans cet article, nous utiliserons cette même chaîne de compilation avec une version de Python installée en local. L’objectif est de générer une version de NumPy liée à msvcrt110.dll, compatible avec Maya 2016.

Créer un « build » Python 2.7.11 avec Visual Studio 2012

Cette version de Python facilitera l'assemblage et le test de modules Python utilisant notre chaîne de compilation Mingw-w64.

Vous devez installer quelques utilitaires pour gérer les scripts de programmation:

Téléchargez la version la plus récente de Python, disponible en archive .tar, pour ensuite l’extraire dans votre espace de travail.

Une fois Python extrait :

Ouvrez une invite de commande et démarrez Python-2.7.11\PCBuild\get_externals.bat.
Ouvrez Python-2.7.11\PCBuild\pcbuild.sln dans Visual Studio 2012, vos projets seront mis à jour automatiquement
Choisissez la configuration de la version x64 et appuyez sur F7 pour démarrer le tout 

Lors de la dernière étape, il est possible que l’installation des modules Tk/TkInter échoue. Ne paniquez pas, ils ne sont pas nécessaires et les binaires compilés dans Python-2.7.11\PCBuild\amd64\ suffiront largement. Il reste quelques détails à ajouter avant que le tout puisse servir à créer des paquets. Toutes les commandes ci-dessous sont déjà dans le mingw-w64 que nous avons préparé dans le billet de blogue mentionné précédemment. Il suffit d’exécuter la commande C:\msys64\mingw64_shell.bat. Les fichiers téléchargés, tels que mentionnés ci-dessous, se trouvent dans le fichier Msys, c’est-à-dire C:\msys64\home\jgamache dans le cas présent.

1— Appliquez le patch de définition de mingw64, tirée du rapport de bogue 11723 de Python, en l’ajoutant à votre nouveau Python :

$ cd /c/Workspace/Python-2.7.11
$ patch -p2 < ~/Downloads/mingw64.patch

2— Appliquez le patch de déclaration de MS_WIN64, tirée du rapport 4709

$ patch -p0 < ~/Downloads/mingw-w64.patch

3— Ajoutez à /c/Workspace/Python2.7.11/Lib/distutils/cygwinccompiler.py les lignes en rouge, afin de mettre à jour la fonction msvcr() : 

        elif msc_ver == '1500':
            # VS2008 / MSVC 9.0
            return ['msvcr90']
        elif msc_ver == '1600':
            # VS2010 / MSVC 10.0
            return ['msvcr100']
        elif msc_ver == '1700':
            # VS2012 / MSVC 11.0
            return ['msvcr110']
        else:
            raise ValueError("Unknown MS Compiler version %s " % msc_ver)

4— Générez le fichier python27.lib pour permettre la création du lien unissant cette librairie Python à la chaîne de compilation Mingw-w64 :

$ cd /c/Workspace/Python-2.7.11/PCbuild/amd64/
$ gendef python27.dll
$ dlltool -D python27.dll -d python27.def -l libpython27.a
$ mkdir /c/Workspace/Python-2.7.11/libs
$ cp *.lib /c/Workspace/Python-2.7.11/libs
$ cp python27.def libpython27.a /c/Workspace/Python-2.7.11/libs

5— Installez « setuptools » :

$ cd ~/Downloads
$ wget https://bootstrap.pypa.io/ez_setup.py
$ python ez_setup.py

6— Éliminez toute mention de –mno-cygwin du script cygwincompiler.py, puisque cette option est désormais obsolète : 

$ perl -pi -e 's/-mno-cygwin//g' /c/Workspace/Python-2.7.11/Lib/distutils/cygwinccompiler.py

Créer votre « build » NumPy

Maintenant que nous avons une chaîne de compilation et un interprèteur Python dignes de ce nom, nous pouvons nous consacrer à notre « build » NumPy. Ouvrez un « shell » Mingw-w64 depuis C:\msys64\mingw64_shell.bat et tronquez votre variable d’environnement PATH pour que les binaires de Mingw-w64 et le nouveau Python soient les seuls à être utilisées : 

$ export PATH=/mingw64/bin:/usr/local/bin:/usr/bin:/bin:/c/Workspace/Python-2.7.11/PCbuild/amd64

Vous devez maintenant extraire et compiler OpenBLAS en utilisant l'option qui assure la compatibilité avec multiples processeurs :

$ mkdir ~/Workspace
$ cd ~/Workspace
$ git clone https://github.com/xianyi/OpenBLAS.git
$ cd OpenBLAS
$ make DYNAMIC_ARCH=1 -j40

Dénichez l’archive .tar de Numpy 1.9.2. depuis SourceForge et décompressez le tout dans votre espace de travail Mingw-w64. Appliquez l’excellente mise à jour pour Mingw-w64 de Carl Kleffner :

 

$ cd ~/Workspace
$ tar -xzf ~/Downloads/numpy-1.9.2.tar.gz
$ patch -p0 < ~/Downloads/numpy-1.9.2.patch
$ cd numpy-1.9.2/
$ vim site.cfg

Ajoutez les lignes suivantes au fichier site.cfg que vous venez d’ouvrir dans VIM : 

[openblas]
libraries = openblas
library_dirs = C:/msys64/home/jgamache/Workspace/OpenBLAS
include_dirs = C:/msys64/home/jgamache/Workspace/OpenBLAS

Ajoutez ce code dès le début de numpy-1.9.2/numpy/__init__.py, à la suite de la ligne «from __future__ import ... » :

# Numpy-Mingw-w64: prepend the path of the Mingw DLLs to os.environ['PATH']
def _add2path():
	import os
	if os.name != 'nt':
		return
	try:
		path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'core')
		if path not in os.environ.get('PATH', ''):
			os.environ['PATH'] = os.pathsep.join((path, os.environ.get('PATH', '')))
	except Exception:
		pass

_add2path()
del _add2path

Vous pouvez maintenant démarrer la compilation de NumPy : 

$ python setup.py build
$ python setup.py bdist
$ cd dist/
$ unzip numpy-1.9.2.win-amd64.zip  # Use pacman -S unzip if not found
$ cp /mingw64/bin/libgfortran-3.dll Workspace/Python-2.7.11/Lib/site-packages/numpy/core/
$ cp /mingw64/bin/libquadmath-0.dll Workspace/Python-2.7.11/Lib/site-packages/numpy/core/
$ cp /mingw64/bin/libgcc_s_seh-1.dll Workspace/Python-2.7.11/Lib/site-packages/numpy/core/
$ cp /mingw64/bin/libwinpthread-1.dll Workspace/Python-2.7.11/Lib/site-packages/numpy/core/
$ cp ~/Workspace/OpenBLAS/libopenblas.dll Workspace/Python-2.7.11/Lib/site-packages/numpy/core/
# Fix the Path. Using Python since we target Maya2016
$ mkdir Python
$ mv Workspace/Python-2.7.11/* Python
$ zip -r9 numpy-1.9.2.win-amd64-Maya2016.zip Python/

L’heure du test :

$ cd ~
$ wget https://raw.github.com/pypa/pip/master/contrib/get-pip.py
$ python get-pip.py
$ python -m pip install -U pip
$ python -m pip install nose
$ python -i
Python 2.7.11 (default, Dec 17 2015, 11:38:06) [MSC v.1700 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path.append("C:\\msys64\\home\\jgamache\\Workspace\\numpy-1.9.2\\dist\\Python\\Lib\\site-packages")
>>> import numpy
>>> numpy.test()
Running unit tests for numpy
NumPy version 1.9.2
NumPy is installed in C:\msys64\home\jgamache\Workspace\numpy-1.9.2\dist\Python\Lib\site-packages\numpy
Python version 2.7.11 (default, Dec 17 2015, 11:38:06) [MSC v.1700 64 bit (AMD64)]
nose version 1.3.7
...
----------------------------------------------------------------------
Ran 5199 tests in 21.908s

OK (KNOWNFAIL=10, SKIP=20)


  

Vous avez maintenant un NumPy pourvu d’une puissante bibliothèque BLAS, prêt à être utilisé dans Maya 2016. Amusez-vous !