web-dev-qa-db-fra.com

Structure de répertoire pour une bibliothèque C++

Je travaille sur une bibliothèque C++. En fin de compte, je voudrais le rendre public pour plusieurs plates-formes (au moins Linux et Windows), avec quelques exemples et Python bindings. Les travaux avancent bien, mais pour le moment, le projet est assez confus, construit uniquement dans et pour Visual C++ et pas du tout multi-plateforme.

Par conséquent, je pense qu'un nettoyage est en ordre. La première chose que je voudrais améliorer est la structure de répertoires du projet. J'aimerais créer une structure adaptée aux outils Automake afin de permettre une compilation facile sur plusieurs plates-formes, mais je ne les utilisais jamais auparavant. Etant donné que je vais toujours faire (la plupart des) codages dans Visual Studio, il me faut un endroit pour conserver mon projet Visual Studio et les fichiers de solution également.

J'ai essayé de rechercher des termes tels que "Structure du répertoire de la bibliothèque C++" sur Google, mais rien d'utile ne semble se présenter. J'ai trouvé des directives très basiques, mais pas de solutions cristallines.

En regardant certaines bibliothèques open source, j'ai trouvé ce qui suit:

\mylib
    \mylib <source files, read somewhere to avoid 'src' directory>
        \include? or just mix .cpp and .h
    \bin <compiled examples, where to put the sources?>
    \python <Python bindings stuff>
    \lib <compiled library>
    \projects <VC++ project files, .sln goes in project root?>
    \include? 
    README
    AUTHORS
    ...

Je n'ai aucune expérience préalable avec des projets de développement multi-plateformes/open source et je suis assez étonné de ne pouvoir trouver de bonnes directives sur la manière de structurer un tel projet.

Comment devrait-on généralement structurer un tel projet de bibliothèque? Que peut-on recommander de lire? Y a-t-il de bons exemples?

66
TC.

Une chose qui est très commune parmi les bibliothèques Unix est qu'elles sont organisées de telle sorte que:

./         Makefile and configure scripts.
./src      General sources
./include  Header files that expose the public interface and are to be installed
./lib      Library build directory
./bin      Tools build directory
./tools    Tools sources
./test     Test suites that should be run during a `make test`

Cela reflète un peu le système de fichiers Unix traditionnel sous /usr où:

/usr/src      Sometimes contains sources for installed programs
/usr/include  Default include directory
/usr/lib      Standard library install path
/usr/share/projectname   Contains files specific to the project.

Bien sûr, ceux-ci peuvent se retrouver dans /usr/local (qui est le préfixe d'installation par défaut pour GNU autoconf), et ils peuvent ne pas adhérer à cette structure du tout.

Il n'y a pas de règle stricte. Personnellement, je n'organise pas les choses de cette façon. (J'évite d'utiliser un répertoire ./src/ du tout, sauf pour les plus gros projets, par exemple. Je n'utilise pas non plus autotools, préférant plutôt CMake.)

Ma suggestion est que vous choisissiez une structure de répertoire qui est logique pour vous (et votre équipe). Faites ce qui est le plus sensé pour l'environnement de développement, les outils de construction et le contrôle de source choisis.

88
greyfade

Je trouve que la bibliothèque wxWidgets (open source) est un bon exemple. Ils supportent de nombreuses plates-formes différentes (Win32, Mac OS X, Linux, FreeBSD, Solaris, WinCE ...) et des compilateurs (MSVC, GCC, CodeWarrior, Watcom, etc.). Vous pouvez voir la disposition de l'arbre ici:

 https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk/

5
Milan Babuškov

Je ne pense pas qu'il y ait de bonnes directives pour cela. La plupart de cela est juste une préférence personnelle. Certains IDE détermineront cependant une structure de base pour vous. Visual Studio, par exemple, créera un dossier bin séparé, divisé en sous-dossiers Debug et Release. Dans VS, cela a du sens lorsque vous compilez votre code avec différentes cibles. (Mode débogage, mode de libération.)

Comme le dit greyfade, utilisez une mise en page qui vous convient. Si quelqu'un d'autre ne l'aime pas, il devra simplement le restructurer lui-même. Heureusement, la plupart des utilisateurs seront satisfaits de la structure que vous aurez choisie. (Sauf si c'est vraiment désordonné.)

5
Wim ten Brink

Je peux vraiment vous recommander d’utiliser CMake ... c’est pour le développement multiplateforme et il est beaucoup plus flexible qu’automake, utilisez CMake et vous pourrez écrire du code multiplateforme avec votre propre structure de répertoire sur tous les systèmes.

0
stuv_2028

Il y a cette convention géniale que j'ai récemment rencontrée qui pourrait être utile: The Pitchfork Layout (également sur GitHub ).

En résumé, la sous-section 1.3 stipule que:

PFL prescrit plusieurs répertoires qui doivent apparaître à la racine de l’arborescence du projet. Tous les répertoires ne sont pas obligatoires, mais ils ont un objectif assigné et aucun autre répertoire du système de fichiers ne peut assumer le rôle de l'un de ces répertoires. C'est-à-dire que ces répertoires doivent être ceux utilisés si leur objectif est requis.

Les autres répertoires ne doivent pas apparaître à la racine.

build/: un répertoire spécial qui ne doit pas être considéré comme faisant partie de la source du projet. Utilisé pour stocker les résultats de construction éphémères. ne doit pas être vérifié dans le contrôle de source. Si vous utilisez le contrôle de source, vous devez l'ignorer à l'aide du contrôle de source ignore-lists.

src/: Emplacement source principal compilable. Doit être présent pour les projets avec des composants compilés qui n'utilisent pas de sous-modules . En présence de include/, contient également des en-têtes privés.

include/: Répertoire des en-têtes publics. Peut être présente. Peut être omis pour les projets ne faisant pas de distinction entre les en-têtes privés et publics. Peut être omis pour les projets utilisant des sous-modules.

tests/: Répertoire pour les tests.

examples/: Répertoire d'échantillons et d'exemples.

external/: Répertoire des packages/projets à utiliser par le projet, mais non édité dans le cadre du projet.

extras/: Répertoire contenant des sous-modules supplémentaires/facultatifs pour le projet.

data/: Répertoire contenant les aspects du projet autres que le code source. Cela peut inclure des graphiques et des fichiers de balisage.

tools/: répertoire contenant les utilitaires de développement, tels que les scripts de construction et de refactoring

docs/: Répertoire pour la documentation du projet.

libs/: Répertoire des sous-modules du projet principal.

De plus, je pense que le répertoire extras/ est l'endroit où vos liaisons Python devraient aller .

0
Gabriel Galli