一个简单的Makefile编译所有c代码文件为每个单独程序
</div>
<!--一个博主专栏付费入口-->
<!--一个博主专栏付费入口结束-->
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-4a3473df85.css">
<div id="content_views" class="markdown_views prism-atelier-sulphurpool-light">
<!-- flowchart 箭头图标 勿删 -->
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
</svg>
<h1><a name="t0"></a><a id="Makefilec_0"></a>一个简单的Makefile编译所有c代码文件为每个单独程序</h1>
笔者初学Makefile
用来方便编译项目,记录一下,若有问题欢迎指正,文件内容附在文末
本文目的
我在./src/
目录下有若干.c
文件,想对每个文件均进行编译,中间代码文件*.o
存放在./build/obj/
下,目标可执行文件放在./build/
下
Makefile的工作流程
- 没有指定输出项目时,Makefile会先在所有目标中找到第一个没有通配符的目标进行构造;例如本文中的
all
,即时它是个伪目标 - 根据构造
all
的规则,需要构造$(BUILD)
,而$(BUILD)
即是$(BUILD_DIR)
下无后缀的可执行文件 - 于是要构造的目标就变为了
$(OBJ_DIR)/%.o
,然后make在规则中继续寻找,找到了一个匹配的规则$(BUILD_DIR)/%: $(OBJ_DIR)/%.o
,但不幸的是该规则依赖OBJS := $(SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
,于是继续寻找 - 下面又找到了
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
,现在不需要继续寻找了,即执行这个规则下的语句进行编译但不链接 - 完成后回到上层进行对
.o
文件的链接,然后继续回到上层,重复这个过程使得对于每一个$(BUILD)
中的目标都得到了生成
不删除中间文件
上述过程会在全部编译完成后使用rm
命令删除中间过程文件,仅保留目标文件,可以通过添加一条
.SECONDARY: $(OBJS)
- 1
让$(OBJS)
成为第二目标,从而不被清理掉
编写clean
方法
我们有时需要对项目进行清理,此时只需要将clean
写进伪目标,然后把它的实现放到最后一个就好了,实现很简单,即使用rm
对编译过程文件和结果文件进行清理即可
一个比较建议的项目树组织
.
├── build
│ ├── 若干可执行文件
│ └── obj
│ └── 若干.o中间代码文件
├── LICENSE
├── Makefile
├── README.md
└── src
└── 若干c源文件
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
附:Makefile全文
# File paths
SRC_DIR := ./src
BUILD_DIR := ./build
OBJ_DIR := $(BUILD_DIR)/obj
Compilation flags
CC := gcc
LD := gcc
CFLAGS := -Wall
Files to be compiled
SRCS := $(wildcard $(SRC_DIR)/*.c)
OBJS :=
(
S
R
C
S
:
(SRCS:
(SRCS:(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
BUILD :=
(
O
B
J
S
:
(OBJS:
(OBJS:(OBJ_DIR)/%.o=$(BUILD_DIR)/%)
Don’t remove *.o files automatically
.SECONDARY: $(OBJS)
all: $(BUILD)
Compile each *.c file as *.o files
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
@echo + CC $<
@mkdir -p
(
O
B
J
D
I
R
)
@
(OBJ_DIR) @
(OBJDIR)@(CC) $(CFLAGS) -c -o $@ $<
Link each *.o file as executable files
$(BUILD_DIR)/%: $(OBJ_DIR)/%.o
@echo + LD $@
@mkdir -p
(
B
U
I
L
D
D
I
R
)
@
(BUILD_DIR) @
(BUILDDIR)@(LD) $(CFLAGS) -o $@ $<
.PHONY: all clean
clean:
rm -rf $(BUILD_DIR)
- 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
- 36
</div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-b6c3c6d139.css" rel="stylesheet">
</div>
</article>
<div class="postTime">
<div class="article-bar-bottom ">
<span class="time">
文章最后发布于: 2018-06-05 14:56:35 </span>
</div>
</div>