1 概述
- 本文基于前文环境
本节目标:target_include_directories 用法
2 作用
- target_include_directories 的作用, 用于给固定目标指定头文件搜索路径。
- modern cmake之前,与之对应的是 include_directories。include_directories也是用于设置头文件搜索路径。
- 它俩对比
名称 | 区别 |
---|---|
target_include_directories | 为指定的目标设置头文件搜索路径设置 |
include_directories | 为当前CMakeLists.txt中的项目设定头文件搜索路径设置 |
- 也就是说,CMakeLists.txt脚本中,可创建多个项目
- 当使用target_include_directories时,只能为某一个项目设置头文件设置
- 当使用include_directories时,当前脚本文件中的所有项目都会使用include_directories参数中的路径。 具有传递性(下面说)
3 一个例子说明
- 目录结构:
│ CMakeLists.txt
│
├─Common
│ CommonOutput.cmake
│
├─include
│ Typedef.h
│
└─src
main.cc
- 有这样一个 CMakeLists.txt 脚本文件, 当前脚本中创建了项目A、B和C, 而这三个项目中,main.cc 又需要 ${CMAKE_CURRENT_SOURCE_DIR}/include 目录下的头文件typedef.h
# 指定CMake脚本解析的最低版本,
cmake_minimum_required(VERSION 3.18)
# 指定项目
project(HelloCMake)
# 引入脚本:参数为脚本文件的全路径
include(${CMAKE_CURRENT_SOURCE_DIR}/Common/CommonOutput.cmake)
# -------------------------------------------
# 项目A
add_executable(ProjectA
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
${CMAKE_CURRENT_SOURCE_DIR}/include/typedef.h
)
# -------------------------------------------
# 项目B
add_executable(ProjectB
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
${CMAKE_CURRENT_SOURCE_DIR}/include/typedef.h
# -------------------------------------------
# 项目C
add_executable(ProjectC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
${CMAKE_CURRENT_SOURCE_DIR}/include/typedef.h
)
上面这段脚本构建没有问题。不过项目编译却无法通过编译, 因为没有指定typedef.h文件的搜索路径。
3.1 如果通过项目编译?
- 设置项目的头文件搜索路径, 下面是解决方法
3.2 使用include_directories
- include_directories用法简单,括号内写路径即可。
- 创建项目A之前,增加下一脚本
# 参数为: 当前脚本目录/include目录所在绝对路径
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
- 此时,CMakeLists.txt完整脚本为
# 指定CMake脚本解析的最低版本,
cmake_minimum_required(VERSION 3.18)
# 指定项目
project(HelloCMake)
# 引入脚本:参数为脚本文件的全路径
include(${CMAKE_CURRENT_SOURCE_DIR}/Common/CommonOutput.cmake)
# 参数为: 当前脚本目录/include目录所在绝对路径
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
# -------------------------------------------
# 项目A
add_executable(ProjectA
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
${CMAKE_CURRENT_SOURCE_DIR}/include/typedef.h
)
# -------------------------------------------
# 项目B
add_executable(ProjectB
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
${CMAKE_CURRENT_SOURCE_DIR}/include/typedef.h
)
# -------------------------------------------
# 项目C
add_executable(ProjectC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
${CMAKE_CURRENT_SOURCE_DIR}/include/typedef.h
)
- 执行项目编译, 可见编译结果为通过:
[build] ProjectC.vcxproj -> C:\A\publish\x64\bin\debug64\ProjectC.exe
[build] ProjectB.vcxproj -> C:\A\publish\x64\bin\debug64\ProjectB.exe
[build] ProjectA.vcxproj -> C:\A\publish\x64\bin\debug64\ProjectA.exe
3.3 使用target_include_directories
- 需要为 每个 项目设置头文件搜寻路径设置
# 为每个项目指定头文件搜索路径
target_include_directories( ProjectA PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_include_directories( ProjectB PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_include_directories( ProjectC PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
- 此时完整CmakeLists.txt脚本
# 指定CMake脚本解析的最低版本,
cmake_minimum_required(VERSION 3.18)
# 指定项目
project(HelloCMake)
# 引入脚本:参数为脚本文件的全路径
include(${CMAKE_CURRENT_SOURCE_DIR}/Common/CommonOutput.cmake)
# -------------------------------------------
# 项目A
add_executable(ProjectA
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
${CMAKE_CURRENT_SOURCE_DIR}/include/typedef.h
)
# -------------------------------------------
# 项目B
add_executable(ProjectB
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
${CMAKE_CURRENT_SOURCE_DIR}/include/typedef.h
)
# -------------------------------------------
# 项目C
add_executable(ProjectC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
${CMAKE_CURRENT_SOURCE_DIR}/include/typedef.h
)
# 为每个项目指定头文件搜索路径
target_include_directories( ProjectA PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_include_directories( ProjectB PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_include_directories( ProjectC PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
- 编译项目,通过。
[build] ProjectB.vcxproj -> C:\A\publish\x64\bin\debug64\ProjectB.exe
[build] ProjectA.vcxproj -> C:\A\publish\x64\bin\debug64\ProjectA.exe
[build] ProjectC.vcxproj -> C:\A\publish\x64\bin\debug64\ProjectC.exe
5 使用注意
- 如果你的CMakeLists.txt脚本中只有单个项目, 那么, target_include_directories 和 include_directories的效果是一样的
- 如果CMakeLists.txt脚本中存在多个项目,建议使用target_include_directories,避免 某些项目引用到其他用不到的目录而引发的问题。
- Modern CMake中 支持 target_include_directories 用法。
- 简明扼要
- include_directories: 1 VS 多
- target_include_directories: 1 VS 1
5.1 include_directories具有传递性
- 什么意思呢? include_directories 为会 子目录中的项目增加头文件路径的设置。
- 还是上面的那个目录结构,此时多了一个文件夹demo, demo目录下也有一个CMakeLists.txt脚本,demo目录下CMakeLists.txt脚本中创建了一个名为 ProjectDemo的项目。
- 目录
.
│ CMakeLists.txt
│
├─Common
│ CommonOutput.cmake
│
├─demo
│ CMakeLists.txt
│ main.cc
│
├─include
│ Typedef.h
│
└─src
main.cc
- 其中,demo目录下CMake脚本内容仅仅为
cmake_minimum_required(VERSION 3.18)
# 指定项目
project(ProjectDemo)
# -------------------------------------------
# 项目A
add_executable(ProjectDemo
${CMAKE_CURRENT_SOURCE_DIR}/main.cc
)
- 而demo目录下的main.cc中的代码 没有 引用 顶层目录/include 目录下的任何文件
#include <iostream>
int main(int argc, char*argv[])
{
std::cout << "hello" << std::endl;
return 0;
}
- 回到顶层的CMakeLists.txt中,代码略微的不一样, 增加 add_subdirectory(demo) 用于创建子项目。
# 指定CMake脚本解析的最低版本,
cmake_minimum_required(VERSION 3.18)
# 指定项目
project(HelloCMake)
# 引入脚本:参数为脚本文件的全路径
include(${CMAKE_CURRENT_SOURCE_DIR}/Common/CommonOutput.cmake)
# 引入头文件
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
# -------------------------------------------
# 项目A
add_executable(ProjectA
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
${CMAKE_CURRENT_SOURCE_DIR}/include/typedef.h
)
# 子项目 Demo
add_subdirectory(demo)
请允许我再总结下: ProjectDemo没有引用 typedef.h文件。 ProjectA项目引用了 Typedef.h文件。 typedef.h位于顶层CMakeLists.txt文件所在目录/include目录下
- 5.2 构建, 查看传递性
- 构建 [5.1] 中的脚本,使用VS2019打开,查看 ProjectDemo项目属性:
- ProjectDemo 明明没有引用,而项目设置中却出现了 对目录的引用设置。
- 这就是 include_directories 的传递性。使用需要注意
6 target_include_directories 使用
- target_include_directories 的作用是为具体的目标设置 INCLUDE_DIRECTORIES 和 INTERFACE_INCLUDE_DIRECTORIES 属性。
- PRIVATE 和 PUBLIC 关键字是用来设定目标的 INCLUDE_DIRECTORIES属性
- INTERFACE 和 PUBLIC 关键字是用来设定目标的 INTERFACE_INCLUDE_DIRECTORIES属性
- 区别:
- PRIVATE: 仅当前目标使用,不会将 PRIVATE后 紧跟的参数进行传递
- PUBLIC: PUBLIC 后面紧跟的参数, 自己使用外, 也传递给给别人使用
- INTERFACE: INTERFACE 后面紧跟的参数,自己不用,传递给别人使用
这三个关键字都是用来限定 其后紧跟的参数的范围。 可见: PUBLIC 就是 PRIVATE 和 INTERFACE 两者的结合 。
7 我的使用经验
- 模块或者项目内,尽量使用 PRIVATE 达到范围使用最小化原则,避免一些不必要的麻烦。
原文地址:http://www.cnblogs.com/pandamohist/p/16920528.html
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请务用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性