简体   繁体   English

在中型项目中CMake的最佳方法是什么?

[英]What is the best way of CMake in a Middle-sized Project?

In my company, we're developing a middle sized project which we plan to use CMake as the build platform generator. 在我的公司中,我们正在开发一个中型项目,我们计划使用CMake作为构建平台生成器。 In this scenario, me and my colleagues were discussing about which way the CMake should be used. 在这种情况下,我和我的同事们正在讨论应使用CMake的方式。 Our discussions came to a turn which we must decide the methods to use. 我们的讨论转向了,我们必须确定使用的方法。 Our directory structure is similar to this: 我们的目录结构与此类似:

<"our project"> \
   modules \
      module_1 \
         tests \
            test_example.cpp
         mock
            some_mock_class.hpp
         some_class.hpp
         some_class.cpp
         ...
      module_2 \
         ...
      module_3 \
         ...
   utility \
      ...

1- First thing is first, my colleague thinks that folders like "src" and "includes" are reminder of C programming and has no place in a modern C++ program, so we don't need them. 1-首先是第一件事,我的同事认为诸如“ src”和“ includes”之类的文件夹是C编程的提醒,在现代C ++程序中没有位置,因此我们不需要它们。 So we removed them from the structure, but being a Linux guy; 因此,我们从结构中删除了它们,但成为了Linux专家。 I'm not sure if this is a good idea. 我不确定这是否是个好主意。 Should we set a "include" directory for headers, so CMake can install them appropriately to the include dirs of the install target; 我们应该为头文件设置一个“ include”目录,以便CMake可以将它们适当地安装到安装目标的include目录中。 or can CMake handle them appropriately? 还是CMake可以适当地处理它们?

2- Should we make a CMakeLists.txt to the root of the project which includes and defines all the targets, or should we make a CMakeLists.txt per module, and then use "add_subdirectory" directives to include them? 2-我们应该在包含并定义所有目标的项目的根目录下创建CMakeLists.txt,还是在每个模块中创建CMakeLists.txt,然后使用“ add_subdirectory”指令将其包括在内? My colleague thinks on CMakeLists.txt is the best, because this way the module implementors don't need to think about CMake at all, and one or two admins of deployment can maintain the file; 我的同事认为CMakeLists.txt是最好的,因为这样模块实现者根本不需要考虑CMake,一个或两个部署管理员就可以维护该文件。 but I think every module implementor is more aware of which libraries they use, and how to compile their modules - which he disagrees. 但是我认为每个模块实现者都更清楚他们使用哪些库以及如何编译其模块-他不同意。 What do you suggest in this case? 在这种情况下,您有何建议?

If you did use CMake for such a middle-sized project before (or know of a case) can you please recommend us what they did and, if possible, why? 如果您之前(或知道一个案例)确实将CMake用于这样的中型项目,能否请您向我们推荐他们的工作,如果可能,为什么?

Sincerely 真诚的

The topic is huge, but in short my personal recommendation. 这个话题很大,但总之我个人推荐。 For a middle project I assime a component model should be already applied. 对于中间项目我要组装一个组件模型。 Then reasonable then is, to have component directories with their onwn CMakeLists.txt which are referenced by the top-level CMakeLists.txt via add_subdirectory(). 那么合理的做法是,使组件目录具有自己的CMakeLists.txt,顶级CMakeLists.txt通过add_subdirectory()对其进行引用。 Each component - a separate library (I like static ones). 每个组件-一个单独的库(我喜欢静态库)。

For the component folders I find reasonable to hide all internal stuff (aka implementation and private headers, ...) under a private sub-directory to do not be exposed to the outside. 对于组件文件夹,我认为可以将所有内部内容(也称为实现和私有标头,...)隐藏在private子目录下,以免暴露在外部。 Then, in the top component directory you have only headers which are to be used by the others. 然后,在顶层组件目录中,只有其他人要使用的标题。 In the private directory you can mix sources and headers - this is only a matter of the taste for mid projects. 在私有目录中,您可以混合使用源代码和标题-这只是中间项目的口味。 And the private directory can also be decomposed if the component is large. 如果组件很大,私有目录也可以分解。 But then you need to decide either to add all artifacts to the single CMakeLists.txt of the component, or to have sub-libraries. 但是随后您需要决定是将所有工件添加到组件的单个CMakeLists.txt中,还是拥有子库。 But in that case the users should link to them individually instead to link to the component's library only. 但是在那种情况下,用户应该单独链接到他们,而不是仅链接到组件的库。

In the best case, the folder structure should follow the dependencies structure and form a tree-view build system, where the components have as less knowlege about internals of the other components as possible. 最好的情况是,文件夹结构应遵循依赖关系结构,并形成树形视图构建系统,在该系统中,组件对其他组件内部的知识应尽可能少。 In that case you will have a good configurability and flexibility in case of possible refactorings. 在这种情况下,在可能进行重构的情况下,您将具有良好的可配置性和灵活性。 In the other words, the design of the build system seems to me similar to the class design in C++ - same principles. 换句话说,在我看来,构建系统的设计类似于C ++中的类设计-相同的原理。

The real (target) build directory where you run cmake can be located anywhere, normally outside of the source directory. 运行cmake的真实(目标)构建目录可以位于任何地方,通常在源目录之外。 A good place for it could be a RAM disc if you enough memory. 如果您有足够的存储空间,则最好使用RAM光盘作为存储空间。 Then for the clean build you need just to remove it, that's it. 然后,对于干净的构建,只需要删除它即可。 But the source and the build itself have no dependency from its location. 但是源和构建本身不受其位置的依赖。

Ah yes, one more hint. 是的,还有一个提示。 My recommendation would be to include headers by the path starting from the component directory like #include "SomeHeader.hpp" which is located as ComponentX/SomeHeader.hpp. 我的建议是从组件目录(如位于ComponentX / SomeHeader.hpp的#include "SomeHeader.hpp"开始的路径中包含标头。 Then the CMakelists.txt is used to do the ComponentX directory known to your component. 然后,CMakelists.txt用于执行ComponentX已知的ComponentX目录。 This means, the paths to the headers are not hardcoded in the source files. 这意味着,头文件的路径未在源文件中进行硬编码。 This brings some limitation like unique file names, but makes changes to the components location much easier. 这带来了一些限制,例如唯一的文件名,但是使组件位置的更改变得更加容易。

Hope this anyhow helps. 希望这对您有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM