当前位置: 首页 > news >正文

2023-11-17 VsCode使用makefile进行多文件编译


点击 <C 语言编程核心突破> 快速C语言入门


VsCode使用makefile进行多文件编译

  • 前言
  • 一、一个简单的多文件示例
  • 二、makefile基本语法
  • 三、VsCode使用makefile
  • 总结


前言

要解决问题: C或C++可以多文件编译, 意味着需要进行代码组织, 为了方便多文件编译, gnu开发了make工具, 但问题是这简直又是一种编程语言, 为了解决一个问题, 又产生另一个问题. 在一个问题回答中, 我了解了作为新手的我们, 对make是如此困惑.

想到的思路: 从一个最简单的多文件编译, 简述makefile的编写, 组织C文件.

其它的补充: 需要更系统的学习, 可以查看陈皓巨佬的相关文章<跟我一起写makefile>.


一、一个简单的多文件示例

一个问题, makefile文件中VPATH路径无法找到, 本来十分简单, 但回答搞得可说乱七八糟, 可以想见, 大家对makefile是如此的不熟悉,

一个有三个文件夹, 若干个.c文件的小项目, 要用makefile组织编译, 我根据这个题目, 模拟了一下:

项目文件

三个文件夹, 分别有一个c文件, 可能含有一个头文件, 文件的名称和文件夹的名称是一致的, 当然也可以不一致, 这没有关系.

现在编写makefile, 将上述文件夹中的所有文件组织为一个名为main的可执行程序.

二、makefile基本语法

既然是用于编译, makefile自然需要提供一些信息, 包括:

  1. 编译器, 一般是gcc, 或clang
  2. 目录信息, 让make自动寻找文件, 省的手动一个个设置
  3. 源文件名
  4. 最终编译出来的目标
  5. 编译依赖的文件
  6. 执行模板
  7. 如果头文件和源文件不在一起, 需指定头文件夹位置
  8. 如果需要引入库文件, 则需要指定库文件夹位置, 以及库文件

下面就是一个编写好的makefile, 用于处理我们上面提到的多文件编译, 大家先看一下.

CC := clang #编译器VPATH := IO_tools menu shapes #自动寻找的目录SRC := IO_tools.c menu.c shapes.c #源文件OBJ := $(SRC:.c=.o) #目标文件, 由.c更换为.oEXEC := main #执行文件all: $(EXEC) #目标all, 依赖main$(EXEC): $(OBJ) #main依赖.o文件, $^是所有依赖文件 $@是目标文件$(CC) $^ -o $@%.o: %.c #将所有的.c文件编译为.o文件, $<是第一个依赖文件, -c是生成.o文件$(CC) -c $< -o $@clean:rm -rf $(OBJ) $(EXEC)
#E:\msys64\clang64\bin\mingw32-make.exe all -f E:\clangC++\answer\C\make\Makefile -C E:\clangC++\answer\C\make\

由于只是基础普及, 示例没有放函数等复杂应用, 对于小项目, 这个就基本够了.

我们一条一条说:

首先是变量赋值, 很遗憾, 你必须将makefile语法当成一门编程语言, 因为这样比较好理解.

CC一般是编译器变量名, :=带冒号的赋值符号意味着非递归赋值, 也就是现在赋值是啥就是啥.

不带冒号的赋值, 则可能涉及递归, 这个不阐述, 暂时用不到.

我们给CC赋值为clang, 用clang进行编译.

VPATH是一个特殊变量, 代表make要搜寻的文件夹, 我们将需要编译的文件所在文件夹IO_tools menu shapes赋值给它.

然后make会帮我们在这些文件夹中寻找我们要编译的源文件.

SCR这个变量, 我们给它赋值为所有需要编译的源文件IO_tools.c menu.c shapes.c

OBJ这个变量, 我们给他赋值为源文件编译后的.o文件, 也就是还未链接的中间文件.

