IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Compilation avec bibliothèques externes


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Par défaut Compilation avec bibliothèques externes
    Bonjour,
    (tout d'abord je ne suis pas certain que ce soit le meilleur forum pour poster, donc merci à un modérateur de déplacer mon message si nécessaire).

    j'ai voulu faire un simple test pour savoir si deux librairies étaient accessibles, en l'occurrence cuda et cudnn.
    J'ai donc utilisé ce petit code :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <cuda.h>
    #include <cudnn.h>
     
    int main(void)
    	{
    	printf("CouCou\n") ;
    	return 0 ;
    	}
    malheureusement ce petit code n'a pas compilé car cuda.h et cudnn.h étaient introuvable.
    J'ai donc dû rajouter "-L/usr/local/cuda/lib/ -I/usr/local/cuda/include/" afin que la compilation puisse se faire.
    Mais ce que je ne comprends pas, c'est que dans mon fichier .profile, j'ai ajouté les liens. Bon... ok... en désespoir de cause je les ai un peu tous ajouter en vrac avec toutes les balises car ça ne compilait pas :
    export LD_LIBRARY_PATH=/usr/local/cuda/lib:$LD_LIBRARY_PATH
    export DYLD_LIBRARY_PATH=/usr/local/cuda/lib:$DYLD_LIBRARY_PATH
    export PATH=/usr/local/cuda/include:$PATH
    export CPATH=/usr/local/cuda/include:$CPATH
    export C_INCLUDE_PATH=/usr/local/cuda/include:$C_INCLUDE_PATH
    Qu'est ce qu'il manque à mon ficher .profile afin que tout puisse compiler normalement sans avoir à ajouter les liens ?
    Merci par avance !
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 485
    Par défaut
    Hello,

    Sur quelle plateforme et avec quel compilateur compiles-tu ?

    « PATH » tout court n'est pas une variable du compilateur, mais est utilisée par le système pour trouver les exécutables en général. Donc, vers les répertoires « */bin » et « */sbin » en tous genres. Elle n'est donc pas censée référencer un répertoire contenant des bibliothèques. Les autres, pour GCC en tous cas, sont ici : https://gcc.gnu.org/onlinedocs/cpp/E...Variables.html

    Mais en principe, au moins avec les distributions Linux, l'usage est de passer les flags à la ligne de commande du compilateur. Plus précisément, soit les bibliothèques se trouvent dans des répertoires standard et il n'y a rien à faire de ce côté, soit elles sont logées dans des répertoires propres et dans ce cas, il faut les spécifier au compilateur.

    Par ailleurs, ton programme n'est pas suffisant pour tester la disponibilité de la bibliothèque concernée. Certes, elle inclut les bons headers, mais ton programme ne fait aucun appel à cette bibliothèque, ni ne fait référence à une quelconque ressource externe. Donc, si tu compiles ton programme, la procédure ira jusqu'à son terme avec succès même si tu ne spécifies pas la bibliothèque à laquelle il est censé être lié. Pour rappel, « -I » indique un répertoire contenant des fichiers à inclure, « -L » indique un répertoire contenant des bibliothèques, et « -l » (L minuscule) spécifie les bibliothèques à lier au programme, sans leur suffixe lib ni leurs extensions. Par exemple, un programme incluant « #include <math.h> » et faisant appel à des fonctions mathématiques doit être liée à la bibliothèque mathématique libm.so à l'aide de l'option « -lm ».

    Et ça, on est malheureusement obligé de s'y astreindre car s'il est possible de spécifier une fois pour toutes tous les répertoires contenant des bibliothèques, il faut bien préciser celles que l'on veut utiliser, d'abord parce qu'il est bien sûr hors de question de lier la totalité les bibliothèques au moindre programme que l'on écrit, mais également parce qu'il existe des bibliothèques concurrentes. Soit parce qu'il s'agit de deux implémentations différentes (OpenClient et FreeTDS, par exemple), soit parce qu'il s'agit de deux versions différentes de la même implémentation, soit encore parce que la bibliothèque sert d'interface et la version à installer dépend du matériel en place (cas d'OpenGL).

    Ensuite, toutes ces bibliothèques sont présentées « à plat » sur un seul niveau, mais s'appuie souvent les unes sur les autres dès lors qu'elles commencent à être un peu sophistiquées. Le compilateur lui-même n'en a aucune notion en lui-même, mais cela oblige le programmeur à passer tous les « -l » nécessaires quand il veut utiliser l'une d'entre elles.

    Tout cela pour dire qu'on utilise généralement un gestionnaire dédié pour conserver la trace de toutes ces dépendances et que c'est lui qu'on invoque le moment venu. Bien sûr, cela nécessite que le mainteneur de la bibliothèque propose une entrée dans ce gestionnaire, et que le package associé soit capable de la mettre en place. Mais concrètement, sous Linux, on utilise généralement pkg-config pour cela. Un « pkg-config --help » donne la liste des informations que l'on peut lui demander. « --list-all » donne la liste des packages connus :

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ pkg-config --list-all
    sqlite3                     SQLite - SQL database engine
    xcb-damage                  XCB Damage - XCB Damage Extension
    xcb-xevie                   XCB Xevie - XCB Xevie Extension
    pixman-1                    Pixman - The pixman library (version 1)
    gmodule-export-2.0          GModule - Dynamic module loader for GLib
    cairo-svg                   cairo-svg - SVG surface backend for cairo graphics library
    gtk+                        GTK+ - GIMP Tool Kit
    gtk+-unix-print-3.0         GTK+ - GTK+ Unix print support
    gtk+-wayland-3.0            GTK+ - GTK+ Graphical UI Library
    gtk+-2.0                    GTK+ - GTK+ Graphical UI Library (x11 target)
    gtk+-3.0                    GTK+ - GTK+ Graphical UI Library
    …

    Ensuite, pkg-config --cflags donne la liste des options à passer au compilateur (en plus des autres) :

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ pkg-config --cflags gtk+-3.0
    -pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/freetype2 -I/usr/include/libdrm -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include

    On voit ici, par exemple, que non seulement GTK+ 3 s'éparpille un peu partout, mais nécessite l'utilisation des Posix Threads, qui désormais font l'objet d'un flag dédié, avec « -pthread ».

    Et pour obtenir la liste des bibliothèques à lier :

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ pkg-config --libs gtk+-3.0
    -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0

    La meilleure pratique, au final, consiste à utiliser un Makefile qui ressemblerait à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CFLAGS= -pedantic -std=c99 -W -Wall -Werror -O3 -g
    CFLAGS+= `pkg-config --cflags --libs ta_bibliothèque`
    
    .PHONY: all
    
    all:
             $(CC) $(CFLAGS) -o programme programme.c
    … puis à compiler le tout avec make.

  3. #3
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Par défaut
    Merci pour ta réponse.
    En fait je suis sur MacOS X.
    Voici l'histoire complète. Je souhaite utiliser Theano, mais j'ai des soucis à l'exécution, vraisemblablement parce que cuda et cudnn ne sont pas bien liés. J'ai donc créé ce petit code pour savoir si les librairies étaient au moins trouvées. Ce n'est visiblement pas le cas, du moins au niveau global, je dois spécifier les chemins dans la ligne de commande, ce que je ne peux faire avec Theano, d'où mon besoin d'avoir un .profile comme il faut.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 485
    Par défaut
    Re-bonsoir,

    Citation Envoyé par ToTo13 Voir le message
    Merci pour ta réponse.
    En fait je suis sur MacOS X.
    Voici l'histoire complète. Je souhaite utiliser Theano,
    Je ne connais Theano que de nom, mais n'est-ce pas une bibliothèque Python plutôt que C ?

    mais j'ai des soucis à l'exécution, vraisemblablement parce que cuda et cudnn ne sont pas bien liés.
    En fait, non. Si les bibliothèques en question n'avaient pas pu être liées, ton programme n'aurait même pas compilé. Et si c'était les bibliothèques dynamiques qui étaient introuvables à l'exécution, normalement ton programme ne devrait pas se lancer du tout. Le seul cas où tu pourrais avoir une exécution partielle est si ton programme est conçu pour ouvrir lui-même les bibliothèques concernées au cours de son exécution, avec dlopen(). Dans ce cas, il faut effectivement avoir une variable LD_LIBRARY_PATH correctement initialisée et, sous Linux en particulier, éventuellement un fichier ld.so.conf dûment rempli.

    Si tu as toujours des problèmes à l'exécution, il faudra nous préciser lesquels, et nous donner les éventuels messages d'erreur.

    J'ai donc créé ce petit code pour savoir si les librairies étaient au moins trouvées. Ce n'est visiblement pas le cas, du moins au niveau global, je dois spécifier les chemins dans la ligne de commande, ce que je ne peux faire avec Theano, d'où mon besoin d'avoir un .profile comme il faut.
    Attention : les fichiers *.h inclus avec #include et situés dans les répertoires repérés par « -I », ce ne sont pas les bibliothèques elles-mêmes, mais les spécifications nécessaires au compilateur pour savoir les utiliser (et donc compiler des programmes sans les avoir sous la main, puisqu'elle seront liées a posteriori, au lancement du programme). Une fois le programme compilé, ils ne servent plus. Cela n'a rien à voir avec le fonctionnement des « import » que l'on trouve dans d'autres langages comme le Java, le PHP, le Python ou « use » en Perl.

    Pour le reste, à la compilation et comme dit plus haut, tu peux ajouter des répertoires dans tes variables pour éviter d'ajouter des « -I » et des « -L » mais tu seras toujours obligé de spécifier les bonnes bibliothèques avec « -l », chose que tu ne précises pas dans ton exemple, et qui ici n'aurait servi à rien parce que ton programme de test n'utilise pas les fonctions des bibliothèques concernées.

Discussions similaires

  1. Compilation avec bibliothèque statique
    Par Blangel dans le forum Boost
    Réponses: 3
    Dernier message: 09/10/2015, 10h58
  2. Problème de compilation avec bibliothèque personelle
    Par yetimothee dans le forum Bibliothèques
    Réponses: 1
    Dernier message: 10/08/2010, 04h01
  3. Réponses: 2
    Dernier message: 27/10/2007, 10h16
  4. Problème de compilation avec gcc et bibliothèques
    Par Fonzy007 dans le forum Linux
    Réponses: 1
    Dernier message: 13/02/2007, 12h14
  5. Compilation avec librairie externe
    Par sniper91 dans le forum NetBeans
    Réponses: 5
    Dernier message: 02/08/2006, 11h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo