c语言的makefile,C语言之Makefile基础(二)

上一章的Makefile写的中规中矩,比较繁琐,是为了讲清楚基本概念,其实Makefile有很多灵活的写法,可以写的更简洁,同时减少出错的可能

一个目标依赖的所有条件不一定非得写在一个规则中,也可以拆开来写,例如:

main.o: main.h stack.h maze.h

main.o: main.c

gcc -c main.c

就相当于:

main.o: main.c main.h stack.h maze.h

gcc -c main.c

如果一个目标拆开写多条规则,其中只有一条规则允许有命令列表,其他规则应该没有命令列表,否则make会报警告并采用最后一条规则的命令列表。

于是,之前的Makefile文件我们还可以写成这样:

main: main.o stack.o maze.o

gcc main.o stack.o maze.o -o main

main.o: main.h stack.h maze.h

stack.o: stack.h main.h

maze.o: maze.h main.h

main.o: main.c

gcc -c main.c

stack.o: stack.c

gcc -c stack.c

maze.o: maze.c

gcc -c maze.c

clean:

-rm main *.o

.PHONY: clean

这样虽然也允许执行,但相比以前更繁琐了些,于是我们把提出来的三条规则删去,写成:

main: main.o stack.o maze.o

gcc main.o stack.o maze.o -o main

main.o: main.h stack.h maze.h

stack.o: stack.h main.h

maze.o: maze.h main.h

clean:

-rm main *.o

.PHONY: clean

这样就比原来简单多了,可是现在main.o、stack.o和maze.o这三个目标连编译命令都没有了,怎么编译呢?试试看:

[[email protected] linux_c]# make

cc -c -o main.o main.c

cc -c -o stack.o stack.c

cc -c -o maze.o maze.c

gcc main.o stack.o maze.o -o main

现在解释一下前三条编译命令怎么来的。如果一个目标在Makefile中的所有规则都没有命令列表,make会尝试在内建的隐含规则数据库中查找适用的规则。make的隐含规则数据库可以用make -p命令来打印,打印出来的格式也是Makefile的格式,包含很多变量和规则,其中和我们这个例子有关的隐含规则有:

# default

OUTPUT_OPTION = -o $@

# default

CC = cc

# default

COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

%.o: %.c

# commands to execute (built-in):

$(COMPILE.c) $(OUTPUT_OPTION) $<

#号在Makefile中表示单行注释。CC是一个Makefile变量,用CC = cc定义和赋值,用$(CC)取它的值,其值应该是cc。Makefile变量像C的宏定义一样,代表一串字符,在取值的地方展开。cc是一个符号链接,通常指向gcc,在有些Unix系统上可能指向另外一种C编译器

[[email protected] linux_c]# which cc

/usr/bin/cc

[[email protected] linux_c]# ls -l /usr/bin/cc

lrwxrwxrwx. 1 root root 3 Feb 13 11:13 /usr/bin/cc -> gcc

在make -p中包含这一段定义:

# default

COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

%.o: %.c

# commands to execute (built-in):

$(COMPILE.c) $(OUTPUT_OPTION) $<

CFLAGS这个变量没有定义,$(CFLAGS)展开是空,CPPFLAGS和TARGET_ARCH也是如此,这样,$(COMPILE.c)展开应该是cc 空 空 空 -c,去掉“空”就得到cc -c。所以,%.o: %.c规则的命令 $(COMPILE.c) $(OUTPUT_OPTION) $

[email protected]$

main.o: main.c

cc -c -o main.o main.c

同理:

stack.o: stack.c

cc -c -o stack.o stack.c

maze.o也同样处理。这三条规则可以由make的隐含规则推导出来,所以就不必写在Makefile中了

先前我们写Makefile都是以目标为中心,一个目标依赖若干条件,现在换个角度,以条件为中心,Makefile还可以这么写:

main: main.o stack.o maze.o

gcc main.o stack.o maze.o -o main

main.o stack.o: main.h

main.o maze.o: maze.h

main.o stack.o: stack.h

clean:

-rm main *.o

.PHONY: clean

写规则的目的是让make建立依赖关系图,不管怎么写,只要把所有的依赖关系描述清楚就行,对于多目标的规则,make会拆成几条单目标的规则来处理,例如:

target1 target2: prerequisite1 prerequisite2

command $< -o $@

这样的规则相当于:

target1: prerequisite1 prerequisite2

command prerequisite1 -o target1

target2: prerequisite1 prerequisite2

command prerequisite1 -o target2

注意这两条规则的命令列表是一样的,[email protected]

原文:https://www.cnblogs.com/beiluowuzheng/p/9266463.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值