Affichage des articles dont le libellé est c++. Afficher tous les articles
Affichage des articles dont le libellé est c++. Afficher tous les articles

lundi, juin 24, 2013

CMake : Compiling for different hardware architectures


  • GCC (on Linux) or Sun Studio
Use compile option -m32 (force 32-bit build), -m64 (force 64-bit build)
  • Windows, Visual Studio generator
Use cmake -G "Visual Studio 9 2008 Win64" path_to_source_dir to compile 64-bit (x64)
  • Mac OS X
Use CMAKE_OSX_ARCHITECTURES CMake variable. You can set more than a single architecture to create universal binary, e.g
 cmake "-DCMAKE_OSX_ARCHITECTURES=i386;pcc" path_to_source 
will build universal binary with 32-bit intel / 32-bit powerpc.
cmake "-DCMAKE_OSX_ARCHITECTURES=x86_64" path_to_source 
will create x86_64 binary.

  • NMake Makefiles
    for 64 bits use the right SetEnv ou vsvarsall.bat command line and then
    cmake path to source -G "NMake Makefiles"
    nmake

mercredi, décembre 17, 2003

Etendre le langage Python


Introduction

Il s'agit là d'étendre le langage en lui rattachant de nouveaux types de données, de nouvelles fonctionnalités, de nouveaux modules.

Pour celà, deux facons:

    Il suffit de créer un module en langage python et de placer les fichiers .py dans le repertoire /lib de python.
    Dans certains cas, cette méthode peut être limitée.

    Il s'agit cette fois d'écrire des fonctionnalités, des nouveaux types de données ... en C ou C++. Dans ce cas là, on passe par la librairie python, qui représente le coeur du langage.


C'est la deuxième méthode qui est détaillée ici.

En employant le C/C++ pour intégrer de nouvelles fonctionnalités à python, on va développer des modules statiques ou dynamiques

