linux C语言Makefile
ChatGPT
在Linux中使用Makefile来自动化C语言项目的构建过程是很普遍的实践。Makefile是一个包含了一系列构建目标及如何构建这些目标的依赖和规则的文本文件。
一个基本的Makefile例子可能会像这样:
# 定义编译器
CC=gcc# 定义编译选项
CFLAGS=-I.# 定义可执行文件
EXECUTABLE=program# 定义源文件
SOURCES=main.c utils.c# 定义对象文件
OBJECTS=$(SOURCES:.c=.o)# 默认目标
all: $(EXECUTABLE)# 构建可执行文件
$(EXECUTABLE): $(OBJECTS)$(CC) -o $@ $^# 依赖规则
%.o: %.c$(CC) $(CFLAGS) -c $< -o $@# 清理规则
clean:rm -f $(EXECUTABLE) $(OBJECTS)
这个Makefile定义了一些变量,例如CC为C编译器,CFLAGS为编译器选项,以及执行文件、源文件和对象文件的名称。
解释一下这些规则和目标:
- 默认目标 all:当仅仅在终端中输入 make 时,默认会尝试构建该目标。在这里,它依赖于 $(EXECUTABLE),即最终的程序。
- 生成可执行文件的规则描述了如何从对象文件 $(OBJECTS) 构建出目标可执行文件 $(EXECUTABLE)。
- 生成对象文件的模式规则 %.o: %.c 说明了怎样从每个 .c 源文件生成 .o 对象文件。
- 清理目标 clean:这个目标可以通过运行 make clean 在命令行中来清理所有的中间文件和可执行文件,以便重新构建。
使用这个Makefile构建项目相当简单,只需要在包含Makefile的目录中运行`make`命令。如果要清除构建生成的文件,可以运行`make clean`命令。
根据实际情况,Makefile可能会包含更复杂的依赖关系、条件判断、函数等,但大部分Makefile都遵循这种基本结构。

文心一言
在Linux系统中,使用C语言编程时,经常需要编写Makefile文件来自动化构建(编译、链接等)程序。Makefile定义了如何从源代码生成目标文件,并最终生成可执行文件。下面是一个简单的C语言项目的Makefile示例:
# 定义编译器
CC=gcc # 定义源文件
SRCS=main.c file1.c file2.c # 定义目标文件
OBJS=$(SRCS:.c=.o) # 定义最终的可执行文件
TARGET=my_program # 默认目标:构建可执行文件
all: $(TARGET) # 构建可执行文件
$(TARGET): $(OBJS) $(CC) $(OBJS) -o $(TARGET) # 编译源文件生成目标文件
%.o: %.c $(CC) -c $< -o $@ # 清除所有生成的目标文件和可执行文件
clean: rm -f $(OBJS) $(TARGET)
在这个Makefile中:
CC 变量定义了使用的编译器(这里是gcc)。
SRCS 变量列出了所有的源文件。
OBJS 变量通过字符串替换将源文件列表中的 .c 后缀替换为 .o 后缀,得到所有目标文件的列表。
TARGET 变量定义了最终的可执行文件的名称。
all 目标是一个默认目标,它依赖于 $(TARGET),所以当你运行 make 命令时,会构建可执行文件。
$(TARGET) 目标依赖于所有的目标文件 $(OBJS),并使用编译器将它们链接成一个可执行文件。
%.o: %.c 是一个模式规则,它告诉make如何将 .c 源文件编译成 .o 目标文件。$< 和 $@ 是自动变量,分别代表依赖项(在这里是 .c 文件)和目标(在这里是 .o 文件)。
clean 目标用于清除所有生成的目标文件和可执行文件。当你运行 make clean 时,它会执行这个目标。
可以根据项目需求修改这个Makefile。例如,如果项目包含头文件或库文件,可能需要添加包含路径(-I 选项)或链接库(-l 选项)到编译和链接命令中。

讯飞星火
在Linux系统中,使用C语言编写的程序可以通过Makefile进行编译和链接。以下是一个简单的Makefile示例:
# 定义编译器
CC = gcc# 定义编译选项
CFLAGS = -Wall -g# 定义目标文件
TARGET = my_program# 定义源文件
SOURCES = main.c file1.c file2.c# 定义目标文件的依赖关系
$(TARGET): $(SOURCES)$(CC) $(CFLAGS) -o $(TARGET) $(SOURCES)# 定义清除规则
clean:rm -f $(TARGET)
在这个示例中,我们定义了编译器(CC)、编译选项(CFLAGS)、目标文件(TARGET)和源文件(SOURCES)。然后,我们定义了一个规则,用于将源文件编译并链接为目标文件。最后,我们定义了一个清除规则,用于删除生成的目标文件。

