Makefile概述——常用操作记录

一、导入

1、编写文件a.c

#include <stdio.h>

int main(void)
{
	func();
	return 0;
}

2、编写文件b.c

#include <stdio.h>

void func(void)
{
	printf("Hello World.\n");
}

3、linux环境下执行命令:

gcc -o test a.c b.c	

 

4、在当前目录下会生成一个test的可执行文件,在linux环境下执行命令运行test

./test

5、分析:通过gcc -o test a.c b.c 命令行对a.c、b.c进行编译、链接生成test可执行程序还是比较简单的,这是因为文件数量少,可以这样用, 但是当文件数量很多时(如几千几万个量级), 没必要每次对所有文件都编译、链接,可以仅对改动的文件进行编译,生成.o文件, 然后再对所有.o文件进行链接生成可执行程序文件

6、上述分析,可以借助编写Makefile文件来实现。

 

 

二、Makefile语法及常用功能

1、Makefile的核心——规则:

目标:依赖1 依赖2...

[TAB]命令

 

2、执行场景:

当“目标文件”不存在,

某个依赖文件比目标文件“新”,

则:执行“命令”

 

3、对上述a.c b.c编写Makefile文件

1) 在与a.c、b.c同级目录下,新建Makefile文件,编写内容如下:

test : a.o b.o
	gcc -o test a.o b.o
	
a.o : a.c
	gcc -c -o a.o a.c
	
b.o : b.c
	gcc -c -o b.o b.c
	
clean:
	rm *.o test

 

 

 

2)linux环境下执行 make 和 make clean命令,观察目录内文件变化:

运行make命令后,目录内生成test可执行程序文件,通过./test命令即可运行该程序;

运行make clean 命令, 目录内左右 .o 和 test 文件被清除。

 

4、Makefile的语法

1)通配符:%.o

  •  $@ 表示目标
  •  $< 表示第一个依赖文件
  • $^ 表示所有依赖文件

使用通配符修改上述Makefile文件,如下:

 

test: a.o b.o
	gcc -o test $^
	
%.o : %.c 
	gcc -c -o $@ $<
	
clean:
	rm *.o test

问题及分析:当前文件夹中若有同名的clean文件时,make clean命令将不会被执行,可以使用假想目标:.PHONY来解决。

2) 假想目标:.PHONY

如下:

test: a.o b.o
	gcc -o test $^
	
%.o : %.c 
	gcc -c -o $@ $<
	
clean:
	rm *.o test
	
.PHONY: clean

 

说明:添加 .PHONY: clean 后,就不会判断名为clean的文件是否存在,而是直接执行make clean命令。

 

3)即时变量、延时变量,export

简单变量(即使变量):

A := xxx         # A的值即可确定,在定义时即确定

B = xxx          # B的值使用到时才确定

 

:=                   # 即时变量

=                    # 延时变量

?=                  # 延时变量,如果是第一次定义才起效果,如果在前面该变量已定义则忽略该句

+=                  # 附加, 它是即时变量还是延时变量取决于前面的定义

 

 

 

三、Makefile语法及常用功能

a.   $(foreach var, list, text)

b.   $(filter pattern..., text)                                                  #在text中取出符合pattern格式的值

      $(filter-out pattern..., text)                                            #在text中取出不符合pattern格式的值

c.   $(wildcard pattern)                                                       #pattern定义了文件名的格式,

                                                                                          #wildcard取出其中存在的文件

d.   $(patsubst pattern, replacement, $(var))                     #从列表中取出每一个值,

                                                                                          #如果符合pattern

                                                                                          #则替换为replacement

 

 

四、Makefile实例

1、改进:支持头文件依赖

(详细介绍可以参考这篇博客: http://blog.csdn.net/qq1452008/article/details/50855810)

gcc -M c.c                                      //打印出依赖

gcc -M -MF c.d c.c                        //把依赖写入文件c.d

gcc -c -o c.o c.c -MD -MF c.d        //编译c.o, 把依赖写入文件c.d

 

自动添加依赖文件, 举例:

objs = a.o b.o c.o

#从objs列表中取出符合%的值(此处取出所有),然后替换为替换为.%.d
dep_files := $(patsubst %, .%.d, $(objs))	

#取出dep_files中存在的文件,即取出所有依赖文件
dep_files := $(wildcard $(dep_files))  

test: $(objs)
	gcc -o test $^
	
#判断是否包含依赖文件,若不包含,则执行include包含依赖文件命令
ifneq ($(dep_files),)
include $(dep_files)
endif
	
c.o : c.c c.h

#编译%.o,把依赖写入文件%.d
%.o : %.c 
	gcc -c -o $@ $< -MD -MF .$@.d  
	
clean:
	rm *.o test
	
distclean:
	rm $(dep_files)
	
.PHONY: clean

 

2、添加CFLAGS

 

#将所有警告设置成错误提醒, 设置所有头文件路径到 ./ 即当前路径查找 CFLAGS = -Werror -I./

objs = a.o b.o c.o

#从objs列表中取出符合%的值(此处取出所有),然后替换为替换为.%.d
dep_files := $(patsubst %, .%.d, $(objs))	

#取出dep_files中存在的文件,即取出所有依赖文件
dep_files := $(wildcard $(dep_files))  

#将所有警告设置成错误提醒, 设置所有头文件路径到 ./ 即当前路径查找
CFLAGS = -Werror -I./	

test: $(objs)
	gcc -o test $^
	
#判断是否包含依赖文件,若不包含,则执行include包含依赖文件命令
ifneq ($(dep_files),)
include $(dep_files)
endif
	
c.o : c.c c.h

#编译%.o,把依赖写入文件%.d
%.o : %.c 
	gcc -c -o $@ $< -MD -MF .$@.d  
	
clean:
	rm *.o test
	
distclean:
	rm $(dep_files)
	
.PHONY: clean

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
makefile 实例分析 Makefile 语法分析 第一部分 VERSION = 2# 给变量VERSION赋值 PATCHLEVEL = 6# 给变量PATCHLEVEL赋值 SUBLEVEL = 22# 给变量SUBLEVEL赋值 EXTRAVERSION = .6# 给变量EXTRAVERSION赋值 NAME = Holy Dancing Manatees, Batman!# 给变量NAME赋值 # *DOCUMENTATION*# To see a list of typical targets execute "make help"# More info can be located in ./README# Comments in this file are targeted only to the developer, do not# expect to learn how to build the kernel reading this file. # Do not:# o use make's built-in rules and variables#    (this increases performance and avoid hard-to-debug behavour);# o print "Entering directory ...";MAKEFLAGS += -rR --no-print-directory# 操作符“+=”的作用是给变量(“+=”前面的MAKEFLAGS)追加值。# 如果变量(“+=”前面的MAKEFLAGS)之前没有定义过,那么,“+=”会自动变成“=”;# 如果前面有变量(“+=”前面的MAKEFLAGS)定义,那么“+=”会继承于前次操作的赋值符;# 如果前一次的是“:=”,那么“+=”会以“:=”作为其赋值符# 在执行make时的命令行选项参数被通过变量 “MAKEFLAGS”传递给子目录下的make程序。# 对于这个变量除非使用指示符“unexport”对它们进行声明,它们在整个make的执行过程中始终被自动的传递给所有的子make。# 还有个特殊变量SHELL与MAKEFLAGS一样,默认情况(没有用“unexport”声明)下在整个make的执行过程中被自动的传递给所有的子make。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xw-何妨吟啸且徐行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值