web-dev-qa-db-fra.com

Meilleure structure de dossiers pour la bibliothèque et les liaisons multiplates-formes C++

Je suis sur le point de commencer à travailler sur une bibliothèque multi-plateformes à écrire en C++. À terme, j’ai l’intention d’implémenter des liaisons pour d’autres langages tels que Python, Java, etc. La bibliothèque doit être disponible sur les principales plates-formes: win32, Linux et Mac OSX.

Bien que l’application soit réellement une bibliothèque, certains programmes de console de base seront fournis avec elle à des fins de démonstration et de test.

J'aimerais proposer une structure de dossiers optimale avant de commencer à stocker des éléments dans Subversion.

Je pense à quelque chose comme:

/project                    //Top level folder

        /bin                //Binaries ready for deployment
            /linux_AMD64    //Linux AMD64 platform
                  /debug    //Debug build - duplicated in all platforms
                  /release  //Release build - duplicated in all platforms
            /linux_i386     //Linux 32-bit platform
            /macosx         //Mac OS X
            /win32          //Windows 32-bit platform
                  /cygwin   //Windows 32-bit platform compiled with Cygwin
                  /vs.net   //Windows 32-bit platform compiled with Visual Studio .NET
            /win64          //Windows 64-bit platform

        /build              //Make and build files, IDE project files
            /linux_AMD64    //Linux AMD64 platform
            /linux_i386     //Linux 32-bit platform
            /macosx         //Mac OS X
            /win32          //Windows 32-bit platform
            /win64          //Windows 64-bit platform

        /config             //Configuration files that accompany the binaries

        /data               //Data files that accompany the binaries

        /doc                //Documentation

        /lib                //External or third-party libraries
            /platforms      //Platform-specific code for ...
                      /linux_AMD64    //Linux AMD64 platform
                      /linux_i386     //Linux 32-bit platform
                      /macosx         //Mac OS X
                      /win32          //Windows 32-bit platform
                      /win64          //Windows 64-bit platform
            /src            //Available library source code in subfolders

        /src                //Source code tree - this will contain main.cpp
            /bindings       //Bindings to other languages such as ...
                      /python
                      /Java
            /h              //Header files
            /modules        //Platform-independent modules, components or subprojects
            /platforms      //Platform-specific code for ...
                      /linux_AMD64 //Linux AMD64 platform-specific code
                      /linux_i386  //Linux 32-bit platform-specific code
                      /macosx
                      /win32       //Windows 32-bit platform-specific code
                      /win64       //Windows 64-bit platform

        /test               //Automated test scripts

Si vous avez des suggestions, j'aimerais les entendre. Je me demande s'il existe un outil pouvant aider à créer cette structure.

Je prévois d'utiliser CMake et Subversion.

52
Kevin P.

La structure me semble bonne, mais il y a quelques points:

  • il est normal de séparer les fichiers source et les en-têtes C++ dans des répertoires différents, ou peut-être existe-t-il une structure dans le répertoire des modules que vous ne montrez pas?
  • vous voulez probablement que les répertoires mettent les fichiers intermédiaires comme * .obj dans
  • vous aurez besoin de différents répertoires pour le débogage et la publication des fichiers de sortie
  • un répertoire pour les installateurs comme InnoSetup et leurs fichiers d'installation peut être utile - vous devez prendre la décision philosophique quant à l'opportunité de contrôler leur version.

En ce qui concerne les outils permettant de créer la structure, quelques minutes consacrées à l’écriture d’un script bash suffisent - il est utile d’avoir les mêmes outils (comme bash) disponibles sur toutes les plateformes.

10
anon

Pourquoi avez-vous besoin de dossiers de plate-forme différents pour les fichiers binaires? Vous allez construire ce code source sous différentes plateformes mais avec le même système de fichiers?

Si oui, je pense que vous avez également besoin de dossiers spécifiques au compilateur. 

Pourquoi n'utilisez-vous pas différents dossiers pour les versions de débogage et de publication, par exemple les versions unicode et non unicode, à thread unique ou multithreading?

Regardez sur bjam ou scons faire des remplaçants. Peut-être que vous n'avez pas besoin de différents dossiers dans le répertoire de construction. 

Je pense que ce sera mieux si tous les modules du répertoire "modules" contiendront le répertoire "tests" pour se tester. 


Et enfin - voir la librairie boost, cette librairie indépendante à la structure agréable. 

Essayez également d’obtenir des idées de projets indépendants de la plate-forme antother.

Structure des dossiers Boost:

boost - root dir
- boost - library header lib ( for users )
- libs - library source dir ( one dir per lib )
    - build - library build files ( if they are needed )
    - doc - documentation files
    - example - sample programs
    - src - library source files
    - test - programs and srcipts for testing module
- bin - created by bjam build system
    - libs
        - <lib-name>
            for all compiled folders from libs [example|test|build]
                - <compiler-name>/<[static|dynamic]-link>/<[debug|release]>/<[threading mode]>
                    contain builded [obj|dll|lib|pdb|so|o|etc] files see detailed information in bjam build system

- doc
- tools

Si vous choisissez bjam - vous ne serez pas concerné par la structure des dossiers build et bin. 

De plus, votre libs/src/dir peut contenir propre pour tous les fichiers de la plate-forme et quelques répères pour les fichiers spécifiques à la plate-forme .

Je ne vois pas de problèmes sérieux dans votre structure de dossiers, vous les verrez peut-être quand vous commencerez à écrire le prototype du projet.

7
bayda

J'ai récemment posté une question sur les en-têtes d'empaquetage dans un seul répertoire, j'ai décidé d'aller avec un petit nombre de répertoires include.

Allez-vous répondre à Win64? Ce sera une cible de plus en plus importante.

Do not placez vos fichiers intermédiaires de construction n'importe où sous une arborescence en cours de contrôle dans svn. Si vous le faites, en fonction de vos outils client svn, ils généreront beaucoup de bruit sous forme de fichiers qui ne figurent pas dans le référentiel. Cela rend difficile de voir les fichiers que vous avez ajoutés et que devraient se trouver dans le référentiel.

Au lieu de cela, si votre compilateur le permet, mettez les répertoires intermédiaires de côté.

Sinon, assurez-vous d'ajouter tous les répertoires intermédiaires à vos propriétés d'exclusion svn. Certaines interfaces utilisateur rendent cela plus facile que d’autres (Tortoise sous Windows, Cornerstone ou Versions sous OS/X).

2
Andy Dent

Puis-je suggérer de ne pas utiliser l'architecture pour classer les fichiers de construction?

J'essayais d'appliquer la structure de dossiers proposée, mais je ne trouvais pas le bon endroit pour insérer les définitions de Makefile Linux courantes et les fichiers de propriétés Visual Studio. Que diriez-vous de ce qui suit:

/project
   /build
      /linux
      /macosx
      /win32 (or win)

Et le cas d'exemple comprendrait:

/project
   /build
      /linux
         Make.defs
         Makefile  [i386, AMD64]
      /win32
         /VC8
            /<project>
               <project>.vcproj
            <solution>.sln  [Win32, x64]
         /VC11
            /<project>
               <project>.vcxproj
            <solution>.sln  [Win32, x64, ARM]

Si vous ne souhaitez pas définir de constructions d'architecture via des configurations, pourquoi pas une autre couche de dossiers sous les types de plate-forme?

/project
   /build
      /linux
         /linux_AMD64
         /linux_i386
      /macosx
         /?
      /win32 (or win)
         /win32
         /win64

Si un projet donné n'a pas de fichier de construction commun pour une plate-forme, la structure d'origine suffira.

0
jdknight