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 :

Gérer correctement les chemins des fichiers dans un programme (avant et après installation)


Sujet :

C

  1. #1
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut Gérer correctement les chemins des fichiers dans un programme (avant et après installation)
    Bonjour à tous,

    Je me suis toujours demander comment on pouvait gérer idéalement les multiples cas des chemins menant aux ressources d'un programme.

    Plus précisément, habituellement, on écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    loadRessource("./data/myRessource");
    cela fonctionnera, jusqu'au jour où je souhaite installer mon programme sur Linux. Souvent, les programme se retrouvent dans /usr/bin et les ressources dans /usr/share, du coup, avec le code vu précédemment, les ressources ne sont pas trouvé.

    Je ne doute pas que c'est un jeu avec le Makefile, mais je n'arrive pas à concevoir comment on peut faire que cela marche, aussi bien une fois que l'on est fait le make (et que les ressources soient dans les dossiers actuels) et que cela fonctionne aussi après avoir installé (make install).

    Quelle est votre proposition pour faire que cela fonctionne et simplement, si possible, sans changement dans le code (et sans recompilation complète du projet ).

    Merci
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  2. #2
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut


    La meilleure solution pour ce cas est de mettre en place des compilations conditionnelles comme ça tu peux même prendre en charge tout autre OS
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifdef LINUX
    #   define RES_PATH "\usr\share\
    #elif defined (WIN32)
    #   define RES_PATH "./data/myRessource"
    #endif
    Enfin en gros quoi
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  3. #3
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Oui, mais vous n'avez pas de flag pour dire comme quoi le programme est installé ou pas, si vous voulez.
    La solution que nous avions actuellement, c'est de directement passé la base du chemin durant la compilation (-DMON_CHEMIN). Mais bon, si le chemin est défini, ça ne marchera pas si le programme n'est pas installé, ou des trucs dans le genre.
    Je n'ai pas demandé une différence LINUX / WINDOWS, mais une différence entre les ./data et /usr/share .
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Ah mon avis, le plus simple est de mettre les 2 chemins... tu recherches si les fichiers existants dans ./data/myRessource, sinon tu recherches dans \usr\share\, sinon, tu hurles
    Sinon, tu as la possibilité d'utiliser un fichier de configuration avec ./data/myRessource par défaut et changer le chemin lors de l'installation (voir avoir un dialogue permettant à l'utilisateur de modifier les chemins)

  5. #5
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Bonjour,

    Dans le monde linux il est courant de faire appel aux autotools (autoconf, automake, libtool, ...). En très gros ils permettent de créer un script appelé configure. Ce script accepte en options plein de paramètres, entre autre le préfixe d'installation (par exemple /usr ou /usr/local), à partir duquel il peut déduire les chemins pour installer les binaires, les bibliothèques, les données statiques, etc ..
    Évidemment on peut spécifier pour chaque chemin un chemin particulier, on peut aussi créer des chemins d'installation particulier (par exemple un endroit on va installer des scripts python, etc ...).
    Ce script configure a l'avantage de pouvoir être lancé de n'importe quel répertoire (pas uniquement la racine du projet). Cela permet entre autre de faire vivre en parallèle des builds release/debug/profiling avec des options différentes, d'y tester l'installation "comme si on y était".
    Par exemple on peut imaginer qu'à partir d'un répértoire ~/Projets/MonProjet/Debug tu lances la commande ../configure --prefix=`pwd`/inst.
    Après un make réussi, tu peux lancer un make install et tester ton programme installé.
    Tu peux également préférer faire ../configure --datadir=../MesDonneesTest et ne pas faire de make install et de lancer ton exécutable directment ... Puis quand tu crées la version release tu passes les bon chemins.

    Dans tous les cas de figures, cela passe par un -D donné à la commande de compilation ou un #define dans le fichier config.h (enfin presque ... mais là on entrerait trop dans les détails )

    Enfin, tu peux faire un peu ce que tu veux, même si maîtriser les autotools peut parfois être fastidieux.
    Toujours dans le monde linux, il est d'usage de sauver les données de l'utilisateur dans un répertoire caché à la racine de son home (par exemple tout se trouveras dans ~/.mon_application/). Il y a aussi certains standards similaires à ceux qu'on trouve sous windows : XDG. Là les chemins peuvent être dans l'environnement.

    Le step suivant est de ne développer que sous linux, et de cross compiler (souvent ça marche pas trop mal). Mais là on se heurte à la création des packages pour distribuer l'application (entre les .deb les .rpm, les packages wix pour windows) ... Il faut en général adapter configure à chaque cas (les prefix peuvent changer, je ne parle pas de windows)

  6. #6
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    J'ai l'impression que vous comprenez pas la question de LittleWhite (ou c'est moi qui n'ai rien compris)
    Il demande pas comment configurer les chemins lors de la compilation, mais avoir des chemins différents selon que l'application tourne en étant installé dans le /usr ou ailleurs. Le choix du chemin doit être fait lors du lancement de l'application et non lors de la compilation

  7. #7
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Je pensais beaucoup aux autotools, même si je n'aime pas trop les utiliser. Mais je pense que c'est la meilleure des solutions, à vrai dire. Peut être CMake en est aussi capable ?

    @gbdivers : Oui, un fichier de configuration et il se trouve où ? Dans mon home, dans mon dossier courant ? et puis, il indique quel chemin ? ceux de l'application installée ou ceux du répertoire courant (chemins relatifs).

    EDIT :
    J'ose croire que autotool répond tout de même correctement à la question. Dans tous les cas, les chemins doivent être définis à la compilation, quitte, à comme tu l'as dit, faire plusieurs essais, puis pleurer. Il y a toujours un moment où cela doit être spécifier.

    Le problème c'est que dans mon cas actuel, j'ai un makefile farfelu et que si j'installe mon logiciel et que je passe une variable avec -D je dois recompiler tout mon programme pour prendre en compte la variable
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  8. #8
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Il demande pas comment configurer les chemins lors de la compilation, mais avoir des chemins différents selon que l'application tourne en étant installé dans le /usr ou ailleurs. Le choix du chemin doit être fait lors du lancement de l'application et non lors de la compilation
    Quand on crée un package qui sera installé (toujours dans le monde *nix) il y a les données statiques installées lors de l'installation du package. Un utilisateur n'y a accès en général qu'en lecture jamais en écriture. Ces chemins peuvent être codés en "dur": car les chemins sont standardisés ; enfin plus ou moins, même si fedora préfèrait placer ces données dans /usr/local alors que opensuse les place dans /usr, mais quel que soit le préfixe les headers iront par défaut dans include, les binaires dans bin, les bibliothèques dans lib, etc ...
    On compile avec des "#define en dur" pour chaque type de distribution.
    Ensuite il y a les données utilisateurs, celles-ci sont librement placées dans le home dir (où l'utilisateur peut lire et écrire). Là aussi on peut (ou non) suivre les recommandations de certaines normes. Celles-ci peuvent être codées relativement en dur mais leurs valeurs devraient pouvoir être modifiées à l'exécution (et uniquement celles-ci), soit par un fichier de configuration, par une option sur la ligne de commande, les variables d'environnements ...

  9. #9
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Je dirais quelquechose de similaire à kwariz qui n'a pas encore été dit j'ai l'impression :
    /etc

    Et dedans, un dossier lié à ton projet (avec un nom donné lors de la compilation avec configure...) qui contient un fichier avec le chemin vers d'autres descripteurs de ressources si elles sont vraiment nombreuses.
    Je citerais beaucoup de projets qui font plus ou moins cela : apache, squid, php, openvpn, openldap, etc....
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  10. #10
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    /etc est un dossier système pour les daemons et autres processus "importants" ou lancer en root. Donc à première vue, je ne suis pas vraiment pour.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  11. #11
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    Oui, mais vous n'avez pas de flag pour dire comme quoi le programme est installé ou pas, si vous voulez.
    La solution que nous avions actuellement, c'est de directement passé la base du chemin durant la compilation (-DMON_CHEMIN). Mais bon, si le chemin est défini, ça ne marchera pas si le programme n'est pas installé, ou des trucs dans le genre.
    Je n'ai pas demandé une différence LINUX / WINDOWS, mais une différence entre les ./data et /usr/share .
    Ouais en fait je crois que j'ai pas bien compris le sens de la question
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  12. #12
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    /etc est un dossier système pour les daemons et autres processus "importants" ou lancer en root. Donc à première vue, je ne suis pas vraiment pour.
    /usr/local/etc !
    Bon ok sur FreeBSD le /etc est réservé au système, et l'autre aux daemons quand même...

    Mais la logique reste la même : écris UN fichier dans /usr/local/share qui va dire où se trouve le reste du projet.
    Et le nom de cet unique fichier sera donné lors du configure/make
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

Discussions similaires

  1. graver les routes des fichiers dans un 'txt'
    Par TARIK'S dans le forum Visual C++
    Réponses: 0
    Dernier message: 26/05/2009, 13h09
  2. Réponses: 2
    Dernier message: 03/09/2008, 17h14
  3. Empaquetage : modifier les chemins des fichiers inclus
    Par AndréPe dans le forum Installation, Déploiement et Sécurité
    Réponses: 3
    Dernier message: 21/08/2008, 11h56
  4. java.util.zip chemin des fichiers dans l'archive ZIP
    Par Bubu017 dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 15/04/2008, 17h36
  5. Ecrire les noms des fichiers dans une colonne
    Par REGIMBAL dans le forum Access
    Réponses: 1
    Dernier message: 20/04/2006, 11h29

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