Makefile 理解(2)

上次提到了伪目标、变量及函数

先说说伪目标 与 变量: 函数不多但用法很灵活 换句话说就是 太复杂了 以后慢慢讨论
先看一个例子:

OBJS = main.o a.o b.o

main: $(OBJS)
	cc -o main $(OBJS)

main.o: main.h

a.o: a.h

b.o: b.h

.PHONY: clean
clean:
	rm -f main $(OBJS)
伪目标就是以关键字.PHONY开头的,表示clean是一个为目标,因为我们并不会去生成一个clean文件,所以伪目标并不是一个文件而是一个标签,既然在编译时生成了一下目标文件与可执行文件,就应该可以将他们都删除(make clean)以便重新编译,
OBJS = main.o a.o b.o

.PHINY: all
all:main

main: $(OBJS)
	cc -o main $(OBJS)

main.o: main.h

a.o: a.h

b.o: b.h

.PHONY: clean
clean:
	rm -f main $(OBJS)
如果将Makefile写成这样就可以使用make all 编译全部  make clean 删除中间件以及生成的可执行文件,这也是写Makefile的一般规则 当然可以有更所的伪目标根据项目需要

变量的使用
在Makefile中变量就是 一个字符串文本 在使用的地方会自动原样展开,上面那个例子就用到了OBJS这个变量, 展开后就是main.o a.o b.o
在变量是使用时 使用$在变量之前最好加上()或者{ }  $(OBJS)   如果要表示真正的$符就得用$$表示,
FOO = $(PHELLO)
PHELLO = $(HELLO)
HELLO = hello
all:
	echo $(FOO)

make all 时候会打印出hello出来, 这样看起来 变量的声明是不需要一定顺序的 ,但是看起来很费劲, 你得FOO引用到PHELLO 而PHELLO在FOO下面定义,这样如果一个定义引用到隔着n多行的定义 看起来就没那么容易了
为了避免上边的问题,make中使用另一种变量定义方法这样他前面的变量不能使用后面的变量

X := main.c
Y := $(X) a.c
Z := $(Y) b.c

Z的值是main.c a.c b.c
而如果这样:

Z := $(Y) b.c
Y := $(X) a.c
X := main.c
那么Z的值也就是 b.c 因为在Z上面没有定义Y所以默认Y就是空

上面是比较简单的例子看一个带MAKELEVEL的(这是指当make嵌套的层数)

ifeq ($(MAKELEVEL), 0)
CUR_DIR := $(shell pwd)
WHOAMI := $(shell whoami)
HOST_TYPE := $(shell arch)
endif

FOO ?= bar
等价于
ifeq($(origin FOO), undefined)
    FOO = bar
endif 

?=表示在此变量没有定义事对变量赋值,如果变量已经定义了则此句无效

追加变量值

OBJS = main.o a.o b.o
OBJS += c.o
OBJS展开后就是main.o a.o b.o c.o



你可能感兴趣的:(shell,中间件,makefile)