VS Code使用 CMake 或 Makefile管理C++多文件编译

VS Code使用 CMake 或 Makefile管理C++多文件编译

  • 一、Cmake方式
    • 1、文件结构
    • 2、构建项目
  • 二、Makefile方式
    • 1、文件结构
    • 2、Makefile
    • 3、构建项目
  • 三、附件
    • 示例中使用到的文件及代码

使用 CMake 或 Makefile 是更加标准和灵活的方法来管理多文件编译。以下是一个简单的示例,展示了如何使用 CMake 来构建包含多个源文件的 C++ 项目。
【注】在我测试C++静态全局对象初始化的过程中,由于使用g++后面跟需要编译的文件名太过于麻烦,特整理下CMake的管理多文件编译的方法。(静态全局对象初始化顺序是未定义,测试的过程中发现和g++后面的文件间顺序有关,CMake也是一样的,感兴趣的可以自己测测,我使用的linux + VS Code + Cmake, windows的可以自己配置环境,windows + VS Code + mingw + CMame)

一、Cmake方式

1、文件结构

假设我们有以下文件结构:

project_folder
│ CMakeLists.txt
│ main.cpp
│ common.h
│ file.cpp
│ file1.cpp
│ file2.cpp

CMakeLists.txt

cmake_minimum_required(VERSION 3.0)
project(MyProject)# 添加可执行文件, 下面的文件顺序会导致我定义的全局静态变量的初始化顺序也不一致
add_executable(myProgram mian.cpp file.cpp file2.cpp file1.cpp  common.h)

2、构建项目

安装 CMake(如果尚未安装)。
在项目文件夹中创建一个名为 build 的子文件夹,用于构建项目。
在 build 文件夹中打开终端,运行以下命令:

cmake …

这将根据 CMakeLists.txt 创建构建文件。
运行以下命令进行编译:

make

这将使用构建文件编译项目,并生成名为 myProgram 的可执行文件。

这些命令将在终端中执行。一旦编译完成,你可以在终端中运行 ./myProgram 来执行你的程序。
使用 CMake 有助于管理更复杂的项目结构,并能够轻松添加其他依赖项、调整编译选项以及添加测试等功能。 Makefile 也是一种相似的方法,它可以用于管理代码的编译和链接过程

二、Makefile方式

下面是一个简单的 Makefile 示例,用于构建包含多个源文件的 C++ 项目。在这个示例中,我们有 main.cpp、 file.cpp、file2.cpp、file1.cpp 四个源文件和一个common.h头文件。我们将使用 Makefile 来编译这些源文件并生成可执行文件。

1、文件结构

假设我们有以下文件结构:

project_folder
│ Makefile
│ main.cpp
│ common.h
│ file.cpp
│ file1.cpp
│ file2.cpp

2、Makefile

把下面内容写到文件结构中的Makefile文件中。(在 Makefile 中,通常不需要显式引入头文件(.h 文件),我在这里引入头文件)

我们创建了一个名为 HEADERS 的变量来存储头文件的名称。然后,我们在生成目标文件的规则中使用 $(HEADERS) 来指示每个 .o 目标都依赖于指定的头文件。这样可以确保在每次头文件发生变化时,相关的源文件将被重新编译。
这种方法使得 Makefile 更加清晰和易于维护,因为头文件的依赖关系被单独定义在一个地方,便于统一管理。

# Makefile
# 编译器
CXX = g++
# 编译选项
CXXFLAGS = -std=c++11 -Wall# 目标文件
TARGET = myProgram
# 源文件
SRCS = main.cpp file.cpp file2.cpp file1.cpp# 目标文件
OBJS = $(SRCS:.cpp=.o)# 头文件
HEADERS = common.h# 默认目标
all: $(TARGET)# 生成可执行文件
$(TARGET): $(OBJS)$(CXX) $(CXXFLAGS) -o $@ $^# 生成目标文件
%.o: %.cpp $(HEADERS)$(CXX) $(CXXFLAGS) -c $<# 清理生成的文件
clean:rm -f $(OBJS) $(TARGET)

3、构建项目

在项目文件夹中打开终端,运行以下命令:
运行 make 来编译项目并生成可执行文件。(在Makefile的同级目录下执行下面命令)

make

然后运行 ./myProgram 来执行你的程序。

./myProgram

通过这种方式,Makefile 负责管理源文件的编译、链接和生成可执行文件的过程。你可以根据需要对 Makefile 进行调整,以满足项目的具体需求。

三、附件

大体内容就这些,下面是我测试时的示例代码。如有疑问,欢迎一起讨论。

示例中使用到的文件及代码

