首选cmake项目结构

时间:2015-11-04 23:33:13

标签: c++ cmake

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

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

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

  1. 由于所有三个项目都在进行中,我希望能够一次性构建CC+BC+B+A
  2. 我更喜欢静态链接而非动态,因此CC+B将是静态库,而C+B+A将是可执行文件
  3. 我想保持cmake列表和配置文件简单干净。我在官方维基和互联网上找到的例子非常庞大而且非常可怕。
  4. 如果我改变ABC的位置,如果它不需要更改多行就会很棒文件系统。
  5. 所有这三个组件都使用谷歌测试,但我不确定它对项目布局是否重要。
  6. 我对cmake很陌生,我甚至不理解编写XXXConfig.cmakeFindXXX.cmake文件会更好。另外,我不确定,我应该如何使用X_INCLUDE_DIRS将子组件的相对路径传递给父组件。

1 个答案:

答案 0 :(得分:4)

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

因此,这部分问题很难回答,我将专注于技术部分:

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

    由于您已经明确要求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构建步骤。