首选cmake项目结构 [英] preferred cmake project structure

查看:23
本文介绍了首选cmake项目结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要以下结构 A ->B->C,其中:

I would like to have the following structure A -> B -> C, where:

  • C 是样板代码,第三方库的包装器,非常基本代码等
  • B 是常用的类、函数和数据特定于项目领域的结构.
  • A 是项目本身.
  • C is boilerplate code, wrappers for third-party libraries, very basic code etc.
  • B is the common classes, functions and data structures specific to the project's domain.
  • A is the project itself.

我希望以后在我的其他项目中可以轻松地重用 CB(+C).另外,我还有以下要求:

I would like to make it easy to reuse C or B(+C) in future in my other projects. In addition, I have the following requirements:

  1. 由于这三个项目都在进行中,我希望能够构建CC+BC+B+A 一次性完成.
  2. 我更喜欢静态链接而不是动态链接,因此 CC+B 将是静态库,而 C+B+A> 将是可执行文件
  3. 我想让 cmake 列表和配置文件保持简单和干净.我在官方 wiki 和互联网上找到的例子非常庞大和可怕.
  4. 如果我更改ABC 的位置,如果不需要更改多于几行,那就太好了 在文件系统中.
  5. 这三个组件都在使用 google-test,但我不确定它对项目布局是否重要.
  1. As all three projects are in-progress, I would like to have an ability to build C, C+B and C+B+A in one shot.
  2. I would prefer the static linkage over dynamic, so that C and C+B would be static libraries, and C+B+A would be the executable
  3. I would like to keep cmake lists and config files simple and clean. Examples which I found in the official wiki and over the internet are pretty big and monstrous.
  4. It would be great if it won't require changing more than a couple of lines if I'd change the locations of A, B or C in the filesystem.
  5. All these three components are using google-test, but I'm not sure if it is important for the project layout.

我对 cmake 很陌生,我什至不明白编写 XXXConfig.cmakeFindXXX.cmake 文件更好.另外,我不确定,我应该如何使用 X_INCLUDE_DIRS 将相对路径从子组件传递到父组件.

I am pretty new to cmake and I don't even understand is it better to write XXXConfig.cmake or FindXXX.cmake files. Also, I am not sure, how should I pass relative paths from subcomponent to the parent component using X_INCLUDE_DIRS.

推荐答案

首先我必须承认我同意 @Tsyvarev.您的 CMake 环境应适合您的流程/工作流程,并应考虑项目规模和团队结构.或者一般来说 CMake 将在其中使用的环境.这往往 - 从积极的方面 - 非常活跃.

First I have to admit that I agree with @Tsyvarev. Your CMake environment should fit to your processes/workflow and should take project sizes and team structure into account. Or generally speaking the environment CMake will be used in. And this tends to be - in a positive way - very alive.

所以你的这部分问题很难回答,我将专注于技术部分:

So this part of your question is difficult to answer and I'll concentrate on the technical part:

  1. CMake 必须知道依赖项的位置 - 相对或绝对 - 通过
  • 优先使用工具链文件而不是 if(SomeCompiler) 语句
  • 将常见/重复代码部分作为 function() 主体移动到共享的 CMake 包含文件中
  • 将复杂的非目标特定代码部分移动到它们自己的 (CMake) 脚本文件中
  • Prefer toolchain files over if(SomeCompiler) statements
  • Move common/repeating code parts as function() bodies into a shared CMake include file
  • Move complex non-target specific code parts into their own (CMake) script files

示例代码

由于您特别要求 find_package() 变体,因此采用 在您的 CMake 项目中使用支持 CMake 的库 以及上面列出的内容:

Example Code

Since you have specifically asked for the find_package() variant, taking Use CMake-enabled libraries in your CMake project and the things listed above:

MyCommonCode.cmake

cmake_policy(SET CMP0022 NEW)

function(my_export_target _target _include_dir)
    file(
        WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_target}Config.cmake"
        "
            include("${CMAKE_CURRENT_LIST_DIR}/${_target}Targets.cmake")
            set_property(
                TARGET ${_target} 
                APPEND PROPERTY 
                    INTERFACE_INCLUDE_DIRECTORIES "${_include_dir}"
            )
        "
    )

    export(
        TARGETS ${_target} 
        FILE "${CMAKE_CURRENT_BINARY_DIR}/${_target}Targets.cmake"
        EXPORT_LINK_INTERFACE_LIBRARIES
    )
    export(PACKAGE ${_target}) 
endfunction(my_export_target)

C/CMakeLists.txt

include(MyCommonCode.cmake)
...
my_export_target(C "${CMAKE_CURRENT_SOURCE_DIR}/include")

B/CMakeLists.txt

include(MyCommonCode.cmake)

find_package(C REQUIRED)
...
target_link_libraries(B C)
my_export_target(B "${CMAKE_CURRENT_SOURCE_DIR}/include")

A/CMakeLists.txt

include(MyCommonCode.cmake)

find_package(B REQUIRED)
...
target_link_libraries(A B)

这将所有 3 个构建环境分开,仅共享相对静态的 MyCommonCode.cmake 文件.因此,在这种方法中,到目前为止我还没有涵盖您的第一点,但建议使用外部脚本来链接/触发 A/B/C 的构建步骤.

This keeps all 3 build environments separate, only sharing the relatively static MyCommonCode.cmake file. So in this approach I have so far not covered your first point, but would recommend the use of a external script to chain/trigger your build steps for A/B/C.

这篇关于首选cmake项目结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