Partage
  • Partager sur Facebook
  • Partager sur Twitter

Création de lib avec cython

Un tout petit problème de PyInit

Sujet résolu
    22 juillet 2013 à 17:11:30

    Bonjours,

    alors voila, j'étais à la recherche d'une application pour tenter d'optimiser mon code, et aussi de pouvoir en faire un executable (de Linux vers Window) J'ai donc transformé tout mes .py en .c à l'aide de la commande suivante : cython *.py

    Une fois fait, j'ai réalisé un petit CMakeLists.txt de la manière suivante :

    cmake_minimum_required(VERSION 2.6)
    project(PYGUIML)
    set(LIBRARY_OUTPUT_PATH lib)
    set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
    include_directories(${python_include_dir} include)
    link_directories(${python_link_dir})
    set(CMAKE_BUILD_TYPE "Release")
    add_definitions(-DSFML_DYNAMIC)
    
    file(
    	GLOB_RECURSE
    	sources_files
    	*.c
    	)
    
    add_library(
    	PYGUIML
    	SHARED
    	${sources_files}
    	)
    
    add_library(
    	PYGUIMLStatic
       	STATIC
    	${sources_files}
    	)
    
    #target link for the .so
    target_link_libraries(
    	PYGUIML
    	${libpython}
    	)
    
    #target link for the .a
    target_link_libraries(
    	PYGUIMLStatic
    	${libpython}
    	)
    
    set_target_properties(PYGUIMLStatic PROPERTIES OUTPUT_NAME PYGUIML)
    set(python_include_dir "/usr/include/python3.3m/" CACHE PATH "Où se situe le Dossier Python")
    set(python_link_dir "/usr/lib" CACHE PATH "Où se situe la lib python3.3")
    set(libpython "python3.3m" CACHE STRING "le nom de la lib python3 utilisé")
    

     Ceci fait, je compile d'abord pour Linux en faisant ceci : cmake . -G "Unix Makefiles" puis lance la commande make. Ma lib ainsi créé, je fais en python "import PYGUIML" et la j'ai le message d'erreur suivant :

    ImportError: dynamic module does not define init function (PyInit_PYGUIML)

    Comme ma lib est composé d'une douzaine de fichiers, d'où pourquoi je passe pas cmake. Une idée de comment créé cette fonction init ? (et surtout où je dois la placer ?). Merci d'avance :) .

    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      22 juillet 2013 à 17:42:56

      Imaginons que tu n'es qu'un seul fichier python à compiler (monfichier.py), voilà comment je ferais

      cython --embed monfichier.py -o monfichier.c


      Là j'ai ensuite un fichier de type .c nommé monfichier.c

      gcc monfichier.c -o monfichier $(pkg-config python-3.2mu --cflags) -lpython3.2

      La ligne dessus peut changer, erreur si tu n'as pas le logiciel pkg-config, dans ce cas tu mets I/usr/include/python2.7 enfin là où se trouve tes en-têtes pour python


      Après tu peux l'exécuter si tout se passe bien

      ./monfichier

      Testes déjà sur un seul fichier...

      -
      Edité par Anonyme 22 juillet 2013 à 17:43:45

      • Partager sur Facebook
      • Partager sur Twitter
        22 juillet 2013 à 17:50:40

        Avec ce que tu me donnes, ça ne compile pas (problème avec pkg-config). J'ai donc fait une compilation assez basique :

        g++ programme.c -o programme -I /usr/include/python3.3m -lpython3.3m


         et sa compile parfaitement.

        Par contre, pourquoi je suis obligé de mettre --embed pour que sa compile ? (sans, j'ai une erreur comme quoi il n'y a pas de fonction main ! )

        -
        Edité par FirstZero 22 juillet 2013 à 17:53:10

        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          22 juillet 2013 à 18:20:24

          Parce-que --embed est l'option permettant de créer un exécutable

          Voici un exemple avec un makefile

          • Partager sur Facebook
          • Partager sur Twitter
            22 juillet 2013 à 18:23:02

            Ceci créé un executable, alors que je souhaite une lib (dépourvue donc de fonction main). Merci d'avance :) .
            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              22 juillet 2013 à 18:25:39

              Ah ok, j'avais pas compris, voilà

              gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python3.3m -o monfichier.so monfichier.c

              :p

              • Partager sur Facebook
              • Partager sur Twitter
                22 juillet 2013 à 18:41:41

                Ceci fonctionne pour un fichier, mais c'est tout un "package" que je veux transformer en .so (j'avais déjà trouvé la commande avant :) ). J'essaye avec un setup.py, mais c'est assez compliqué je trouve.
                • Partager sur Facebook
                • Partager sur Twitter
                Anonyme
                  22 juillet 2013 à 18:42:55

                  Tu as regardé mon lien avec un exemple de makefile?
                  • Partager sur Facebook
                  • Partager sur Twitter
                    22 juillet 2013 à 18:46:27

                    Oui j'ai regardé, il ne compile qu'un seul fichier : embedded.pyx

                    Bon voici le __init__.py que j'ai :

                    from Updatable import *
                    from Widget import *
                    from Render import *
                    from Window import *
                    from EventManager import *
                    from Widget import *
                    from Image import *
                    from Label import *
                    from CheckBox import *
                    from CheckCircle import *
                    from Layout import *
                    from Active import *
                    from Frame import *
                    from SelectionMenu import *
                    from TextArray import *
                    from Slide import *
                    from ProgressBar import *
                    from RadioButton import *
                    
                    import decorator
                    import functions

                    Ce que j'aimerai faire c'est créé un package "pyguiml" à l'aide de cython qui utilise les imports écrits ci dessus

                    -
                    Edité par FirstZero 22 juillet 2013 à 19:07:33

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Anonyme
                      22 juillet 2013 à 19:07:11

                      Avec distutils?

                      from distutils.core import setup
                      from distutils.extension import Extension
                      from Cython.Distutils import build_ext
                      
                      setup(
                          cmdclass = {'build_ext': build_ext},
                          ext_modules = [Extension("helloworld", ["helloworld.pyx"])]
                      )
                      

                      http://docs.cython.org/src/userguide/tutorial.html

                      Ci-dessus, tu as la liste des fichiers à ajouter dans ton projet.

                      • Partager sur Facebook
                      • Partager sur Twitter
                        22 juillet 2013 à 19:10:10

                        Je suis justement entrain de voir si avec distutils je peux essayé de faire un package qui import tout dans tout les fichiers présent dans __init__.py
                        • Partager sur Facebook
                        • Partager sur Twitter
                          22 juillet 2013 à 19:25:41

                          Voici d'ailleurs le setup.py que j'utilise :

                          from distutils.core import setup
                          from distutils.extension import Extension
                          from Cython.Distutils import build_ext
                          
                          ext_modules = [Extension("pyguiml", sources=["pyguiml/__cinit__.c", "pyguiml/Updatable.c", \
                          		"pyguiml/Widget.c", "pyguiml/Window.c", "pyguiml/EventManager.c", \
                          		"pyguiml/Render.c"])]
                          
                          setup(
                          	name="pyguiml",
                          	cmdclass = {'build_ext': build_ext},
                          	ext_modules=ext_modules
                          )


                          Mais j'ai ceci comme erreur : ImportError: dynamic module does not define init function (PyInit_pyguiml) ....

                          -
                          Edité par FirstZero 22 juillet 2013 à 19:31:47

                          • Partager sur Facebook
                          • Partager sur Twitter
                            22 juillet 2013 à 20:20:40

                            EN réalité j'ai trouvé : je ne savais pas qu'il fallait placé le __init__.py avec les différents .so créé par cython et distutils x) . Merci beaucoup :)
                            • Partager sur Facebook
                            • Partager sur Twitter

                            Création de lib avec cython

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown