【问题标题】:CMAKE for modular c++ framework用于模块化 C++ 框架的 CMAKE
【发布时间】:2012-03-29 02:47:06
【问题描述】:

我正在重构一个独立于平台的大型 c++ 框架,这样它的库和可执行文件就不必再位于同一目录(甚至存储库)中,这被证明是相当具有挑战性的。该框架目前仅由我使用,它现在应该适用于我们整个工作组,因此我必须使其尽可能模块化和自动化。

我的基本结构是这样的

  • 应用程序/
    • app1,app2,...
  • 库/
    • 核心、lib1、lib2、...
  • 斌:
    • app1、app2、libcore、liblib1、liblib2、...(在 NIX 上)
    • app1.exe、app2.exe、core.dll、lib1.dll、lib2.dll、...(在 Windows 上)

应用程序依赖于libs,所有的libs都依赖于core lib。这一切都可以在同一个根目录和 add_subdirectory 机制中正常工作。

项目依赖项按我调用 add_subdirectory 的顺序处理:首先是 libs(核心是第一个),然后是 apps。 Cmake 非常友好地将 ${core_SOURCE_IR} 设置为相应的目录,并且所有二进制文件(库和应用程序)都在同一目录中生成。

我需要的建议是:

  • 我是否应该转向基于 find_package 的方法(为每个 lib 和 FindLib.cmake 文件编写)
  • appslibs 如何找到彼此
  • 存放二进制文件的位置
  • 如何传递依赖目标的包含目录
  • ExternalProject_Add ?

谢谢

【问题讨论】:

    标签: c++ cross-platform build-process cmake modularity


    【解决方案1】:

    我建议同时使用INSTALL(TARGETS...INSTALL(EXPORT...

    有关详细信息,请运行:

    cmake --help-command INSTALL
    

    FIND_PACKAGE 通常用于查找已安装的外部项目(并且未使用 CMake 的 INSTALL(EXPORT... 命令安装),ExternalProject_Add 用于下载、配置、构建和安装外部项目。

    如果您将 INSTALL(EXPORT... 与您的每个库和 exe 一起使用,然后只在您的主 CMakeLists.txt 中使用 INCLUDE 安装的 <target>.cmake,这些将成为适当的 CMake 目标,每个配置的依赖项已经设置。

    至于在哪里安装这些导出文件 - 这取决于您,但只要您指定的路径与您稍后 INCLUDE 文件时使用的相同位置,它应该可以正常工作。

    【讨论】:

    • +1 用于安装导出。起初,这背后的机制可能看起来非常复杂,但我发现它确实是让像这样的模块化构建工作而无需用户一直手动修改库路径的唯一方法。
    • 感谢您的建议。我阅读了 INSTALL 命令的描述,我同意 ComicSansMS,它有点令人生畏并且很有希望。您是否知道任何在线示例或一些良好实践指南?
    • 感谢您的教程。由于此库将被其他人使用,因此很难确保 INSTALL path 会受到尊重。我选择构建静态库并在MylibConfig.cmake 文件中标记它们的路径。在 Ubuntu 和 Mac 上使用了一个多星期,效果很好。如果事情变得更复杂,我会记住安装;)再次感谢
    • 事情确实变得更复杂了,现在我开始使用 INSTALL 来安装我的包含文件、库和执行程序,以及 MYLibConfig.cmake。我还想出了如何在 linux 和 osx 上管理INSTALL path。尽管我在如何导出项目配置以便其他项目可以找到它(通过find_package)方面遇到了困难。这是使用INSTALL的正确方法吗?
    【解决方案2】:

    首先,您可以按任意顺序add_subdirectory()es,而无需关心依赖关系。 CMake 在解析所有 CMakeLists.txt 时处理它们。

    其次,如果您希望您的任何库或应用程序可以独立构建,您当然应该使用find_package() 之类的东西。对于简单的情况,可以是find_library()find_file(lib.h)

    在这种情况下,在find_package() 调用之后,您将定义 LIB_INCLUDE_DIRS、LIB_LIBRARY_DIRS、LIB_LIBRARIES 变量,它们可以分别传递给 include_directories()link_directories()target_link_libraries()。这就是应用程序查找库的方式。

    至于将二进制文件放在哪里 - 在 *NIX 中,将它们放入 ${CMAKE_INSTALL_PREFIX}/bin 是一种广泛的做法。

    如果您有不清楚的地方,请对此答案发表评论。

    【讨论】:

    • 感谢您的建议,我对 find_package() 最大的担忧是如何在所有其他项目中同步所有 Find[MYPROJECT].cmake 文件。由于我有一个 core 库,因此 Findcore.cmake 应该被复制(或以某种方式可用)到依赖它的所有项目中。即使复制 Find***.cmake 文件,我也会对其进行测试,看看它如何根据我的要求进行扩展。
    • 不,它不应该被复制。您应该定义 CMAKE_PREFIX_PATH 指向您的库安装位置(或 CMAKE_MODULE_PATH 在 Find*.cmake 文件的情况下)。另外,您可以创建YourLibConfig.cmake 而不是FindYourLib.cmake,它似乎更适合您的需求,请参阅此链接:vtk.org/Wiki/CMake/Tutorials/…
    • 这很酷。我更新了我所有的库以拥有MylibConfig.cmake 文件,现在我可以通过在调用find_package( Mylib ) 之前设置Mylib_DIR 很容易地找到它们:)
    猜你喜欢
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 2018-03-13
    相关资源
    最近更新 更多