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

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

时间:2022-11-20 11:56:32浏览次数:58  
标签:11 cmake target windows directories SOURCE CMAKE include DIR

1 概述

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

2 目标

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

2.1 目录结构

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

2.2 main.cc代码

  • 使用头文件 Typedef.h 中的函数 engine_count 和 结构体stAir
#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
  • 上码:
#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 使用时, 一次调用,可以指定多个路径, 比如
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
)
  • 上面的代码也可以写成:
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本文演示中的例子
# 指定 ${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的第一个参数需要指定目标。
...
add_library( 项目A ...) # add_executable(...)
...
target_include_directories( 项目A ...)

3.3 CMakeLists.txt完整脚本

# 指定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):
>cmake:Build
  • 项目编译结果:
[proc] Executing command: C:\major\development\tools\cmake_64\bin\cmake.exe --build c:/A/build --config Debug --target HelloCMake -j 14 --
[build] 用于 .NET Framework 的 Microsoft (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的调用
# 指定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 项目编译结果

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

7 总结

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

标签:11,cmake,target,windows,directories,SOURCE,CMAKE,include,DIR
From: https://www.cnblogs.com/pandamohist/p/16908142.html

相关文章

  • SRTP_Log_20221120
    WorkingContent:1.原来的思路和当前的思路如下:把两个参数的噪声当成另外两个参数,现在神经网络就有了四个输出,由于我们noise一般较小,我们需要使用regularization的方法......
  • Windows11 Docker镜像存储路径更改(非C盘路径)
    https://blog.csdn.net/Ber_Bai/article/details/120816638?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~aggregatepage~first_rank_ecpm_v1~rank_v......
  • flower in 11.20 感言:果然还是手写比较适宜
    我推开门。我期望着我能看到什么?期望什么并不重要。但我确实看到了她吊死的尸体。小小的惊异。我觉得是不是我的打开方式不太对。所以我关上门。倒数五秒,我又打开门。没......
  • 【日总结】2022.11.20
    持续更新做了多少东西就放多少东西)次小质因子前缀和【UR#13】Sanrd设\(f(x)\)为\(x\)的次大质因子,若\(x\)为质数或\(1\)则\(f(x)=0\),求\(f(x)\)的前缀和。......
  • Avalonia UI 升级至 11.0 注意事项 Q&A
    Q1:更改V11后无法编译,显示FluentTheme不存在当前AvaloniaUIV11.0仍处于预览阶段,因此VisualStudio和Rider插件中的默认模板仍然没有更新。如果通过默认模板创建项目并......
  • 感悟-20221119
    生活中总有一盏灯照亮前行的路;总有一些品质让内心满怀憧憬;总有一些信仰让灵魂有栖息之所。人生最好的风景,竟是内心的淡定与从容。 ......
  • 从 Windows 过度到 Mac 必备快捷键对照表
    从Windows过度到Mac必备快捷键对照表Mac键盘符号说明⌘==Command⇧==Shift⇪==CapsLock⌥==Option⌃==Control↩==Return/Enter⌫==Delete......
  • 2022-11-19学习内容-Server端代码编写-Client端代码编写
    1.Server端代码编写1.1UserDBHelper.javapackagecom.example.chapter07_server.database;importandroid.content.Context;importandroid.database.sqlite.SQLiteD......
  • Windows之应用安装程序 —— winget
    大家都用过Linux中的应用程序安装工具,如yum、apt、rpm等工具进行安装自己想要的一些工具或则软件之类的,当然Linux操作系统还是很强大的有很多类似的命令来安装我们所需......
  • 11.19小记
    上午参加洛谷模拟赛,想了3hT1仍不会正解,想着打个暴力拿80,没想到数组开小只有60,开大之后就100了下午参加端点星,T1一眼,T2写了个nklog,没开O2只有30,T3少看条件认为不可做就溜去......