关于Makefile中模式规则,自动推导以及包含头文件

关于Makefile中模式规则,自动推导以及包含头文件

一、Makefile里有什么?

Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。
1、显式规则。
显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
2、隐晦规则。
由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。
3、变量的定义。
在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
4、文件指示。
其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。
5、注释
Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“#”。

二、Makefile的文件名

默认的情况下,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件,找到了解释这个文件。在这三个文件名中,最好使用“Makefile”这个文件名,因为,这个文件名第一个字符为大写,这样有一种显目的感觉。最好不要用“GNUmakefile”,这个文件是GNU的make识别的。有另外一些make只对全小写的“makefile”文件名敏感,但是基本上来说,大多数的make都支持“makefile”和“Makefile”这两种默认文件名。
当然,你可以使用别的文件名来书写Makefile,比如:“Make.Linux”,“Make.Solaris”,“Make.AIX”等,如果要指定特定的Makefile,你可以使用make的“-f”和“–file”参数,如:make -f Make.Linux或make --file Make.AIX。

三、Makefile的特殊变量以及变量高级用法

@:表示当前规则中的目标;
^:表示当前规则中所有的依赖;
<:表示当前规则中所有依赖中的第一个依赖;

变量的高级用法:变量值的替换
可以替换变量中的共有的部分,其格式是“ ( v a r : a = b ) ” 或 是 “ (var:a=b)”或是“ (var:a=b){var:a=b}”,其意思是,把变量“var”中所有以“a”字串“结尾”的“a”替换成“b”字串。这里的“结尾”意思是“空格”或是“结束符”。
如:当前文件夹有main.c 和 test.c 文件
OBJ = $(SRCS:.c=.o) 等价于 OBJ = main.o test.o

四、Makefile自动推导规则

CFLAGS:指定头文件路径;
LDFLAGS:指定gcc编译器优化参数以及库文件路径;
LIBS :指定所使用的库如 -lpthread

%.o = %.c
    $(cc) $(CFLAGS) $(LDFLAGS) $(LIBS) -c -o $@ $<

若makefile中只存在以下语句

a.out:main.o test.o
   gcc main.o test.o -o a.out

则,makefile自动推导规则为以下语句

#makefile自动推导
%.o = %.c
    $(cc) $(CFLAGS) $(LDFLAGS) $(LIBS) -c -o $@ $<

(若当前文件下存在main.c 和test.c两个.c文件)自动推导规则展开之后为:

main.o:main.c
   gcc -c -o main.o  main.c

test.o:test.c
   gcc -c -o test.o test.c

五、Makefile中包含头文件

Ubuntu下执行gcc -MM 文件名.c 执行的结果为:

xxx@ubuntu:~/CSDN/about_makefile/makefile_include$ gcc -MM main.c 
main.o: main.c test.h
xxx@ubuntu:~/CSDN/about_makefile/makefile_include$ gcc -MM test.c
test.o: test.c

main.c代码如下

#include "test.h"
#include <stdio.h>

int main(int argc, char const *argv[])
{
    test();
    return 0;
}

test.c代码为:

#include <stdio.h>

void test()
{
    printf("hello world\n");
}

test.h代码如下:

void test();

gcc -MM 文件名.c会输出生成.o文件所依赖的文件(不包括C库文件)
在makefile中可通过gcc -MM 文件名.c生成.h文件的依赖,也即修改.h也许重新make。代码如下:

%.dep:%.c
    $(CC) -MM $< > $@
-include $(DEP)
# - 表示不显示警告信息, include 最先执行 

六、总结并实现

当前目录下-ls:

xxx@ubuntu:~/CSDN/about_makefile/makefile_include$ ls
main.c  Makefile  test.c  test.h

其中main.c test.c test.h文件在第五部分中给出
Makefile代码如下:

TGT = a.out
SRCS = main.c test.c
OBJ = $(SRCS:.c=.o)
DEP = $(SRCS:.c=.dep) 
CC = gcc 
RM = rm

$(TGT):$(OBJ)
    $(CC) $^ -o $@

#a.out:main.o test.o
#   gcc main.o test.o -o a.out

#makefile自动推导

#%.o:%.c
#   $(CC) -c -o $@  $<

#main.o:main.c
#   gcc -c -o main.o  main.c

#test.o:test.c
#   gcc -c -o test.o test.c

%.dep:%.c
    $(CC) -MM $< > $@
-include $(DEP)
# - 表示不显示警告信息, include 最先执行 

#main.dep:main.c
#   gcc -MM main.c > main.dep

#test.dep:test.c
#   gcc -MM test.c > test.dep

clean:
    $(RM) -rf $(TGT)  $(OBJ)  $(DEP)

执行make:

xxx@ubuntu:~/CSDN/about_makefile/makefile_include$ make
gcc  -MM test.c > test.dep
gcc  -MM main.c > main.dep
gcc     -c -o main.o main.c
gcc     -c -o test.o test.c
gcc  main.o test.o -o a.out
xxx@ubuntu:~/CSDN/about_makefile/makefile_include$ ./a.out 
hello world

修改test.h文件:

xxx@ubuntu:~/CSDN/about_makefile/makefile_include$ cat test.h
#include <stdio.h>
void test();
xxx@ubuntu:~/CSDN/about_makefile/makefile_include$ make
gcc     -c -o main.o main.c
gcc  main.o test.o -o a.out
  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值