L'écriture de ces modules se base sur la librairie python livrée avec le langage. On utilise alors des fonctions, macros et constantes définies dans cette librairie.
(Lot d'éléments commencant par py, API Doc à http://www.python.org/doc/current/api/api.html)

Module dynamique :
Il faut ici compiler le nouveau module sous forme de shared object (.so) pour Unix ou de DLL pour Windows.

Je ne traite ici que de la compilation de module dynamique pour windows.
Il s'agit de créer des fichiers .pyd, sorte d'équivalent aux DLLs.
L'exemple suivant se base sur un environnement MinGW (GNU Win32) et python2.2.1 pour windows.
(Se reporter à la configuration d'une plateforme GNU Win32,
si vous désirez compiler des .pyd en environnement de developpement Visual Studio 6, et non GNU Win32, se reporter a la documentation livrée avec python)

A.La librairie python

Pour tout développement sur un environnement MinGW (gnu win32) il faut d'abord effectuer un travail préliminaire sur la librairie python. Elle contient le code compilé de l'interpréteur. Cette librairie a été écrite en C. Sur un syteme windows, elle se présente sous la forme de 3 fichiers
* system\python22.dll (librairie dynamique systeme)
* c:\python22\include\python.h (include à utiliser dans les modules)
* c:\python22\libs\python.lib (librairie statique)
Elle est directement exploitable avec Visual Studio, mais pour MinGW il nous faut obtenir les équivalents de ces fichiers.

1.Localiser le fichier python22.dll sur le syteme windows (en général dans \system32\)
2.Copier la dll dans un répertoire c:\lib
3.Lancer un mode console (ne pas oublier davoir régler le path pour la plateforme GNU)
4.Se placer dans le repertoire c:\lib
5.Utiliser pexports pour créer le fichier .def






Code:
pexports python22.dll >python22.def

6.Utiliser dlltool pour créer le fichier .a






Code:
dlltool --dllname python22.dll --def python22.def --output-lib libpython22.a




B.Réalisation d'un module

1.Création du fichier source
Le fichier source C/C++ doit contenir les différents éléments du module. Il doit se baser sur les fonctions, macros et constantes de python définis dans python.h (tout ce qui commence par Py).


Donc premier cas : Utiliser les fonctions C/C++ de la librairie python (de python.h). Et écrire entièrement le module. Ca sera le cas de l'exemple plus bas.

On peut ici utiliser un scrypt python qui, une fois paramétrer, va nous créer un fichier.c contenant toutes les déclarations nécessaires en exploitant les éléménts Py. Il génère en fin de compte un squelette vide, dans lequel il ne reste plus qu'a déposer le code C/C++.
Il s'agit de modulator.py et se trouve dans l'arborescence CVS des sources pythons à python\dist\src\Tools\modulator.

Deuxième cas : Compiler sous forme de module du code C/C++ déja existant. Il faut ici créer un wrapper du code existant. En général on utilise des outils se chargeant de ce travail.


Comme SWIG (http://www.swig.org). Il génère un fichier intermédiaire en analysant le code source C/C++ existant et y crée des fonctions qui vont faire appel à ce meme code source. SWIG est un générateur de wrapper. (Il supporte d'autres langagaes que python, comme perl ou ruby)


On peut aussi employer la librairie Boost.python, ( http://www.boost.org ) qui est une librairie C++ comprenant des classes et méthodes pour écrire à la main un wrapper.



Exemple 1er cas : Fichier C, représentant le module "myexemple" contenant une fonction "systeme" :







Code:

#include <Python.h>
static PyObject * myexemple_system(PyObject *self, PyObject *args)
{
    char *command;
    int sts;

    if (!PyArg_ParseTuple(args, "s", &command))
        return NULL;
    sts = system(command);
    return Py_BuildValue("i", sts);
}

static PyMethodDef SpamMethods[] = {
     {"system",  myexemple_system, METH_VARARGS,
     "Execute une commande shell."},
     {NULL, NULL, 0, NULL}        /* Sentinel */
};

void initmyexemple(void)
{
    (void) Py_InitModule("myexemple", SpamMethods);
}


2.Compilation de myexemple.c






Code:
gcc -g -Wall -I c:\python22\include -fpic -c myexemple.c

Un fichier myexemple.o est alors généré. Pour chaque include que le fichier source utilise en plus de python.h, rajouter






Code:
-I rep_include


3.Compilation en module dynamique
En deux étapes:

* Génération d'un fichier .def
Tout d'abord créer dans le meme repertoire que myexemple.o, un fichier myexemple.def contenant :






Code:
EXPORTS
   initmyexemple


* Compilation du fichier .pyd






Code:
dllwrap --dllname myexemple.pyd --driver-name gcc --def myexemple.def -o myexemple.pyd myexemple.o -s --entry _DllMain@12 --target=i386-mingw32 -Lc:\lib -lpython22

Un fichier myexemple.pyd est alors généré. Pour chaque librairie utilisée en plus de celle de python, placer son chemin dans l'argument -L et le nom de la librairie avec -l.
Par exemple, pour c:\dev\lib\libmonfichier.a :






Code:
-Lc:\dev\lib -lmonfichier


4.Déploiement
Il suffit de copier le fichier myexemple.pyd dans c:\python22\DLLs. Pour le tester en mode console, essayer :






Code:
import myexemple



Module statique :

Il faut recompiler l'interpréteur lui-même en meme temps que le nouveau module. On utilise cette façon de procéder quand on veut intégrer définitivement le module à python. Ou encore sur un systeme d'exploitation ne supportant pas le chargement dynamique.
Il faut alors placer le fichier .C contenant le code source du module dans Modules/ directory et modifier le fichier de configuration Modules/Setup.local en ajoutant la ligne






Code:
nom_module nom_fichier.o

.
(pour chaque librairie utilisée, ajouter à la ligne -lmalib)
Il reste à relancer la compilation de l'interpréteur par un make




Ressources Webs :
Instructions for Python Extensions with GCC/mingw32


 

Intégration de code c inline dans un code python

 


Introduction


Il est possible avec certains modules comme PyInline ou Weave d'intégrer du code d'autres langages à l'intérieur même du code python.

Il est en fait compilé en direct à l'intérieur du code python. Il faut évidement avoir présent sur la machine un compilateur du langage concerné. (Pour le C, en environnement Windows, VC++6.0 fonctionne tel quel).

Analyse de performance de code "inline":
http://www.scipy.org/site_content/weave/python_performance.html


Test simple avec InLine

Environnement:
-Microsoft Visual C++ 6.0 installé
-Python 2.3 installé

Installation:
-dl package PyInline 0.03 sur http://sourceforge.net/project/showfiles.php?group_id=34103&release_id=50179
-lancer python setup.py install

Test:
-dans l'interpréteur python:






>>> import PyInline
>>> m= PyInline.build(code="""
        ... int my_add(int a,intb) {
        ...    return a+b;
        ... }
        ... """,language="C")
running build
running build_ext
building '_PyInline_de9a14d2a39aa28e67cab7f2a2a9727d' extension
creating build
creating build\temp.win32-2.3
creating build\temp.win32-2.3\Release
C:\Program Files\Microsoft Visual Studio\VC98\BIN\cl.exe /c /nologo /Ox /MD /W3
/GX /DNDEBUG -IC:\Python23\include -IC:\Python23\PC /Tc_PyInline_de9a14d2a39aa28
e67cab7f2a2a9727d.c /Fobuild\temp.win32-2.3\Release\_PyInline_de9a14d2a39aa28e67
cab7f2a2a9727d.obj
_PyInline_de9a14d2a39aa28e67cab7f2a2a9727d.c
creating build\lib.win32-2.3
C:\Program Files\Microsoft Visual Studio\VC98\BIN\link.exe /DLL /nologo /INCREME
NTAL:NO /LIBPATH:C:\Python23\libs /LIBPATH:C:\Python23\PCBuild /EXPORT:init_PyIn
line_de9a14d2a39aa28e67cab7f2a2a9727d build\temp.win32-2.3\Release\_PyInline_de9
a14d2a39aa28e67cab7f2a2a9727d.obj /OUT:build\lib.win32-2.3\_PyInline_de9a14d2a39
aa28e67cab7f2a2a9727d.pyd /IMPLIB:build\temp.win32-2.3\Release\_PyInline_de9a14d
2a39aa28e67cab7f2a2a9727d.lib
   Creating library build\temp.win32-2.3\Release\_PyInline_de9a14d2a39aa28e67cab
7f2a2a9727d.lib and object build\temp.win32-2.3\Release\_PyInline_de9a14d2a39aa2
8e67cab7f2a2a9727d.exp
>>> m.my_add(3,8)
11