C++跨平台库和绑定的最佳文件夹结构

54

我即将开始编写一个跨平台的C++库,未来还打算实现其他语言(如Python、Java等)的绑定。该库需要在主要平台上可用:win32、Linux和Mac OSX。

虽然这个应用程序实际上是一个库,但会附带一些基本的控制台程序以进行演示和测试。

在我开始存储东西到Subversion之前,我想先设计一个最佳的文件夹结构。

我的想法是类似于:

/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

如果你有建议,我很想听听。 我想知道是否有一个工具可以帮助创建这个结构。

我计划使用CMake和Subversion。


我有一个问题要问你:作为一个库,main.cpp是什么,别人会如何使用它?我现在正在面临这个问题,我认为main.cpp实际上是对库的测试。不是吗? - d-_-b
2
我在这里有一个相关的答案:编写特定于平台的代码的最佳(最干净)方法 - Marc.2377
3个回答

11

结构看起来不错,但有几点需要注意:

  • 将C++头文件和源文件分开放置在不同的目录中是很正常的,或者你没有展示modules目录中的结构吗?
  • 你可能需要创建目录来存放*.obj等中间文件。
  • 你需要为调试和发布输出文件创建不同的目录。
  • 一个用于安装程序(如InnoSetup)及其安装文件的目录可能会很有用 - 你必须做出哲学决定,是否对这些进行版本控制。

至于创建这种结构的工具,花费几分钟编写一个bash脚本就足够了 - 在所有平台上都可以使用相同的工具(如bash)。


谢谢,我已经将你的一些建议添加到树中了。 - Kevin P.

9
为什么需要为不同平台的二进制文件使用不同的文件夹?您是否要在不同平台下使用相同的文件系统构建此源代码?如果是,我认为您也需要特定于编译器的文件夹。为什么不为调试和发布版本、Unicode和非Unicode版本、单线程或多线程版本使用不同的文件夹?可以查看bjam或Scons make replacers。也许您不需要在build目录中使用不同的文件夹。我认为,如果所有来自“modules”目录的模块都包含用于自我测试的“tests”目录将会更好。最后,请参考Boost库,这是一个具有良好结构的独立于平台的库。还可以从其他独立于平台的项目中获取灵感。 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

如果您选择使用bjam,您将不必担心构建和二进制文件夹的结构。
此外,您的libs/src/目录可以包含所有平台文件以及几个用于特定平台文件的目录。
我认为您的文件夹结构没有任何严重的问题,但是当您开始编写项目原型时,可能会发现一些问题。

我不打算进行交叉编译,即macosx必须在macosx上构建。为调试和发布设置不同的文件夹是个好主意。 - Kevin P.
我看了一下boost,但很难看出他们是如何管理平台的。他们似乎在使用boost jam。 - Kevin P.
bjam(boost jam)的学习曲线陡峭,更像是一门花哨的语言。不建议使用。我发现最好的替代方法是rake,因为它灵活、广泛使用且相对容易学习和使用。 - srcspider

2

我最近发布了一个有关在一个目录中打包头文件的问题,决定只使用少量的include目录。

您会考虑支持Win64吗?这将是一个越来越重要的目标。

不要将构建中间文件放在正在检查到svn的树下的任何位置。如果这样做,取决于您的svn客户端工具,它们将生成许多噪音作为未在存储库中的文件。这使得很难看到您添加的应该在存储库中的文件。

相反,如果您的编译器允许,请将中间目录放在一侧。

否则,请确保将整个中间目录添加到您的svn排除属性中。某些GUI比其他GUI更容易(Windows上的Tortoise,OS / X上的Cornerstone或Versions)。


我之前没有考虑过win64,但已经把它加入到列表中了。谢谢!svn使得通过在包含文件夹上使用一个svn-ignore属性来排除中间文件(如.o和.obj)变得容易。 - Kevin P.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接