Makefile文件编写

简介: 源代码文件 main3.c 1 #include 2 #include "static_lib.h" 3 #include "fun.h" 4 5 int main(void){ 6 int a=2,b=3; 7 printf("add:%d s...

源代码文件

main3.c

 1 #include <stdio.h>
 2 #include "static_lib.h"
 3 #include "fun.h"
 4 
 5 int main(void){
 6     int a=2,b=3;
 7     printf("add:%d sub:%d mul:%d div:%d\n",add(a,b),sub(a,b),mul(a,b),div(a,b));
 8     fun1();
 9     return 0;
10 }

static_lib.h和

1 extern int add(int a,int b);
2 extern int sub(int a,int b);
3 extern int mul(int a,int b);
4 extern int div(int a,int b);

static_lib.c

 1 int add(int a,int b){
 2     return a + b;
 3 }
 4 
 5 int sub(int a,int b){
 6     return a - b;
 7 }
 8 
 9 int mul(int a,int b){
10     return a * b;
11 }
12 
13 int div(int a,int b){
14     return a / b;
15 }

fun.h和

1 extern void fun1();

fun.c

1 #include <stdio.h>
2 void fun1(){
3     printf("fun1 ...");
4 }

其中stati_lib.c中的文件编译成静态库

正常编译

按照正常的编译方法,这个程序可以按如下顺序编译

但是每次改了源代码之后都这样子编译显然是不明智的,所以需要编写一个Makefile规则文件

Makefile Base

Makefile的规则为

其中target是目标文件或者动作

prerequisites是生成目标依赖的文件

command是规则执行的命令,如果命令与依赖规则在一行,则以';'分割,如果在另一行,则以tab开头

编写一个最简单的Makefile编译这些源码

 1 app3  : static_lib.a fun.o
 2     gcc main3.c static_lib.a fun.o -o app3
 3 
 4 fun.o :
 5     gcc -c fun.c
 6 static_lib.o : 
 7     gcc -c static_lib.c
 8 
 9 static_lib.a : static_lib.o
10     ar rcs static_lib.a static_lib.o
11 
12 clean :
13     rm static_lib.a static_lib.o fun.o app3

执行make clean可以将原来的清理掉

执行make会重新编译源码

 这样当我们修改源代码之后就可以简单的编译源码了

Makefile hidden

但上面的Makefile显然不够简洁,我们可以利用一些make的隐式规则,简写makefile,这些隐含规则可以通过 make -p 指令查看。

1 app3  : static_lib.a fun.o main3.o
2     gcc main3.o fun.o static_lib.a -o app3
3 
4 static_lib.a : static_lib.o # 隐含会寻找*.c文件编译成*.o文件
5     ar rcs static_lib.a static_lib.o
6 
7 clean :
8     rm *.a *.o app3

执行make可以看到依然能够编译成功

其中cc是一个符号链接

Makefile Var

还可以进一步使用一些变量,进一步提高Makefile的可维护性

 1 CC       = gcc
 2 OBJS     = main3.o static_lib.a fun.o
 3 GEN_OPTS = -o 
 4 app3  : $(OBJS)
 5     $(CC) $(OBJS) $(GEN_OPTS) app3
 6 
 7 static_lib.a : static_lib.o # 隐含会寻找*.c文件编译成*.o文件
 8     ar rcs static_lib.a static_lib.o
 9 
10 clean :
11     rm *.a *.o app3

执行make

而且可以看到 1,2,4行的gcc存在缩进,说明隐含规则也使用指明的CC变量编译。

Makefile autoVar

进一步的,我们可以使用一些自动化的变量。

 1 CC       = gcc
 2 OBJS     = main3.o static_lib.a fun.o
 3 GEN_OPTS = -o 
 4 app3  : $(OBJS)
 5     $(CC) $(OBJS) $(GEN_OPTS) app3
 6 
 7 static_lib.a : static_lib.o # 隐含会寻找*.c文件编译成*.o文件
 8     ar rcs $@ $^
 9 
10 clean :
11     rm *.a *.o app3

其中自动化变量 $@表示规则中的目标文件集,$^表示依赖集,这个Makefile执行之后也能得到想要的结果

Makefile Fun

最后结合前面的变量,再结合函数,等写一个更完善的makefile,可以做到增加了新的c文件或h文件不需要修改Makefile文件,再次之前,首先将static_lib.* 移动到lib目录下,将其余源码文件移动到src目录。

