target : dependency_files
command
hello.o : hello.c hello.h
gcc -c hello.c -o hello.o
hello.c
#include
void func(void)
{
printf("hello\n");
}
hello.h
void func(void);
main.c
#include
#include "hello.h"
int main(int argc, char **argv)
{
func();
return 0;
}
Makefile
test:hello.o main.o
gcc hello.o main.o -o test
hello.o:hello.c
gcc -c hello.c -o hello.o
main.o:main.c
gcc -c main.c -o main.o
.PHONY:clean
clean:
rm *.o test
创建变量的目的:用来代替一个字符文本字符串:
变量定义的两种方式
变量使用$(VAR)
用“ ”和“ ” 和 “ ”和“$”来表示
类似于编程语言中的宏
eg:
OBJS = kang.o yul.o
CC = gcc
CFLAGS = -Wall -O -g
sunq: $(OBJS)
$(CC) $(OBJS) -o sunq.o
kang.o: kang.c kang.h
$(CC) $(CFLAGS) -c kang.c -o hang.o
yul.o: yul.c yul.h
$(CC) $(CFLAGS) -c yul.c -o yul.o
将上面的例子修改后:
OBJS = hello.o main.o
CC = gcc
CFLAGS = -Wall -O -g
test:$(OBJS)
$(CC) $(OBJS) -o test
hello.o:hello.c
$(CC) $(CFLAGS) -c hello.c -o hello.o
main.o:main.c
$(CC) $(CFLAGS) -c main.c -o main.o
.PHONY:clean
clean:
rm *.o test
m:=mm
x:=$(m)
y:=$(x)bar
x:=late
echo $(x) $(y)
dir:=/foo/bar
FOO?=bar
含义是,如果FOO没有被定义过,那么变量FOO的值就是"bar",如果FOO先前被定义过,那么这条语句将什么也不做,其等价于:
ifeq ($(origin FOO),undefined)
FOO = bar
endif
你可以通过+=为已定义的变量添加新的值
Main=hello.o hello-1.o
Main+=hello-2.o
eg:
Hello: main.c main.h
$(CC) -o hello main.c
clean:
$(RM) hello
修改后例子:
OBJS = hello.o main.o
CC = gcc
CFLAGS = -Wall -O -g
test: $(OBJS)
$(CC) $(OBJS) -o $@
hello.o: hello.c
$(CC) $(CFLAGS) -c $< -o hello.o
main.o: main.c
$(CC) $(CFLAGS) -c $^ -o main.o
.PHONY: clean
clean:
rm *.o test
直接运行make
选项
VPATH : 虚路径
在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存放在不同的目录中。所以,当make需要去找寻文件的依赖关系时,你可以在文件前加上路径,但最好的方法是把一个路径告诉make,让make在自动去找。
Makefile文件中的特殊变量“VPATH”就是完成这个功能的,如果没有指明这个变量,make只会在当前的目录中去找寻依赖文件和目标文件。如果定义了这个变量,那么,make就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件了。
VPATH = src:…/headers
上面的的定义指定两个目录,“src”和“…/headers”,make会按照这个顺序进行搜索。目录由“冒号”分隔。(当然,当前目录永远是最高优先搜索的地方)
#include
void func()
{
printf("hello\n");
}
hello/Makefile
../$(OBJ_DIR)/hello.o: hello.c
$(CC) -c $^ -o $@
hello1/hello1.c
#include
void func1()
{
printf("hello1\n");
}
hello1/Makefile
../$(OBJ_DIR)/hello1.o: hello1.c
$(CC) -c $^ -o $@
main/main.c
#include "hello.h"
#include "hello1.h"
int main(int argc, char **argv)
{
func();
func1();
return 0;
}
main/Makefile
../$(OBJ_DIR)/main.o: main.c
$(CC) -c $^ -o $@ -I ../include
obj/Makefile
../$(BIN_DIR)/$(BIN): $(OBJS)
gcc $^ -o $@
./Makefile
SUBDIRS += hello \
hello1 \
main \
obj
OBJS = hello.o hello1.o main.o
CC = gcc
CFLAGS = -Wall -O -g
OBJ_DIR = obj
BIN_DIR = bin
BIN = myapp
#将参数传给子目录的makefile
export CC OBJS SUBDIRS CFLAGS OBJ_DIR BIN_DIR BIN
all: CHECK_DIR $(SUBDIRS)
CHECK_DIR:
mkdir -p $(BIN_DIR)
$(SUBDIRS): ECHO
make -C $@
ECHO:
@echo $(SUBDIRS)
@echo begin complie
clean:
$(RM) $(OBJ_DIR)/*.o
rm -rf $(BIN_DIR)