Makefile
这里主要通过示例展示makefile的用法
make
(GNU make) 是一个项目构建工具,即方便地编译、链接多个源代码文件,自动决定哪些源文件需要重新编译,从而高效地构建自己的项目。
- 基本规则
1
2
3
4
5
目标文件:依赖文件
命令1
命令2
...
命令n
- 一些符号含义
$*
不包含扩展名的目标文件名称。$+
所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。$<
第一个依赖文件的名称。$?
所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。$@
目标的完整名称。$^
所有的依赖文件,以空格分开,不包含重复的依赖文件。$%
如果目标是归档成员,则该变量表示目标的归档成员名称。
Example 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 变量定义
INCL=-I${HOME}/incl
BIN=$(HOME)/bin
OBJ1=hellocpp.o
OBJ2=hello.o
# 隐含规则,即所有的.o文件都首先通过以下规则编译生成
.SUFFIXES: .cpp .c
.cpp.o:
g++ ${INCL} -c $<
.c.o:
gcc ${INCL} -c $<
# 目标可执行文件
all: hellocpp hello
# C++编译
hellocpp:${OBJ1}
# @表示当前命令不显示
@echo "开始编译"
g++ -o $@ $?
@rm -f ${OBJ1}
@mv $@ ${BIN}
@echo "编译结束"
@echo ""
#C编译
hello:${OBJ2}
@echo "开始编译"
gcc -o $@ $?
@rm -f ${OBJ2}
@mv $@ ${BIN}
@echo "编译结束"
@echo ""
Reference: Makefile由浅入深
Example 2
示例项目:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.
├── include # 本文件下包含构建目标文件所需的头文件
│ ├── become_daemon.h
│ ├── error_functions.h
│ ├── get_num.h
│ ├── inet_sockets.h
│ └── tlpi_hdr.h
├── lib # 本文件夹下包含构建目标文件所需的库文件和依赖文件
│ ├── become_daemon.c
│ ├── ename.c.inc
│ ├── error_functions.c
│ ├── get_num.c
│ └── inet_sockets.c
└── src # 本文件夹包含项目的源文件、Makefile、目标文件以及可执行文件
├── obj
│ ├── become_daemon.o
│ ├── client.o
│ ├── error_functions.o
│ ├── get_num.o
│ ├── inet_sockets.o
│ └── server.o
├── Makefile
├── client
├── client.c
├── server
└── server.c
-
simple Makefile
-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
# compile obj/error_functions.o: ../lib/error_functions.c gcc -c -o obj/error_functions.o ../lib/error_functions.c obj/get_num.o: ../lib/get_num.c gcc -c -o obj/get_num.o ../lib/get_num.c obj/inet_sockets.o: ../lib/inet_sockets.c gcc -c -o obj/inet_sockets.o ../lib/inet_sockets.c obj/become_daemon.o: ../lib/become_daemon.c gcc -c -o obj/become_daemon.o ../lib/become_daemon.c obj/client.o: client.c gcc -c -o obj/client.o client.c obj/server.o: server.c gcc -c -o obj/server.o server.c # link client: obj/client.o obj/error_functions.o obj/get_num.o obj/inet_sockets.o obj/become_daemon.o gcc -o client obj/client.o obj/error_functions.o obj/get_num.o obj/inet_sockets.o obj/become_daemon.o server: obj/server.o obj/error_functions.o obj/get_num.o obj/inet_sockets.o obj/become_daemon.o gcc -o server obj/server.o obj/error_functions.o obj/get_num.o obj/inet_sockets.o obj/become_daemon. # .PHONY表示clean不是一个文件而是一个命令的名字。 .PHONY: clean clean: rm obj/*.o client server
-
-
使用变量、模式规则、函数后的Makefile
-
make
内建函数的语法为:-
1
$(function arguments)
-
-
如下,
make
内建函数patsubst
,它的作用是给_DEPS
变量的每个元素(空格分开)添加$(ODIR)/
前缀。 -
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
CC=gcc CFLAGS=-Wall -Wformat=0 ODIR=obj IDIR=../include LDIR=../lib PROGRAM=client server _DEPS = error_functions.o get_num.o inet_sockets.o become_daemon.o DEPS = $(patsubst %, $(ODIR)/%,$(_DEPS)) all: $(PROGRAM) # compile # 模式规则,将$(LDIR)中的所有.c和当前文件夹下的.c文件编译生成.o文件 $(ODIR)/%.o: $(LDIR)/%.c $(CC) -c -o $@ $< $(ODIR)/%.o: %.c $(CC) -c -o $@ $< # link # addsuffix函数表示给$(PROGRAM)每个元素添加.o后缀 $(PROGRAM): $(patsubst %, $(ODIR)/%,$(addsuffix .o,$(PROGRAM))) $(DEPS) $(CC) -o $@ $(ODIR)/$@.o $(DEPS) .PHONY: clean clean: rm $(ODIR)/*.o $(PROGRAM)
-
Reference: GNU make/Makefile 简明实用教程
Example 3
-
更简单的例子
-
1 2 3 4 5 6
. ├── hello.c ├── hellomake.c ├── helloworld.c ├── thread.c └── multithreads.c
-
1 2 3 4 5 6 7
CC=gcc CFLAGS=-O2 -pthread TRAGET=hello hellomake helloworld thread multithreads all:$(TRAGET) clean: rm $(TRAGET)