优选cmake项目结构

编程入门 行业动态 更新时间:2024-10-17 15:24:06
本文介绍了优选cmake项目结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

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

  • C ,第三方库的包装器,非常的基本代码等。
  • B 是常见的类,函数和数据
  • / ul>

    我想方便地重用 C 或 B(+ C)在未来在我的其他项目。此外,我有以下要求:

  • 由于所有三个项目都在进行中,我想有能力建立 C , C + B 和 C + B + A 一个镜头。
  • 我宁愿静态链接超过动态,因此 C 和 C + / code>将是静态库, C + B + A 将是可执行文件
  • cmake列表和配置文件简单干净。我在官方wiki和互联网上发现的例子都是相当大和怪异的。
  • 如果它不需要改变多于几行,这将是巨大的更改 A , B 或 C 的位置文件系统。
  • 所有这三个组件都使用google-test,但我不确定是否对项目布局很重要。
  • 我对cmake很新鲜,我甚至不明白是否更好写 XXXConfig.cmake 或 FindXXX.cmake 文件。另外,我不知道,我应该如何使用 X_INCLUDE_DIRS 传递从子组件到父组件的相对路径。

    解决方案

    首先我必须承认我同意@Tsyvarev。您的CMake环境应适合您的流程/工作流程,并应考虑项目规模和团队结构。

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

  • CMake必须知道依赖关系的位置 - 相对或绝对 - by
    • 有一个单一的源代码树(你不想要的那个)
      • 具有多个可执行文件的CMake共享库
      • CMake:如何设置源,库和CMakeLists.txt依赖?
    • 包含/ libraries /二进制文件的公共目录位置
      • CMake库输出的自定义目录
      • cmake install不在Windows上安装库
    • 通过配置文件/变量定义获取路径
      • 如何获取cmake以查找我的boost安装

        a>
      • 如何为CMake构建过程本身添加_custom_command()?
    • 在主机上提供
      • 使cmake库自动通过其他cmake包访问
      • cmake不会在ExternalProject_Add中正确运行build_command
  • 为了使您的CMake文件尽可能简单,我建议将您的CMake代码分成单独的专用文件:
    • 首选工具链文件 if(SomeCompiler)语句
    • 将共同/重复代码零件移动为
    • 将复杂的非目标特定代码零件移动到自己的(CMake)脚本文件中

    示例代码

    请求 find_package()变体,使用在CMake项目中使用CMake启用的库和上面列出的内容:

    MyCommonCode.cmake

    )文件( 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 b

    B / CMakeLists.txt

    include(MyCommonCode.cmake) find_package(C REQUIRED) ... target_link_libraries(BC) my_export_target(B$ {CMAKE_CURRENT_SOURCE_DIR} / include)

    A / CMakeLists.txt

    code> include(MyCommonCode.cmake) find_package(B REQUIRED) ... target_link_libraries(AB)

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

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

    • 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.

    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:

  • 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.
  • 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
  • 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.
  • 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.
  • All these three components are using google-test, but I'm not sure if it is important for the project layout.
  • 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.

    解决方案

    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:

  • CMake has to know the location of the dependencies - relative or absolute - by
    • having a monolithic source tree (the one you don't want anymore)
      • CMake share library with multiple executables
      • CMake: How to setup Source, Library and CMakeLists.txt dependencies?
    • a common directory location for includes/libraries/binaries
      • Custom Directory for CMake Library Output
      • cmake install not installing libraries on windows
    • getting the paths via config files/variable definitions
      • How can I get cmake to find my boost installation
      • How to add_custom_command() for the CMake build process itself?
    • using registration in or installation from a database provided on the host
      • Making cmake library accessible by other cmake packages automatically
      • cmake wont run build_command in ExternalProject_Add correctly
  • To keep your CMake files as simple as possible I would recommend to group your CMake code into separate dedicated files:
    • 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
  • 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)

    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项目结构

本文发布于:2023-11-02 14:18:53,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1552636.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:结构   项目   cmake

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!