并修改main3.c的include为 ../lib/static_lib.h,修改Makefile文件如下

 1 CC       = gcc
 2 SRC      = ./src
 3 LIB      = ./lib
 4 OBJS     = $(patsubst %.c, %.o, $(wildcard $(SRC)/*.c))
 5 LIBS     = $(patsubst %.c, %.a, $(wildcard $(LIB)/*.c))
 6 GEN_OPTS = -o 
 7 app3  : $(OBJS) $(LIBS)
 8     $(CC) $(OBJS) $(LIBS) $(GEN_OPTS) app3
 9     @echo "gen done"
10 # 将lib目录下的c文件编译成a库文件
11 $(LIBS) : $(patsubst %.c, %.o, $(wildcard $(LIB)/*.c))
12     ar rcs $@ $^
13 
14 clean :
15     -rm $(SRC)/*.o $(LIB)/*.a app3
16     @echo clean done.

其中patsubst是一个函数,替换通配符,wildcard函数扩展通配符,展开目录下的所有匹配文件。

命令前面加'-'的话表示即便出错也继续执行。

 

目录
相关文章
|
存储 C语言 C++
37.【C/C++ 静态数据成员和静态成员函数 (超详解)】
37.【C/C++ 静态数据成员和静态成员函数 (超详解)】
381 0
|
5月前
|
数据采集 存储 算法
人才招聘系统开发全解析:从技术底层到商业逻辑的完整架构优雅草卓伊凡|小无|果果|阿才
人才招聘系统开发全解析:从技术底层到商业逻辑的完整架构优雅草卓伊凡|小无|果果|阿才
197 2
人才招聘系统开发全解析:从技术底层到商业逻辑的完整架构优雅草卓伊凡|小无|果果|阿才
|
10月前
|
Java
Java 面向对象编程的三大法宝:封装、继承与多态
本文介绍了Java面向对象编程中的三大核心概念:封装、继承和多态。
514 15
|
11月前
|
人工智能 自然语言处理 自动驾驶
当视觉大模型陷入认知失调,马里兰大学构建了一个幻觉自动生成框架
马里兰大学研究人员提出AutoHallusion框架,旨在通过自动化生成幻觉图像和问题对,深入研究大型视觉语言模型(LVLMs)中的幻觉现象。幻觉指LVLMs生成与图像内容不符的描述,限制其广泛应用。AutoHallusion通过异常对象插入、配对对象插入和相关对象删除三种策略,揭示LVLMs在处理视觉信息时的弱点。实验结果显示,该框架能在多种SOTA模型上以高成功率引发幻觉,为改进模型提供宝贵线索。未来将提升图像质量和扩展问题设计范围。论文链接:https://arxiv.org/pdf/2406.10900
183 27
|
10月前
|
Java API
一个线上问题让我发现了Calendar类中的秘密-周一真的是每周的第一天吗?
在开发一个查询未完成业务的需求时,遇到了一个问题:清明节后周日提前查出了应于周一才显示的未完成业务。原因是代码中使用了`Calendar`类,默认将周日视为一周的第一天,导致当天获取的“本周一”实际上是下周一。通过调试发现,`Calendar`类的默认设置与实际需求不符。为解决此问题,提出了三种方案:1. 加入判断机制,对周日特殊处理;2. 修改`Calendar`类的设置,将周一设为一周的第一天;3. 使用其他日期处理库如Hutool,默认以周一为一周的开始。此次排错提醒我们在日常开发中需深入了解所用类库的实现细节,以便更好地应对潜在问题。
335 14
|
10月前
|
存储 缓存 安全
分布式系统架构7:本地缓存
这是小卷关于分布式系统架构学习的第10篇文章,主要介绍本地缓存的基础理论。文章分析了引入缓存的利弊,解释了缓存对CPU和I/O压力的缓解作用,并讨论了缓存的吞吐量、命中率、淘汰策略等属性。同时,对比了几种常见的本地缓存工具(如ConcurrentHashMap、Ehcache、Guava Cache和Caffeine),详细介绍了它们的访问控制、淘汰策略及扩展功能。
235 6
|
Windows
Windows的mklink使用方法
【5月更文挑战第20天】Windows的mklink使用方法
1079 0
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
318 1
|
负载均衡 应用服务中间件 数据库
公有云降本增效最佳实践
公有云降本增效最佳实践