$(SRC:.c=.o)大家看, 这是一个变量引用的语法, 它引用变量SRC, 需要用$()括号将变量包裹,

.c=.o这个操作, 是将SRC中的.c结尾变成.o结尾, 于是OBJ就应该是IO_tools.o menu.o shapes.o

EXEC := main这句很好懂, 就是最终的可执行文件EXEC的名字叫main

all: $(EXEC) 这一句是makefile的精髓, 意思很简单, 生成的目标叫all, 这也是默认最终目标, 它依赖变量EXEC也就是main

然后递归, main现在作为目标, 又需要OBJ这些文件来链接, 于是就有$(EXEC): $(OBJ)这个语句.

注意, 下面是执行编译命令模板, $(CC) $^ -o $@这个前面空白必须是一个tab符号, 否则无法编译, 这句命令的意思是

clang IO_tools.o menu.o shapes.o -o main 这就是模板完成的语句, 我们说明一下

$(CC) 是编译器, 我们这里就是clang , 这个符号$^代表所有依赖项, 也就是所有的.o文件, 这个 -o是编译选项, 输出编译结果名 , 这个符号$@是目标项, 也就是main

将所有模板扩充之后就是我们的编译命令行.

之后继续递归, %.o: %.c, 所有.o文件依赖对应的.c文件, 这里的百分号%是一个识别模式,

代表在makefile文件中查找所有前面可以是任意字符组成, 最后必须是.o的文件名, 除了后缀不同, 目标和依赖这两个文件的名字是一致的.

将所有的.c文件编译为.o文件, $<是第一个依赖文件, -c是生成.o文件

$(CC) -c $< -o $@是编译命令模板, -c是编译但不链接, 这个符号$<是依赖的第一项, 也就是.c文件,

因为一对一对应, 所以没必要用全部依赖. 这个模板扩展之后, 是三个编译命令行, 如clang -c menu/menu.c -o menu.o,

注意, 因为我们使用了VPATH这个变量, make自动帮我们查找.c文件的路径, 并补全,

但开头提到的makefile文件中VPATH路径无法找到, 问题就在于不是使用模板编译命令, 而是直接写死了命令行, 导致VPATH这个设置无法使用.

最后是clean:, 这是删除所有生成的文件, 包括中间文件以及最终的可执行文件.

rm -rf $(OBJ) $(EXEC) 这是执行语句, 记住前面必须是tab, rm -rf这个是大家熟悉的Linux命令, 强制删除文件夹及文件.

三、VsCode使用makefile

为了在vscode中方便使用makefile组织项目, 可以下载插件, 微软官方的VS Code Makefile Tools, 编写makefile后可以一件运行, 以及生成各种子目标.

make tools

以及Makefile-Creator作者是Antoine aka. Zenor, 可以通过右键文件夹, 自动生成makefile模板.
在这里插入图片描述

CXX = g++
CXXFLAGS = -Wall -Werror -Wextra -pedantic -std=c++17 -g -fsanitize=address
LDFLAGS =  -fsanitize=addressSRC = 
OBJ = $(SRC:.cc=.o)
EXEC = mainall: $(EXEC)$(EXEC): $(OBJ)$(CXX) $(LDFLAGS) -o $@ $(OBJ) $(LBLIBS)clean:rm -rf $(OBJ) $(EXEC)

之后根据需要进行调整.


总结

到这里, 基础普及知识就完成了, 对于小项目, 可以说基本能覆盖百分之八十了, 大项目, 还是自己去学吧, 网上的内容很多, 推荐开头说的陈皓巨佬的文章, 我们十分怀念这位前辈, 他所留下的文字, 始终指引着一批批程序员.

最后, 如果你觉得makefile很麻烦, 可以看看xmake, 这个国产的项目工具, 一定能找到惊喜.


点击 <C 语言编程核心突破> 快速C语言入门


相关文章:

2023-11-17 VsCode使用makefile进行多文件编译

点击 <C 语言编程核心突破> 快速C语言入门 VsCode使用makefile进行多文件编译 前言一、一个简单的多文件示例二、makefile基本语法三、VsCode使用makefile总结 前言 要解决问题: C或C可以多文件编译, 意味着需要进行代码组织, 为了方便多文件编译, gnu开发了make工具, …...

Network(四)NAT实现方式与VRRP概述

一 NAT 1 NAT概述 &#xff08;1&#xff09;NAT的作用 Network Address Translation&#xff0c;网络地址转换 通过将内部网络的私有IP地址转换成全球唯一的公网IP地址使内部网络可以连接到互联网。 &#xff08;2&#xff09;私有IP地址分类 A类10.0.0.0~10.255.255.…...

C#_键盘钩子

一、class class KeyboardHook{public event KeyEventHandler KeyDownEvent;public event KeyPressEventHandler KeyPressEvent;public event KeyEventHandler KeyUpEvent;public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);static int hKeyboardHook 0;…...

YOLO免费数据集网站收集

目录 Roboflow Universe: Open Source Computer Vision Community Find Open Datasets and Machine Learning Projects | Kaggle ​编辑 【火焰和烟雾图像数据集】-计算机视觉数据集-极市开发者平台 (cvmart.net) 开放数据集- 飞桨AI Studio星河社区 - 人工智能学习与实训社…...

拼图小游戏

package li;import ui.tu; //启动类 public class 主 {public static void main(String[] args) {new tu(); //创建登陆界面} }package ui;import javax.swing.*; import javax.swing.border.BevelBorder; import java.awt.event.ActionEvent; import java.awt.event.ActionLi…...

卷积神经网络(CNN)天气识别

文章目录 前期工作1. 设置GPU&#xff08;如果使用的是CPU可以忽略这步&#xff09;我的环境&#xff1a; 2. 导入数据3. 查看数据 二、数据预处理1. 加载数据2. 可视化数据3. 再次检查数据4. 配置数据集 三、构建CNN网络四、编译五、训练模型六、模型评估 前期工作 1. 设置GP…...

Linux进程间通信之匿名管道

文章目录 为什么要有进程间通信pipe函数共享管道原理管道特点管道的四种情况 管道的应用场景&#xff08;进程池&#xff09;ProcessPool.ccTask.hpp 为什么要有进程间通信 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享&#xff1a;多个进程之间共享…...

【PTA题目】6-19 使用函数输出指定范围内的Fibonacci数 分数 20

6-19 使用函数输出指定范围内的Fibonacci数 分数 20 全屏浏览题目 切换布局 作者 C课程组 单位 浙江大学 本题要求实现一个计算Fibonacci数的简单函数&#xff0c;并利用其实现另一个函数&#xff0c;输出两正整数m和n&#xff08;0<m≤n≤10000&#xff09;之间的所有F…...

运行ps显示msvcp140.dll丢失怎么恢复?msvcp140.dll快速解决的4个不同方法

msvcp140.dll无法继续执行代码的主要原因有以下几点 系统缺失&#xff1a;msvcp140.dll是Visual Studio 2015编译的程序默认的库文件&#xff0c;如果系统中没有这个库文件&#xff0c;那么在运行相关程序时就会出现找不到msvcp140.dll的错误提示。 文件损坏&#xff1a;如果…...

Java多线程(3)

Java多线程(3) 深入剖析Java线程的生命周期&#xff0c;探秘JVM的线程状态&#xff01; 线程的生命周期 Java 线程的生命周期主要包括五个阶段&#xff1a;新建、就绪、运行、阻塞和销毁。 **新建&#xff08;New&#xff09;&#xff1a;**线程对象通过 new 关键字创建&…...

Java线程周期

