make工具和Makefile文件

一个简单的Makefile文件

现在有五个文件:main.c add.c add.h sub.c sub.h

main.c中的内容如下:

int main()
{
    return 0;
}

main.c假设是依赖于add.c和sub.c

于是Makefile的内容如下:

.PHONY:clean
main:main.o add.o sub.o
        gcc -Wall -g main.o add.o sub.o -o main
main.o:main.c
        gcc -Wall -g -c main.c -o main.o
add.o:add.c add.h
        gcc -Wall -g -c add.c -o add.o
sub.o:sub.c sub.h
        gcc -Wall -g -c sub.c -o sub.o
clean:
        rm -f main main.o add.o sub.o

main行表示需要生成main目标文件,它的依赖文件是main.o add.o sub.o

main第二行表示需要执行的命令,

gcc的前面必须是一个tab,如果是在vim下编辑的,可能有配置过把tab换成空格

clean是一个伪目标,执行删除文件的操作,在命令行中:make clean即可执行该操作

.PHONY显示指定一个伪目标

Makefile自动化变量

$@:规则的目标文件名

$<:规则的第一个依赖文件名

$^:规则的所有依赖文件列表

所以Makefile文件还可以是这样:

.PHONY:clean
OBJECTS=main.o add.o sub.o
main:$(OBJECTS)
        gcc -Wall -g $^ -o $@
main.o:main.c
        gcc -Wall -g -c $< -o $@
add.o:add.c add.h
        gcc -Wall -g -c $< -o $@
sub.o:sub.c sub.h
        gcc -Wall -g -c $< -o $@
clean:
        rm -f main $(OBJECTS)

OBJECTS表示一个变量名为这main.o add.o sub.o三个文件

第一个gcc 中的$^表示所有依赖的文件列表,$@表示目标文件

以此类推。

Makefile生成多个可执行文件

现在有两个文件,分别是01test.c 02test.c

Makefile文件格式如下:

.PHONY:clean all
BIN=01test 02test
all:$(BIN)
clean:
        rm -f $(BIN)

在命令行执行:make命令,就会生成相应的可执行文件

因为没有给出all的生成命令,而all依赖于$(BIN),编译器推导出$(BIN)的生成规则,生成目标文件

如果不想让编译器推导的话,可以按照下面方法:

.PHONY:clean all
CC=gcc
CFLAGS=-Wall -g
BIN=01test 02test
all:$(BIN)
#%.o:%.c
.c.o:
        $(CC) $(CFLAGS) -c $< -o $@
01test:01test.o
        $(CC) $(CFLAGS) $^ -o $@
02test:02test.o
        $(CC) $(CFLAGS) $^ -o $@
clean:
        rm -r $(BIN) *.o

这里使用了两个变量CC和CFLAGS代替了编译器和编译选项

这里可以使用使用模式规则(%.o:%.c)和后缀规则(.c.o:)将该目录下的.c文件生成相应的.o文件

之后如下希望添加新的文件的话,直接用同样的方法在后面添加就可以了。

Makefile完成二级目录的编译链接

.PHONY:clean
CC=gcc
CFLAGS=-Wall -g
BIN=main
#想要生成的目标文件
SUBDIR=$(shell ls -d */)
#保存的是子文件夹列表
ROOTSRC=$(wildcard *.c)
#匹配所有的.c文件
ROOTOBJ=$(ROOTSRC:%.c=%.o)
#将.c文件替换成.o
SUBSRC=$(shell find $(SUBDIR) -name '*.c')
#将子文件的所有.c文件列出来
SUBOBJ=$(SUBSRC:%.c=%.o)
#将子文件的所有.c文件替换成.o文件

$(BIN):$(ROOTOBJ) $(SUBOBJ)
#$(CC) $(CFLAGS) -o $(BIN) $(ROOTOBJ) $(SUBOBJ)
        $(CC) $(CFLAGS) $^ -o $@
#这里不能将$(BIN)提前到-o之前,因为现在还没有$(BIN)文件
.c.o:
        $(CC) $(CFLAGS) -c $< -o $@
clean:
        rm -f $(BIN) $(ROOTOBJ) $(SUBOBJ)

在该目录下有.c文件,在其他子目录下也有相应的.c文件,

通过Makefile完成对二级目录的编译链接工作。

Makefile多级目录编译

SUBDIRS=test1 test2
.PHONY:default all clean $(SUBDIRS)

default:all
all clean:
        $(MAKE) $(SUBDIRS) TARGET=$@
#$(MAKE)等于MAKE,是一个内置变量,当输入make命令的时候,$@=all
#扩展开=make test1 test2 all
$(SUBDIRS):
        $(MAKE) -C $@ $(TARGET)
#进入test1或者test2的时候,它的依赖就是上一行
#会执行如:make -C test1 all
#make -C 表示:会进入test1文件夹,调用其中的Makefile文件
#相当于make all test1/Makefile

此Makefile文件在多级目录之上,通过这个多级目录调用子目录中的Makefile文件

其中一个子目录Makefile文件:

CC=gcc
BIN=test1
OBJS=test1.o
.PHONY:all clean print
all:print $(BIN)
print:
        @echo "---make all in $(PWD)---"
$(BIN):$(OBJS)
        $(CC) $(OBJS) -o $@
%.o:%.c
        $(CC) -c $<
clean:
        @echo "---make clean in $(PWD)---"
        rm -f $(BIN) $(OBJS)

通过调用子目录的Makefile文件,生成所需要的可执行文件,从而可以实现多级目录的make命令操作

 

 

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部