首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么不在CMake中使用"include_directories“呢?

为什么不在CMake中使用"include_directories“呢?
EN

Stack Overflow用户
提问于 2021-12-27 10:48:50
回答 1查看 249关注 0票数 0

我读过和看过一些关于CMake的视频,每个人都建议不要使用include_directories,而应该使用target_include_directories。但我不明白这个建议背后的真正原因是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-27 12:16:08

有三个主要原因

  • 将包含目录的范围限制在需要它们的目标上--
  • 允许修改一个目标,而不需要更新其他项目的cmake逻辑
  • 允许更容易地重用项目作为大型项目

的一部分。

限制包含dirs的范围

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

subdir/CMakeLists.txt

代码语言:javascript
运行
复制
add_library(subdir_lib ...)
...

CMakeLists.txt

代码语言:javascript
运行
复制
add_subdirectory(subdir)
...
include_directories(some_include_dir)

vs

代码语言:javascript
运行
复制
include_directories(some_include_dir)
...
add_subdirectory(subdir)

两个CMakeLists.txt文件之间的区别可能很难看出,特别是当两个命令之间有大量的逻辑时;这使得这种逻辑很难维护。

重组的“遗传”/Ease

使用target_include_directories还可以更容易地提供将库与所需的包含dirs链接起来的目标。通过include_directories添加的目录不能自动链接目标,但是使用target_include_directories(... PUBLIC ...)很容易实现这一点。include_directories不会处理从包含命令的子目录中创建的目录中创建的目标。

示例项目

A

  • Library B
  • Library B需要库AB的公共标题不使用AB

档案系统:

代码语言:javascript
运行
复制
.
|---A
|   |---include
|   |      |---- A
|   |            |---- a.hpp
|   |
|   |--- a.cpp
|
|---B
|   |---include
|   |      |---- B
|   |            |---- b.hpp
|   |
|   |--- b.cpp
|
|---C
|   |---include
|   |      |---- C
|   |            |---- c.hpp
|   |
|   |--- c.cpp
|
|---CMakeLists.txt

现在您需要给B,而不是CA头的访问。使用target_link_libraries很简单,但是对于include_directories,您需要注意CMakeLists.txtadd_subdirectory的顺序

CMakeList.txt

代码语言:javascript
运行
复制
add_subdirectory(A)
add_subdirectory(B)
add_subdirectory(C)

A/CMakeLists.txt

代码语言:javascript
运行
复制
add_library(A ...)
target_include_directories(A PUBLIC include)

B/CMakeLists.txt

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
add_library(C ...)
target_include_directories(C PUBLIC include)

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

或者,假设您希望使用库BC作为更大项目的一部分:如果使用target_include_directories而不是include_directories,只需使用add_subdirectory添加包含toplevel CMakeLists.txt的目录,只需使用target_link_libraries(NewTarget PRIVATE B C)来访问所有必需的包含目录,而不是执行。

代码语言:javascript
运行
复制
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 ...)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70494485

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档