首页 > 系统相关 >windows--cmake与c++的使用教程(14)

windows--cmake与c++的使用教程(14)

时间:2022-11-23 23:33:34浏览次数:74  
标签:cmake 14 windows directories CURRENT SOURCE CMAKE include DIR

1 概述

本节目标:target_include_directories 用法

2 作用

  • target_include_directories 的作用, 用于给固定目标指定头文件搜索路径。
  • modern cmake之前,与之对应的是 include_directoriesinclude_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_directoriesinclude_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_DIRECTORIESINTERFACE_INCLUDE_DIRECTORIES 属性。
  • PRIVATEPUBLIC 关键字是用来设定目标的 INCLUDE_DIRECTORIES属性
  • INTERFACEPUBLIC 关键字是用来设定目标的 INTERFACE_INCLUDE_DIRECTORIES属性
  • 区别:
    • PRIVATE: 仅当前目标使用,不会将 PRIVATE后 紧跟的参数进行传递
    • PUBLIC: PUBLIC 后面紧跟的参数, 自己使用外, 也传递给给别人使用
    • INTERFACE: INTERFACE 后面紧跟的参数,自己不用,传递给别人使用

这三个关键字都是用来限定 其后紧跟的参数的范围。 可见: PUBLIC 就是 PRIVATE 和 INTERFACE 两者的结合 。

7 我的使用经验

  • 模块或者项目内,尽量使用 PRIVATE 达到范围使用最小化原则,避免一些不必要的麻烦。

标签:cmake,14,windows,directories,CURRENT,SOURCE,CMAKE,include,DIR
From: https://www.cnblogs.com/pandamohist/p/16920528.html

相关文章

  • 题解 LGP7914【[CSP-S 2021] 括号序列】
    solution最终括号串形如:(***(...)(...)***(...)),或者((...)(...)***(...)***),或者((...)(...)***(...)),就是说中间可有可无,两边只留一个。令\(st_{l,r}\)表示\([l,r......
  • windows11专业版控制面板如何打开的方法
    有深度技术的用户,在使用win11系统的时候,发现找不到控制面板了。其实,控制面板是windows系统中非常重要的部分,允许用户查看并更改基本的系统设置,比如添加/删除软件,除了通过桌......
  • S1 - Lesson 13 -14
    colorcolour Whatcolor?Whatcolorisit?Whatcolorisyourcar? Whatmake/time/nationalityWhatnationalityareyou? greengreenteaagreenhand.......
  • Windows系统DOS命令详解
    一、DOS的历史DOS(DiskOperatingSystem),磁盘操作系统1980年,西雅图程序员蒂姆-帕特森,86-DOS1981年由微软公司购买并改进,更名为MS-DOS微软为IBM开发的PC-DOS,19......
  • 题解 LGP4211【[LNOI2014]LCA】
    problem一棵树,多次给定\(l,r,z\)询问\(\sum_{l\leqi\leqr}dep_{lca(i,z)}\),允许离线,\(n\leq50000\)。solution转换:这个\(dep_u\)的定义为\(u\)到根节点的点数......
  • 添加扩展 Windows 的资源管理器中预览 SVG
    在Windows的资源管理器中预览SVG图标的扩展打开链接https://github.com/maphew/svg-explorer-extension/releases,下载一个适合你电脑的版本。清空缓存打开cmd窗......
  • Luogu P1453 城市环路(基环树DP)
    法一:dsu#include<bits/stdc++.h>usingll=longlong;usingnamespacestd;constintN=100010;structnode{intv,nxt;}e[N......
  • windows 用其它用户运行程序
    在配置金碟k3客户端时,碰到个问题,如果启用域很好处理,否则要保存客户端电脑和服务器上有相当用户且密码要一致,客户端只能用这个用户登陆并启动客户端。这样用起来很不方便,服务......
  • 解决问题 1474 个,Flink 1.11 究竟有哪些易用性上的改善?
    7月7日,​​Flink1.11.0正式发布了​​,作为这个版本的releasemanager之一,我想跟大家分享一下其中的经历感受以及一些代表性feature的解读。在进入深度解读前,我们先简......
  • Windows 下 ElasticSearch8.5.1下载安装及使用
    ElasticSearch下载安装及使用前言Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式的全文搜索引擎,基于restfulweb接口。Elasticsearch是用Java语言开发......