【问题标题】:preferred cmake project structure首选的 cmake 项目结构
【发布时间】:2015-11-04 23:33:12
【问题描述】:

我希望有以下结构A -> B -> C,其中:

  • C 是样板代码,第三方库的包装器,非常 基本代码等
  • B是常用的类、函数和数据 特定于项目领域的结构。
  • A 是项目本身。

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

  1. 由于所有三个项目都在进行中,我希望能够一次性构建 CC+BC+B+A
  2. 我更喜欢静态链接而不是动态链接,这样CC+B 将是静态库,C+B+A 将是可执行文件
  3. 我想让 cmake 列表和配置文件保持简单和干净。我在官方 wiki 和 Internet 上找到的示例非常庞大和可怕。
  4. 如果我在文件系统中更改ABC 的位置,那么它不需要更改超过几行,那就太好了。
  5. 这三个组件都在使用 google-test,但我不确定它对项目布局是否重要。

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

【问题讨论】:

  • 项目布局主要由作者决定。您的每个要求都有许多可能的决定,而不仅仅是来自 cmake 方面。例如,在其他项目中重用 C 可能是版本控制系统的任务。由于您是 cmake 的新手,因此您最好从 任何简单的布局开始,只是为了 使项目正常工作
  • @Tsyvarev 项目已经在运行,但是通过我所做的简单 cmake 配置,它非常单一。如果实现目标有很多选择,那么哪个选择是最好的?如果问题中的信息不够,还有什么附加条件?
  • 没有“最佳选择”。有许多“附加条件”可能会影响不同决策的“好”顺序。其中一些条件,例如您的 3d 条件,是主观的。您的问题可能有助于收集关于可能布局的不同意见,但 SO 网站属于 问答 类型,此类问题根本不适合它。

标签: c++ cmake


【解决方案1】:

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

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

  1. CMake 必须知道依赖项的位置 - 相对或绝对 - 通过
  2. 为了使您的 CMake 文件尽可能简单,我建议您将 CMake 代码分组到单独的专用文件中:
    • 工具链文件优于 if(SomeCompiler) 语句
    • 将公共/重复代码部分作为 function() 主体移动到共享的 CMake 包含文件中
    • 将复杂的非目标特定代码部分移动到它们自己的 (CMake) 脚本文件中

示例代码

由于您特别要求find_package() 变体,因此请使用Use CMake-enabled libraries in your CMake project 和上面列出的内容:

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 的构建步骤。

【讨论】:

    猜你喜欢
    • 2014-10-06
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 1970-01-01
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    相关资源
    最近更新 更多