【问题标题】:Why not use "include_directories" in CMake?为什么不在 CMake 中使用“include_directories”?
【发布时间】:2021-12-27 10:48:50
【问题描述】:

我已经阅读和观看了一些关于 CMake 的视频,大家建议不要使用include_directories,而是使用target_include_directories。但我不明白这个建议背后的真正原因是什么?

【问题讨论】:

    标签: cmake


    【解决方案1】:

    有3个主要原因

    • 将包含目录的范围限制为仅需要它们的目标
    • 允许修改一个目标,而无需更新其他项目的 cmake 逻辑
    • 允许将项目作为更大项目的一部分更轻松地重用

    限制包含目录的范围

    目标是将包含目录的可见性降至最低。如果在执行include_directories 之后使用add_subdirectory,则从子目录或子目录的后代创建的所有目标都可以看到使用include_directories 添加的包含目录。

    subdir/CMakeLists.txt

    add_library(subdir_lib ...)
    ...
    

    CMakeLists.txt

    add_subdirectory(subdir)
    ...
    include_directories(some_include_dir)
    

    include_directories(some_include_dir)
    ...
    add_subdirectory(subdir)
    

    这两个CMakeLists.txt 文件之间的区别可能很难看出,尤其是如果这两个命令之间有很多逻辑;这使得这种逻辑难以维护。

    “继承”/重组容易

    使用target_include_directories 还可以更轻松地提供将库与所需的包含目录链接的目标。通过include_directories 添加的包含目录不能用于自动链接目标,但使用target_include_directories(... PUBLIC ...) 这很容易实现。 include_directories 不适用于从不在包含该命令的子目录中创建的目录创建的目标。

    示例项目

    • A
    • B 需要库AB 的公共标头使用公共包括来自 A
    • C 不使用AB

    文件系统:

    .
    |---A
    |   |---include
    |   |      |---- A
    |   |            |---- a.hpp
    |   |
    |   |--- a.cpp
    |
    |---B
    |   |---include
    |   |      |---- B
    |   |            |---- b.hpp
    |   |
    |   |--- b.cpp
    |
    |---C
    |   |---include
    |   |      |---- C
    |   |            |---- c.hpp
    |   |
    |   |--- c.cpp
    |
    |---CMakeLists.txt
    

    现在您需要授予B,而不是C 访问A 的标头。使用target_link_libraries 这很简单,但是使用include_directories 你需要注意add_subdirectorys 在CMakeLists.txt 中的顺序

    CMakeList.txt

    add_subdirectory(A)
    add_subdirectory(B)
    add_subdirectory(C)
    

    A/CMakeLists.txt

    add_library(A ...)
    target_include_directories(A PUBLIC include)
    

    B/CMakeLists.txt

    add_library(B ...)
    target_include_directories(B PUBLIC include)
    target_link_libraries(B PUBLIC A) # quite simple to provide access to A's include dir to linking libs using PUBLIC here, if required
    

    C/CMakeLists.txt

    add_library(C ...)
    target_include_directories(C PUBLIC include)
    

    现在假设您要将目录A 重命名为AB。您需要做的就是重命名文件系统上的目录并将CMakeLists.txt 中的add_subdirectory(A) 替换为add_subdirectory(AB)

    或者假设您想将库BC 用作更大项目的一部分:如果您使用target_include_directories 而不是include_directories,您需要做的就是添加包含顶级@ 的目录987654361@ 使用 add_subdirectory 并且您需要做的就是使用 target_link_libraries(NewTarget PRIVATE B C) 来访问所有必需的包含目录,而不是这样做

    add_subdirectory(OriginalProject)
    
    include_directories(OriginalProject/B/include)
    include_directories(OriginalProject/C/include)
    include_directories(OriginalProject/A/include) # did you remember this one is needed by B?
    
    add_executable(NewTarget ...)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-05
      • 2011-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多