Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Quelle arborescence de fichiers utiliser pour nos dépôts ?
Venez décrire votre organisation et en débattre !

Le , par Neckara

14PARTAGES

2  0 
Quelle arborescence de fichiers utiliser pour nos dépôts ?
Venez décrire votre organisation et en débattre !

Lorsqu'on travaille sur un projet, respecter les bons principes de la programmation et ajouter des commentaires pour pouvoir générer une documentation n'est pas suffisant.

En effet, pensez à la personne qui essayera de relire vos dizaines voire centaines de fichiers. Il faut qu'elle puisse trouver le plus rapidement les informations/fichiers qu'elle cherche.

J'ai souvent vu des projets avec à la racine :
- un dossier bin pour les exécutables ;
- un dossier lib pour les dépendances ;
- un dossier include pour les fichiers d'en-têtes de la bibliothèque ;
- un dossier src pour les sources (.cpp et .h) ;
- un dossier doc pour la documentation ;
- un fichier Makefile/CMake/de projet pour compiler ;
- un README ;
- un fichier INSTALL décrivant la procédure d’installation ;
- un dossier datafile/ressources pour tous les fichiers sons/images.

Mais quand on se penche sur le contenu de ces dossiers et des fichiers, chacun fait un peu à sa sauce.
On peut se retrouver avec 50 fichiers dans un seul dossier dans les sources ou à l'inverse avoir 7 fichiers pour 4 dossiers.



D'après vous,
Comment devrait être constituée l'arborescence d'un projet ?
Que mettre dans les fichiers README et INSTALL ? Quel « plan » adopter, quel « pattern » suivre pour ces fichiers ?
Pour les fichiers sources, faut-il créer un dossier par namespace ?
Comment regrouper/trier les fichiers sources ? Combien faut-il mettre de fichiers « maximum » dans un dossier ?
Quelle profondeur donner à notre arborescence ?

Bref, quel est pour vous le squelette type d'une arborescence idéale de fichiers et quelles seraient vos consignes pour le remplir ?

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de koala01
Expert éminent sénior https://www.developpez.com
Le 20/09/2013 à 22:03
Salut,