Java线程的生命周期包含以下状态&#xff1a; 新建&#xff08;New&#xff09;&#xff1a;当一个线程被创建但还没有被启动时&#xff0c;它的状态是新建。就绪&#xff08;Runnable&#xff09;&#xff1a;当线程已经被启动并且没有任何阻止它立即运行的条件时&#xff0c;…...

map与set的封装

目录 红黑树的结点 与 红黑树的迭代器 红黑树的实现&#xff1a; 迭代器&#xff1a; ​编辑 红黑树的查找&#xff1a; 红黑树的插入&#xff1a; ​编辑 检查红色结点&#xff1a;​编辑红黑树的左旋 ​编辑红黑树的右旋 ​编辑红黑树的双旋 Map的封装 ​编辑set的…...

mac无法向移动硬盘拷贝文件怎么解决?不能读取移动硬盘文件怎么解决

有时候我们在使用mac的时候&#xff0c;会遇到一些问题&#xff0c;比如无法向移动硬盘拷贝文件或者不能读取移动硬盘文件。这些问题会给我们的工作和生活带来不便&#xff0c;所以我们需要找到原因和解决办法。本文将为你介绍mac无法向移动硬盘拷贝文件怎么回事&#xff0c;以…...

基于Netty实现的简单聊天服务组件

目录 基于Netty实现的简单聊天服务组件效果展示技术选型&#xff1a;功能分析聊天服务基础设施配置&#xff08;基于Netty&#xff09;定义组件基础的配置&#xff08;ChatProperties&#xff09;定义聊天服务类&#xff08;ChatServer&#xff09;定义聊天服务配置初始化类&am…...

视频封面:从视频中提取封面,轻松制作吸引人的视频

在当今的数字时代&#xff0c;视频已成为人们获取信息、娱乐和交流的重要方式。一个吸引人的视频封面往往能抓住眼球&#xff0c;提高点击率和观看率。今天将介绍如何从视频中提取封面&#xff0c;轻松制作吸引人的视频封面。 一、准备素材选择合适的视频片段 首先&#xff0…...

CICD 持续集成与持续交付——gitlab

部署 虚拟机最小需求&#xff1a;4G内存 4核cpu 下载&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/ 安装依赖性 [rootcicd1 ~]# yum install -y curl policycoreutils-python openssh-server perl[rootcicd1 ~]# yum install -y gitlab-ce-15.9.3-ce.0…...

Linux - 驱动开发 - RNG框架

说明 公司SOC上有一个新思的真随机数&#xff08;TRNG&#xff09;模块&#xff0c;Linux平台上需要提供接口给外部使用。早期方式是提供一个独立的TRNG驱动&#xff0c;实现比较简单的&#xff0c;但是使用方式不open&#xff0c;为了加入Linux生态环境&#xff0c;对接linux…...

qsort使用举例和qsort函数的模拟实现

qsort使用举例 qsort是C语言中的一个标准库函数&#xff0c;用于对数组或者其他数据结构中的元素进行排序。它的原型如下&#xff1a; void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); 我们可以去官网搜来看一看&#xff1a;…...

AttributeError: module ‘gradio‘ has no attribute ‘ClearButton‘解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

Kafka 集群如何实现数据同步?

哈喽大家好&#xff0c;我是咸鱼 最近这段时间比较忙&#xff0c;将近一周没更新文章&#xff0c;再不更新我那为数不多的粉丝量就要库库往下掉了 T﹏T 刚好最近在学 Kafka&#xff0c;于是决定写篇跟 Kafka 相关的文章&#xff08;文中有不对的地方欢迎大家指出&#xff09;…...

javaweb图书馆借阅管理系统设计与实现uv6546wm

目录同行可拿货,招校园代理 ,本人源头供货商功能分析用户管理模块图书管理模块借阅管理模块预约与通知模块统计与报表模块系统设置模块技术实现要点扩展功能&#xff08;可选&#xff09;项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同…...

效率倍增,使用快马生成ansible playbook自动化部署ubuntu生产服务器

