Un meilleur job mieux payé ?

Deviens chef de projet, développeur, ingénieur, informaticien

Mets à jour ton profil pro

ça m'intéresse

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

Le , par Neckara, Expert éminent sénior
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 ?


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster une réponse

Avatar de koala01 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
Avatar de CedricMocquillon 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.
Avatar de Neckara 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 ?
Avatar de Bousk 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
Avatar de CedricMocquillon CedricMocquillon - Membre averti https://www.developpez.com
le 22/09/2013 à 13:42
@Neckara : oui c'est bien ça: tout ce qui est nécessaire pour que le module puisse fonctionner mais qui n'est pas utile pour l'utilisateur du module (hors interface donc du dit module)
Avatar de koala01 koala01 - Expert éminent sénior https://www.developpez.com
le 22/09/2013 à 14:47
Citation Envoyé par CedricMocquillon  Voir le message
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, ...)

En effet, cela permet de garder très certainement une hiérarchie plus "propre" et, à bien y réfléchir, je vais très certainement "migrer" vers ce type d'organisation
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.

Et encore, cela dépend fortement : rien ne t'interdit effectivement d'avoir un dossier doxygen (pour ne citer que lui) dans chaque module, pour tout ce qui a trait au module en question, mais qu'est ce qui t'interdit d'avoir un dossier doxygen également dans le dossier racine de ton application / projet, pour tout ce qui est relatif au projet en général et pas forcément à un module particulier

L'avantage en générant la documentation sur le dossier racine, c'est que tu obtiens directement la doc de tous les modules, sans devoir commencer à ouvrir un onglet par module (à cause des interdépendances) et que cela te permet, justement, d'avoir une vision plus globale de ces dépendances

Et, même si tu décides de placer le contenu de tous tes modules dans l'espace de noms global (c'est un choix que je ne cautionne pas, mais bon, certains le font ), tu peux avantageusement utiliser la notion de groupe ( @group pour en définir un, @ingroup pour indiquer qu'une classe ou une fonction fait partie du groupe en question) pour que la documentation se répartisse dans les différents modules (d'ailleurs, il semble cohérent d'utiliser la notion de groupe même si tu utilises des espaces de noms différents en fonction de tes modules )
Avatar de germinolegrand germinolegrand - Membre expert https://www.developpez.com
le 22/09/2013 à 19:47
Pour ma part, ça a tendance à ressembler à ça pour les projets sérieux :
(en + les éléments versionnés, en - les éléments ignorés dans le dépôt)
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
+depot 
|+.bzrignore 
|+executive (répertoire d'exécution, réplique de l'environnement client) 
|+projects 
||+Projet.cbp 
||-bin (contient les binaires) 
|||-BuildTarget1 
|||-BuildTarget2 
||-obj (contient les temporaires nécessaires durant le build) 
|||-BuildTarget1 
|||-BuildTarget2 
|+Projet1 (ici une application) 
||+dossier 
||+fichier.cpp 
||+fichier.h 
|+Projet2 (ici une lib) 
||-bin (contient les .dll) 
||-lib (contient les .a) 
||+dossier 
||+fichier.cpp 
||+fichier.h 
|+Projet3 
|+codecommun1 
|+codecommun2
Avatar de deusyss deusyss - Rédacteur/Modérateur https://www.developpez.com
le 23/09/2013 à 10:29
Personnellement, jusqu'à il y a peu, je m'adaptais à mes développements, me focalisant surtout sur une structure bien ordrée et rangée.

Récemment, ayant cherché à créer un exécutable windows à partir de code source PYTHON, les outils m'ont imposés d'eux mêmes une certaine structure. Maintenant, donc, mes projets sont plutôt organisé avec cette structure:
<DOSS PJ>
----<fichiers sources *.py>
----<fichier icone>
----<packages>
----<Dossiers doc>
----<Dossier bdd>
----<Dossier img>
----<Autre dossier data>
----<Dossier pour la creation de l'exe>
--------Fichier de licence
--------Fichier texte pre install
--------Fichier texte post install

J'integre le contenu de readme dans la documentation. Pour le reste, je met à dispo code source, paquet .deb, zip windows standalone et un exe d'install windows. Je me passe donc de fichier INSTALL.txt

EDIT: A titre personnel, je pense que la structure retenue et utilisée importe peu, du moment que celle-ci utilise une certaine logique et reste cohérente
Avatar de r0d r0d - Expert éminent https://www.developpez.com
le 23/09/2013 à 10:45
pour moi, ça dépend du type de projet. Par exemple, si je fais une lib (donc destinée à être utilisée par d'autres), je sépare bien les en-têtes des sources, sinon je préfère autant regrouper les fichiers par classe (en-tête et source d'une même classe dans le même dossier). Pour les programmes qui requièrent des ressources (images, vidéos, sons, ...), je crée un fichier ressource à la racine. En gros, ça ressemblera à ça:
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 
+trunk 
-- bin // les binaires qui sont générés 
    |-- win64 
          |-debug 
          |-release 
    |-- win32 
          |-debug 
          |-release 
    |-- linux64 
          |-debug 
          |-release 
    |-- linux32 
          |-debug 
          |-release 
-- ext // code externe 
    |-- bin // les binaires compilés 
          |-- win64 
              |-debug 
              |-release 
          |-- win32 
              |-debug 
              |-release 
          |-- linux64 
              |-debug 
              |-release 
          |-- linux32 
              |-debug 
              |-release 
    |-- libs // ici je met les libs telles que je les ai récupéré, avec la doc, le code source, etc. j'aime bien les mettre dans le dépôt, mais ce n'est pas systématique 
          |-- boost 
          |-- sfml 
-- ressources // images, videos, sons, fichier de config, etc. 
-- projects 
    | -- visual 
    | -- codeblocks 
    | -- cmake 
-- src 
    | -- model 
    | -- view 
    | -- controller 
    | -- common 
-- temp // ici tous les fichiers temporaires (objets, etc.), ce répertoire n'est présent qu'en local (pas sur le dépôt) 
-- doc
Avatar de imikado imikado - Rédacteur https://www.developpez.com
le 23/09/2013 à 12:35
On peut répondre pour les projets web, ou c'est réservé aux langages compilés ?
Offres d'emploi IT
Ingénieur analyste programmeur (H/F)
Safran - Auvergne - Montluçon (03100)
Architecte et intégrateur scade/simulink H/F
Safran - Ile de France - Vélizy-Villacoublay (78140)
Responsable transverse - engagement métiers H/F
Safran - Ile de France - Corbeil-Essonnes (91100)

Voir plus d'offres Voir la carte des offres IT
Contacter le responsable de la rubrique C++