Tcl.h no such file or directory

Bonjour,

J'ai un programme à compiler qui a besoin de <tcl.h> mais arrivée à l'étape du make l'erreur suivante s'affiche:
../../server/tcl/communicationTcl.c:39:17: fatal error: tcl.h: No such file or directory


les packages tcl8.5 tk8.5 tcl8.5-dev tk8.5-dev sont installés dans le repertoire par defaut (/usr/include)

Quelqu'un a-t-il une idée sur le roblème?
Merci d'avance!

5 réponses

  1. Modérateur
    Si le programme inclue <tcl.h> il va chercher par exemple /usr/include/tcl.h. Or si on regarde comment c'est empaqueté :

    (mando@aldur) (~) $ apt-file search tcl.h | grep "/usr/include/" | grep "/tcl.h$"
    tcl8.4-dev: /usr/include/tcl8.4/tcl-private/generic/tcl.h
    tcl8.4-dev: /usr/include/tcl8.4/tcl.h
    tcl8.5-dev: /usr/include/tcl8.5/tcl-private/generic/tcl.h
    tcl8.5-dev: /usr/include/tcl8.5/tcl.h
    


    ... on voit que tcl.h est en réalité dans un sous-répertoire de /usr/include.

    Approche 1 :

    Dans l'absolu, une solution qui corrige le problème à ce stade serait donc de corriger le #include par :

    #include <tcl8.5/tcl.h>


    Mais c'est pas top, car déjà quand tu installeras une autre version de tcl ça ne marchera plus. De plus il est probable que dans ton programme tu aies de nombreux #include à corriger. Voyons comment améliorer ça.

    Approche 2 :

    Il est très probable que dans /usr/include un lien symbolique soit créé pour pointer vers la dernière version de tcl (typiquement tu dois avoir un lien symbolique /usr/include/tcl qui pointe sur /usr/include/tcl8.5/. Tu peux le vérifier avec la commande :

    ls -l /usr/include/tcl*


    Si ce n'est pas le cas, on peut créer le lien soi-même, mais c'est pas top non plus car normalement c'est au paquet de le faire. En admettant que ce lien soit présent, on peut indifféremment écrire l'une de ces deux instructions :

    #include <tcl8.5/tcl.h>
    #include <tcl/tcl.h>


    Ça résout le problème de version, mais toujours pas le fait qu'on devra changer tous les #include !

    Approche 3 :

    Corriger les options de compilation. Il suffit dans le Makefile qui sert à compiler ton programme de configurer les options passées à gcc pour qu'il aille chercher des headers dans d'autres répertoires que /usr/include, typiquement /usr/include/tcl8.5, ou encore mieux, /usr/include/tcl si le lien symbolique est présent.

    Généralement les options de compilation passées à gcc sont définies dans une variable CFLAGS. Il suffit de rajouter la bonne option dans cette variable.

    Exemple : pour le moment CFLAGS est ainsi définie :

    CFLAGS = -W -Wall -O2


    ... il suffit de la compléter comme suit :

    CFLAGS = -W -Wall -O2 -I/usr/include/tcl8.5


    ... ou encore si le lien symbolique est défini :

    CFLAGS = -W -Wall -O2 -I/usr/include/tcl


    Bonne chance
    1
    1. Bonjour,

      Désolée pour le retard!! J'avais un problème de connexion!

      J'ai parcouru le fichier configure et voila ce que j'ai trouvé:
      case $host_cpu-$host_os in
            x86_64-linux*)
      	libsuffix=64
      	;;
            *)
      	libsuffix=
      	;;
         esac
      
      
      # Check whether --with-tcl was given.
      if test "${with_tcl+set}" = set; then :
        withval=$with_tcl; tcl_prefix=$withval
      else
        for ac_dir in \
               ${exec_prefix}/lib      	\
               /usr/local/lib/tcl8.4   	\
               /usr/local/lib/tcl8.3   	\
               /usr/local/lib          	\
               /usr/pkg/lib            	\
               /usr/lib${libsuffix} 		\
               /usr/lib${libsuffix}/tcl8.4	\
               /usr/lib${libsuffix}/tcl-8.4	\
               /usr/lib${libsuffix}/tcl8.3	\
              ; \
             do
               if test -r "$ac_dir/tclConfig.sh"; then
                  tcl_prefix=$ac_dir
                  break
               fi
             done
      fi
      


      puisque j'ai un système 64 bits, il cherchait le fichier tclConfig.h dans /usr/lib64 qui n'existe pas
      ls /usr | grep lib
      lib
      lib32


      J'ai copié le fichier en question dans un nouveau repertoire lib64/tcl8.5 et ajouté la ligne /usr/lib${libsuffix}/tcl8.5 dans la liste des répertoires de recherche de tclConfig.h.
      Je ne sais pas comment mais le problème a été réglé (le problème étatit tcl.h not found le j'ai modifié le chemin d'accès à tclConfig.h et non pas tcl.h!!!)

      Est-ce que je peux enlever le fichier tclConfig.h copié dans lib64 et mettre un lien symbolique depuis repertoire lib vers lib64?
      0
      1. Modérateur
        En fait je pense que fondamentalement, il ne faut pas copier ou déplacer de fichier pour résoudre ton problème, car ils sont installés par des paquets (ça veut dire que dès que tu désinstalleras / réinstalleras / mettras à jour ces paquets, tu t'exposes à des problèmes).

        Pour moi, tu dois faire en sorte de configurer ton makefile de sorte à ce qu'il marche avec une installation standard.

        Je pense aussi que tu fais une confusion. Normalement :
        - les headers (fichiers ".h" ou ".hpp") sont rangés dans /usr/include.
        - les librairies (fichiers ".a" ou ".so") sont rangés dans /lib, /usr/lib, /usr/local/lib (et éventuellement leur déclinaison en lib64)

        On peut préciser à gcc où il peut trouver des headers et des librairies en dehors de ces répertoires
        - pour les headers : grâce à l'option -I ou -isystem (qui sont grosso modo équivalentes)
        - pour les librairies : grâce aux option -Wl,R et -L (respectivement pour les ".a" et les ".so" si ma mémoire est bonne)

        Exemple : la commande suivante permet à gcc de trouver des headers qui seraient dans /home/tata/include et des librairies (.so) qui seraient dans /home/tata/lib :

        gcc -W -Wall -I/home/tata/include -L/home/tata/lib truc.c


        Pour moi il paradoxal que ton programme cherche un header (qui se récupère avec un #include) quelque part dans /usr/lib, normalement ce header devrait être dans /usr/include ou dans les sources que tu compiles.

        Par ailleurs, dans ton cas, tu es manifestement sur une architecture 64 bits. Si on regarde ce que tu as reporté, cela signifie que la variable libsuffix sera évaluée à "64" au lieu de la chaîne vide. En d'autres termes, la chaîne /usr/lib${libsuffix}/tcl8.5 est évaluée à /urs/lib64/tcl8.5.

        Bonne chance
        0
        1. bonjour,

          Oui c'est exact libsuffix est évaluée à lib64 mais je ne dispose pas de fichier s'appelant ainsi dans /usr!
          0
          1. Modérateur
            Alors dans ce cas, après cette section :

            if test "${with_tcl+set}" = set; then :  
              withval=$with_tcl; tcl_prefix=$withval  
            else  
              for ac_dir in \  
                     ${exec_prefix}/lib       \  
                     /usr/local/lib/tcl8.4    \  
                     /usr/local/lib/tcl8.3    \  
                     /usr/local/lib           \  
                     /usr/pkg/lib             \  
                     /usr/lib${libsuffix}   \  
                     /usr/lib${libsuffix}/tcl8.4 \  
                     /usr/lib${libsuffix}/tcl-8.4 \  
                     /usr/lib${libsuffix}/tcl8.3 \  
                    ; \  
                   do  
                     if test -r "$ac_dir/tclConfig.sh"; then  
                        tcl_prefix=$ac_dir  
                        break  
                     fi  
                   done  
            fi


            Rajoute la ligne suivante :

            # Fix Debian  
            tcl_prefix=/usr/lib/tcl8.5


            Si ça ne marche toujours pas, rajoute également la ligne

            libsuffix=


            Petite explication, le script tel qu'il est écrit ne parcourt pas le répertoire dans lequel Debian installe tcl, car d'une part Debian ne fait pas apparaître de suffixe "64" et d'autre part, tu utilise la version 8.5 alors que le script est prévu pour les versions 8.3 et 8.4.

            Par ailleurs, je viens de comprendre un truc. En recopiant tu as écrit tclConfig.h au lieu de tclConfig.sh, et donc c'est pour ça que je ne comprenais pas. En effet, il s'agit d'un script shell qui est effectivement dans /usr/lib. Bref, le répertoire dans lequel il est recherché doit effectivement dans ton cas être évalué à /usr/lib.

            En effet si on installe apt-file :

            sudo apt-get update 
            sudo apt-get install apt-file 
            apt-file update


            .. et qu'on lance cette recherche :

            apt-file list tcl8.5-dev | grep tclConfig  


            ... on obtient :

            tcl8.5-dev: /usr/lib/tcl8.5/tclConfig.sh  


            Bonne chance
            0