效率倍增&#xff0c;使用快马生成ansible playbook自动化部署ubuntu生产服务器 重复性的ubuntu环境安装与配置工作&#xff0c;往往让开发者感到头疼。每次新服务器上线&#xff0c;都需要手动执行一系列繁琐的操作&#xff0c;不仅耗时耗力&#xff0c;还容易出错。最近我发…...

大模型领域岗位梯队详解:小白程序员转型宝典,速收藏![特殊字符]

大模型领域岗位梯队详解&#xff1a;小白程序员转型宝典&#xff0c;速收藏&#xff01;&#x1f525; 本文详细解析了大模型领域的岗位梯队&#xff0c;从底层架构到应用开发&#xff0c;涵盖了预训练、基础设施、模型优化、后训练、多模态等多个方向。文章强调了当前大模型领…...

如何通过AI技术让千年中医智慧赋能现代诊疗?仲景中医大语言模型的创新实践

如何通过AI技术让千年中医智慧赋能现代诊疗&#xff1f;仲景中医大语言模型的创新实践 【免费下载链接】CMLM-ZhongJing 首个中医大语言模型——“仲景”。受古代中医学巨匠张仲景深邃智慧启迪&#xff0c;专为传统中医领域打造的预训练大语言模型。 The first-ever Traditiona…...

GTE-Pro企业级语义智能实战:从模型加载到热力评分可视化的完整链路

GTE-Pro企业级语义智能实战&#xff1a;从模型加载到热力评分可视化的完整链路 1. 引言&#xff1a;告别关键词匹配&#xff0c;拥抱语义理解 想象一下&#xff0c;你是一个新员工&#xff0c;想查一下公司怎么报销餐费。你打开公司的知识库&#xff0c;输入“怎么报销吃饭的…...

深入解析AdminBSB:Bootstrap 3.x与Material Design完美融合的终极指南

深入解析AdminBSB&#xff1a;Bootstrap 3.x与Material Design完美融合的终极指南 【免费下载链接】AdminBSBMaterialDesign AdminBSB - Free admin panel that is based on Bootstrap 3.x with Material Design 项目地址: https://gitcode.com/gh_mirrors/ad/AdminBSBMateri…...

AI赋能嵌入式:借助快马平台为单片机生成轻量级语音唤醒代码框架

AI赋能嵌入式&#xff1a;借助快马平台为单片机生成轻量级语音唤醒代码框架 最近在做一个智能家居的小项目&#xff0c;需要给STM32单片机加上语音唤醒功能。作为嵌入式开发者&#xff0c;最头疼的就是把AI模型移植到资源有限的单片机上。好在发现了InsCode(快马)平台&#xf…...

从安装到实战:基于快马AI生成openclaw的网站内容监控应用项目

最近在做一个网站内容监控的小工具&#xff0c;尝试用openclaw框架来实现自动化采集和变更检测。这个项目从环境搭建到功能实现踩了不少坑&#xff0c;记录下完整过程给有类似需求的同学参考。 环境准备与openclaw安装 openclaw的安装其实挺简单&#xff0c;直接用pip就能搞定…...

OpenClaw内存优化:千问3.5-35B-A3B-FP8在8GB设备的运行技巧

OpenClaw内存优化&#xff1a;千问3.5-35B-A3B-FP8在8GB设备的运行技巧 1. 为什么需要内存优化 当我第一次尝试在8GB内存的MacBook Pro上运行千问3.5-35B-A3B-FP8模型时&#xff0c;系统几乎立即崩溃了。这让我意识到&#xff0c;想要在资源有限的设备上运行大型语言模型&…...

从“技术迷宫“到“一键导航“:OpCore-Simplify如何让黑苹果配置变得像搭积木一样简单

从"技术迷宫"到"一键导航"&#xff1a;OpCore-Simplify如何让黑苹果配置变得像搭积木一样简单 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-S…...