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

1 概述

本节目标:设置项目包含头文件路径, 关键语法target_include_directories

2 目标

  • main.cc 与 Typedef.h不在同一个目录下, Typedef.h 位于include目录下,main.cc位于src目录下
  • main.cc 使用TypeDef.h中定义的类型和函数

2.1 目录结构#

  • 目录结构
Copy Highlighter-hljs
. │ CMakeLists.txt │ ├─Common │ CommonOutput.cmake │ ├─include │ Typedef.h │ └─src main.cc

2.2 main.cc代码#

  • 使用头文件 Typedef.h 中的函数 engine_count 和 结构体stAir
Copy Highlighter-hljs
#include <iostream> #include <Typedef.h> /// 调用飞机属性 void call_air_demo() { // 结构体使用范例 cmake_demo::stAir aircraft(5678, std::string("B-0001")); // 输出 std::cout << "\nid=" << aircraft.id_ << ", name=" << aircraft.name_.c_str() << "\n"; // 函数使用范例 std::cout << "engine_count=" << cmake_demo::air_engine_count() << "\n"; } /// 程序入口 int main(int argc, char* argv[], char* env[]) { call_air_demo(); return 0; }

2.3 Typedef.h代码#

  • 定义函数engine_count 和 结构体 stAir
  • 上码:
Copy Highlighter-hljs
#ifndef TYPE_DEF_H_ #define TYPE_DEF_H_ #include <string> namespace cmake_demo { //---------------------------------------------------------------- // 飞机引擎数量 //---------------------------------------------------------------- int air_engine_count() { return 4; } ///---------------------------------------------------------------- /// 定义飞机属性 ///---------------------------------------------------------------- struct stAir_ { public: stAir_(const int & id, const std::string& newName) { id_ = id; name_ = newName; } public: /// 飞机ID int id_; /// 唯一飞机机号 std::string name_; }; using stAir = stAir_; } // namespace #endif /// ! TYPE_DEF_H_

3 编写CMake脚本

3.1 头文件加入项目#

  • 项目因为使用到了 typedef.h 文件, 所以, 也需要将其纳入项目中

3.2 指定项目搜索头文件路径 target_include_directories#

  • 主角: target_include_directories
  • 具体用法可参考官方文档。 这里仅仅演示自己够用的语法
  • target_include_directories使用时,需要指定 目标路径 以及 属性传递(这里,不展开,以后专门出一随笔说明) (属性传递有3个: PRIVATE, PUBLIC 和 INTERFACE)
  • target_include_directories 使用时, 一次调用,可以指定多个路径, 比如