Kimi
在Linux环境下,使用C语言进行项目开发时,Makefile是一个常用的工具,它定义了一套规则来指定如何编译和链接程序。下面是一个简单的Makefile示例,它展示了如何编译一个C语言项目。
# 定义项目名称
PROJECT_NAME = my_project# 定义源文件目录
SRC_DIR = src# 定义头文件目录
INC_DIR = include# 定义对象文件目录
OBJ_DIR = obj# 定义编译器
CC = gcc# 定义编译选项
CFLAGS = -Wall -I$(INC_DIR) -c# 定义链接选项
LDFLAGS = -L./lib -lmylib# 定义链接器
LD = $(CC)# 定义源文件
SRC = $(wildcard $(SRC_DIR)/*.c)# 定义对象文件
OBJ = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC))# 定义默认目标
all: $(PROJECT_NAME)# 链接目标
$(PROJECT_NAME): $(OBJ)$(LD) $(LDFLAGS) $^ -o $@# 编译对象文件
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c@mkdir -p $(OBJ_DIR)$(CC) $(CFLAGS) $< -o $@# 清理生成的对象文件和可执行文件
clean:rm -rf $(OBJ_DIR) $(PROJECT_NAME)# 打印Makefile中定义的变量
print:@echo "Project Name: $(PROJECT_NAME)"@echo "Source Directory: $(SRC_DIR)"@echo "Include Directory: $(INC_DIR)"@echo "Object Directory: $(OBJ_DIR)"@echo "Compiler: $(CC)"@echo "Compilation Flags: $(CFLAGS)"@echo "Linker Flags: $(LDFLAGS)"@echo "Linker: $(LD)"@echo "Source Files: $(SRC)"@echo "Object Files: $(OBJ)".PHONY: all clean print
这个Makefile包含了以下几个部分:
项目名称:定义项目的名称,用于生成最终的可执行文件。
目录定义:定义源文件、头文件和对象文件的存放目录。
编译器和链接器:指定使用的C编译器和链接器。
编译选项:定义编译时的选项,如包含目录和警告选项。
链接选项:定义链接时的选项,如链接库的路径和名称。
源文件和对象文件:使用通配符匹配所有源文件,并生成对应的对象文件。
默认目标:定义make命令执行时的默认目标。
链接规则:定义如何将对象文件链接成最终的可执行文件。
编译规则:定义如何编译单个源文件生成对象文件。
清理规则:定义如何清理生成的对象文件和可执行文件。
打印规则:定义一个规则来打印Makefile中定义的变量。
伪目标:.PHONY声明指定了clean和print是伪目标,即使在文件系统中没有与它们同名的文件,也可以执行它们定义的命令。
要使用这个Makefile,需要将其保存为Makefile或makefile,并在项目根目录下运行make命令来编译项目。如果想执行清理或打印变量,可以运行make clean或make print。

通义灵码
在Linux环境下,编写C语言项目的Makefile是为了自动化编译和链接过程,确保项目中的源文件按照正确的顺序和依赖关系编译成可执行文件或库文件。以下是一个通用的Makefile示例,适用于一个简单的C语言项目:
# 定义编译器、编译选项、目标文件名、源文件列表等变量
CC := gcc
CFLAGS := -std=c11 -pedantic -Wall -Wextra -O2
LDFLAGS := -lm # 如果项目需要链接数学库,例如使用了数学函数TARGET := my_program
SRCS := $(wildcard *.c) # 获取当前目录下所有.c文件
OBJS := $(SRCS:.c=.o) # 将源文件名替换为对应的对象文件名# 默认目标(phony target),编译整个项目
.PHONY: all
all: $(TARGET)# 主要目标(可执行文件)的规则
$(TARGET): $(OBJS)$(CC) $(CFLAGS) $(OBJS) -o $@ $(LDFLAGS)# 普通对象文件的规则(%.o: %.c)
%.o: %.c$(CC) $(CFLAGS) -c $< -o $@# 清理目标,删除中间对象文件和最终生成的可执行文件
.PHONY: clean
clean:rm -f $(OBJS) $(TARGET)
解释各部分含义:
CC: 定义C编译器为gcc。CFLAGS: 定义编译选项,如遵循C11标准(-std=c11)、启用额外警告(-pedantic -Wall -Wextra)和优化级别(-O2)。根据项目需求调整这些选项。LDFLAGS: 定义链接选项,此处假设项目需要链接数学库(-lm),如果有其他库依赖,应在此处添加相应的链接选项。TARGET: 定义生成的可执行文件名。SRCS: 使用wildcard函数查找当前目录下的所有.c文件,将其路径赋值给变量。OBJS: 将SRCS中的.c扩展名替换为.o,得到相应的对象文件列表。
规则部分:
.PHONY: all: 声明all是一个伪目标(不是实际文件),表示其存在的目的是为了组织其他目标的依赖关系。all: $(TARGET): 规定all目标依赖于$(TARGET)(即主程序),当执行make all时,会先确保$(TARGET)被正确构建。$(TARGET): $(OBJS): 定义主程序目标的依赖关系,即由所有的对象文件$(OBJS)链接而成。规则体中使用编译器$(CC),编译选项$(CFLAGS),对象文件列表$(OBJS),输出文件名$@(即$(TARGET)),以及链接选项$(LDFLAGS)来完成链接过程。%.o: %.c: 这是一条模式规则,定义了如何从单个.c源文件生成对应的.o对象文件。规则体中使用编译器$(CC),编译选项$(CFLAGS),源文件名$<(即%.c),输出文件名$@(即%.o),执行编译命令。.PHONY: clean: 声明clean是一个伪目标。规则体中使用rm命令删除中间对象文件$(OBJS)和最终生成的可执行文件$(TARGET)。
使用此Makefile,只需在终端中执行make命令即可编译整个项目。若想清理中间文件和生成物,执行make clean。如果有新增或删除源文件,Makefile会自动识别变化并仅编译改动过的源文件。

相关链接
makefile_makefile 固化字符串-CSDN博客
重新configure和生成Makefile_configure重新编译-CSDN博客
Makefile变量赋值_makefile变量赋值命令的结果-CSDN博客
Makefile中执行pwd赋值给变量_makefile中赋路径至变量-CSDN博客
Makefile搜索到字符串后,添加字符串-CSDN博客
configure指定编译头文件和库文件路径_configure 指定库路径-CSDN博客
动态链接库so_.so动态链接库-CSDN博客
make install 安装的卸载_make install怎么卸载-CSDN博客
相关文章:
linux C语言Makefile
ChatGPT 在Linux中使用Makefile来自动化C语言项目的构建过程是很普遍的实践。Makefile是一个包含了一系列构建目标及如何构建这些目标的依赖和规则的文本文件。 一个基本的Makefile例子可能会像这样: # 定义编译器 CCgcc# 定义编译选项 CFLAGS-I.# 定义可执行文件…...
pgvector扩展在IvorySQL Oracle兼容模式下的应用实践
向量数据库是生成式人工智能(GenAI)的关键组成部分。作为PostgreSQL的重要扩展,pgvector支持高达16000维的向量计算能力,使得PostgreSQL能够直接转化为高效的向量数据库。 IvorySQL基于PostgreSQL开发,因此它同样支持添加pgvector扩展。在Ora…...
c++ 线程概述
C中的线程是并发编程的重要组成部分,它允许程序同时执行多个任务。以下是对C线程的概述: 基本概念: 并发:意味着两个或多个任务同时执行。在单核CPU上,由于只有一个CPU,某一时刻只能执行一个任务࿰…...
纯血鸿蒙APP实战开发——短视频切换实现案例
短视频切换实现案例 介绍 短视频切换在应用开发中是一种常见场景,上下滑动可以切换视频,十分方便。本模块基于Swiper组件和Video组件实现短视频切换功能。 效果图预览 使用说明 上下滑动可以切换视频。点击屏幕暂停视频,再次点击继续播放…...
36.Docker-Dockerfile自定义镜像
镜像结构 镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。 镜像是分层机构,每一层都是一个layer BaseImage层:包含基本的系统函数库、环境变量、文件系统 EntryPoint:入口,是镜像中应用启动的命令 其他:在…...
【webrtc】MessageHandler 4: 基于线程的消息处理:以Fake 收发包模拟为例
G:\CDN\rtcCli\m98\src\media\base\fake_network_interface.h// Fake NetworkInterface that sends/receives RTP/RTCP packets.虚假的网络接口,用于模拟发送包、接收包单纯仅是处理一个ST_RTP包 消息的id就是ST_RTP 类型,– 然后给到目的地:mediachannel处理: 最后消息消…...
C#运算符“/”使用方法
C#中,当需要对两个整数进行除法运算时,结果会被截断为整数部分,即使结果本应是一个小数。这是因为整数除法会丢弃小数部分,只保留整数部分。 要想保留小数部分,需要将至少其中一个操作数转换为float、double或者 deci…...
虚拟机网络桥接模式无法通信,获取到的ip为169.254.X.X
原因:VMware自动选择的网卡可能不对 解决:编辑-虚拟网络编辑器-更改桥接模式-选择宿主机物理网卡,断开虚拟机网络连接后重新连接即可...
【数据结构】初识数据结构
引入: 哈喽大家好,我是野生的编程萌新,首先感谢大家的观看。数据结构的学习者大多有这样的想法:数据结构很重要,一定要学好,但数据结构比较抽象,有些算法理解起来很困难,学的很累。我…...
相机知识的补充
一:镜头 1.1MP的概念 相机中MP的意思是指百万像素。MP是mega pixel的缩写。mega意为一百万,mega pixel 指意为100万像素。“像素”是相机感光器件上的感光最小单位。就像是光学相机的感光胶片的银粒一样,记忆在数码相机的“胶片”ÿ…...
在Linux操作系统中实现磁盘开机自动挂载
当一个分区创建好,然后文件系统创建完毕之后, 需要使用mount命令将分区挂载到空目录上,这个挂载关系是临时的,也就是说当重启机器的时候,硬盘分区于空目录之间的挂载关系就会解除。 磁盘于目录之间的挂载关系断开意味…...
单片机编程实例400例大全(100-200)
今天继续分享单片机编程实例第100-200例。 今天的实例会比前面100复杂一些,我大概看了下,很多都具备实际产品的参考价值。 今天继续分享单片机编程实例第100-200例。 今天的实例会比前面100复杂一些,我大概看了下,很多都具备实际…...
新兴游戏引擎Godot vs. 主流游戏引擎Unity和虚幻引擎,以及版本控制工具Perforce Helix Core如何与其高效集成
游戏行业出现一个新生事物——Godot,一个免费且开源的2D和3D游戏引擎。曾经由Unity和虚幻引擎(Unreal Engine)等巨头主导的领域如今迎来了竞争对手。随着最近“独特”定价模式的变化,越来越多的独立开发者和小型开发团队倾向于选择…...
Leetcode—1652. 拆炸弹【简单】
2024每日刷题(127) Leetcode—1652. 拆炸弹 实现代码 class Solution { public:vector<int> decrypt(vector<int>& code, int k) {int codeSize code.size();vector<int> ans(codeSize, 0);if(k 0) {return ans;}if(k > 0)…...
JAVASE---抽象类相关
instanceof 和类型转换 System.out.println(X instanceof Y );主要看X与Y之间是否存在父子(继承)关系,如果存在则编译可完成,否则无法 进行编译。 1.父类引用指向子类的对象 2.把子类转换为父类,向上转型; 3.把父类转…...
深入理解C++中的inline函数
在C编程中,我们经常会遇到inline关键字,它用于修饰函数,以建议编译器将该函数的调用替换为函数体的直接拷贝。这就是inline函数的基本概念。然而,inline函数并非真正意义上的函数,而只是一种"在调用点插入函数体&…...
Rust 动态数组Vector
导航 一、动态数组是什么,怎么用1、动态数组Vector是什么2、动态数组怎么用(1)创建动态数组(2)尾部追加元素(3)尾部删除元素(4)删除指定位置元素(5࿰…...
Linux主机重启后报错:[FAILED] Failed to start Switch Root.
一、问题描述 某次云主机因计费问题,导致批量重启,重启后发现某台云主机竟进入紧急救援模式(emergency模式),如下所示: 二、原因及处理 1)原因:加载根分区失败,导致无…...
git--.gitignore--使用/详解/实例
简介 本文介绍git的.gitignore忽略文件的用法。 项目中并不是所有文件都需要保存到版本库中的,例如“target”目录及目录下的文件就可以忽略。 忽略某个文件(不提交到版本库的方法):在Git工作区的根目录下创建一个.gitignore文件…...
初识java——javaSE(2)--运算符与逻辑控制【求个关注】
文章目录 一 运算符1.1 算术运算符当两个不同类型的值相加时:/ 运算符%运算符 1.2 关系运算符1.3 逻辑运算符短路:逻辑非 1.4 位运算符&|^位运算符当作逻辑运算符中使用 ~>><<>>> 1.5 赋值运算符1.6 三目运算符 二 逻辑控制if语…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