// main.cpp
#include"common.h"int main()
{std::cout << "hello world." << std::endl;test_classA();test_classB();test_classC();return 0;}
// common.h
#include<iostream>
class classA;
class classB;
class classC;void test_classA();
void test_classB();
void test_classC();
// file.cpp
#include"common.h"#include"common.h"class classC
{
private:int x;
public:classC(/* args */);~classC();void print() {std::cout << __FUNCTION__ << "(), " << __FILE__<< ", x = " << x << std::endl;  }
};classC::classC(/* args */)
{std::cout << __FUNCTION__ << "(), " __FILE__ << std::endl;  
}classC::~classC()
{std::cout << __FUNCTION__ << "(), " __FILE__ << std::endl;  
}static classC objC;
void test_classC()
{objC.print();
}
// file1.cpp
#include"common.h"class classA
{
private:int x;
public:classA(/* args */);~classA();void print() {std::cout << __FUNCTION__ << "(), " << __FILE__<< ", x = " << x << std::endl;  }
};classA::classA(/* args */)
{std::cout << __FUNCTION__ << "(), " __FILE__ << std::endl;  
}classA::~classA()
{std::cout << __FUNCTION__ << "(), " __FILE__ << std::endl;  
}static classA objA;
void test_classA()
{objA.print();
}
// file2.cpp
#include"common.h"class classB
{
private:int m;
public:classB(/* args */);~classB();void print() {std::cout << __FUNCTION__ << "(), " << __FILE__<< ", m = " << m << std::endl;  }
};classB::classB(/* args */)
{std::cout << __FUNCTION__ << "(), " __FILE__ << std::endl;  
}classB::~classB()
{std::cout << __FUNCTION__ << "(), " __FILE__ << std::endl;  
}static classB objB;
void test_classB()
{objB.print();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/214337.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

80个常用shell命令及简单用法

Shell命令是Linux和Unix系统中的基础&#xff0c;用于完成各种操作&#xff0c;如文件管理、程序执行、文本处理等。下面列举一些常用的Shell命令&#xff0c;并详细解释它们的功能及应用场景&#xff1a; ls - 列出目录内容 功能&#xff1a;列出指定目录中的文件和目录。应用…

智能优化算法应用:基于郊狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于郊狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于郊狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.郊狼算法4.实验参数设定5.算法结果6.参考文献7.MA…

Mybatis增删改查基础

MyBatis可根据查询的结果类型、查询条件的不同进行统一处理。 1 查询数据 1.1 根据查询数据条数来分析不同的情况 1.1.1 查询单条数据 可以通过实体类、list集合、map等处理查询结果。 通过实体类查询单条数据 User queryUserById(Param("id") Integer id);<…

C、C++、C#的区别概述

C、C、C#的区别概述 https://link.zhihu.com/?targethttps%3A//csharp-station.com/understanding-the-differences-between-c-c-and-c/文章翻译源于此链接 01、C语言 ​ Dennis Ritchie在1972年创造了C语言并在1978年公布。Ritchie设计C的初衷是用于开发新版本的Unix。在那之…

express框架使用

一、express介绍 express 是一个基于 Node.js 平台的极简、灵活的 WEB 应用开发框架&#xff0c;简单来说&#xff0c;express 是一个封装好的工具包&#xff0c;封装了很多功能&#xff0c;便于我们开发 WEB 应用&#xff08;HTTP 服务&#xff09; 二、express 使用 2.1 e…

【组合数学】递推关系

目录 1. 递推关系建立2. 常系数齐次递推关系的求解3. 常系数非齐次递推关系的求解4. 迭代法 1. 递推关系建立 给定一个数的序列 f ( 0 ) , f ( 1 ) , . . . , f ( n ) , . . . , f (0), f(1), ..., f(n ),... , f(0),f(1),...,f(n),..., 若存在整数 n 0 n_0 n0​ &#xff…

datav-实现轮播表,使用updateRows方法-无缝衔接加载数据

前言 最近在做大屏需求的时候&#xff0c;遇到一个轮播数据的需求&#xff0c;查看datav文档发现确实有这个组件 但这个组件只提供了一次加载轮播的例子&#xff0c;虽然提供了轮播加载数据updateRows方法 但是文档并没有触发事件&#xff0c;比如轮播完数据触发事件&#xf…

ESL电子标签的真相:电子墨水屏没墨水?

一说到电子墨水屏 你大概率会想到Kindle 如果你问是不是墨水做的 那这篇文章你就得好好看看了 在我们日常与客户的沟通中 为数不多却出乎意料地有好几个以下对话↓ 在此辟谣 电子墨水屏里确实 没 有 墨 水 那它是什么样的原理&#xff1f;为什么越来越多显示设备采用&…

Abp vNext在Docker部署并导出镜像

Docker介绍 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中&#xff0c;然后发布到任何流行的 Linux或Windows操作系统的机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不会有任何…

深度剖析中国居民消费价格指数CPI数据可视化案例-Python可视化技术实现(附完整源码)【数据可视化项目案例-16】

🎉🎊🎉 你的技术旅程将在这里启航! 🚀🚀 本专栏包括所有的可视化技术学习,感兴趣可以到本专栏页面,查阅可视化宝典可快速了解本专栏。订阅专栏用户可以在每篇文章底部下载对应案例源码以供大家深入的学习研究。 🎓 每一个案例都会提供完整代码和详细的讲解,不论…

Win11在Virtualbox上安装ubuntu操作系统

注&#xff1a;原创笔记&#xff0c;以下图片水印为本人 相关工具展示 第四个&#xff1a;ubuntu的vmdk文件&#xff0c;用于配置虚拟机 第5/6个&#xff1a;virtualbox安装包 一、安装 VirtualBox 由于win11版本问题&#xff0c;如果装不了 virtualBox需要在官网安装最新版…

新零售模式:跨境电商如何实现线上线下融合?

随着数字时代的发展&#xff0c;新零售模式逐渐崭露头角&#xff0c;成为跨境电商发展的重要趋势。线上线下融合不仅拓宽了销售渠道&#xff0c;更提供了更丰富、更便捷的购物体验。 本文将深入探讨新零售模式在跨境电商中的应用&#xff0c;以及如何实现线上线下融合&#xf…

前后端请求之nginx配置

问题&#xff1a; 前端发送的请求&#xff0c;是如何请求到后端服务器的&#xff1f; 如&#xff0c;前端请求地址&#xff1a;http://loclhost/api/employee/login&#xff1a; 后端相应请求地址&#xff1a;http://loclhost:8080/admin/employee/login 回答&#xff1a; …

使用MfgTool烧写前需准备的文件

一. 简介 本文我们就来学习&#xff0c;如何将我们编译的 uboot&#xff0c;zImage&#xff08;内核镜像&#xff09;&#xff0c;xxx.dtb设备树文件&#xff0c;还有制作的根文件系统&#xff0c;这四个文件烧写到开发板中&#xff0c;最后 开发板能正常启动。 本文这里使用…

【日志技术】附Logback入门教程

文章目录 日志概论日志的体系Logback快速入门日志配置文件配置日志级别 日志概论 什么是日志&#xff1f;其实可以通过下面几个问题来了解的。 系统系统能记住某些数据被谁操作&#xff0c;比如被谁删除了&#xff1f;想分析用户浏览系统的具体情况&#xff0c;比如挖掘用户的…

一个简单的Python自动化测试 logging 日志模块,为何会难住一个工作6年的测试?

写Python程序的时候&#xff0c; 我们经常需要写日志&#xff0c; 以便调试程序&#xff0c;发现问题&#xff0c;以及查看程序的运行状态。 Python自带了logging模块&#xff0c;可以将日志保存到.txt文件中&#xff0c; 也可以输入到界面上。 我们希望日志有一定的格式, 比…

【性能优化】性能优化实战

一、背景 在做code review的时候&#xff0c;经常会发现&#xff0c;因为开发习惯问题&#xff0c;很多研发人员喜欢在for循环中查询数据库。今天用一个真实例子&#xff0c;记录一次查询性能优化的例子 二、示例 代码如下: classmethod fn_performance() def get_task_ins…

Linux常用调试工具gdb

程序编译后&#xff0c;调试是十分重要的环节&#xff0c;如何更好更快的定位程序中的问题&#xff0c; 是加快程序开发进度的重要因素。Gdb 调试器是一款 GNU 开发组织并发布的 UNIX/Linux 下的程序调试工 具。GDB调试 编译要点 对代码进行编译&#xff0c;注意一定要加上选项…

【C语言】【数据结构】自定义类型:结构体

引言 这是一篇对结构体的详细介绍&#xff0c;这篇文章对结构体声明、结构体的自引用、结构体的初始化、结构体的内存分布和对齐规则、库函数offsetof、以及进行内存对齐的原因、如何修改默认对齐数、结构体传参进行介绍和说明。 ✨ 猪巴戒&#xff1a;个人主页✨ 所属专栏&am…

Ubuntu——永久挂载/卸载硬盘

Ubuntu——永久挂载/卸载硬盘 一、挂载1. 查询硬盘2. 格式化硬盘3. 挂载硬盘4. 开机自动挂载5. 查看挂载是否成功 二、取消挂载参考资料&#xff1a; 一、挂载 1. 查询硬盘 sudo fdisk -l2. 格式化硬盘 # 格式化硬盘(/dev/sda)的文件系统&#xff0c;这里格式化为 ext4 系统…