C/C++文档阅读笔记-A Simple Makefile Tutorial解析
Makefile文件可以使得程序编译变得简单。本博文并不是很系统的讲解makefile,本博文的目标是让读者快速编写自己的makefile文件并能应用到中小项目中。
简单实例
举个例子有下面3个文件,分别是hellomake.c,hellofunc.c,hellomake.h这3个文件构成了一个基本的带有main函数的程序。
| hellomake.c | hellofunc.c | hellomake.h |
| #include <hellomake.h> int main() { //call a function in another file myPrintHelloMake(); return(0); } | #include <stdio.h> #include <hellomake.h> void myPrintHelloMake(void) { printf("Hello makefiles!\n"); return; } | /* example include file */ void myPrintHelloMake(void); |
通常在不使用makefile时,使用如下的命令编译程序:
gcc -o hellomake hellomake.c hellofunc.c -I.
此命令会编译2个.c文件,包括hellomake.c和hellofunc.c并生成hellomake这个可执行程序。-I . 是告知gcc去当前目录(.)找.h文件,也就是找hellomake.h。没用makefile文件,程序员对代码进行修改后,就需要不停按键盘的↑键去找对应的命令进行编译,如果新增了一个.c文件,还需要修改对应的命令。
所以这种方式就存在2个缺点:
1.如果电脑重启,或者新增了.c文件,就需要重新敲边缘命令,这样十分不方便;
2.如果仅仅只修改了一个.c文件,使用编译命令就会把项目所有的.c重新编译,这样编译就会变得十分慢。
创建一个最简单的makefile文件
Makefile1
hellomake: hellomake.c hellofunc.cgcc -o hellomake hellomake.c hellofunc.c -I.
文件名可以叫Makefile或makefile,在命名行中输入make执行编译命令,这个make是不需要带参数的。
第一行的hellomake只是一个tab,后面*.c是文件名。关键的命令是在第2行,程序员通常写的makefile,执行make命令时当选择的文件有一个被修改了,才会执行。
Makefile1解决开发时不停使用键盘↑键带来的操作不方便的问题,但他属于把所有文件都编译,所以没有解决效率问题。
注意:在makefile的首行“:”号的前面都要有个tab,这个是必须存在的。
为了提高编译效率,就有了下面这个Makefile2:
Makefile2
CC=gcc
CFLAGS=-I.hellomake: hellomake.o hellofunc.o$(CC) -o hellomake hellomake.o hellofunc.o
上面定义了CC和CFLAGS两个宏,目的是方便makefile后面的脚本使用,CC=gcc并且后面的$(CC) -o hellomake hellomake.o hellofunc.o说明这个CC=gcc是使用C编译器,CFLAGS列出来标签的list, -I . 编译成.o文件需要依赖当前目录的.h文件。make命令首先会编译每一个.c文件,最后构建成可执行的hellomake文件。
上面这种方式已经可以用于小项目了,但是如果hellomake.h文件改变了,make命令也不会去重编译.c文件。对于这种情况,需要告诉make,哪个.h文件改变了,需要重新编译,这里就有了Makefile3。
Makefile3
CC=gcc
CFLAGS=-I .
DEPS=hellomake.h%.o: %.c $(DEPS)$(CC) -c -o $@ $< $(CFLAGS)hellomake: hellomake.o hellofunc.o$(CC) -o hellomake hellomake.o hellofunc.o
新建了DEPS宏,这个宏里面包含了.cpp代码中需要关注的.h文件,这里需要注意的是,make生成object文件就需要检测这个.h文件是否改变。下面是各个符号的含义:
%.o:当前目录匹配到所有.o结尾的文件;
%.c:当前目录匹配到所有.c结尾的文件;
-c:生成对应的object文件;
-o $@:编译时进行输出,输出时文件的名字放到“:”的左边;
$<:依赖的第一个文件;
下面对上面的Makefile3进行简化,使用了$@和$^。对编译规则重写进行了编写,在下面的示例中所有的include文件都在DEPS宏中,所有的object文件都在OBJ宏中列出。
Makefile4
CC=gcc
CFLAGS=-I .
DEPS=hellomake.h
OBJ=hellomake.o hellofunc.o%.o: %.c $(DEPS)$(CC) -c -o $@ $< $(CFLAGS)hellomake: $(OBJ)$(CC) -o $@ $^ $(CFLAGS)
对符合解释的补充:
$^:所有依赖文件
如果要将.h文件放到include目录,source文件放到src目录,库文件放到lib目录。.o文件也要规范位置,这样就需要编写新的makefile文件,举个例子当下面这个程序依赖m.so库,这个m是math的意思,并且还需要编写make clean的规则,这样的makefile可以这样写:
Makefile5
IDIR =../include
CC=gcc
CFLAGS=-I$(IDIR)ODIR=obj
LDIR =../libLIBS=-lm_DEPS = hellomake.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))_OBJ = hellomake.o hellofunc.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))$(ODIR)/%.o: %.c $(DEPS)$(CC) -c -o $@ $< $(CFLAGS)hellomake: $(OBJ)$(CC) -o $@ $^ $(CFLAGS) $(LIBS).PHONY: cleanclean:rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
解释下参数:
patsubst:
名称:模式字符串替换函数——patsubst。
功能:查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换。
这里,<pattern>可以包括通配符“%”,表示任意长度的字串。如果<replacement>中也包含“%”,那么,<replacement>中的这个“%”将是<pattern>中的那个“%”所代表的字串。
(可以用“\”来转义,以“\%”来表示真实含义的“%”字符)
返回:函数返回被替换过后的字符串。
示例:
$(patsubst %.c,%.o, a.c b.c)
把字串“a.c b.c”符合模式[%.c]的单词替换成[%.o],返回结果是“a.o b.o”
实例代码打包下载地址:
https://github.com/fengfanchen/CAndCPP/tree/master/MakeFileExample
相关文章:
C/C++文档阅读笔记-A Simple Makefile Tutorial解析
Makefile文件可以使得程序编译变得简单。本博文并不是很系统的讲解makefile,本博文的目标是让读者快速编写自己的makefile文件并能应用到中小项目中。 简单实例 举个例子有下面3个文件,分别是hellomake.c,hellofunc.c,hellomake.…...
GraphSAGE的基础理论
文章目录GraphSAGE原理(理解用)GraphSAGE工作流程GraphSAGE的实用基础理论(编代码用)1. GraphSAGE的底层实现(pytorch)PyG中NeighorSampler实现节点维度的mini-batch GraphSAGE样例PyG中的SAGEConv实现2. …...
Windows 安装 GDAL C++库
Windows 安装 GDAL C库1. 方法1:下载配置网友编译的GDAL版本1.1 下载1.2 配置1.3 测试1.4 缺点2. 方法2:自己编译3. 参考1. 方法1:下载配置网友编译的GDAL版本 1.1 下载 CSDN: GDAL,geos联合编译的库,版本为1.8.0&am…...
二叉树基础概念
1.二叉树种类 1.1 满二叉树 满二叉树:如果一棵二叉树只有度为 0 0 0 的结点和度为 2 2 2 的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。 如图所示: 这棵二叉树为满二叉树,也可以说深度为 k k k&…...
【MySQL】(1)数据库基础,库与表的增删查改,数据库的备份与还原
文章目录服务器,数据库,表关系MySQL 数据存储逻辑SQL 分类存储引擎库的操作查看数据库创建数据库查看创建语句删除数据库选择(切换)数据库查看当前选择的数据库修改数据库字符集和排序规则表的操作创建表查询表查询表结构插入数据…...
Python基础-01 变量
注释 注释的分类 在Python中,支持单行及多行注释 单行注释 使用#对代码进行说明,#右边的所有内容就是注释的内容,起辅助说明作用 # #右边的都是注释,解析器会忽略 print(hello world) #在控制台里打印一段话多行注释 多行注释中,允许换行,使用三个单引号开始,三个单引号结…...
springcloud2.1.0整合seata1.5.2+nacos2.10(附源码)
springcloud2.1.0整合seata1.5.2nacos2.10(附源码) 1.创建springboot2.2.2springcloud2.1.0的maven父子工程如下,不过多描述: 搭建过程中也出现很多问题,主要包括: 1.seataServer.properties配置文件的组…...
map原理
map源码结构体: type hmap struct {count int // 元素的个数B uint8 // buckets 数组的长度就是 2^B 个overflow uint16 // 溢出桶的数量buckets unsafe.Pointer // 2^B个桶对应的数组指针oldbuckets unsafe.Pointer // 发生扩容时࿰…...
[Ext JS]3.6 Ext JS 表格(Grid)概览
Grid, 翻译过来是网格, 也就是表格。 Grid 的基本构成 面板 :Ext.grid.Panel表格视图 :Ext.view.Table。 不直接使用, 通过面板的viewConfig配置项进行配置。比如可以用来配置表格中行是否跳色显示列: Ext.grid.column.Column。 表格中的列定义store , 表格的数据示例代码…...
关于使用云渲染的五大优势
在不影响质量或性能的情况下节省时间、金钱和资源,对于需要在通常较短且严格的期限内创建高质量 3D 内容的专业人士来说,云渲染都是最好的选择!云渲染作为数字媒体生产的最新趋势,与传统的渲染农场和机器相比具有许多优势…...
CSS基础样式
1.高度和宽度 .c1{height:300px;width:500px; } 注意事项: 宽度,支持百分比 行内标签:默认无效 块级标签:默认有效(右侧区域就算是空白,也不给占用) 2.块级和行内标签 css样式:标签…...
第03章_流程控制语句
第03章_流程控制语句 讲师:尚硅谷-宋红康(江湖人称:康师傅) 官网:http://www.atguigu.com 本章专题与脉络 流程控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模…...
配电网电压调节及通信联系研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
stegano(图片隐写、摩斯密码)
附件是PDF,我们在选择内容时发现光标溢出了文本 说明这里还存在一些我们看不到的内容 直接CtrlA全选,CtrlC复制后新建一个纯文本文件 将复制的东西粘贴过去 粘贴后发现果然多出来了一些东西,提取出来 BABA BBB BA BBA ABA AB B AAB ABAA A…...
wsl安装torch_geometric
在官网选择需要的版本 选择安装途径,选择runfile 执行第一行,会下载一个文件到目录下 需要降低C的版本,否则 执行sudo sh cuda_11.1.0_455.23.05_linux.run,会出现 查看对应的文件,会有 可以加上override参数之后,…...
ASP.NET Core - 依赖注入(二)
2,NET Core 依赖注入的基本用法 话接上篇,这一章介绍 .NET Core 框架自带的轻量级 Ioc 容器下服务使用的一些知识点,大家可以先看看上一篇文章 [ASP.NET Core - 依赖注入(一)] 2.3 服务解析 通过 IServiceCollection 注册了服务之后…...
Scala之集合(1)
目录 集合介绍: 不可变集合继承图:编辑 可变集合继承图 数组: 不可变数组: 样例代码: 遍历集合的方法: 1.for循环 2.迭代器 3.转换成List列表: 4.使用foreach()函数&a…...
公网使用SSH远程登录macOS服务器【内网穿透】
文章目录前言1. macOS打开远程登录2. 局域网内测试ssh远程3. 公网ssh远程连接macOS3.1 macOS安装配置cpolar3.2 获取ssh隧道公网地址3.3 测试公网ssh远程连接macOS4. 配置公网固定TCP地址4.1 保留一个固定TCP端口地址4.2 配置固定TCP端口地址5. 使用固定TCP端口地址ssh远程前言…...
PVE相关的各种一键脚本(一键安装PVE)(一键开设KVM虚拟化的NAT服务器-自带内外网端口转发)
PVE 原始仓库:https://github.com/spiritLHLS/pve 前言 建议debian在使用前尽量使用最新的系统 非debian11可使用 debian一键升级 来升级系统 当然不使用最新的debian系统也没问题,只不过得不到官方支持 请确保使用前机器可以重装系统,…...
CSDN目录博客(zhaoshuangjian)
总目录 一、Java1.1 高并发1.2 多线程1.3 集合1.4 I/O1.5 异常1.6 事务1.7 锁机制1.8 JVM 二、数据库2.1 mysql2.1.1 mysql索引2.1.1 mysql锁2.1.1 mysql事务2.1.1 2.2 oracle2.3 postgresql2.4 达梦2.5 人大金仓kingbase 三、设计模式四、中间件4.1 缓存中间件-redis4.2 缓存中…...
终极Gmail桌面体验:告别浏览器标签混乱,拥抱高效邮件管理
终极Gmail桌面体验:告别浏览器标签混乱,拥抱高效邮件管理 【免费下载链接】gmail-desktop :postbox: Gmail desktop app for macOS, Windows & Linux (formerly Gmail Desktop) 项目地址: https://gitcode.com/gh_mirrors/gm/gmail-desktop 厌…...
Java Stream流式编程实战
前言 在现代软件开发中,Java Stream流式编程实战是一个非常重要的技术点。本文将从原理到实践,带你深入理解这一技术,并通过完整的代码示例帮助你快速掌握核心知识点。 核心概念 基本原理 Java Stream流式编程实战的核心在于理解其底层机制。…...
工业 DC-DC 标准封装设计探讨 钡特电源 DB2-12D15D 与金升阳 A1215D-2WR3 工业模块电源盘点
在工业控制与嵌入式系统设计中,12V 输入转 15V 输出的 2W 隔离供电方案,是模拟电路、信号调理模块的核心供电选择。伴随国内电子制造技术持续突破,国产直流电源模块在标准化封装、电气性能稳定性上不断贴合行业通用规范,成为推动国…...
观察Taotoken模型广场在项目初期技术选型中的辅助作用
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 观察Taotoken模型广场在项目初期技术选型中的辅助作用 在启动一个涉及大模型能力的新项目时,技术选型往往是第一道门槛…...
RK3399嵌入式Linux开发:Sysfs内核虚拟文件系统深度探索与实践指南
1. 项目概述:为什么从Sysfs开始内核探索拿到一块RK3399这样的高性能开发板,无论是做产品原型还是学习嵌入式Linux,第一步往往都是“点亮”和“跑起来”。但当系统启动,命令行提示符闪烁时,很多开发者,尤其是…...
别再用默认筛选器了!用Tableau集和计算字段打造“老板最爱看”的交互仪表板
别再用默认筛选器了!用Tableau集和计算字段打造“老板最爱看”的交互仪表板 每次给管理层汇报数据时,最怕遇到什么场景?当你精心准备了20页分析报告,老板却直接翻到最后一页说:"我只关心A事业部和B事业部的表现&a…...
告别GitHub!手把手教你用Gitblit在Windows 10上搭建私人局域网Git服务器(附SourceTree配置)
告别GitHub!手把手教你用Gitblit在Windows 10上搭建私人局域网Git服务器(附SourceTree配置) 在当今代码托管平台高度集中的环境下,越来越多的开发者开始关注数据主权和隐私保护。特别是对于金融、医疗等敏感行业的开发团队&#x…...
GD32C103RBT6 I2C 驱动全解析
一、I2C 通信基础概述 1. I2C 硬件接口 GD32C10x 提供 I2C0、I2C1 两组硬件 I2C: SCL:串行时钟线(由主机产生) SDA:串行数据线 需外接 上拉电阻(4.7kΩ 经典值) 支持 多主机、多从机 2. 通信模式 主机模式:MCU 主动发起通信(最常用) 从机模式:MCU 被其他主机访问 …...
GJB 128B-2021标准变更深度解析:VDMOS产品试验方法的影响与应对
1. GJB 128B-2021标准变更的核心要点 对于从事VDMOS产品研发和质量控制的工程师来说,2022年3月正式实施的GJB 128B-2021标准带来了不少值得关注的调整。相比旧版标准,这次修订在试验条件、热平衡判定、静电防护等多个关键环节都做出了具体规定。我仔细研…...
对比按量计费Taotoken的官方价折扣与活动价带来哪些实际节省
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 对比按量计费:Taotoken的官方价折扣与活动价带来哪些实际节省 1. 理解Taotoken的计费模式 Taotoken作为大模型API的聚…...
