Forum Programmation.c++ Savoir où chercher les données utilisées après un make install

Posté par  (site web personnel) .
Étiquettes : aucune
1
3
sept.
2011

Bonjour!

Je viens vous demander conseil pour un problème récurrent que j'ai eu avec tous les jeux que j'ai développé et que je compile à l'aide de cmake.
Comment faire pour qu'après compilation, le jeu cherche les données dans le dossier courant, mais qu'après installation, il aille chercher dans le dossier d'installation? (typiquement /usr/share/nomdujeu)

Je m'explique:
Il me semble que la commande "make install" ne donne lieu à aucune compilation, donc on ne peut changer un define ou une variable du code lors du make install.
La solution que j'ai souvent utiliser et qui consiste à indiquer au jeu une liste de chemins dans lesquels chercher a de gros défauts : si le jeu est installé sur le PC et que le gars teste la version git, soit les deux utiliseront les données installées, soit les deux utiliseront les données du git, selon l'ordre de recherche. (dossier courant puis installation ou l'inverse)

Comment faire pour avoir un jeu qui sait où sont ses données? Qui peut s’exécuter après le make, et qui après le make install va chercher ses données là où il faut?

  • # fichier de configuration ?

    Posté par  . Évalué à 2.

    tu ne fais pas un fichier .monjeurc ou un /etc/monjeu ?

    qui definirait ou tu trouves les datas ?

    make install fait ce que tu lui demandes,
    si tu lui demandes de modifier un fichier il le fera, si tu lui demande de copier un dossier dans un autre, il le fera aussi..

    • [^] # Re: fichier de configuration ?

      Posté par  (site web personnel) . Évalué à 1.

      J'avais aussi pensé à ça, le problème reste le même, le mec lance la version git, elle va aller voir ce fichier .monjeurc et elle va aller chercher les données au mauvais endroit.

      J'utilise CMake, j'arrive à lui faire copier des fichiers, dossiers et binaires lors du make install, mais je crois pas qu'on puisse lui dire de recompiler avec une option différente lors du make install. En tous cas si ça existe je veux bien la syntaxe ^^

      • [^] # Re: fichier de configuration ?

        Posté par  (site web personnel) . Évalué à 5. Dernière modification le 04 septembre 2011 à 13:48.

        Il y a pas mal de solutions toutes aussi pourries les unes que les autres...

        • Commencer par scanner le pwd puis /usr/shar/bipbip et donc la version git doit être lancer dans le répertoire avec ses donnée et l'autre n'importe ou ailleurs
        • Fournir des options DESTDIR ou PREFIX au moment du make et les utiliser pour régler des #define (classique)
        • Utiliser un paramètre en ligne de commande pour annuler la recherche par défaut.
        • Utiliser autoconf et le parametre --datadir (sûrement la pire solution...)

        Ça reste un gros problème qu'à ma connaissance personne n'a résolu correctement, que ce soit sous Linux, BSD, MacOS ou Windows. Les différentes solutions ont toujours des problèmes plus ou moins graves.
        Au final, je pense que la meilleure solution reste :

        • Si l'utilisateur donne un chemin en ligne de commande, l'utiliser ;
        • Sinon, (si le logiciel est en dev actif) chercher dans le répertoire courant ;
        • Sinon, utiliser une liste de quelques répertoires courants.

        Dans la liste tu mets en premier un chemin spécifiable au moment de la compilation (soit par ./configure soit au moment du make).

        • [^] # Re: fichier de configuration ?

          Posté par  . Évalué à 0.

          As-tu lu cette partie de la FAQ de Cmake : Lien ?
          Ça répond (en partie) a ton problème :)

        • [^] # Re: fichier de configuration ?

          Posté par  (site web personnel) . Évalué à 2.

          Merci, j'ai fait (plus ou moins) comme ça du coup.

          C'est frustrant de pas avoir de solution propre.

        • [^] # Re: fichier de configuration ?

          Posté par  (site web personnel) . Évalué à 2.

          Et scanner le path pour trouver son binaire de lancement pour ensuite aller chercher le fichier en fonction de son lieu d'installation ?

          En fait ce qu'il manque à un programme unix, c'est d'avoir son path complet de lancement pour ensuite s'en servir comme point de référence.

          "La première sécurité est la liberté"

          • [^] # Re: fichier de configuration ?

            Posté par  . Évalué à 1.

            ce qu'il manque à un programme unix, c'est d'avoir son path complet de lancement

            En Bash: $0
            En C: argv[0]
            Ruby: $0
            Etc etc.

            • [^] # Re: fichier de configuration ?

              Posté par  . Évalué à 0.

              Cette méthode n'est pas fiable. Alors oui, on peut commencer par tester si $0 est absolut où relatif, rechercher le $PATH, résoudre les éventuels liens symboliques parents (../../bin/binary), les races entre le chargement du programme et le test de $0, le fait qu'on passe l'argv (avec argv[0]) en plus du nom du binaires au syscall excve ("The first argument, by convention, should point to the filename associated with the file being executed", pas obligatoire),... Bref c'est pas top.

              La meilleure solution sous linux est de regarder la cible du lien /prod/[mypid]/self.

              Ceci dit, je ne vois pas comment connaître le répertoire du binaire résoud totalement le problème mentionné. J'opterais perso pour un mode de compilation en devel/release, plus une surcharge par variable d'environement (export PROG_DATA=~/devel/data).

            • [^] # Re: fichier de configuration ?

              Posté par  (site web personnel) . Évalué à 2.

              Il s'agit du nom du binaire, ou alors un path relatif et pas le path absolu dont on a besoin.

              "La première sécurité est la liberté"

      • [^] # Re: fichier de configuration ?

        Posté par  . Évalué à 2.

        je ne vois pas en quoi c'est pas propre ?
        c'est deja ce que se fait dans pas mal de situation

        par exemple pour les fichiers de configurations :

        si tu es developpeur :
        1°) tu regardes dans /home/leuser/.monjeurc
        si le fichier n'existe pas
        2°) dans /etc/monjeu/maconfig
        3°) si aucun des deux n'existent, tu utilisel le reglage par defaut.

        si tu es juste utilisateur/installateur, tu as en general des options à passer à make ou à configure (les prefix/datadir et leurs amis).

        tu peux donc tres bien faire un make/make install sans option (qui prend les data dans le dossier courant), un avec option qui va utiliser les prefix pour mettre les data dans un dossier special /opt/monjeu/data...

        • [^] # Re: fichier de configuration ?

          Posté par  (site web personnel) . Évalué à 3.

          Le soucis n'est pas, pour un seul programme, de savoir ou aller chercher les données. Ça on sait très bien le faire et de manière à peu près propre.
          Les problèmes commencent quand tu as plusieurs versions du même programme en même temps et que chacune d'elle doit donc utiliser une version différente des données.

          Si toutes les versions du programme suivent la procédure que tu indiques, elles vont toutes utiliser les même données.
          Pour que chacune utilise sa propre version, tu n'as que deux solutions possibles :

          1/ tu indiques, au moment de la compilation qu'elles données doivent être utilisées. Que ce soit en donnant directement le chemin des données ou le chemin de la config spécifique à cette version, ou bien en déduisant le chemin du numéro de version.
          Dans les deux cas tu as le problème que le chemin est codé en dur dans le programme.

          2/ tu fournis un paramètre en ligne de commande, et dans ce cas, il faut ce souvenir à chaque lancement d'une des version, quelle versions des données il faut utiliser.

          Personnellement j'ai tendance à coder les deux, mais ce n'est pas vraiment satisfaisant. Si quelqu'un à une meilleure solution, je suis intéressé aussi.

          • [^] # Re: fichier de configuration ?

            Posté par  . Évalué à 2.

            moi j'ai plus tendance a avoir un .trucrc dans le $HOME ou $HOME/.config/typeApp/app

            Et lorsque je lance le jeux en dev j'ai un $HOME=$PWD/envDev ./application généralement.

            Sinon c'est juste une variable d'environnement qui précise ou sont des datas et si elle n'est pas précisé ça va les chercher dans le répertoire par défaut.

            Il ne faut pas décorner les boeufs avant d'avoir semé le vent

            • [^] # Re: fichier de configuration ?

              Posté par  . Évalué à 2.

              moi j'ai plus tendance a avoir un .trucrc dans le $HOME ou $HOME/.config/typeApp/app

              La bonne pratique recommandée par Freedesktop c'est le .config.

              Pour éviter ça:

              ls -a ~ | grep "^\..*" | wc -l
              165
              
              

              THIS IS JUST A PLACEHOLDER. YOU SHOULD NEVER SEE THIS STRING.

      • [^] # Re: fichier de configuration ?

        Posté par  . Évalué à 0.

        Oï,

        J'utilise CMake, j'arrive à lui faire copier des fichiers, dossiers et binaires lors du make install, mais je crois pas qu'on puisse lui dire de recompiler avec une option différente lors du make install. En tous cas si ça existe je veux bien la syntaxe ^^

        Tu peux fixer tes variables lors de ton appel à make :

        bash$ make FOO=bar
        
        

        Et dans ton makefile, de t'assurer que tu n'utilises plus tes valeurs par :

        # definir FOO s'il n'exsite pas
        ifeq ($(FOO),))
            FOO = foobar
        endif
        
        # Utiliser FOO lors des regles de compilation
        %.o: %.c
            $(CC) $(CFLAGS) -DUSER_FLAG=$(FOO) -c $^ -o $@
        
        mon_truc: barba.o truc.o
            $(CC) $(LDFLAGS) $^ -o $@
        
        

        Dans mon exemple c'est pour la compilation, mais tu dois pouvoir te débrouiller pour faire la même chose pour les copies de fichiers ...

  • # Une autre solution

    Posté par  (site web personnel) . Évalué à 3.

    1) Lors du 'configure', générer un nom de profil: ça peut être un uuid ou le numéro de révision de git et l'écrire dans un fichier source:

    const char* profile = "lenumerogenere";
    
    

    2) Ecrire et lire données dans le dossier:

    ~/.monapplication/profiles/%profile%/...
    
    

    Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

  • # configure ?

    Posté par  (site web personnel) . Évalué à 0.

    Dans le monde autotools, on donne le chemin d'installation lors du configure (genre ../configure -- prefix=$HOME/local) ce qui permet de connaître avant la compilation cette précieuses valeur et de la mettre quelque part.

    Comment cela fonctionne-t-il sous cmake ? c'est un paramètre du makefile ?

  • # La foire au hack

    Posté par  . Évalué à 1.

    Je ne sais pas trop pour les jeux, mais la plupart des programmes qui supportent de fonctionner en mode "pas installé" le font de la façon suivante:

    D'abord tu as une fonction qui te retourne le chemin de base pour les données, qui en temps normal va retourner DATADIR "/monprog" (c'est toujours utile, et ça laisse le code propre)

    Si tu buildes avec une option spécifique (genre --enable-uninstalled-build si je prends le cas de totem), alors la fonction est altérée pour aussi chercher dans . si ce n'est pas installé.

    Alternativement tu peux te baser sur une variable d'environnement ou quelque chose du genre. Peut-être même que quand tu lances le programme sans l'installer il est en fait remplacé par un script shell qui exporte plein de trucs comme avec les autotools.

    Ou alors tu t'en moques, et vu que de toute façon les données ne changent pas si souvent tu ne supportes pas le fait que ton programme soit lancé sans être installé. Si quelqu'un veut builder ton jeu sous windows par exemple, libre à lui de changer ton get_data_path() pour correspondre à ce qui est attendu par son système.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.