CC = gcc
ELF = ./Executable/main
SRC = $(wildcard ./Source/*.c)
CONFIG = -I./Include -L./Library
OBJ = $(patsubst %.c,%.o,$(SRC))
$(ELF):$(OBJ)
$(CC) $^ -o $@ $(CONFIG)
%.o:%.c
$(CC) $< -o $@ -c $(CONFIG)
clean:
$(RM) $(ELF) $(OBJ)
1. 变量定义
CC = gcc
-
CC
:指定 C 编译器为gcc
。
ELF = ./Executable/main
-
ELF
:指定最终生成的可执行文件路径为./Executable/main
。
SRC = $(wildcard ./Source/*.c)
-
SRC
:使用wildcard
函数获取./Source/
目录下所有.c
文件的列表。-
例如,如果
./Source/
目录下有main.c
和utils.c
,则SRC = ./Source/main.c ./Source/utils.c
。
-
CONFIG = -I./Include -L./Library
-
CONFIG
:定义编译和链接的配置选项。-
-I./Include
:指定头文件搜索路径为./Include
。 -
-L./Library
:指定库文件搜索路径为./Library
。
-
OBJ = $(patsubst %.c,%.o,$(SRC))
-
OBJ
:使用patsubst
函数将SRC
中的.c
文件替换为.o
文件。-
例如,如果
SRC = ./Source/main.c ./Source/utils.c
,则OBJ = ./Source/main.o ./Source/utils.o
。
-
2. 目标规则
$(ELF):$(OBJ)
$(CC) $^ -o $@ $(CONFIG)
-
目标:
$(ELF)
(即./Executable/main
)。 -
依赖:
$(OBJ)
(即所有的.o
文件)。 -
命令:
-
使用
$(CC)
(即gcc
)将所有的.o
文件($^
)链接为可执行文件($@
)。 -
$(CONFIG)
提供了-I./Include
和-L./Library
选项。
-
3. 编译规则
%.o:%.c
$(CC) $< -o $@ -c $(CONFIG)
-
目标:
%.o
(即所有的.o
文件)。 -
依赖:
%.c
(即对应的.c
文件)。 -
命令:
-
使用
$(CC)
(即gcc
)将.c
文件($<
)编译为目标文件($@
)。 -
-c
选项表示只编译不链接。 -
$(CONFIG)
提供了-I./Include
选项。
-
4. 清理规则
clean:
$(RM) $(ELF) $(OBJ)
-
目标:
clean
。 -
命令:
-
使用
$(RM)
(即rm -f
)删除可执行文件($(ELF)
)和所有的.o
文件($(OBJ)
)。
-
5. 目录结构
假设项目的目录结构如下:
.
├── Include/
│ └── utils.h
├── Library/
│ └── libmylib.a
├── Source/
│ ├── main.c
│ └── utils.c
├── Executable/
└── Makefile
-
Include/
:存放头文件(如utils.h
)。 -
Library/
:存放库文件(如libmylib.a
)。 -
Source/
:存放源代码文件(如main.c
和utils.c
)。 -
Executable/
:存放生成的可执行文件(如main
)。
6. 编译和链接过程
-
编译:
-
main.c
和utils.c
会被编译为目标文件main.o
和utils.o
。 -
编译时,
-I./Include
确保编译器能够找到utils.h
。
-
-
链接:
-
main.o
和utils.o
会被链接为可执行文件./Executable/main
。 -
链接时,
-L./Library
确保链接器能够找到libmylib.a
。
-
7. 运行 Makefile
-
编译和链接:
make
生成可执行文件
./Executable/main
。 -
清理生成的文件:
make clean
删除
./Executable/main
和所有的.o
文件。
8. 改进建议
-
添加库链接:
-
如果项目需要链接库文件(如
libmylib.a
),可以在链接命令中添加-l
选项:$(ELF):$(OBJ) $(CC) $^ -o $@ $(CONFIG) -lmylib
-
-
支持动态库:
-
如果使用动态库(如
libmylib.so
),可以添加-fPIC
选项:%.o:%.c $(CC) $< -o $@ -c $(CONFIG) -fPIC
-
-
优化
clean
规则:-
确保
clean
规则不会误删文件:clean: $(RM) $(ELF) $(OBJ) @echo "Clean complete."
-
总结
-
该 Makefile 实现了从源代码到可执行文件的完整编译和链接过程。
-
通过
wildcard
和patsubst
函数,自动处理源文件和目标文件。 -
通过
CONFIG
变量,集中管理编译和链接选项。 -
通过
clean
规则,清理生成的文件。