【make】
利用make工具可以自动完成编译工作,这些工作包括:如果只修改了某几个源文件,则只编译这几个源文件。可以大大简化开发工作
【Makefile】make工具通过makefile文件来完成自动维护和编译工作,Makefile文件描述了整个工程的编译连接工作
makefile格式:
目标:依赖
[tab]命令
start:hello.o //start表示开始
gcchello.o –o hello //必须是tab键
@echo“----------compile ok------------------” //@表示不输出echo本身
hello.o:
gcc–c hello.c –o hello.o
//如果hello.o存在则不执行后续语句
clean:
rm–f hello.o //需要通过make clean执行
生成文件名不能设为test,test为内部关键字
【变量使用实例】
CC=gcc
SRCS=hello.c
OBJS=$(SRCS:.c=.o)
EXEC=hello
start:$(OBJS)
gcc $(OBJS) -o $(EXEC)
@echo "-------link finished--------"
$(OBJS):
gcc -c $(SRCS) -o $(OBJS)
@echo "------compile finshed!--------"
clean:
rm -f $(OBJS) hello
@echo "------clean finished!--------"
例如:makefile
.PHONY:clean(显示指定clean为伪目标,以防止该目录下有个clean文件导致无法执行make 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(伪目标无依赖列表只是用来执行代码,可以通过make clean命令执行删除):
rm-f main main.o add.o sub.o
注:如果只想编译某一条文件,可以通过make+目标文件名
【Makefile自动化变量】
$@:规则的目标文件名
$<:规则的第一个依赖文件名
$^:规则的所有依赖文件列表
OBJECTS=value //定义变量
例如:makefile_1
.PHONY:clean
OBJECTS=main.o add.o sub.o
main:$(OBJECTS)
gcc-Wall -g $^-o $@
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:
echo"hello"(如果不想打印在前加@)
rm-f main main.o add.o sub.o
可以通过make -f makefile_1 执行makefile_1中的命令
【makefile编译多个可执行文件】
【模式生成】:%.o:%.c
例1:
.PHONY:clean all
BIN= test1 test2
all:$(BIN)//自动匹配生成同名可执行文件
%.o:%.c //也可以是.c.o:
gcc-Wall -g -c $<-o $@
clean:
rm-f $(BIN)
例2:
.PHONY:clean all
CC=gcc
CFLAGES=-Wall -g
BIN= test1 test2
all:$(BIN)
%.o:%.c
$(CC)$(CFLAGES) -c $<-o $@
test1:test1.o
$(CC)$(CFLAGES) $^ -o $@
test2:test2.o
$(CC)$(CFLAGES) $^ -o $@
clean:
rm-f *.o $(BIN)
例3:
.SUFFIXES:.c .o
CC=g++
SRCS=hello.c
OBJS=$(SRCS:.c=.o)
EXEC=hello
.PHONY:clean
ALL=$(OBJS) $(EXEC)
start:$(OBJS)
$(CC) $(OBJS) -o $(EXEC)
@echo "-------linkfinished--------"
.c.o:
$(CC) -c $< -o $@
@echo "------compile finshed!--------"
clean:
rm -f $(ALL)
@echo "------clean finished!--------"
【同时编译多个源文件】
1.SUFFIXES:.c .o
2 CC=g++
3 SRCS=hello.c\
4 add.c //必须是换行而且Tab
5 OBJS=$(SRCS:.c=.o)
6 EXEC=hello
7 .PHONY:clean
8 ALL=$(OBJS) $(EXEC)
9 start:$(OBJS)
10 $(CC) $(OBJS) -o $(EXEC)
11 @echo "-------link finished--------"
12.c.o:
13 $(CC) -c $< -o $@ 自动根据$(OBJS) 中.o的数量循环编译, 直到编译完所有的.c文件
14 @echo "------compile finshed!--------"
15 clean:
16 rm -f $(ALL)
17 @echo "------clean finished!--------"
【make只编译改变后的文件】
Gcc/g++通过 .o目标文件和对应的.c文件的最晚修改时间比较,判断是否修改了源文件,如果修改了,则重新编译
【make常用内嵌函数】
【函数调用】
$(function argument)
【模式匹配】
$(wildcard PATTREN)
例如:src=$(wildcard *.c)
【模式替换函数】
$(patsubst PATTREN,REPLACEMENT,TEXT)
例如:$(patsubst%.c,%.o.$src)或者$(src:.c=.o)
【shell函数】
$(shell 命令)
【多级目录makefile】
例1:bll dal ui三个目录下均有.c文件,合并生成一个可执行文件
CC = gcc
CFLAGS =-Wall -g
BIN = main
SUBDIR = $(shell ls -d */)
ROOTSRC = $(wildcard *.c)
ROOTOBJ = $(ROOTSRC:%.c=%.o)
SUBSRC = $(shell find $(SUBDIR) -name '*.c')
SUBOBJ = $(SUBSRC:%.c=%.o)
$(BIN):$(ROOTOBJ) $(SUBOBJ)
$(CC) $(CFLAGS) -o $(BIN) $(ROOTOBJ) $(SUBOBJ)
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(BIN) $(ROOTOBJ) $(SUBOBJ)
例2:
SUBDIRS=test1 test2
.PHONY:default all clean $(SUBDIRS)
default:all
all clean:
$(MAKE)$(SUBDIRS) TARGET=$@
$(SUBDIRS):
$(MAKE)-C $@ $(TARGET) //相当于 make all test1/makefile ,进入文件夹中makefile文件将参数all传递进去