博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Linux基础】Makefile改进
阅读量:4282 次
发布时间:2019-05-27

本文共 2613 字,大约阅读时间需要 8 分钟。

现在,我们对上面的makefile进行逐步改进,改进过程如下:
改进一:使用变量
OBJ=//TAB键隔开ain.o mytool1.o mytool2.o
make(OBJ)
//TAB键隔开gcc -o main $(OBJ)
main.o:main.c mytool1.h mytool2.h
//TAB键隔开gcc -c main.c
mytool1.o:mytool1.c mytool1.h
//TAB键隔开gcc -c mytool1.c
mytool2.o:mytool2.c mytool2.h
//TAB键隔开gcc -c mytool2.c
clean:
rm -f main $(OBJ)
Makefile中的变量分为用户自定义变量、预定义变量、自动变量及环境变量。如上例中的OBJ就是用户自定义变量,自定义变量的值由用户自行设定,而预定义变量和自动变量为通常在Makefile都会出现的变量,其中部分有默认值,也就是常见的设定值,当然用户可以对其进行修改。
在Makefile中的定义的变量,就像是C/C++语言中的宏一样,他代表了一个文本字串,在Makefile中执行的时候其会自动原模原样地展开在所使用的地方。其与C/C++所不同的是,你可以在Makefile中改变其值。在Makefile中,变量可以使用在“目标”、“依赖目标”、“命令”或是Makefile的其它部分中。
预定义变量包含了常见编译器、汇编器的名称及其编译选项。Makefile中常见预定义变量及其部分默认值如表 3‑12所示。

01.jpg (78.46 KB, 下载次数: 0)

前天 09:37 上传

变量在声明时需要给予初值,而在使用时,需要给在变量名前加上“$”符号,但最好用小括号“()”或是大括号“{}”把变量给包括起来。如果你要使用真实的“$”字符,那么你需要用“$$”来表示。
在定义变量的值时,在Makefile中有两种方式来定义变量的值。
先看第一种方式,也就是简单的使用“=”号,在“=”左侧是变量,右侧是变量的值,右侧变量的值可以定义在文件的任何一处,也就是说,右侧中的变量不一定非要是已定义好的值,其也可以使用后面定义的值。我们可以使用make中的另一种用变量来定义变量的方法。这种方法使用的是“:=”操作符。
一般在书写Makefile时,各部分变量引用的格式如下:
1.make变量(Makefile中定义的或者是make的环境变量)的引用使用“$(VAR)”格式,无论“VAR”是单字符变量名还是多字符变量名。
2.出现在规则命令行中shell变量(一般为执行命令过程中的临时变量,它不属于Makefile变量,而是一个shell变量)引用使用shell的“$tmp”格式。
3.对出现在命令行中的make变量同样使用“$(CMDVAR)”格式来引用。
改进二:使用自动推导
CC = gcc
OBJ = main.o mytool1.o mytool2.o
make: $(OBJ)
$(CC) -o main $(OBJ)
main.o: mytool1.h mytool2.h
mytool1.o: mytool1.h
mytool2.o: mytool2.h
.PHONY: clean
clean:
rm -f main $(OBJ)
让make自动推导,只要make看到一个.o文件,它就会自动的把对应的.c文件加到依赖文件中,并且gcc -c *.c也会被推导出来,所以Makefile就简化了。
改进三:自动变量($^ $< $@)的应用
CC = gcc
OBJ = main.o mytool1.o mytool2.o
main: $(OBJ)
$(CC) -o $@ $^
main.o: main.c mytool1.h mytool2.h
$(CC) -c $<
mytool1.o: mytool1.c mytool1.h
$(CC) -c $<
mytool2.o: mytool2.c mytool2.h
$(CC) -c $<
.PHONY: clean
clean:
rm -f main $(OBJ)
命令中的“$<”和“$@”是自动化变量,“$^”表示所有的依赖目标集,“$@”表示目标集。“$^”表示依赖文件列表中的第一个依赖文件
改进四:使用函数
CC = gcc
CFLAGS = -Wall -c
LDFLAGS = -lpthread
SRCS = $(wildcard *.c)
OBJS = $(patsubst %c,%o,$(SRCS))
TARGET = main
.PHONY: all clean //“.PHONY”表示,all clean 是个伪目标文件。
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -o $@ $<
clean:
@rm -f *.o $(TARGET)
在这个Makefile中使用wildcard 和patsubst函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智能。make所支持的函数也不算很多,不过已经足够我们的操作了。函数调用后,函数的返回值可以当做变量来使用。wildcard 和patsubst函数的作用分别是扩展通配符和替换通配符。SRCS = $(wildcard *.c)等于指定编译当前目录下所有.c文件。在$(patsubst %.c,%.o,$(SRCS) )中,patsubst把$(SRCS)中的变量符合后缀是.c的全部替换成.o。
通过上面的例子我们得到如下总结:
makefile文件保存了编译器和连接器的参数选项,还表述了所有源文件之间的关系(源代码文件需要的特定的包含文件,可执行文件要求包含的目标文件模块及库等)。创建程序(make程序)首先读取makefile文件,然后再激活编译器、汇编器、资源编译器和连接器以便产生最后的输出,最后输出并生成的通常是可执行文件。创建程序利用内置的推理规则来激活编译器,以便通过对特定cpp文件的编译来产生特定的obj文件。
本文转载于,【Linux基础】Makefile改进
(出处: )
你可能感兴趣的文章
pkg-config
查看>>
Linux内核分析-1/反汇编(堆栈)
查看>>
Linux内核分析-2/时间片轮转多道程序
查看>>
Linux内核分析-4/5/系统调用
查看>>
Linux内核分析-6/进程fork
查看>>
Linux内核分析-7/程序的装载(基于fork)
查看>>
Linux内核分析-8/进程的调度
查看>>
Linux内核分析-9/进程的调度时机
查看>>
访问外部设备寄存器的方法
查看>>
u-boot命令解析
查看>>
GDB调试行号错位
查看>>
vsftpd 配置
查看>>
Failed to initialize Xrander
查看>>
C程序的入口
查看>>
git 中 HEAD 概念
查看>>
autoconf 源码编译 ./configure
查看>>
uboot boot ags
查看>>
oh-my-zsh安装及配置(ubuntu)
查看>>
GDB多线程调试方法
查看>>
驱动 (2.1) 字符驱动框架函数解析
查看>>