Lorsque je crées un projet qui est destiné à être compilé par plusieurs systèmes ( autotools, code::blocks et cmake, pour ne citer qu'eux), j'ai tendance à créer un dossier par catégorie.

Pour ce qui est de la documentation, je rajoute (parce que je l'utilise ) souvent un dossier "doxygen" qui contiendra la configuration (doxyfile, par défaut ) et les éventuelles pages connexes ("group.dox", "namespace.dox" et autres joyeusetés qui permettent de créer des pages en relation avec un concept en général mais non relative à une classe particulière), le tout en faisant en sorte que la documentation générée se trouve dans le dossier doc.

Je place d'office tous mes fichiers d'en-tête dans le dossier include, mais je le subdivise régulièrement en fonction de "modules" particuliers.

De la même manière, je mets tous mes fichier d'implémentation, à l'exception des fichiers relatifs au tests unitaire, dans le dossier src, subdivisé par espace de noms ou par "module".

Ceci dit, j'essaye généralement que la compilation ne se fasse pas dans le même dossier, afin d'éviter que le gestionnaire de version concurrente n'en vienne à essayer de commiter des choses qui n'ont pas lieu d'être (comme les fichiers objets par exemple).

au final, l'arborescence ressemble à quelque chose comme
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<root_directory>
    |-> autotool (toutes les joyeusetés prorpres au outils autocof, autoheader, et automake)
    |    |-> src (les joyeusetés propres à la compilation des sources, en 
                  respectant l'aborescence du dossier contenant les fichier d'implémentation)
    |    |-> tests (et celles pour les tests unitaires)
    |-> codeblocks (les fichiers propes aux projet code::blocks)
    |-> cmake (et ceux propres au système CMake)
    |-> doc (gentillement rempli par doxygen)
    |-> doxygen (j'en ai parlé plus haut)
    |-> include
    |    |-> module1
    |    |-> module2
    |-> src
    |    |-> module1
    |    |-> module2
    |-> test 
    |    |-> module1
    |    |-> module2
Quant aux bibliothèques externes, elles sont installées dans des dossiers clairement séparés (boost dans un dossier qui lui est propre, et Qt dans un autre), à part quelques unes (libiconv, icu ou libxml2) qui sont directement dans le dossier de mon compilateur.

J'utilise des variables d'environnement pour maintenir tout cela en place, comme
  • QTDIR qui est le dossier racine dans lequel se trouve Qt
  • QTBIN qui est le dossier dans lequel se trouvent les exécutables et les dll de Qt (définie sous windows comme étant égale à %QTDIR%\qtbase\bin et sous linux comme étant égale à ${QTDIR}/qtbase/bin)
  • BOOSTDIR qui est le dossier racine de boost
  • BOOST_VERSION qui correspond à une chaine de caractères représentant la version de boost (actuellement 1_54)
  • BOOST_HEADERS qui indique le dossier dans lequel se trouvent les en-tête de boost (définie, sous windows comme étant égale à %BOOSTDIR%\include\boost-%BOOST_VERSION% , sous linux comme étant égale à ${BOOSTDIR}/include/boost-${BOOST_VERSION} et
  • BOOST_LIB (définie sous windows comme étant égale à %BOOSTDIR%\lib et sous linux comme étant égale à ${BOOSTDIR}/lib )
De cette manière, je peux passer d'une version à l'autre rien qu'en changeant la valeur de QTDIR ou de BOOST_VERSION, et je peux les utiliser dans les différents scripts / EDI pour la configuration

Note que je dispose de scripts pour définir ces variables sans devoir toucher au variables d'environnement au niveau du panneau de configuration

Enfin, je n'ai aucun a priori quant au nombre (minimal ou maximal) de fichiers qu'un dossier peut / doit contenir.

Je structure mon arborescence en fonction des modules que je crées et chaque dossier contient donc les fichiers nécessaires et utiles au module en question

S'il y en a un qui contient 7 fichiers et l'autre qui en contient 150, c'est qu'un module est beaucoup plus complexe que l'autre, tout simplement
2  0 
Avatar de CedricMocquillon
Membre averti https://www.developpez.com
Le 22/09/2013 à 11:31
Chez moi ça ressemblait pas mal à ce que viens d'exposer koala01. J'ai cependant récemment changé mon organisation pour privilégier un dossier par module (un module étant une entité compilée à part généralement sous forme de lib statique ou dynamique) :
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
<root_directory>
    |-> module1
    |    |-> module1 (include)
    |    |-> src
    |    |-> test
    |-> module2
    |    |-> module2 (include)
    |    |-> src
    |    |-> test
J'utilise également des sous-répertoires "detail" (dans les includes ou les sources) à la manière de boost.
Je trouve le découpage par module plus "propre" si tes modules sont très indépendants (ça permet notamment de partager plus facilement un module, de le versionner à part, ...)
Après (honte à moi) je n'ai pas de répertoire doc, doxygen et autres, mais pour respecter l'idée, je devrais sans doute en avoir un dans chaque module.
2  0 
Avatar de germinolegrand
Membre expert https://www.developpez.com
Le 23/09/2013 à 15:03
Pour ce qui est des binaires, de mon côté il y a un dépôt exprès "releases" qui contient des versions des logiciels compilées à l'usage de ceux qui n'ont pas de compilateur dans l'équipe, mais il y a aussi les outils destinés à entretenir l'environnement de développement (dépôt "tools", ainsi que les .a et .dll dont on n'assure pas la maintenance ou dont le processus de génération est trop complexe pour être faite par tous les devs (exemple la SFML qu'il faut générer depuis un dépôt github, nécessite les outils supplémentaires git et cmake).
2  0 
Avatar de cob59
Membre éprouvé https://www.developpez.com
Le 23/09/2013 à 15:06
Citation Envoyé par Bousk Voir le message
Oui, il y a toujours un binaire/executable release fonctionnel qui est dans le repo.
Il n'y a pas que des développeurs dans une équipe.
En général je préfère créer un dossier package/ en haut de l'arborescence, et y livrer régulièrement (pas forcément à chaque commit) des archives ou installateurs prêts à l'emploi, qui contiennent les bin/lib/data requis. Dans mon cas, via l'utilisation de CPack.

C'est aussi simple pour les non-dev qui ont juste à télécharger 1 setup/.zip et ça évite de commiter systématiquement des binaires volumineux, longs à uploader et pas forcément stables/livrables.
2  0 
Avatar de esperanto
Membre éprouvé https://www.developpez.com
Le 25/09/2013 à 15:42
Citation Envoyé par cob59 Voir le message
Vous commitez vos binaires, vous ?
En aucun cas!
Une règle qui me semble fondamentale dans un gestionnaire de versions est de ne jamais valider (traduction du mot commit) ce qui est créé par des outils (compilateur, langage de formatage, ou autre) : on doit pouvoir relancer les outils et reconstituer les fichiers.

Si vous le faites :
- vous n'êtes pas certain que le fichier généré est synchro avec les sources (il peut avoir été compilé avant vos dernières modifs), parfois on voudrait que ce soit le cas, parfois non (genre mettre dans le dépôt la dernière version de prod...)
- à chaque fois que vous relancez toute la chaîne de compilation, vous allez recréer ces fichiers et vous prenez le risque qu'ils soient absorbés quand vous lancez le commit
(exemple vécu avec un projet libre dont je ne suis pas l'auteur mais auquel je collabore : un fichier html est généré à chaque fois avec des numéros de version dedans; à chaque commit le VCS le voit comme un fichier modifié, et une fois sur 2 j'ai un conflit avec le même fichier "modifié" par un collègue...)
D'autant plus qu'un diff entre binaires est toujours moins bon que pour des fichiers textes (il n'existe pas d'algorithme "merge" capable de fonctionner sur n'importe quel format binaire, alors que pour le texte divisé en ligne ça existe).

Donc, d'accord pour un répertoire "bin" à la racine, mais dans le gestionnaire de versions, il doit être vide (ou se limiter à des .ignore ou ce genre de choses).
D'ailleurs je trouve que c'est également valable pour un répertoire lib/ contenant les dépendances : avec Ant ou Maven (Java) on a prévu des dépôts spécifiques pour les dépendances, je ne vois pas pourquoi on ne ferait pas de même dans d'autres langages.

Citation Envoyé par Bousk

Oui, il y a toujours un binaire/executable release fonctionnel qui est dans le repo.
Il n'y a pas que des développeurs dans une équipe.
En général les non-développeurs ne vont pas chercher dans Git ou Subversion. Ceux qui veulent les binaires n'ont rien à faire des sources, et inversement, c'est pour ça qu'on n'utilise pas les mêmes outils pour les deux dépôts (pour les dépôts de binaires, le plus souvent un simple FTP suffit)
3  1 
Avatar de jblecanard
Membre expert https://www.developpez.com
Le 04/10/2013 à 12:32
Salut à tous

Je ne commite pas mes binaires non plus, ni tout ce qui peut être régénéré. Si un non développeur à un niveau suffisamment élevé pour utiliser un repo git ou svn, alors il doit aussi être capable de lancer la compile et générer le projet. Dans le cas contraire, on met un dépôt de binaires prêt à sa disposition via un autre canal.

Je me permet de compléter un peu le débat avec un point qui n'a pas été vraiment soulevé : le code multi-plateforme. Je n'utilise pas la technique des macros pour sélectionner le code qui va sur une plateforme ou sur l'autre. Je préfère les mettre dans des .cc (ou .cpp selon votre convention) séparés totalement et laisser l'outil de compilation construire la liste des fichiers à utiliser.

Un .cc mutliplateforme ira dans:
src/[chemin]/fichier.cc

Un .cc qui doit être implémenté différemment ira dans:
src/[platform1]/[chemin]/fichier.cc
src/[platform2]/[chemin]/fichier.cc
2  0 
Avatar de white_tentacle
Membre émérite https://www.developpez.com
Le 15/10/2013 à 14:32
En général, les libs externes ne sont pas intégrées au repository. Il y aura exception si la lib est petite, que ça a du sens de la recompiler (par exemple : elle est modifiée par rapport à la version upstream).

Du coup, la question ne se pose pas trop en terme d’organisation projet.
1  0 
Avatar de germinolegrand
Membre expert https://www.developpez.com
Le 15/10/2013 à 14:37
Pour ma part j'ai choisi d'intégrer les lib externes dans un dépôt exprès. J'ai des dépendances entre mes différents dépôts. Je pense que je vais rencontrer des problèmes quand il s'agira de revenir sur un vieux commit (encore que, non, suffit de regarder la date et de revert les différents dépôts à la même date), mais en tout cas c'est plus pratique pour travailler.
1  0 
Avatar de Neckara
Expert éminent sénior https://www.developpez.com
Le 22/09/2013 à 12:48
Bonjour,

Que mets-tu dans tes dossiers "détails" ?
Je présume que tu mets dedans toutes les classes/fonctions qui ne se retrouvent pas "exposées" dans l'interface de ta bibliothèque ?
0  0 
Avatar de Bousk
Rédacteur/Modérateur https://www.developpez.com
Le 22/09/2013 à 13:38
Bonjour,

en général je suis plus ou moins toujours le même schéma:

Code : Sélectionner tout
1
2
3
4
5
6
- root
-- Docs
-- Exe
-- Dev
--- Src
--- Externals
0  0