Copy Highlighter-hljs
target_include_directories( ${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include # 路径1 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src # 路径2 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} # 路径3 )
  • 上面的代码也可以写成:
Copy Highlighter-hljs
target_include_directories( ${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include # 路径1 ${CMAKE_CURRENT_SOURCE_DIR}/src # 路径2, 少了关键字 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} # 路径3, 少了关键字 PRIVATE )
  • target_include_directories本文演示中的例子
Copy Highlighter-hljs
# 指定 ${PROJECT_NAME}, 也就是 HelloCMake 的头文件搜索路径 target_include_directories( ${PROJECT_NAME} # 参数1 项目名称 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include # 参数2, 指定哪个搜索头文件路径, 这里的PRIVATE是cmake内置系统关键字,这里不展开,后面专门出一期随笔说清楚 )

target_include_directories 作用#

target_include_directories 作用#

target_include_directories 作用#

  • target_include_directories 用于解决代码中使用 #include<头文件> ,编译器无法找到头文件的问题。它的作用就是告诉编译器,应该去哪个目录下搜索头文件
  • 本文范例中的例子,告诉编译器, 编译HelloCmake时, 应该去${CMAKE_CURRENT_SOURCE_DIR}/include目录下找 头文件Typedef.h

target_include_directories 使用顺序#

  • 使用 target_include_directories 需要创建项目后再使用,也就是位于 add_libraryadd_executable之后使用,否则不会生效。 因为target_include_directories的第一个参数需要指定目标。
Copy Highlighter-hljs
... add_library( 项目A ...) # add_executable(...) ... target_include_directories( 项目A ...)

3.3 CMakeLists.txt完整脚本#

Copy Highlighter-hljs
# 指定CMake脚本解析的最低版本, cmake_minimum_required(VERSION 3.18) # 指定项目 project(HelloCMake) # 引入脚本:参数为脚本文件的全路径 include(${CMAKE_CURRENT_SOURCE_DIR}/Common/CommonOutput.cmake) # 用于可执行程序 add_executable(${PROJECT_NAME} # 参数1: 要生成的项目名称,这里对应的是HelloCMake, 而HelloCMake就是projec中的参数 ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc # 参数2 : 项目所需的文件 ${CMAKE_CURRENT_SOURCE_DIR}/include/typedef.h # 参数3: 项目所需的文件 ) # 指定 ${PROJECT_NAME}, 也就是 HelloCMake 的头文件搜索路径 target_include_directories( ${PROJECT_NAME} # 参数1 项目名称 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include # 参数2, 指定哪个搜索头文件路径, 这里的PRIVATE是cmake内置系统关键字,这里不展开,后面专门出一期文章说清楚 )

5. 结果#

  • CMake Tools 编译, 使用VSCode命令面板 (ctrl+shift+p):
Copy Highlighter-hljs
>cmake:Build
  • 项目编译结果:
Copy Highlighter-hljs
[proc] Executing command: C:\major\development\tools\cmake_64\bin\cmake.exe --build c:/A/build --config Debug --target HelloCMake -j 14 -- [build] 用于 .NET FrameworkMicrosoft (R) 生成引擎版本 16.11.2+f32259642 [build] 版权所有(C) Microsoft Corporation。保留所有权利。 [build] [build] main.cc [build] C:\A\src\main.cc(1,1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 [C:\A\build\HelloCMake.vcxproj] [build] C:\A\include\Typedef.h(1,1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 [C:\A\build\HelloCMake.vcxproj] [build] HelloCMake.vcxproj -> C:\A\publish\x64\bin\debug64\HelloCMake.exe [build] Build finished with exit code 0

可见项目已经编译成功

6 去掉 target_include_directories 调用

6.1 CMakeLists.txt脚本修改#

  • 简单修改CMakeLists.txt中的脚本,注释 target_include_directories的调用
Copy Highlighter-hljs
# 指定CMake脚本解析的最低版本, cmake_minimum_required(VERSION 3.18) # 指定项目 project(HelloCMake) # 引入脚本:参数为脚本文件的全路径 include(${CMAKE_CURRENT_SOURCE_DIR}/Common/CommonOutput.cmake) # 用于可执行程序 add_executable(${PROJECT_NAME} # 参数1: 要生成的项目名称,这里对应的是HelloCMake, 而HelloCMake就是projec中的参数 ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc # 参数2 : 项目所需的文件 ${CMAKE_CURRENT_SOURCE_DIR}/include/typedef.h # 参数3: 项目所需的文件 ) # # 指定 ${PROJECT_NAME}, 也就是 HelloCMake 的头文件搜索路径 # target_include_directories( ${PROJECT_NAME} # 参数1 项目名称 # PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include # 参数2, 指定哪个搜索头文件路径, 这里的PRIVATE是cmake内置系统关键字,这里不展开,后面专门出一期文章说清楚 # )

VSCode编写CMake脚本中, 多行注释 与取消注释 快捷键: ctrl + /

6.2 项目编译结果#

  • 你瞧, 编译器报错提示,说找不到头文件
Copy Highlighter-hljs
[build] C:\A\src\main.cc(2,10): fatal error C1083: 无法打开包括文件: “Typedef.h”: No such file or directory [C:\A\build\HelloCMake.vcxproj]
  • 看图嘛, 一图胜千言。

7 总结

  • 这下,可以将头文件和源文件分类存放,使得代码文件结构有序。解决之前需要将所有文件放在一个目录下的问题了。

posted @   mohist  阅读(377)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示
CONTENTS